diff --git a/services/core/java/com/android/server/wm/DisplayPolicy.java b/services/core/java/com/android/server/wm/DisplayPolicy.java index 844867b2ea9f0..44dc6870b309b 100644 --- a/services/core/java/com/android/server/wm/DisplayPolicy.java +++ b/services/core/java/com/android/server/wm/DisplayPolicy.java @@ -1037,8 +1037,8 @@ public class DisplayPolicy { mStatusBarController.setWindow(win); final TriConsumer frameProvider = (displayFrames, windowState, rect) -> { - rect.top = 0; - rect.bottom = getStatusBarHeight(displayFrames); + rect.set(windowState.getFrameLw()); + rect.bottom = rect.top + getStatusBarHeight(displayFrames); }; mDisplayContent.setInsetProvider(ITYPE_STATUS_BAR, win, frameProvider); mDisplayContent.setInsetProvider(ITYPE_TOP_GESTURES, win, frameProvider); @@ -1058,8 +1058,7 @@ public class DisplayPolicy { displayFrames.mDisplayHeight, displayFrames.mRotation) == NAV_BAR_BOTTOM && !mNavButtonForcedVisible) { - - sTmpRect.set(displayFrames.mUnrestricted); + sTmpRect.set(windowState.getFrameLw()); sTmpRect.intersectUnchecked(displayFrames.mDisplayCutoutSafe); inOutFrame.top = sTmpRect.bottom - getNavigationBarHeight(displayFrames.mRotation, @@ -1687,12 +1686,11 @@ public class DisplayPolicy { if (isSimulatedLayout) { w.setSimulatedWindowFrames(simulatedFrames); } + Rect bounds = w.getBounds(); final WindowFrames windowFrames = w.getLayoutingWindowFrames(); - windowFrames.setFrames(displayFrames.mUnrestricted /* parentFrame */, - displayFrames.mUnrestricted /* displayFrame */, - displayFrames.mUnrestricted /* contentFrame */, - displayFrames.mUnrestricted /* visibleFrame */, sTmpRect /* decorFrame */, - displayFrames.mUnrestricted /* stableFrame */); + windowFrames.setFrames(bounds /* parentFrame */, bounds /* displayFrame */, + bounds /* contentFrame */, bounds /* visibleFrame */, sTmpRect /* decorFrame */, + bounds /* stableFrame */); try { w.computeFrame(displayFrames); } finally { @@ -1749,14 +1747,13 @@ public class DisplayPolicy { if (mStatusBar == null) { return false; } - // apply any navigation bar insets + // apply any status bar insets + Rect bounds = mStatusBar.getBounds(); sTmpRect.setEmpty(); final WindowFrames windowFrames = mStatusBar.getLayoutingWindowFrames(); - windowFrames.setFrames(displayFrames.mUnrestricted /* parentFrame */, - displayFrames.mUnrestricted /* displayFrame */, - displayFrames.mStable /* contentFrame */, - displayFrames.mStable /* visibleFrame */, sTmpRect /* decorFrame */, - displayFrames.mStable /* stableFrame */); + windowFrames.setFrames(bounds /* parentFrame */, bounds /* displayFrame */, + bounds /* contentFrame */, bounds /* visibleFrame */, sTmpRect /* decorFrame */, + bounds /* stableFrame */); // Let the status bar determine its size. mStatusBar.computeFrame(displayFrames); @@ -1827,18 +1824,20 @@ public class DisplayPolicy { final Rect dockFrame = displayFrames.mDock; final int navBarPosition = navigationBarPosition(displayWidth, displayHeight, rotation); + navigationFrame.set(mNavigationBar.getBounds()); + final Rect cutoutSafeUnrestricted = sTmpRect; cutoutSafeUnrestricted.set(displayFrames.mUnrestricted); cutoutSafeUnrestricted.intersectUnchecked(displayFrames.mDisplayCutoutSafe); if (navBarPosition == NAV_BAR_BOTTOM) { // It's a system nav bar or a portrait screen; nav bar goes on bottom. - final int topNavBar = cutoutSafeUnrestricted.bottom + final int topNavBar = Math.min(cutoutSafeUnrestricted.bottom, navigationFrame.bottom) - getNavigationBarFrameHeight(rotation, uiMode); - final int top = mNavButtonForcedVisible - ? topNavBar - : cutoutSafeUnrestricted.bottom - getNavigationBarHeight(rotation, uiMode); - navigationFrame.set(0, topNavBar, displayWidth, displayFrames.mUnrestricted.bottom); + final int top = mNavButtonForcedVisible ? topNavBar : + Math.min(cutoutSafeUnrestricted.bottom, navigationFrame.bottom) + - getNavigationBarHeight(rotation, uiMode); + navigationFrame.top = topNavBar; displayFrames.mStable.bottom = displayFrames.mStableFullscreen.bottom = top; if (transientNavBarShowing) { mNavigationBarController.setBarShowingLw(true); @@ -1858,9 +1857,9 @@ public class DisplayPolicy { } } else if (navBarPosition == NAV_BAR_RIGHT) { // Landscape screen; nav bar goes to the right. - final int left = cutoutSafeUnrestricted.right + final int left = Math.min(cutoutSafeUnrestricted.right, navigationFrame.right) - getNavigationBarWidth(rotation, uiMode); - navigationFrame.set(left, 0, displayFrames.mUnrestricted.right, displayHeight); + navigationFrame.left = left; displayFrames.mStable.right = displayFrames.mStableFullscreen.right = left; if (transientNavBarShowing) { mNavigationBarController.setBarShowingLw(true); @@ -1880,9 +1879,9 @@ public class DisplayPolicy { } } else if (navBarPosition == NAV_BAR_LEFT) { // Seascape screen; nav bar goes to the left. - final int right = cutoutSafeUnrestricted.left + final int right = Math.max(cutoutSafeUnrestricted.left, navigationFrame.left) + getNavigationBarWidth(rotation, uiMode); - navigationFrame.set(displayFrames.mUnrestricted.left, 0, right, displayHeight); + navigationFrame.right = right; displayFrames.mStable.left = displayFrames.mStableFullscreen.left = right; if (transientNavBarShowing) { mNavigationBarController.setBarShowingLw(true); @@ -2065,7 +2064,7 @@ public class DisplayPolicy { final @InsetsType int typesToFit = attrs.getFitInsetsTypes(); final @InsetsSide int sidesToFit = attrs.getFitInsetsSides(); final ArraySet types = InsetsState.toInternalType(typesToFit); - final Rect dfu = displayFrames.mUnrestricted; + final Rect dfu = win.getBounds(); Insets insets = Insets.of(0, 0, 0, 0); for (int i = types.size() - 1; i >= 0; i--) { final InsetsSource source = mDisplayContent.getInsetsPolicy() diff --git a/services/core/java/com/android/server/wm/InsetsSourceProvider.java b/services/core/java/com/android/server/wm/InsetsSourceProvider.java index c8d9fe0f0a659..952966824f63c 100644 --- a/services/core/java/com/android/server/wm/InsetsSourceProvider.java +++ b/services/core/java/com/android/server/wm/InsetsSourceProvider.java @@ -462,7 +462,10 @@ class InsetsSourceProvider { mCapturedLeash = animationLeash; final Rect frame = mWin.getWindowFrames().mFrame; - t.setPosition(mCapturedLeash, frame.left, frame.top); + Point position = new Point(); + mWin.transformFrameToSurfacePosition(frame.left, frame.top, position); + + t.setPosition(mCapturedLeash, position.x, position.y); } @Override diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java index 374848d83a0f4..b370bc6af7407 100644 --- a/services/core/java/com/android/server/wm/WindowState.java +++ b/services/core/java/com/android/server/wm/WindowState.java @@ -5410,7 +5410,7 @@ class WindowState extends WindowContainer implements WindowManagerP } } - private void transformFrameToSurfacePosition(int left, int top, Point outPoint) { + void transformFrameToSurfacePosition(int left, int top, Point outPoint) { outPoint.set(left, top); // If changed, also adjust getTransformationMatrix diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java index 1922351ac1eb3..b69a1f3f7766c 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyLayoutTests.java @@ -43,11 +43,15 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR; import static android.view.WindowManager.LayoutParams.TYPE_STATUS_BAR_SUB_PANEL; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; + import static org.hamcrest.Matchers.is; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertThat; +import static org.mockito.Mockito.doCallRealMethod; import static org.mockito.Mockito.doNothing; +import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.spy; import static org.testng.Assert.expectThrows; @@ -61,6 +65,7 @@ import android.util.SparseArray; import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.InsetsState; +import android.view.View; import android.view.WindowInsets.Side; import android.view.WindowInsets.Type; import android.view.WindowManager; @@ -95,6 +100,8 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { private boolean mIsLongEdgeDisplayCutout; private static final int DECOR_WINDOW_INSET = 50; + private final Rect mDisplayBounds = new Rect(); + @Before public void setUp() throws Exception { mWindow = spy(createWindow(null, TYPE_APPLICATION, "window")); @@ -107,6 +114,15 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { attrs.height = MATCH_PARENT; attrs.format = PixelFormat.TRANSLUCENT; + spyOn(mStatusBarWindow); + spyOn(mNavBarWindow); + + // Disabling this call for most tests since it can override the systemUiFlags when called. + doReturn(0).when(mDisplayPolicy).updateSystemUiVisibilityLw(); + + mDisplayPolicy.mLastSystemUiFlags |= View.STATUS_BAR_TRANSPARENT; + mDisplayPolicy.mLastSystemUiFlags |= View.NAVIGATION_BAR_TRANSPARENT; + updateDisplayFrames(); } @@ -128,7 +144,12 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { private void updateDisplayFrames() { mFrames = createDisplayFrames(); + mDisplayBounds.set(0, 0, mFrames.mDisplayWidth, mFrames.mDisplayHeight); mDisplayContent.mDisplayFrames = mFrames; + + doReturn(mDisplayBounds).when(mStatusBarWindow).getBounds(); + doReturn(mDisplayBounds).when(mNavBarWindow).getBounds(); + doReturn(mDisplayBounds).when(mWindow).getBounds(); } private DisplayFrames createDisplayFrames() { @@ -808,6 +829,7 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { @Test public void forceShowSystemBars_clearsSystemUIFlags() { + doCallRealMethod().when(mDisplayPolicy).updateSystemUiVisibilityLw(); mDisplayPolicy.mLastSystemUiFlags |= SYSTEM_UI_FLAG_FULLSCREEN; mWindow.mAttrs.subtreeSystemUiVisibility |= SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; mWindow.mAttrs.flags = @@ -829,12 +851,15 @@ public class DisplayPolicyLayoutTests extends DisplayPolicyTestsBase { @Test public void testScreenDecorWindows() { - final WindowState decorWindow = createWindow(null, TYPE_APPLICATION_OVERLAY, "decorWindow"); + final WindowState decorWindow = spy( + createWindow(null, TYPE_APPLICATION_OVERLAY, "decorWindow")); mWindow.mAttrs.flags = FLAG_NOT_FOCUSABLE | FLAG_LAYOUT_IN_SCREEN | FLAG_LAYOUT_INSET_DECOR | FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; decorWindow.mAttrs.privateFlags |= PRIVATE_FLAG_IS_SCREEN_DECOR; addWindow(decorWindow); addWindow(mWindow); + doReturn(new Rect(0, 0, mFrames.mDisplayWidth, mFrames.mDisplayHeight)) + .when(decorWindow).getBounds(); // Decor on top updateDecorWindow(decorWindow, MATCH_PARENT, DECOR_WINDOW_INSET, TOP); diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java index 7ba3fd815b2d0..1e1c3998670e4 100644 --- a/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/DisplayPolicyTestsBase.java @@ -27,7 +27,7 @@ import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn; -import static com.android.dx.mockito.inline.extended.ExtendedMockito.spy; +import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn; import static com.android.server.wm.utils.CoordinateTransforms.transformPhysicalToLogicalCoordinates; import static org.junit.Assert.assertEquals; @@ -68,7 +68,8 @@ public class DisplayPolicyTestsBase extends WindowTestsBase { @Before public void setUpDisplayPolicy() { - mDisplayPolicy = spy(mDisplayContent.getDisplayPolicy()); + mDisplayPolicy = mDisplayContent.getDisplayPolicy(); + spyOn(mDisplayPolicy); final TestContextWrapper context = new TestContextWrapper( mDisplayPolicy.getContext(), mDisplayPolicy.getCurrentUserResources());