26
26
import android .media .ImageReader ;
27
27
import android .os .Build ;
28
28
import android .view .DisplayCutout ;
29
+ import android .view .Surface ;
29
30
import android .view .View ;
30
31
import android .view .ViewGroup ;
31
32
import android .view .WindowInsets ;
@@ -270,10 +271,7 @@ public void setPaddingTopToZeroForFullscreenMode() {
270
271
271
272
// Verify.
272
273
verify (flutterRenderer , times (3 )).setViewportMetrics (viewportMetricsCaptor .capture ());
273
- assertEquals (100 , viewportMetricsCaptor .getValue ().viewPaddingTop );
274
- assertEquals (100 , viewportMetricsCaptor .getValue ().viewPaddingBottom );
275
- assertEquals (100 , viewportMetricsCaptor .getValue ().viewPaddingLeft );
276
- assertEquals (100 , viewportMetricsCaptor .getValue ().viewPaddingRight );
274
+ validateViewportMetricPadding (viewportMetricsCaptor , 100 , 100 , 100 , 100 );
277
275
}
278
276
279
277
// This test uses the pre-API 30 Algorithm for window insets.
@@ -303,18 +301,12 @@ public void setPaddingTopToZeroForFullscreenModeLegacy() {
303
301
304
302
// Then we simulate the system applying a window inset.
305
303
WindowInsets windowInsets = mock (WindowInsets .class );
306
- when (windowInsets .getSystemWindowInsetTop ()).thenReturn (100 );
307
- when (windowInsets .getSystemWindowInsetBottom ()).thenReturn (100 );
308
- when (windowInsets .getSystemWindowInsetLeft ()).thenReturn (100 );
309
- when (windowInsets .getSystemWindowInsetRight ()).thenReturn (100 );
304
+ mockSystemWindowInsets (windowInsets , 100 , 100 , 100 , 100 );
310
305
flutterView .onApplyWindowInsets (windowInsets );
311
306
312
307
// Verify.
313
308
verify (flutterRenderer , times (2 )).setViewportMetrics (viewportMetricsCaptor .capture ());
314
- assertEquals (0 , viewportMetricsCaptor .getValue ().viewPaddingTop );
315
- assertEquals (0 , viewportMetricsCaptor .getValue ().viewPaddingBottom );
316
- assertEquals (100 , viewportMetricsCaptor .getValue ().viewPaddingLeft );
317
- assertEquals (100 , viewportMetricsCaptor .getValue ().viewPaddingRight );
309
+ validateViewportMetricPadding (viewportMetricsCaptor , 100 , 0 , 100 , 0 );
318
310
}
319
311
320
312
// This test uses the API 30+ Algorithm for window insets. The legacy algorithm is
@@ -354,10 +346,7 @@ public void reportSystemInsetWhenNotFullscreen() {
354
346
// Verify.
355
347
verify (flutterRenderer , times (3 )).setViewportMetrics (viewportMetricsCaptor .capture ());
356
348
// Top padding is reported as-is.
357
- assertEquals (100 , viewportMetricsCaptor .getValue ().viewPaddingTop );
358
- assertEquals (100 , viewportMetricsCaptor .getValue ().viewPaddingBottom );
359
- assertEquals (100 , viewportMetricsCaptor .getValue ().viewPaddingLeft );
360
- assertEquals (100 , viewportMetricsCaptor .getValue ().viewPaddingRight );
349
+ validateViewportMetricPadding (viewportMetricsCaptor , 100 , 100 , 100 , 100 );
361
350
}
362
351
363
352
// This test uses the pre-API 30 Algorithm for window insets.
@@ -385,32 +374,21 @@ public void reportSystemInsetWhenNotFullscreenLegacy() {
385
374
386
375
// Then we simulate the system applying a window inset.
387
376
WindowInsets windowInsets = mock (WindowInsets .class );
388
- when (windowInsets .getSystemWindowInsetTop ()).thenReturn (100 );
389
- when (windowInsets .getSystemWindowInsetBottom ()).thenReturn (100 );
390
- when (windowInsets .getSystemWindowInsetLeft ()).thenReturn (100 );
391
- when (windowInsets .getSystemWindowInsetRight ()).thenReturn (100 );
377
+ mockSystemWindowInsets (windowInsets , 100 , 100 , 100 , 100 );
392
378
flutterView .onApplyWindowInsets (windowInsets );
393
379
394
380
// Verify.
395
381
verify (flutterRenderer , times (2 )).setViewportMetrics (viewportMetricsCaptor .capture ());
396
382
// Top padding is reported as-is.
397
- assertEquals (100 , viewportMetricsCaptor .getValue ().viewPaddingTop );
398
- assertEquals (0 , viewportMetricsCaptor .getValue ().viewPaddingBottom );
399
- assertEquals (100 , viewportMetricsCaptor .getValue ().viewPaddingLeft );
400
- assertEquals (100 , viewportMetricsCaptor .getValue ().viewPaddingRight );
383
+ validateViewportMetricPadding (viewportMetricsCaptor , 100 , 100 , 100 , 0 );
401
384
}
402
385
403
386
@ Test
404
387
@ Config (minSdk = 23 , maxSdk = 29 )
405
388
public void systemInsetHandlesFullscreenNavbarRight () {
406
389
RuntimeEnvironment .setQualifiers ("+land" );
407
390
FlutterView flutterView = spy (new FlutterView (RuntimeEnvironment .systemContext ));
408
- ShadowDisplay display =
409
- Shadows .shadowOf (
410
- ((WindowManager )
411
- RuntimeEnvironment .systemContext .getSystemService (Context .WINDOW_SERVICE ))
412
- .getDefaultDisplay ());
413
- display .setRotation (1 );
391
+ setExpectedDisplayRotation (Surface .ROTATION_90 );
414
392
assertEquals (0 , flutterView .getSystemUiVisibility ());
415
393
when (flutterView .getWindowSystemUiVisibility ())
416
394
.thenReturn (View .SYSTEM_UI_FLAG_FULLSCREEN | View .SYSTEM_UI_FLAG_HIDE_NAVIGATION );
@@ -431,37 +409,24 @@ public void systemInsetHandlesFullscreenNavbarRight() {
431
409
432
410
// Then we simulate the system applying a window inset.
433
411
WindowInsets windowInsets = mock (WindowInsets .class );
434
- when (windowInsets .getSystemWindowInsetTop ()).thenReturn (100 );
435
- when (windowInsets .getSystemWindowInsetBottom ()).thenReturn (100 );
436
- when (windowInsets .getSystemWindowInsetLeft ()).thenReturn (100 );
437
- when (windowInsets .getSystemWindowInsetRight ()).thenReturn (100 );
438
- if (Build .VERSION .SDK_INT == Build .VERSION_CODES .Q ) {
439
- when (windowInsets .getSystemGestureInsets ()).thenReturn (Insets .NONE );
440
- }
412
+ mockSystemWindowInsets (windowInsets , 100 , 100 , 100 , 100 );
413
+ mockSystemGestureInsetsIfNeed (windowInsets );
441
414
442
415
flutterView .onApplyWindowInsets (windowInsets );
443
416
444
417
verify (flutterRenderer , times (2 )).setViewportMetrics (viewportMetricsCaptor .capture ());
445
418
// Top padding is removed due to full screen.
446
- assertEquals (0 , viewportMetricsCaptor .getValue ().viewPaddingTop );
447
- // Bottom padding is removed due to hide navigation.
448
- assertEquals (0 , viewportMetricsCaptor .getValue ().viewPaddingBottom );
449
- assertEquals (100 , viewportMetricsCaptor .getValue ().viewPaddingLeft );
450
419
// Right padding is zero because the rotation is 90deg
451
- assertEquals (0 , viewportMetricsCaptor .getValue ().viewPaddingRight );
420
+ // Bottom padding is removed due to hide navigation.
421
+ validateViewportMetricPadding (viewportMetricsCaptor , 100 , 0 , 0 , 0 );
452
422
}
453
423
454
424
@ Test
455
425
@ Config (minSdk = 20 , maxSdk = 22 )
456
426
public void systemInsetHandlesFullscreenNavbarRightBelowSDK23 () {
457
427
RuntimeEnvironment .setQualifiers ("+land" );
458
428
FlutterView flutterView = spy (new FlutterView (RuntimeEnvironment .systemContext ));
459
- ShadowDisplay display =
460
- Shadows .shadowOf (
461
- ((WindowManager )
462
- RuntimeEnvironment .systemContext .getSystemService (Context .WINDOW_SERVICE ))
463
- .getDefaultDisplay ());
464
- display .setRotation (3 );
429
+ setExpectedDisplayRotation (Surface .ROTATION_270 );
465
430
assertEquals (0 , flutterView .getSystemUiVisibility ());
466
431
when (flutterView .getWindowSystemUiVisibility ())
467
432
.thenReturn (View .SYSTEM_UI_FLAG_FULLSCREEN | View .SYSTEM_UI_FLAG_HIDE_NAVIGATION );
@@ -482,37 +447,24 @@ public void systemInsetHandlesFullscreenNavbarRightBelowSDK23() {
482
447
483
448
// Then we simulate the system applying a window inset.
484
449
WindowInsets windowInsets = mock (WindowInsets .class );
485
- when (windowInsets .getSystemWindowInsetTop ()).thenReturn (100 );
486
- when (windowInsets .getSystemWindowInsetBottom ()).thenReturn (100 );
487
- when (windowInsets .getSystemWindowInsetLeft ()).thenReturn (100 );
488
- when (windowInsets .getSystemWindowInsetRight ()).thenReturn (100 );
489
- if (Build .VERSION .SDK_INT == Build .VERSION_CODES .Q ) {
490
- when (windowInsets .getSystemGestureInsets ()).thenReturn (Insets .NONE );
491
- }
450
+ mockSystemWindowInsets (windowInsets , 100 , 100 , 100 , 100 );
451
+ mockSystemGestureInsetsIfNeed (windowInsets );
492
452
493
453
flutterView .onApplyWindowInsets (windowInsets );
494
454
495
455
verify (flutterRenderer , times (2 )).setViewportMetrics (viewportMetricsCaptor .capture ());
496
456
// Top padding is removed due to full screen.
497
- assertEquals (0 , viewportMetricsCaptor .getValue ().viewPaddingTop );
498
- // Bottom padding is removed due to hide navigation.
499
- assertEquals (0 , viewportMetricsCaptor .getValue ().viewPaddingBottom );
500
457
// Right padding is zero because the rotation is 270deg under SDK 23
501
- assertEquals ( 0 , viewportMetricsCaptor . getValue (). viewPaddingRight );
502
- assertEquals ( 100 , viewportMetricsCaptor . getValue (). viewPaddingLeft );
458
+ // Bottom padding is removed due to hide navigation.
459
+ validateViewportMetricPadding ( viewportMetricsCaptor , 100 , 0 , 0 , 0 );
503
460
}
504
461
505
462
@ Test
506
463
@ Config (minSdk = 23 , maxSdk = 29 )
507
464
public void systemInsetHandlesFullscreenNavbarLeft () {
508
465
RuntimeEnvironment .setQualifiers ("+land" );
509
466
FlutterView flutterView = spy (new FlutterView (RuntimeEnvironment .systemContext ));
510
- ShadowDisplay display =
511
- Shadows .shadowOf (
512
- ((WindowManager )
513
- RuntimeEnvironment .systemContext .getSystemService (Context .WINDOW_SERVICE ))
514
- .getDefaultDisplay ());
515
- display .setRotation (3 );
467
+ setExpectedDisplayRotation (Surface .ROTATION_270 );
516
468
assertEquals (0 , flutterView .getSystemUiVisibility ());
517
469
when (flutterView .getWindowSystemUiVisibility ())
518
470
.thenReturn (View .SYSTEM_UI_FLAG_FULLSCREEN | View .SYSTEM_UI_FLAG_HIDE_NAVIGATION );
@@ -533,24 +485,16 @@ public void systemInsetHandlesFullscreenNavbarLeft() {
533
485
534
486
// Then we simulate the system applying a window inset.
535
487
WindowInsets windowInsets = mock (WindowInsets .class );
536
- when (windowInsets .getSystemWindowInsetTop ()).thenReturn (100 );
537
- when (windowInsets .getSystemWindowInsetBottom ()).thenReturn (100 );
538
- when (windowInsets .getSystemWindowInsetLeft ()).thenReturn (100 );
539
- when (windowInsets .getSystemWindowInsetRight ()).thenReturn (100 );
540
- if (Build .VERSION .SDK_INT == Build .VERSION_CODES .Q ) {
541
- when (windowInsets .getSystemGestureInsets ()).thenReturn (Insets .NONE );
542
- }
488
+ mockSystemWindowInsets (windowInsets , 100 , 100 , 100 , 100 );
489
+ mockSystemGestureInsetsIfNeed (windowInsets );
543
490
544
491
flutterView .onApplyWindowInsets (windowInsets );
545
492
546
493
verify (flutterRenderer , times (2 )).setViewportMetrics (viewportMetricsCaptor .capture ());
494
+ // Left padding is zero because the rotation is 270deg
547
495
// Top padding is removed due to full screen.
548
- assertEquals (0 , viewportMetricsCaptor .getValue ().viewPaddingTop );
549
496
// Bottom padding is removed due to hide navigation.
550
- assertEquals (0 , viewportMetricsCaptor .getValue ().viewPaddingBottom );
551
- // Left padding is zero because the rotation is 270deg
552
- assertEquals (0 , viewportMetricsCaptor .getValue ().viewPaddingLeft );
553
- assertEquals (100 , viewportMetricsCaptor .getValue ().viewPaddingRight );
497
+ validateViewportMetricPadding (viewportMetricsCaptor , 0 , 0 , 100 , 0 );
554
498
}
555
499
556
500
// This test uses the API 30+ Algorithm for window insets. The legacy algorithm is
@@ -561,12 +505,7 @@ public void systemInsetHandlesFullscreenNavbarLeft() {
561
505
public void systemInsetGetInsetsFullscreen () {
562
506
RuntimeEnvironment .setQualifiers ("+land" );
563
507
FlutterView flutterView = spy (new FlutterView (RuntimeEnvironment .systemContext ));
564
- ShadowDisplay display =
565
- Shadows .shadowOf (
566
- ((WindowManager )
567
- RuntimeEnvironment .systemContext .getSystemService (Context .WINDOW_SERVICE ))
568
- .getDefaultDisplay ());
569
- display .setRotation (3 );
508
+ setExpectedDisplayRotation (Surface .ROTATION_270 );
570
509
assertEquals (0 , flutterView .getSystemUiVisibility ());
571
510
when (flutterView .getWindowSystemUiVisibility ())
572
511
.thenReturn (View .SYSTEM_UI_FLAG_FULLSCREEN | View .SYSTEM_UI_FLAG_HIDE_NAVIGATION );
@@ -588,19 +527,13 @@ public void systemInsetGetInsetsFullscreen() {
588
527
Insets insets = Insets .of (10 , 20 , 30 , 40 );
589
528
// Then we simulate the system applying a window inset.
590
529
WindowInsets windowInsets = mock (WindowInsets .class );
591
- when (windowInsets .getSystemWindowInsetTop ()).thenReturn (-1 );
592
- when (windowInsets .getSystemWindowInsetBottom ()).thenReturn (-1 );
593
- when (windowInsets .getSystemWindowInsetLeft ()).thenReturn (-1 );
594
- when (windowInsets .getSystemWindowInsetRight ()).thenReturn (-1 );
530
+ mockSystemWindowInsets (windowInsets , -1 , -1 , -1 , -1 );
595
531
when (windowInsets .getInsets (anyInt ())).thenReturn (insets );
596
532
597
533
flutterView .onApplyWindowInsets (windowInsets );
598
534
599
535
verify (flutterRenderer , times (2 )).setViewportMetrics (viewportMetricsCaptor .capture ());
600
- assertEquals (10 , viewportMetricsCaptor .getValue ().viewPaddingLeft );
601
- assertEquals (20 , viewportMetricsCaptor .getValue ().viewPaddingTop );
602
- assertEquals (30 , viewportMetricsCaptor .getValue ().viewPaddingRight );
603
- assertEquals (40 , viewportMetricsCaptor .getValue ().viewPaddingBottom );
536
+ validateViewportMetricPadding (viewportMetricsCaptor , 10 , 20 , 30 , 40 );
604
537
}
605
538
606
539
// This test uses the pre-API 30 Algorithm for window insets.
@@ -610,12 +543,7 @@ public void systemInsetGetInsetsFullscreen() {
610
543
public void systemInsetGetInsetsFullscreenLegacy () {
611
544
RuntimeEnvironment .setQualifiers ("+land" );
612
545
FlutterView flutterView = spy (new FlutterView (RuntimeEnvironment .systemContext ));
613
- ShadowDisplay display =
614
- Shadows .shadowOf (
615
- ((WindowManager )
616
- RuntimeEnvironment .systemContext .getSystemService (Context .WINDOW_SERVICE ))
617
- .getDefaultDisplay ());
618
- display .setRotation (3 );
546
+ setExpectedDisplayRotation (Surface .ROTATION_270 );
619
547
assertEquals (0 , flutterView .getSystemUiVisibility ());
620
548
when (flutterView .getWindowSystemUiVisibility ())
621
549
.thenReturn (View .SYSTEM_UI_FLAG_FULLSCREEN | View .SYSTEM_UI_FLAG_HIDE_NAVIGATION );
@@ -636,21 +564,15 @@ public void systemInsetGetInsetsFullscreenLegacy() {
636
564
637
565
// Then we simulate the system applying a window inset.
638
566
WindowInsets windowInsets = mock (WindowInsets .class );
639
- when (windowInsets .getSystemWindowInsetTop ()).thenReturn (100 );
640
- when (windowInsets .getSystemWindowInsetBottom ()).thenReturn (101 );
641
- when (windowInsets .getSystemWindowInsetLeft ()).thenReturn (102 );
642
- when (windowInsets .getSystemWindowInsetRight ()).thenReturn (103 );
567
+ mockSystemWindowInsets (windowInsets , 102 , 100 , 103 , 101 );
643
568
644
569
flutterView .onApplyWindowInsets (windowInsets );
645
570
646
571
verify (flutterRenderer , times (2 )).setViewportMetrics (viewportMetricsCaptor .capture ());
572
+ // Left padding is zero because the rotation is 270deg
647
573
// Top padding is removed due to full screen.
648
- assertEquals (0 , viewportMetricsCaptor .getValue ().viewPaddingTop );
649
574
// Bottom padding is removed due to hide navigation.
650
- assertEquals (0 , viewportMetricsCaptor .getValue ().viewPaddingBottom );
651
- // Left padding is zero because the rotation is 270deg
652
- assertEquals (0 , viewportMetricsCaptor .getValue ().viewPaddingLeft );
653
- assertEquals (103 , viewportMetricsCaptor .getValue ().viewPaddingRight );
575
+ validateViewportMetricPadding (viewportMetricsCaptor , 0 , 0 , 103 , 0 );
654
576
}
655
577
656
578
// This test uses the API 30+ Algorithm for window insets. The legacy algorithm is
@@ -661,11 +583,6 @@ public void systemInsetGetInsetsFullscreenLegacy() {
661
583
public void systemInsetDisplayCutoutSimple () {
662
584
RuntimeEnvironment .setQualifiers ("+land" );
663
585
FlutterView flutterView = spy (new FlutterView (RuntimeEnvironment .systemContext ));
664
- ShadowDisplay display =
665
- Shadows .shadowOf (
666
- ((WindowManager )
667
- RuntimeEnvironment .systemContext .getSystemService (Context .WINDOW_SERVICE ))
668
- .getDefaultDisplay ());
669
586
assertEquals (0 , flutterView .getSystemUiVisibility ());
670
587
when (flutterView .getWindowSystemUiVisibility ()).thenReturn (0 );
671
588
when (flutterView .getContext ()).thenReturn (RuntimeEnvironment .systemContext );
@@ -688,10 +605,7 @@ public void systemInsetDisplayCutoutSimple() {
688
605
// Then we simulate the system applying a window inset.
689
606
WindowInsets windowInsets = mock (WindowInsets .class );
690
607
DisplayCutout displayCutout = mock (DisplayCutout .class );
691
- when (windowInsets .getSystemWindowInsetTop ()).thenReturn (-1 );
692
- when (windowInsets .getSystemWindowInsetBottom ()).thenReturn (-1 );
693
- when (windowInsets .getSystemWindowInsetLeft ()).thenReturn (-1 );
694
- when (windowInsets .getSystemWindowInsetRight ()).thenReturn (-1 );
608
+ mockSystemWindowInsets (windowInsets , -1 , -1 , -1 , -1 );
695
609
when (windowInsets .getInsets (anyInt ())).thenReturn (insets );
696
610
when (windowInsets .getSystemGestureInsets ()).thenReturn (systemGestureInsets );
697
611
when (windowInsets .getDisplayCutout ()).thenReturn (displayCutout );
@@ -706,10 +620,7 @@ public void systemInsetDisplayCutoutSimple() {
706
620
flutterView .onApplyWindowInsets (windowInsets );
707
621
708
622
verify (flutterRenderer , times (2 )).setViewportMetrics (viewportMetricsCaptor .capture ());
709
- assertEquals (150 , viewportMetricsCaptor .getValue ().viewPaddingTop );
710
- assertEquals (150 , viewportMetricsCaptor .getValue ().viewPaddingBottom );
711
- assertEquals (200 , viewportMetricsCaptor .getValue ().viewPaddingLeft );
712
- assertEquals (200 , viewportMetricsCaptor .getValue ().viewPaddingRight );
623
+ validateViewportMetricPadding (viewportMetricsCaptor , 200 , 150 , 200 , 150 );
713
624
714
625
assertEquals (100 , viewportMetricsCaptor .getValue ().viewInsetTop );
715
626
}
@@ -913,6 +824,41 @@ public void ViewportMetrics_initializedPhysicalTouchSlop() {
913
824
assertFalse (-1 == viewportMetricsCaptor .getValue ().physicalTouchSlop );
914
825
}
915
826
827
+ private void setExpectedDisplayRotation (int rotation ) {
828
+ ShadowDisplay display =
829
+ Shadows .shadowOf (
830
+ ((WindowManager )
831
+ RuntimeEnvironment .systemContext .getSystemService (Context .WINDOW_SERVICE ))
832
+ .getDefaultDisplay ());
833
+ display .setRotation (rotation );
834
+ }
835
+
836
+ private void validateViewportMetricPadding (
837
+ ArgumentCaptor <FlutterRenderer .ViewportMetrics > viewportMetricsCaptor ,
838
+ int left ,
839
+ int top ,
840
+ int right ,
841
+ int bottom ) {
842
+ assertEquals (left , viewportMetricsCaptor .getValue ().viewPaddingLeft );
843
+ assertEquals (top , viewportMetricsCaptor .getValue ().viewPaddingTop );
844
+ assertEquals (right , viewportMetricsCaptor .getValue ().viewPaddingRight );
845
+ assertEquals (bottom , viewportMetricsCaptor .getValue ().viewPaddingBottom );
846
+ }
847
+
848
+ private void mockSystemWindowInsets (
849
+ WindowInsets windowInsets , int left , int top , int right , int bottom ) {
850
+ when (windowInsets .getSystemWindowInsetLeft ()).thenReturn (left );
851
+ when (windowInsets .getSystemWindowInsetTop ()).thenReturn (top );
852
+ when (windowInsets .getSystemWindowInsetRight ()).thenReturn (right );
853
+ when (windowInsets .getSystemWindowInsetBottom ()).thenReturn (bottom );
854
+ }
855
+
856
+ private void mockSystemGestureInsetsIfNeed (WindowInsets windowInsets ) {
857
+ if (Build .VERSION .SDK_INT == Build .VERSION_CODES .Q ) {
858
+ when (windowInsets .getSystemGestureInsets ()).thenReturn (Insets .NONE );
859
+ }
860
+ }
861
+
916
862
/*
917
863
* A custom shadow that reports fullscreen flag for system UI visibility
918
864
*/
0 commit comments