From: Adrian Roos Date: Thu, 29 Mar 2018 17:41:30 +0000 (+0200) Subject: WindowLayout: Layout IN_SCREEN floating windows in screen X-Git-Tag: android-x86-9.0-r1~143^2~41^2 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=c8045bf7e1aa6448389de49f5b3cd01a244d7945;p=android-x86%2Fframeworks-base.git WindowLayout: Layout IN_SCREEN floating windows in screen Uses screen coordinates when placing floating LAYOUT_IN_SCREEN windows, even when there is a cutout. Making sure that the window does not overlap the cutout area is instead made sure by the clip/shift-to-displayFrame logic in WindowState. Change-Id: Ic485b8f191db737bb7a10b1694a489111afd5f2c Fixes: 76199703 Test: Run CalcyIV, make sure that the expanded window is properly attached to the non-expanded window. --- diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index 2e6e348c51a4..1cfcbac668d4 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java @@ -87,6 +87,7 @@ import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST; import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_STARTING; +import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION; import static android.view.WindowManager.LayoutParams.TYPE_BOOT_PROGRESS; import static android.view.WindowManager.LayoutParams.TYPE_DISPLAY_OVERLAY; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; @@ -5397,6 +5398,12 @@ public class PhoneWindowManager implements WindowManagerPolicy { final boolean attachedInParent = attached != null && !layoutInScreen; final boolean requestedHideNavigation = (requestedSysUiFl & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) != 0; + + // TYPE_BASE_APPLICATION windows are never considered floating here because they don't get + // cropped / shifted to the displayFrame in WindowState. + final boolean floatingInScreenWindow = !attrs.isFullscreen() && layoutInScreen + && type != TYPE_BASE_APPLICATION; + // Ensure that windows with a DEFAULT or NEVER display cutout mode are laid out in // the cutout safe zone. if (cutoutMode != LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS) { @@ -5431,7 +5438,10 @@ public class PhoneWindowManager implements WindowManagerPolicy { } // Windows that are attached to a parent and laid out in said parent already avoid // the cutout according to that parent and don't need to be further constrained. - if (!attachedInParent) { + // Floating IN_SCREEN windows get what they ask for and lay out in the full screen. + // They will later be cropped or shifted using the displayFrame in WindowState, + // which prevents overlap with the DisplayCutout. + if (!attachedInParent && !floatingInScreenWindow) { mTmpRect.set(pf); pf.intersectUnchecked(displayCutoutSafeExceptMaybeBars); parentFrameWasClippedByDisplayCutout |= !mTmpRect.equals(pf); diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java index b6be3a4719d6..97a716f6bd99 100644 --- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java +++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerLayoutTest.java @@ -22,6 +22,7 @@ import static android.view.View.SYSTEM_UI_FLAG_FULLSCREEN; import static android.view.View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN; import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS; +import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR; import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; @@ -29,6 +30,7 @@ import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_M import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_DRAW_STATUS_BAR_BACKGROUND; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_SCREEN_DECOR; import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; @@ -260,6 +262,23 @@ public class PhoneWindowManagerLayoutTest extends PhoneWindowManagerTestBase { } @Test + public void layoutWindowLw_withDisplayCutout_floatingInScreen() { + addDisplayCutout(); + + mAppWindow.attrs.flags = FLAG_LAYOUT_IN_SCREEN; + mAppWindow.attrs.type = TYPE_APPLICATION_OVERLAY; + mAppWindow.attrs.width = DISPLAY_WIDTH; + mAppWindow.attrs.height = DISPLAY_HEIGHT; + mPolicy.addWindow(mAppWindow); + + mPolicy.beginLayoutLw(mFrames, 0 /* UI mode */); + mPolicy.layoutWindowLw(mAppWindow, null, mFrames); + + assertInsetByTopBottom(mAppWindow.parentFrame, 0, NAV_BAR_HEIGHT); + assertInsetByTopBottom(mAppWindow.displayFrame, STATUS_BAR_HEIGHT, NAV_BAR_HEIGHT); + } + + @Test public void layoutWindowLw_withDisplayCutout_fullscreenInCutout_landscape() { addDisplayCutout(); setRotation(ROTATION_90); diff --git a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java index 195dd39758df..2c47a9432eff 100644 --- a/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java +++ b/services/tests/servicestests/src/com/android/server/policy/PhoneWindowManagerTestBase.java @@ -229,7 +229,8 @@ public class PhoneWindowManagerTestBase { void addWindow(WindowState state) { if (state instanceof FakeWindowState) { ((FakeWindowState) state).surfaceLayer = - getWindowLayerFromTypeLw(state.getAttrs().type); + getWindowLayerFromTypeLw(state.getAttrs().type, + true /* canAddInternalSystemWindow */); } adjustWindowParamsLw(state, state.getAttrs(), true /* hasStatusBarPermission */); assertEquals(WindowManagerGlobal.ADD_OKAY, prepareAddWindowLw(state, state.getAttrs()));