|
21 | 21 | import android.util.AttributeSet;
|
22 | 22 | import android.util.Log;
|
23 | 23 | import android.util.SparseArray;
|
| 24 | +import android.view.DisplayCutout; |
24 | 25 | import android.view.KeyEvent;
|
25 | 26 | import android.view.MotionEvent;
|
26 | 27 | import android.view.PointerIcon;
|
@@ -588,47 +589,100 @@ private int guessBottomKeyboardInset(WindowInsets insets) {
|
588 | 589 | @RequiresApi(20)
|
589 | 590 | @SuppressLint({"InlinedApi", "NewApi"})
|
590 | 591 | public final WindowInsets onApplyWindowInsets(WindowInsets insets) {
|
591 |
| - boolean statusBarHidden = (SYSTEM_UI_FLAG_FULLSCREEN & getWindowSystemUiVisibility()) != 0; |
592 |
| - boolean navigationBarHidden = |
593 |
| - (SYSTEM_UI_FLAG_HIDE_NAVIGATION & getWindowSystemUiVisibility()) != 0; |
594 |
| - |
595 |
| - // We zero the left and/or right sides to prevent the padding the |
596 |
| - // navigation bar would have caused. |
597 |
| - ZeroSides zeroSides = ZeroSides.NONE; |
598 |
| - if (navigationBarHidden) { |
599 |
| - zeroSides = calculateShouldZeroSides(); |
| 592 | + // getSystemGestureInsets() was introduced in API 29 and immediately deprecated in 30. |
| 593 | + if (Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) { |
| 594 | + Insets systemGestureInsets = insets.getSystemGestureInsets(); |
| 595 | + mMetrics.systemGestureInsetTop = systemGestureInsets.top; |
| 596 | + mMetrics.systemGestureInsetRight = systemGestureInsets.right; |
| 597 | + mMetrics.systemGestureInsetBottom = systemGestureInsets.bottom; |
| 598 | + mMetrics.systemGestureInsetLeft = systemGestureInsets.left; |
600 | 599 | }
|
601 | 600 |
|
602 |
| - // The padding on top should be removed when the statusbar is hidden. |
603 |
| - mMetrics.physicalPaddingTop = statusBarHidden ? 0 : insets.getSystemWindowInsetTop(); |
604 |
| - mMetrics.physicalPaddingRight = |
605 |
| - zeroSides == ZeroSides.RIGHT || zeroSides == ZeroSides.BOTH |
606 |
| - ? 0 |
607 |
| - : insets.getSystemWindowInsetRight(); |
608 |
| - mMetrics.physicalPaddingBottom = 0; |
609 |
| - mMetrics.physicalPaddingLeft = |
610 |
| - zeroSides == ZeroSides.LEFT || zeroSides == ZeroSides.BOTH |
611 |
| - ? 0 |
612 |
| - : insets.getSystemWindowInsetLeft(); |
613 |
| - |
614 |
| - // Bottom system inset (keyboard) should adjust scrollable bottom edge (inset). |
615 |
| - mMetrics.physicalViewInsetTop = 0; |
616 |
| - mMetrics.physicalViewInsetRight = 0; |
617 |
| - // We perform hidden navbar and keyboard handling if the navbar is set to hidden. Otherwise, |
618 |
| - // the navbar padding should always be provided. |
619 |
| - mMetrics.physicalViewInsetBottom = |
620 |
| - navigationBarHidden |
621 |
| - ? guessBottomKeyboardInset(insets) |
622 |
| - : insets.getSystemWindowInsetBottom(); |
623 |
| - mMetrics.physicalViewInsetLeft = 0; |
624 |
| - |
625 |
| - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { |
626 |
| - Insets systemGestureInsets = insets.getSystemGestureInsets(); |
| 601 | + boolean statusBarVisible = (SYSTEM_UI_FLAG_FULLSCREEN & getWindowSystemUiVisibility()) == 0; |
| 602 | + boolean navigationBarVisible = |
| 603 | + (SYSTEM_UI_FLAG_HIDE_NAVIGATION & getWindowSystemUiVisibility()) == 0; |
| 604 | + |
| 605 | + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { |
| 606 | + int mask = 0; |
| 607 | + if (navigationBarVisible) { |
| 608 | + mask = mask | android.view.WindowInsets.Type.navigationBars(); |
| 609 | + } |
| 610 | + if (statusBarVisible) { |
| 611 | + mask = mask | android.view.WindowInsets.Type.statusBars(); |
| 612 | + } |
| 613 | + Insets uiInsets = insets.getInsets(mask); |
| 614 | + mMetrics.physicalPaddingTop = uiInsets.top; |
| 615 | + mMetrics.physicalPaddingRight = uiInsets.right; |
| 616 | + mMetrics.physicalPaddingBottom = uiInsets.bottom; |
| 617 | + mMetrics.physicalPaddingLeft = uiInsets.left; |
| 618 | + |
| 619 | + Insets imeInsets = insets.getInsets(android.view.WindowInsets.Type.ime()); |
| 620 | + mMetrics.physicalViewInsetTop = imeInsets.top; |
| 621 | + mMetrics.physicalViewInsetRight = imeInsets.right; |
| 622 | + mMetrics.physicalViewInsetBottom = imeInsets.bottom; // Typically, only bottom is non-zero |
| 623 | + mMetrics.physicalViewInsetLeft = imeInsets.left; |
| 624 | + |
| 625 | + Insets systemGestureInsets = |
| 626 | + insets.getInsets(android.view.WindowInsets.Type.systemGestures()); |
627 | 627 | mMetrics.systemGestureInsetTop = systemGestureInsets.top;
|
628 | 628 | mMetrics.systemGestureInsetRight = systemGestureInsets.right;
|
629 | 629 | mMetrics.systemGestureInsetBottom = systemGestureInsets.bottom;
|
630 | 630 | mMetrics.systemGestureInsetLeft = systemGestureInsets.left;
|
| 631 | + |
| 632 | + // TODO(garyq): Expose the full rects of the display cutout. |
| 633 | + |
| 634 | + // Take the max of the display cutout insets and existing padding to merge them |
| 635 | + DisplayCutout cutout = insets.getDisplayCutout(); |
| 636 | + if (cutout != null) { |
| 637 | + Insets waterfallInsets = cutout.getWaterfallInsets(); |
| 638 | + mMetrics.physicalPaddingTop = |
| 639 | + Math.max( |
| 640 | + Math.max(mMetrics.physicalPaddingTop, waterfallInsets.top), |
| 641 | + cutout.getSafeInsetTop()); |
| 642 | + mMetrics.physicalPaddingRight = |
| 643 | + Math.max( |
| 644 | + Math.max(mMetrics.physicalPaddingRight, waterfallInsets.right), |
| 645 | + cutout.getSafeInsetRight()); |
| 646 | + mMetrics.physicalPaddingBottom = |
| 647 | + Math.max( |
| 648 | + Math.max(mMetrics.physicalPaddingBottom, waterfallInsets.bottom), |
| 649 | + cutout.getSafeInsetBottom()); |
| 650 | + mMetrics.physicalPaddingLeft = |
| 651 | + Math.max( |
| 652 | + Math.max(mMetrics.physicalPaddingLeft, waterfallInsets.left), |
| 653 | + cutout.getSafeInsetLeft()); |
| 654 | + } |
| 655 | + } else { |
| 656 | + // We zero the left and/or right sides to prevent the padding the |
| 657 | + // navigation bar would have caused. |
| 658 | + ZeroSides zeroSides = ZeroSides.NONE; |
| 659 | + if (!navigationBarVisible) { |
| 660 | + zeroSides = calculateShouldZeroSides(); |
| 661 | + } |
| 662 | + |
| 663 | + // Status bar (top) and left/right system insets should partially obscure the content |
| 664 | + // (padding). |
| 665 | + mMetrics.physicalPaddingTop = statusBarVisible ? insets.getSystemWindowInsetTop() : 0; |
| 666 | + mMetrics.physicalPaddingRight = |
| 667 | + zeroSides == ZeroSides.RIGHT || zeroSides == ZeroSides.BOTH |
| 668 | + ? 0 |
| 669 | + : insets.getSystemWindowInsetRight(); |
| 670 | + mMetrics.physicalPaddingBottom = 0; |
| 671 | + mMetrics.physicalPaddingLeft = |
| 672 | + zeroSides == ZeroSides.LEFT || zeroSides == ZeroSides.BOTH |
| 673 | + ? 0 |
| 674 | + : insets.getSystemWindowInsetLeft(); |
| 675 | + |
| 676 | + // Bottom system inset (keyboard) should adjust scrollable bottom edge (inset). |
| 677 | + mMetrics.physicalViewInsetTop = 0; |
| 678 | + mMetrics.physicalViewInsetRight = 0; |
| 679 | + mMetrics.physicalViewInsetBottom = |
| 680 | + navigationBarVisible |
| 681 | + ? insets.getSystemWindowInsetBottom() |
| 682 | + : guessBottomKeyboardInset(insets); |
| 683 | + mMetrics.physicalViewInsetLeft = 0; |
631 | 684 | }
|
| 685 | + |
632 | 686 | updateViewportMetrics();
|
633 | 687 | return super.onApplyWindowInsets(insets);
|
634 | 688 | }
|
|
0 commit comments