diff options
| author | 2021-09-22 06:01:42 +0000 | |
|---|---|---|
| committer | 2021-09-22 06:01:42 +0000 | |
| commit | 5996de34d228dceae5dcc2a9b44ccdfdcc37eb2e (patch) | |
| tree | c330205bfe3b255d62c98a71fe851b7cb102d2b4 | |
| parent | 11f14b1e2e33d301a2289c0c2519ede88779445b (diff) | |
| parent | 809296282af47ad5d9d422b5a1ce7d29677d15a5 (diff) | |
Merge changes I27530b15,Ic5d88cf3 into sc-v2-dev
* changes:
Fixing the a11y floating menu could overlap the keyboard when rotated in a foldable device.
Fixing the a11y floating menu could overlap the taskbar in a foldable device.
5 files changed, 129 insertions, 57 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java index 17818cd9c7ee..59d9aff2ef46 100644 --- a/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java +++ b/packages/SystemUI/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuView.java @@ -19,8 +19,9 @@ package com.android.systemui.accessibility.floatingmenu; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.util.MathUtils.constrain; import static android.util.MathUtils.sq; +import static android.view.WindowInsets.Type.displayCutout; import static android.view.WindowInsets.Type.ime; -import static android.view.WindowInsets.Type.navigationBars; +import static android.view.WindowInsets.Type.systemBars; import static java.util.Objects.requireNonNull; @@ -41,7 +42,6 @@ import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.LayerDrawable; import android.os.Handler; import android.os.Looper; -import android.util.DisplayMetrics; import android.view.Gravity; import android.view.MotionEvent; import android.view.ViewConfiguration; @@ -95,7 +95,6 @@ public class AccessibilityFloatingMenuView extends FrameLayout private boolean mIsShowing; private boolean mIsDownInEnlargedTouchArea; private boolean mIsDragging = false; - private boolean mImeVisibility; @Alignment private int mAlignment; @SizeType @@ -108,8 +107,10 @@ public class AccessibilityFloatingMenuView extends FrameLayout private int mRadiusType; private int mMargin; private int mPadding; - private int mScreenHeight; - private int mScreenWidth; + // The display width excludes the window insets of the system bar and display cutout. + private int mDisplayHeight; + // The display Height excludes the window insets of the system bar and display cutout. + private int mDisplayWidth; private int mIconWidth; private int mIconHeight; private int mInset; @@ -118,6 +119,8 @@ public class AccessibilityFloatingMenuView extends FrameLayout private int mRelativeToPointerDownX; private int mRelativeToPointerDownY; private float mRadius; + private final Rect mDisplayInsetsRect = new Rect(); + private final Rect mImeInsetsRect = new Rect(); private final Position mPosition; private float mSquareScaledTouchSlop; private final Configuration mLastConfiguration; @@ -506,9 +509,21 @@ public class AccessibilityFloatingMenuView extends FrameLayout } private WindowInsets onWindowInsetsApplied(WindowInsets insets) { - final boolean currentImeVisibility = insets.isVisible(ime()); - if (currentImeVisibility != mImeVisibility) { - mImeVisibility = currentImeVisibility; + final WindowMetrics windowMetrics = mWindowManager.getCurrentWindowMetrics(); + final Rect displayWindowInsetsRect = getDisplayInsets(windowMetrics).toRect(); + if (!displayWindowInsetsRect.equals(mDisplayInsetsRect)) { + updateDisplaySizeWith(windowMetrics); + updateLocationWith(mPosition); + } + + final Rect imeInsetsRect = windowMetrics.getWindowInsets().getInsets(ime()).toRect(); + if (!imeInsetsRect.equals(mImeInsetsRect)) { + if (isImeVisible(imeInsetsRect)) { + mImeInsetsRect.set(imeInsetsRect); + } else { + mImeInsetsRect.setEmpty(); + } + updateLocationWith(mPosition); } @@ -520,6 +535,11 @@ public class AccessibilityFloatingMenuView extends FrameLayout || (side == Alignment.LEFT && downX > currentRawX); } + private boolean isImeVisible(Rect imeInsetsRect) { + return imeInsetsRect.left != 0 || imeInsetsRect.top != 0 || imeInsetsRect.right != 0 + || imeInsetsRect.bottom != 0; + } + private boolean hasExceededTouchSlop(int startX, int startY, int endX, int endY) { return (sq(endX - startX) + sq(endY - startY)) > mSquareScaledTouchSlop; } @@ -546,9 +566,9 @@ public class AccessibilityFloatingMenuView extends FrameLayout private void updateDimensions() { final Resources res = getResources(); - final DisplayMetrics dm = res.getDisplayMetrics(); - mScreenWidth = dm.widthPixels; - mScreenHeight = dm.heightPixels; + + updateDisplaySizeWith(mWindowManager.getCurrentWindowMetrics()); + mMargin = res.getDimensionPixelSize(R.dimen.accessibility_floating_menu_margin); mInset = @@ -560,6 +580,15 @@ public class AccessibilityFloatingMenuView extends FrameLayout updateItemViewDimensionsWith(mSizeType); } + private void updateDisplaySizeWith(WindowMetrics metrics) { + final Rect displayBounds = metrics.getBounds(); + final Insets displayInsets = getDisplayInsets(metrics); + mDisplayInsetsRect.set(displayInsets.toRect()); + displayBounds.inset(displayInsets); + mDisplayWidth = displayBounds.width(); + mDisplayHeight = displayBounds.height(); + } + private void updateItemViewDimensionsWith(@SizeType int sizeType) { final Resources res = getResources(); final int paddingResId = @@ -684,11 +713,11 @@ public class AccessibilityFloatingMenuView extends FrameLayout } private int getMaxWindowX() { - return mScreenWidth - getMarginStartEndWith(mLastConfiguration) - getLayoutWidth(); + return mDisplayWidth - getMarginStartEndWith(mLastConfiguration) - getLayoutWidth(); } private int getMaxWindowY() { - return mScreenHeight - getWindowHeight(); + return mDisplayHeight - getWindowHeight(); } private InstantInsetLayerDrawable getMenuLayerDrawable() { @@ -699,8 +728,13 @@ public class AccessibilityFloatingMenuView extends FrameLayout return (GradientDrawable) getMenuLayerDrawable().getDrawable(INDEX_MENU_ITEM); } + private Insets getDisplayInsets(WindowMetrics metrics) { + return metrics.getWindowInsets().getInsetsIgnoringVisibility( + systemBars() | displayCutout()); + } + /** - * Updates the floating menu to be fixed at the side of the screen. + * Updates the floating menu to be fixed at the side of the display. */ private void updateLocationWith(Position position) { final @Alignment int alignment = transformToAlignment(position.getPercentageX()); @@ -716,15 +750,9 @@ public class AccessibilityFloatingMenuView extends FrameLayout * @return the moving interval if they overlap each other, otherwise 0. */ private int getInterval() { - if (!mImeVisibility) { - return 0; - } - - final WindowMetrics windowMetrics = mWindowManager.getCurrentWindowMetrics(); - final Insets imeInsets = windowMetrics.getWindowInsets().getInsets( - ime() | navigationBars()); - final int imeY = mScreenHeight - imeInsets.bottom; - final int layoutBottomY = mCurrentLayoutParams.y + getWindowHeight(); + final int currentLayoutY = (int) (mPosition.getPercentageY() * getMaxWindowY()); + final int imeY = mDisplayHeight - mImeInsetsRect.bottom; + final int layoutBottomY = currentLayoutY + getWindowHeight(); return layoutBottomY > imeY ? (layoutBottomY - imeY) : 0; } @@ -855,11 +883,12 @@ public class AccessibilityFloatingMenuView extends FrameLayout @VisibleForTesting Rect getAvailableBounds() { - return new Rect(0, 0, mScreenWidth - getWindowWidth(), mScreenHeight - getWindowHeight()); + return new Rect(0, 0, mDisplayWidth - getWindowWidth(), + mDisplayHeight - getWindowHeight()); } private int getMaxLayoutHeight() { - return mScreenHeight - mMargin * 2; + return mDisplayHeight - mMargin * 2; } private int getLayoutWidth() { @@ -875,7 +904,7 @@ public class AccessibilityFloatingMenuView extends FrameLayout } private int getWindowHeight() { - return Math.min(mScreenHeight, mMargin * 2 + getLayoutHeight()); + return Math.min(mDisplayHeight, mMargin * 2 + getLayoutHeight()); } private void setSystemGestureExclusion() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java index f09d7b78ea6f..7e9f84c1ef8c 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/AccessibilityFloatingMenuViewTest.java @@ -19,8 +19,9 @@ package com.android.systemui.accessibility.floatingmenu; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.view.View.OVER_SCROLL_ALWAYS; import static android.view.View.OVER_SCROLL_NEVER; +import static android.view.WindowInsets.Type.displayCutout; import static android.view.WindowInsets.Type.ime; -import static android.view.WindowInsets.Type.navigationBars; +import static android.view.WindowInsets.Type.systemBars; import static com.google.common.truth.Truth.assertThat; @@ -39,6 +40,7 @@ import static org.mockito.Mockito.when; import android.content.Context; import android.content.res.Resources; import android.graphics.Insets; +import android.graphics.Rect; import android.graphics.drawable.GradientDrawable; import android.graphics.drawable.LayerDrawable; import android.testing.AndroidTestingRunner; @@ -98,14 +100,15 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase { private AccessibilityFloatingMenuView mMenuView; private RecyclerView mListView = new RecyclerView(mContext); - private int mScreenHeight; private int mMenuWindowHeight; private int mMenuHalfWidth; private int mMenuHalfHeight; - private int mScreenHalfWidth; - private int mScreenHalfHeight; + private int mDisplayHalfWidth; + private int mDisplayHalfHeight; private int mMaxWindowX; private int mMaxWindowY; + private final int mDisplayWindowWidth = 1080; + private final int mDisplayWindowHeight = 2340; @Before public void initMenuView() { @@ -113,7 +116,10 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase { doAnswer(invocation -> wm.getMaximumWindowMetrics()).when( mWindowManager).getMaximumWindowMetrics(); mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager); - + when(mWindowManager.getCurrentWindowMetrics()).thenReturn(mWindowMetrics); + when(mWindowMetrics.getBounds()).thenReturn(new Rect(0, 0, mDisplayWindowWidth, + mDisplayWindowHeight)); + when(mWindowMetrics.getWindowInsets()).thenReturn(fakeDisplayInsets()); mMenuView = spy( new AccessibilityFloatingMenuView(mContext, mPlaceholderPosition, mListView)); } @@ -129,18 +135,16 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase { res.getDimensionPixelSize(R.dimen.accessibility_floating_menu_small_width_height); final int menuWidth = padding * 2 + iconWidthHeight; final int menuHeight = (padding + iconWidthHeight) * mTargets.size() + padding; - final int screenWidth = mContext.getResources().getDisplayMetrics().widthPixels; - mScreenHeight = mContext.getResources().getDisplayMetrics().heightPixels; mMenuHalfWidth = menuWidth / 2; mMenuHalfHeight = menuHeight / 2; - mScreenHalfWidth = screenWidth / 2; - mScreenHalfHeight = mScreenHeight / 2; + mDisplayHalfWidth = mDisplayWindowWidth / 2; + mDisplayHalfHeight = mDisplayWindowHeight / 2; int marginStartEnd = mContext.getResources().getConfiguration().orientation == ORIENTATION_PORTRAIT ? margin : 0; - mMaxWindowX = screenWidth - marginStartEnd - menuWidth; + mMaxWindowX = mDisplayWindowWidth - marginStartEnd - menuWidth; mMenuWindowHeight = menuHeight + margin * 2; - mMaxWindowY = mScreenHeight - mMenuWindowHeight; + mMaxWindowY = mDisplayWindowHeight - mMenuWindowHeight; } @Test @@ -279,15 +283,15 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase { final MotionEvent moveEvent = mMotionEventHelper.obtainMotionEvent(2, 3, MotionEvent.ACTION_MOVE, - /* screenCenterX */mScreenHalfWidth - - /* offsetXToScreenLeftHalfRegion */ 10, - /* screenCenterY */ mScreenHalfHeight); + /* displayCenterX */mDisplayHalfWidth + - /* offsetXToDisplayLeftHalfRegion */ 10, + /* displayCenterY */ mDisplayHalfHeight); final MotionEvent upEvent = mMotionEventHelper.obtainMotionEvent(4, 5, MotionEvent.ACTION_UP, - /* screenCenterX */ mScreenHalfWidth - - /* offsetXToScreenLeftHalfRegion */ 10, - /* screenCenterY */ mScreenHalfHeight); + /* displayCenterX */ mDisplayHalfWidth + - /* offsetXToDisplayLeftHalfRegion */ 10, + /* displayCenterY */ mDisplayHalfHeight); listView.dispatchTouchEvent(downEvent); listView.dispatchTouchEvent(moveEvent); @@ -315,15 +319,15 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase { final MotionEvent moveEvent = mMotionEventHelper.obtainMotionEvent(2, 3, MotionEvent.ACTION_MOVE, - /* screenCenterX */mScreenHalfWidth - + /* offsetXToScreenRightHalfRegion */ 10, - /* screenCenterY */ mScreenHalfHeight); + /* displayCenterX */mDisplayHalfWidth + + /* offsetXToDisplayRightHalfRegion */ 10, + /* displayCenterY */ mDisplayHalfHeight); final MotionEvent upEvent = mMotionEventHelper.obtainMotionEvent(4, 5, MotionEvent.ACTION_UP, - /* screenCenterX */ mScreenHalfWidth - + /* offsetXToScreenRightHalfRegion */ 10, - /* screenCenterY */ mScreenHalfHeight); + /* displayCenterX */ mDisplayHalfWidth + + /* offsetXToDisplayRightHalfRegion */ 10, + /* displayCenterY */ mDisplayHalfHeight); listView.dispatchTouchEvent(downEvent); listView.dispatchTouchEvent(moveEvent); @@ -332,12 +336,12 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase { assertThat((float) menuView.mCurrentLayoutParams.x).isWithin(1.0f).of(mMaxWindowX); assertThat((float) menuView.mCurrentLayoutParams.y).isWithin(1.0f).of( - /* newWindowY = screenCenterY - offsetY */ mScreenHalfHeight - mMenuHalfHeight); + /* newWindowY = displayCenterY - offsetY */ mDisplayHalfHeight - mMenuHalfHeight); } @Test - public void tapOnAndDragMenuToScreenSide_transformShapeHalfOval() { + public void tapOnAndDragMenuToDisplaySide_transformShapeHalfOval() { final Position alignRightPosition = new Position(1.0f, 0.8f); final RecyclerView listView = new RecyclerView(mContext); final AccessibilityFloatingMenuView menuView = new AccessibilityFloatingMenuView(mContext, @@ -355,13 +359,13 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase { mMotionEventHelper.obtainMotionEvent(2, 3, MotionEvent.ACTION_MOVE, /* downX */(currentWindowX + mMenuHalfWidth) - + /* offsetXToScreenRightSide */ mMenuHalfWidth, + + /* offsetXToDisplayRightSide */ mMenuHalfWidth, /* downY */ (currentWindowY + mMenuHalfHeight)); final MotionEvent upEvent = mMotionEventHelper.obtainMotionEvent(4, 5, MotionEvent.ACTION_UP, /* downX */(currentWindowX + mMenuHalfWidth) - + /* offsetXToScreenRightSide */ mMenuHalfWidth, + + /* offsetXToDisplayRightSide */ mMenuHalfWidth, /* downY */ (currentWindowY + mMenuHalfHeight)); listView.dispatchTouchEvent(downEvent); @@ -423,7 +427,7 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase { } @Test - public void showMenuAndIme_withHigherIme_alignScreenTopEdge() { + public void showMenuAndIme_withHigherIme_alignDisplayTopEdge() { final int offset = 99999; setupBasicMenuView(mMenuView); @@ -475,10 +479,21 @@ public class AccessibilityFloatingMenuViewTest extends SysuiTestCase { private WindowInsets fakeImeInsetWith(AccessibilityFloatingMenuView menuView, int offset) { // Ensure the keyboard has overlapped on the menu view. final int fakeImeHeight = - mScreenHeight - (menuView.mCurrentLayoutParams.y + mMenuWindowHeight) + offset; + mDisplayWindowHeight - (menuView.mCurrentLayoutParams.y + mMenuWindowHeight) + + offset; + return new WindowInsets.Builder() + .setVisible(ime(), true) + .setInsets(ime(), Insets.of(0, 0, 0, fakeImeHeight)) + .build(); + } + + private WindowInsets fakeDisplayInsets() { + final int fakeStatusBarHeight = 75; + final int fakeNavigationBarHeight = 125; return new WindowInsets.Builder() - .setVisible(ime() | navigationBars(), true) - .setInsets(ime() | navigationBars(), Insets.of(0, 0, 0, fakeImeHeight)) + .setVisible(systemBars() | displayCutout(), true) + .setInsets(systemBars() | displayCutout(), + Insets.of(0, fakeStatusBarHeight, 0, fakeNavigationBarHeight)) .build(); } diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipViewTest.java index eb1f15b30d6f..3553a0adce27 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/BaseTooltipViewTest.java @@ -23,12 +23,16 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import android.content.Context; +import android.graphics.Rect; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.MotionEvent; +import android.view.WindowInsets; import android.view.WindowManager; +import android.view.WindowMetrics; import android.view.accessibility.AccessibilityNodeInfo; import androidx.test.filters.SmallTest; @@ -52,6 +56,9 @@ public class BaseTooltipViewTest extends SysuiTestCase { @Mock private WindowManager mWindowManager; + @Mock + private WindowMetrics mWindowMetrics; + private AccessibilityFloatingMenuView mMenuView; private BaseTooltipView mToolTipView; @@ -66,6 +73,9 @@ public class BaseTooltipViewTest extends SysuiTestCase { doAnswer(invocation -> wm.getMaximumWindowMetrics()).when( mWindowManager).getMaximumWindowMetrics(); mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager); + when(mWindowManager.getCurrentWindowMetrics()).thenReturn(mWindowMetrics); + when(mWindowMetrics.getBounds()).thenReturn(new Rect()); + when(mWindowMetrics.getWindowInsets()).thenReturn(new WindowInsets.Builder().build()); mMenuView = new AccessibilityFloatingMenuView(mContext, mPlaceholderPosition); mToolTipView = new BaseTooltipView(mContext, mMenuView); diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/DockTooltipViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/DockTooltipViewTest.java index ca4e3e914a8c..9eba49daaf6b 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/DockTooltipViewTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/DockTooltipViewTest.java @@ -21,12 +21,16 @@ import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import android.content.Context; +import android.graphics.Rect; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; import android.view.MotionEvent; +import android.view.WindowInsets; import android.view.WindowManager; +import android.view.WindowMetrics; import androidx.test.filters.SmallTest; @@ -49,6 +53,9 @@ public class DockTooltipViewTest extends SysuiTestCase { @Mock private WindowManager mWindowManager; + @Mock + private WindowMetrics mWindowMetrics; + private AccessibilityFloatingMenuView mMenuView; private DockTooltipView mDockTooltipView; private final Position mPlaceholderPosition = new Position(0.0f, 0.0f); @@ -62,6 +69,9 @@ public class DockTooltipViewTest extends SysuiTestCase { doAnswer(invocation -> wm.getMaximumWindowMetrics()).when( mWindowManager).getMaximumWindowMetrics(); mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager); + when(mWindowManager.getCurrentWindowMetrics()).thenReturn(mWindowMetrics); + when(mWindowMetrics.getBounds()).thenReturn(new Rect()); + when(mWindowMetrics.getWindowInsets()).thenReturn(new WindowInsets.Builder().build()); mMenuView = spy(new AccessibilityFloatingMenuView(mContext, mPlaceholderPosition)); mDockTooltipView = new DockTooltipView(mContext, mMenuView); diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/ItemDelegateCompatTest.java b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/ItemDelegateCompatTest.java index dae436427319..ea104a724b8a 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/ItemDelegateCompatTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/floatingmenu/ItemDelegateCompatTest.java @@ -22,12 +22,15 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import android.content.Context; import android.graphics.Rect; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; +import android.view.WindowInsets; import android.view.WindowManager; +import android.view.WindowMetrics; import android.view.accessibility.AccessibilityNodeInfo; import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; @@ -57,6 +60,8 @@ public class ItemDelegateCompatTest extends SysuiTestCase { @Mock private WindowManager mWindowManager; + @Mock + private WindowMetrics mWindowMetrics; private RecyclerView mListView; private AccessibilityFloatingMenuView mMenuView; private ItemDelegateCompat mItemDelegateCompat; @@ -69,6 +74,9 @@ public class ItemDelegateCompatTest extends SysuiTestCase { doAnswer(invocation -> wm.getMaximumWindowMetrics()).when( mWindowManager).getMaximumWindowMetrics(); mContext.addMockSystemService(Context.WINDOW_SERVICE, mWindowManager); + when(mWindowManager.getCurrentWindowMetrics()).thenReturn(mWindowMetrics); + when(mWindowMetrics.getBounds()).thenReturn(new Rect()); + when(mWindowMetrics.getWindowInsets()).thenReturn(new WindowInsets.Builder().build()); mListView = new RecyclerView(mContext); mMenuView = |