Loading core/java/android/view/InsetsFrameProvider.java +42 −5 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ public class InsetsFrameProvider implements Parcelable { private static final int HAS_INSETS_SIZE_OVERRIDE = 2; private static Rect sTmpRect = new Rect(); private static Rect sTmpRect2 = new Rect(); /** * The type of insets to provide. Loading Loading @@ -88,6 +89,18 @@ public class InsetsFrameProvider implements Parcelable { */ public InsetsSizeOverride[] insetsSizeOverrides = null; /** * This field, if set, is indicating the insets needs to be at least the given size inside the * display cutout safe area. This will be compared to the insets size calculated based on other * attributes, and will be applied when this is larger. This is independent of the * PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT in LayoutParams, as this is not going to change * the layout of the window, but only change the insets frame. This can be applied to insets * calculated based on all three source frames. * * Be cautious, this will not be in effect for the window types whose insets size is overridden. */ public Insets minimalInsetsSizeInDisplayCutoutSafe = null; public InsetsFrameProvider(int type) { this(type, SOURCE_FRAME, null, null); } Loading Loading @@ -202,7 +215,8 @@ public class InsetsFrameProvider implements Parcelable { public static void calculateInsetsFrame(Rect displayFrame, Rect containerBounds, Rect displayCutoutSafe, Rect inOutFrame, int source, Insets insetsSize, @WindowManager.LayoutParams.PrivateFlags int privateFlags) { @WindowManager.LayoutParams.PrivateFlags int privateFlags, Insets displayCutoutSafeInsetsSize) { boolean extendByCutout = false; if (source == InsetsFrameProvider.SOURCE_DISPLAY) { inOutFrame.set(displayFrame); Loading @@ -214,6 +228,33 @@ public class InsetsFrameProvider implements Parcelable { if (insetsSize == null) { return; } if (displayCutoutSafeInsetsSize != null) { sTmpRect2.set(inOutFrame); } calculateInsetsFrame(inOutFrame, insetsSize); if (extendByCutout) { WindowLayout.extendFrameByCutout(displayCutoutSafe, displayFrame, inOutFrame, sTmpRect); } if (displayCutoutSafeInsetsSize != null) { // The insets is at least with the given size within the display cutout safe area. // Calculate the smallest size. calculateInsetsFrame(sTmpRect2, displayCutoutSafeInsetsSize); WindowLayout.extendFrameByCutout(displayCutoutSafe, displayFrame, sTmpRect2, sTmpRect); // If it's larger than previous calculation, use it. if (sTmpRect2.contains(inOutFrame)) { inOutFrame.set(sTmpRect2); } } } /** * Calculate the insets frame given the insets size and the source frame. * @param inOutFrame the source frame. * @param insetsSize the insets size. Only the first non-zero value will be taken. */ private static void calculateInsetsFrame(Rect inOutFrame, Insets insetsSize) { // Only one side of the provider shall be applied. Check in the order of left - top - // right - bottom, only the first non-zero value will be applied. if (insetsSize.left != 0) { Loading @@ -227,10 +268,6 @@ public class InsetsFrameProvider implements Parcelable { } else { inOutFrame.setEmpty(); } if (extendByCutout) { WindowLayout.extendFrameByCutout(displayCutoutSafe, displayFrame, inOutFrame, sTmpRect); } } /** Loading packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java +18 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.systemui.statusbar.window; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.InsetsState.ITYPE_TOP_MANDATORY_GESTURES; import static android.view.InsetsState.ITYPE_TOP_TAPPABLE_ELEMENT; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR; Loading @@ -27,6 +30,7 @@ import static com.android.systemui.util.leak.RotationUtils.ROTATION_UPSIDE_DOWN; import android.content.Context; import android.content.res.Resources; import android.graphics.Insets; import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.Binder; Loading @@ -36,6 +40,7 @@ import android.util.Log; import android.view.DisplayCutout; import android.view.Gravity; import android.view.IWindowManager; import android.view.InsetsFrameProvider; import android.view.Surface; import android.view.View; import android.view.ViewGroup; Loading Loading @@ -221,6 +226,19 @@ public class StatusBarWindowController { lp.setTitle("StatusBar"); lp.packageName = mContext.getPackageName(); lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; final InsetsFrameProvider gestureInsetsProvider = new InsetsFrameProvider(ITYPE_TOP_MANDATORY_GESTURES); final int safeTouchRegionHeight = mContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.display_cutout_touchable_region_size); if (safeTouchRegionHeight > 0) { gestureInsetsProvider.minimalInsetsSizeInDisplayCutoutSafe = Insets.of(0, safeTouchRegionHeight, 0, 0); } lp.providedInsets = new InsetsFrameProvider[] { new InsetsFrameProvider(ITYPE_STATUS_BAR), new InsetsFrameProvider(ITYPE_TOP_TAPPABLE_ELEMENT), gestureInsetsProvider }; return lp; } Loading services/core/java/com/android/server/wm/DisplayPolicy.java +77 −91 Original line number Diff line number Diff line Loading @@ -28,8 +28,6 @@ import static android.view.InsetsState.ITYPE_LEFT_GESTURES; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_RIGHT_GESTURES; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.InsetsState.ITYPE_TOP_MANDATORY_GESTURES; import static android.view.InsetsState.ITYPE_TOP_TAPPABLE_ELEMENT; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS; Loading Loading @@ -118,7 +116,6 @@ import android.util.ArraySet; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.Gravity; import android.view.InsetsFlags; Loading Loading @@ -1150,24 +1147,6 @@ public class DisplayPolicy { break; case TYPE_STATUS_BAR: mStatusBar = win; final TriConsumer<DisplayFrames, WindowContainer, Rect> gestureFrameProvider = (displayFrames, windowContainer, rect) -> { rect.bottom = rect.top + getStatusBarHeight(displayFrames); final DisplayCutout cutout = displayFrames.mInsetsState.getDisplayCutout(); if (cutout != null) { final Rect top = cutout.getBoundingRectTop(); if (!top.isEmpty()) { rect.bottom = Math.max(rect.bottom, top.bottom + mDisplayCutoutTouchableRegionSize); } } }; mDisplayContent.setInsetProvider(ITYPE_STATUS_BAR, win, null); mDisplayContent.setInsetProvider( ITYPE_TOP_MANDATORY_GESTURES, win, gestureFrameProvider); mDisplayContent.setInsetProvider(ITYPE_TOP_TAPPABLE_ELEMENT, win, null); mInsetsSourceWindowsExceptIme.add(win); break; case TYPE_NAVIGATION_BAR: mNavigationBar = win; Loading @@ -1185,7 +1164,8 @@ public class DisplayPolicy { displayFrames.mUnrestricted, win.getBounds(), displayFrames.mDisplayCutoutSafe, inOutFrame, provider.source, provider.insetsSize, lp.privateFlags); provider.insetsSize, lp.privateFlags, provider.minimalInsetsSizeInDisplayCutoutSafe); } } inOutFrame.inset(win.mGivenContentInsets); Loading Loading @@ -1231,18 +1211,24 @@ public class DisplayPolicy { mInsetsSourceWindowsExceptIme.add(win); if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar); break; default: if (attrs.providedInsets != null) { } // TODO(b/239145252): Temporarily skip the navigation bar as it is still with the hard-coded // logic. if (attrs.providedInsets != null && attrs.type != TYPE_NAVIGATION_BAR) { for (int i = attrs.providedInsets.length - 1; i >= 0; i--) { final InsetsFrameProvider provider = attrs.providedInsets[i]; switch (provider.type) { case ITYPE_STATUS_BAR: if (attrs.type != TYPE_STATUS_BAR) { mStatusBarAlt = win; mStatusBarAltPosition = getAltBarPosition(attrs); } break; case ITYPE_NAVIGATION_BAR: if (attrs.type != TYPE_NAVIGATION_BAR) { mNavigationBarAlt = win; mNavigationBarAltPosition = getAltBarPosition(attrs); } break; case ITYPE_CLIMATE_BAR: mClimateBarAlt = win; Loading Loading @@ -1271,7 +1257,8 @@ public class DisplayPolicy { windowContainer.getBounds(), displayFrames.mDisplayCutoutSafe, inOutFrame, ifp.source, ifp.insetsSize, lp.privateFlags); ifp.insetsSize, lp.privateFlags, ifp.minimalInsetsSizeInDisplayCutoutSafe); } : null; final InsetsFrameProvider.InsetsSizeOverride[] overrides = provider.insetsSizeOverrides; Loading @@ -1296,7 +1283,8 @@ public class DisplayPolicy { inOutFrame, ifp.source, ifp.insetsSizeOverrides[ overrideIndex].insetsSize, lp.privateFlags); lp.privateFlags, null); }; overrideProviders.put(overrides[j].windowType, overrideFrameProvider); Loading @@ -1309,8 +1297,6 @@ public class DisplayPolicy { mInsetsSourceWindowsExceptIme.add(win); } } break; } } @WindowManagerPolicy.AltBarPosition Loading services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +27 −15 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.InsetsState.ITYPE_TOP_MANDATORY_GESTURES; import static android.view.InsetsState.ITYPE_TOP_TAPPABLE_ELEMENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR; Loading @@ -45,6 +47,7 @@ import static org.mockito.Mockito.verify; import android.app.StatusBarManager; import android.platform.test.annotations.Presubmit; import android.view.InsetsFrameProvider; import android.view.InsetsSource; import android.view.InsetsSourceControl; import android.view.InsetsState; Loading @@ -70,7 +73,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @Test public void testControlsForDispatch_regular() { addWindow(TYPE_STATUS_BAR, "statusBar"); addStatusBar(); addWindow(TYPE_NAVIGATION_BAR, "navBar"); final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch(); Loading @@ -82,7 +85,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @Test public void testControlsForDispatch_multiWindowTaskVisible() { addWindow(TYPE_STATUS_BAR, "statusBar"); addStatusBar(); addWindow(TYPE_NAVIGATION_BAR, "navBar"); final WindowState win = createWindow(null, WINDOWING_MODE_MULTI_WINDOW, Loading @@ -95,7 +98,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @Test public void testControlsForDispatch_freeformTaskVisible() { addWindow(TYPE_STATUS_BAR, "statusBar"); addStatusBar(); addWindow(TYPE_NAVIGATION_BAR, "navBar"); final WindowState win = createWindow(null, WINDOWING_MODE_FREEFORM, Loading @@ -108,8 +111,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @Test public void testControlsForDispatch_forceStatusBarVisible() { addWindow(TYPE_STATUS_BAR, "statusBar").mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR; addStatusBar().mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR; addWindow(TYPE_NAVIGATION_BAR, "navBar"); final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch(); Loading @@ -123,7 +125,7 @@ public class InsetsPolicyTest extends WindowTestsBase { public void testControlsForDispatch_statusBarForceShowNavigation() { addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade").mAttrs.privateFlags |= PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION; addWindow(TYPE_STATUS_BAR, "statusBar"); addStatusBar(); addWindow(TYPE_NAVIGATION_BAR, "navBar"); final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch(); Loading Loading @@ -152,7 +154,7 @@ public class InsetsPolicyTest extends WindowTestsBase { public void testControlsForDispatch_remoteInsetsControllerControlsBars_appHasNoControl() { mDisplayContent.setRemoteInsetsController(createDisplayWindowInsetsController()); mDisplayContent.getInsetsPolicy().setRemoteInsetsControllerControlsSystemBars(true); addWindow(TYPE_STATUS_BAR, "statusBar"); addStatusBar(); addWindow(TYPE_NAVIGATION_BAR, "navBar"); final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch(); Loading @@ -163,7 +165,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @Test public void testControlsForDispatch_topAppHidesStatusBar() { addWindow(TYPE_STATUS_BAR, "statusBar"); addStatusBar(); addWindow(TYPE_NAVIGATION_BAR, "navBar"); // Add a fullscreen (MATCH_PARENT x MATCH_PARENT) app window which hides status bar. Loading Loading @@ -256,7 +258,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @SetupWindows(addWindows = W_ACTIVITY) @Test public void testShowTransientBars_bothCanBeTransient_appGetsBothFakeControls() { final WindowState statusBar = addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar"); final WindowState statusBar = addStatusBar(); statusBar.setHasSurface(true); statusBar.getControllableInsetProvider().setServerVisible(true); final WindowState navBar = addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar"); Loading Loading @@ -298,8 +300,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @SetupWindows(addWindows = W_ACTIVITY) @Test public void testShowTransientBars_statusBarCanBeTransient_appGetsStatusBarFakeControl() { addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar") .getControllableInsetProvider().getSource().setVisible(false); addStatusBar().getControllableInsetProvider().getSource().setVisible(false); addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar") .getControllableInsetProvider().setServerVisible(true); Loading Loading @@ -328,8 +329,8 @@ public class InsetsPolicyTest extends WindowTestsBase { @SetupWindows(addWindows = W_ACTIVITY) @Test public void testAbortTransientBars_bothCanBeAborted_appGetsBothRealControls() { final InsetsSource statusBarSource = addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar") .getControllableInsetProvider().getSource(); final InsetsSource statusBarSource = addStatusBar().getControllableInsetProvider().getSource(); final InsetsSource navBarSource = addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar") .getControllableInsetProvider().getSource(); statusBarSource.setVisible(false); Loading Loading @@ -381,8 +382,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @Test public void testShowTransientBars_abortsWhenControlTargetChanges() { addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar") .getControllableInsetProvider().getSource().setVisible(false); addStatusBar().getControllableInsetProvider().getSource().setVisible(false); addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar") .getControllableInsetProvider().getSource().setVisible(false); final WindowState app = addWindow(TYPE_APPLICATION, "app"); Loading @@ -406,6 +406,18 @@ public class InsetsPolicyTest extends WindowTestsBase { return win; } private WindowState addStatusBar() { final WindowState win = createWindow(null, TYPE_STATUS_BAR, "statusBar"); win.mAttrs.flags |= FLAG_NOT_FOCUSABLE; win.mAttrs.providedInsets = new InsetsFrameProvider[] { new InsetsFrameProvider(ITYPE_STATUS_BAR), new InsetsFrameProvider(ITYPE_TOP_TAPPABLE_ELEMENT), new InsetsFrameProvider(ITYPE_TOP_MANDATORY_GESTURES) }; mDisplayContent.getDisplayPolicy().addWindowLw(win, win.mAttrs); return win; } private WindowState addWindow(int type, String name) { final WindowState win = createWindow(null, type, name); mDisplayContent.getDisplayPolicy().addWindowLw(win, win.mAttrs); Loading services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +8 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.provider.DeviceConfig.NAMESPACE_CONSTRAIN_DISPLAY_APIS; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.InsetsState.ITYPE_TOP_MANDATORY_GESTURES; import static android.view.InsetsState.ITYPE_TOP_TAPPABLE_ELEMENT; import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_180; import static android.view.Surface.ROTATION_270; Loading Loading @@ -84,6 +86,7 @@ import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.provider.DeviceConfig; import android.provider.DeviceConfig.Properties; import android.view.InsetsFrameProvider; import android.view.InsetsVisibilities; import android.view.WindowManager; Loading Loading @@ -3079,6 +3082,11 @@ public class SizeCompatTests extends WindowTestsBase { attrs.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; attrs.setFitInsetsTypes(0 /* types */); attrs.providedInsets = new InsetsFrameProvider[] { new InsetsFrameProvider(ITYPE_STATUS_BAR), new InsetsFrameProvider(ITYPE_TOP_TAPPABLE_ELEMENT), new InsetsFrameProvider(ITYPE_TOP_MANDATORY_GESTURES) }; final TestWindowState statusBar = new TestWindowState( displayContent.mWmService, mock(Session.class), new TestIWindow(), attrs, token); token.addWindow(statusBar); Loading Loading
core/java/android/view/InsetsFrameProvider.java +42 −5 Original line number Diff line number Diff line Loading @@ -59,6 +59,7 @@ public class InsetsFrameProvider implements Parcelable { private static final int HAS_INSETS_SIZE_OVERRIDE = 2; private static Rect sTmpRect = new Rect(); private static Rect sTmpRect2 = new Rect(); /** * The type of insets to provide. Loading Loading @@ -88,6 +89,18 @@ public class InsetsFrameProvider implements Parcelable { */ public InsetsSizeOverride[] insetsSizeOverrides = null; /** * This field, if set, is indicating the insets needs to be at least the given size inside the * display cutout safe area. This will be compared to the insets size calculated based on other * attributes, and will be applied when this is larger. This is independent of the * PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT in LayoutParams, as this is not going to change * the layout of the window, but only change the insets frame. This can be applied to insets * calculated based on all three source frames. * * Be cautious, this will not be in effect for the window types whose insets size is overridden. */ public Insets minimalInsetsSizeInDisplayCutoutSafe = null; public InsetsFrameProvider(int type) { this(type, SOURCE_FRAME, null, null); } Loading Loading @@ -202,7 +215,8 @@ public class InsetsFrameProvider implements Parcelable { public static void calculateInsetsFrame(Rect displayFrame, Rect containerBounds, Rect displayCutoutSafe, Rect inOutFrame, int source, Insets insetsSize, @WindowManager.LayoutParams.PrivateFlags int privateFlags) { @WindowManager.LayoutParams.PrivateFlags int privateFlags, Insets displayCutoutSafeInsetsSize) { boolean extendByCutout = false; if (source == InsetsFrameProvider.SOURCE_DISPLAY) { inOutFrame.set(displayFrame); Loading @@ -214,6 +228,33 @@ public class InsetsFrameProvider implements Parcelable { if (insetsSize == null) { return; } if (displayCutoutSafeInsetsSize != null) { sTmpRect2.set(inOutFrame); } calculateInsetsFrame(inOutFrame, insetsSize); if (extendByCutout) { WindowLayout.extendFrameByCutout(displayCutoutSafe, displayFrame, inOutFrame, sTmpRect); } if (displayCutoutSafeInsetsSize != null) { // The insets is at least with the given size within the display cutout safe area. // Calculate the smallest size. calculateInsetsFrame(sTmpRect2, displayCutoutSafeInsetsSize); WindowLayout.extendFrameByCutout(displayCutoutSafe, displayFrame, sTmpRect2, sTmpRect); // If it's larger than previous calculation, use it. if (sTmpRect2.contains(inOutFrame)) { inOutFrame.set(sTmpRect2); } } } /** * Calculate the insets frame given the insets size and the source frame. * @param inOutFrame the source frame. * @param insetsSize the insets size. Only the first non-zero value will be taken. */ private static void calculateInsetsFrame(Rect inOutFrame, Insets insetsSize) { // Only one side of the provider shall be applied. Check in the order of left - top - // right - bottom, only the first non-zero value will be applied. if (insetsSize.left != 0) { Loading @@ -227,10 +268,6 @@ public class InsetsFrameProvider implements Parcelable { } else { inOutFrame.setEmpty(); } if (extendByCutout) { WindowLayout.extendFrameByCutout(displayCutoutSafe, displayFrame, inOutFrame, sTmpRect); } } /** Loading
packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowController.java +18 −0 Original line number Diff line number Diff line Loading @@ -16,6 +16,9 @@ package com.android.systemui.statusbar.window; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.InsetsState.ITYPE_TOP_MANDATORY_GESTURES; import static android.view.InsetsState.ITYPE_TOP_TAPPABLE_ELEMENT; import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR; Loading @@ -27,6 +30,7 @@ import static com.android.systemui.util.leak.RotationUtils.ROTATION_UPSIDE_DOWN; import android.content.Context; import android.content.res.Resources; import android.graphics.Insets; import android.graphics.PixelFormat; import android.graphics.Rect; import android.os.Binder; Loading @@ -36,6 +40,7 @@ import android.util.Log; import android.view.DisplayCutout; import android.view.Gravity; import android.view.IWindowManager; import android.view.InsetsFrameProvider; import android.view.Surface; import android.view.View; import android.view.ViewGroup; Loading Loading @@ -221,6 +226,19 @@ public class StatusBarWindowController { lp.setTitle("StatusBar"); lp.packageName = mContext.getPackageName(); lp.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; final InsetsFrameProvider gestureInsetsProvider = new InsetsFrameProvider(ITYPE_TOP_MANDATORY_GESTURES); final int safeTouchRegionHeight = mContext.getResources().getDimensionPixelSize( com.android.internal.R.dimen.display_cutout_touchable_region_size); if (safeTouchRegionHeight > 0) { gestureInsetsProvider.minimalInsetsSizeInDisplayCutoutSafe = Insets.of(0, safeTouchRegionHeight, 0, 0); } lp.providedInsets = new InsetsFrameProvider[] { new InsetsFrameProvider(ITYPE_STATUS_BAR), new InsetsFrameProvider(ITYPE_TOP_TAPPABLE_ELEMENT), gestureInsetsProvider }; return lp; } Loading
services/core/java/com/android/server/wm/DisplayPolicy.java +77 −91 Original line number Diff line number Diff line Loading @@ -28,8 +28,6 @@ import static android.view.InsetsState.ITYPE_LEFT_GESTURES; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_RIGHT_GESTURES; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.InsetsState.ITYPE_TOP_MANDATORY_GESTURES; import static android.view.InsetsState.ITYPE_TOP_TAPPABLE_ELEMENT; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; import static android.view.WindowInsetsController.APPEARANCE_LOW_PROFILE_BARS; Loading Loading @@ -118,7 +116,6 @@ import android.util.ArraySet; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; import android.view.DisplayCutout; import android.view.DisplayInfo; import android.view.Gravity; import android.view.InsetsFlags; Loading Loading @@ -1150,24 +1147,6 @@ public class DisplayPolicy { break; case TYPE_STATUS_BAR: mStatusBar = win; final TriConsumer<DisplayFrames, WindowContainer, Rect> gestureFrameProvider = (displayFrames, windowContainer, rect) -> { rect.bottom = rect.top + getStatusBarHeight(displayFrames); final DisplayCutout cutout = displayFrames.mInsetsState.getDisplayCutout(); if (cutout != null) { final Rect top = cutout.getBoundingRectTop(); if (!top.isEmpty()) { rect.bottom = Math.max(rect.bottom, top.bottom + mDisplayCutoutTouchableRegionSize); } } }; mDisplayContent.setInsetProvider(ITYPE_STATUS_BAR, win, null); mDisplayContent.setInsetProvider( ITYPE_TOP_MANDATORY_GESTURES, win, gestureFrameProvider); mDisplayContent.setInsetProvider(ITYPE_TOP_TAPPABLE_ELEMENT, win, null); mInsetsSourceWindowsExceptIme.add(win); break; case TYPE_NAVIGATION_BAR: mNavigationBar = win; Loading @@ -1185,7 +1164,8 @@ public class DisplayPolicy { displayFrames.mUnrestricted, win.getBounds(), displayFrames.mDisplayCutoutSafe, inOutFrame, provider.source, provider.insetsSize, lp.privateFlags); provider.insetsSize, lp.privateFlags, provider.minimalInsetsSizeInDisplayCutoutSafe); } } inOutFrame.inset(win.mGivenContentInsets); Loading Loading @@ -1231,18 +1211,24 @@ public class DisplayPolicy { mInsetsSourceWindowsExceptIme.add(win); if (DEBUG_LAYOUT) Slog.i(TAG, "NAVIGATION BAR: " + mNavigationBar); break; default: if (attrs.providedInsets != null) { } // TODO(b/239145252): Temporarily skip the navigation bar as it is still with the hard-coded // logic. if (attrs.providedInsets != null && attrs.type != TYPE_NAVIGATION_BAR) { for (int i = attrs.providedInsets.length - 1; i >= 0; i--) { final InsetsFrameProvider provider = attrs.providedInsets[i]; switch (provider.type) { case ITYPE_STATUS_BAR: if (attrs.type != TYPE_STATUS_BAR) { mStatusBarAlt = win; mStatusBarAltPosition = getAltBarPosition(attrs); } break; case ITYPE_NAVIGATION_BAR: if (attrs.type != TYPE_NAVIGATION_BAR) { mNavigationBarAlt = win; mNavigationBarAltPosition = getAltBarPosition(attrs); } break; case ITYPE_CLIMATE_BAR: mClimateBarAlt = win; Loading Loading @@ -1271,7 +1257,8 @@ public class DisplayPolicy { windowContainer.getBounds(), displayFrames.mDisplayCutoutSafe, inOutFrame, ifp.source, ifp.insetsSize, lp.privateFlags); ifp.insetsSize, lp.privateFlags, ifp.minimalInsetsSizeInDisplayCutoutSafe); } : null; final InsetsFrameProvider.InsetsSizeOverride[] overrides = provider.insetsSizeOverrides; Loading @@ -1296,7 +1283,8 @@ public class DisplayPolicy { inOutFrame, ifp.source, ifp.insetsSizeOverrides[ overrideIndex].insetsSize, lp.privateFlags); lp.privateFlags, null); }; overrideProviders.put(overrides[j].windowType, overrideFrameProvider); Loading @@ -1309,8 +1297,6 @@ public class DisplayPolicy { mInsetsSourceWindowsExceptIme.add(win); } } break; } } @WindowManagerPolicy.AltBarPosition Loading
services/tests/wmtests/src/com/android/server/wm/InsetsPolicyTest.java +27 −15 Original line number Diff line number Diff line Loading @@ -21,6 +21,8 @@ import static android.app.WindowConfiguration.WINDOWING_MODE_FREEFORM; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; import static android.view.InsetsState.ITYPE_NAVIGATION_BAR; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.InsetsState.ITYPE_TOP_MANDATORY_GESTURES; import static android.view.InsetsState.ITYPE_TOP_TAPPABLE_ELEMENT; import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR; Loading @@ -45,6 +47,7 @@ import static org.mockito.Mockito.verify; import android.app.StatusBarManager; import android.platform.test.annotations.Presubmit; import android.view.InsetsFrameProvider; import android.view.InsetsSource; import android.view.InsetsSourceControl; import android.view.InsetsState; Loading @@ -70,7 +73,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @Test public void testControlsForDispatch_regular() { addWindow(TYPE_STATUS_BAR, "statusBar"); addStatusBar(); addWindow(TYPE_NAVIGATION_BAR, "navBar"); final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch(); Loading @@ -82,7 +85,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @Test public void testControlsForDispatch_multiWindowTaskVisible() { addWindow(TYPE_STATUS_BAR, "statusBar"); addStatusBar(); addWindow(TYPE_NAVIGATION_BAR, "navBar"); final WindowState win = createWindow(null, WINDOWING_MODE_MULTI_WINDOW, Loading @@ -95,7 +98,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @Test public void testControlsForDispatch_freeformTaskVisible() { addWindow(TYPE_STATUS_BAR, "statusBar"); addStatusBar(); addWindow(TYPE_NAVIGATION_BAR, "navBar"); final WindowState win = createWindow(null, WINDOWING_MODE_FREEFORM, Loading @@ -108,8 +111,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @Test public void testControlsForDispatch_forceStatusBarVisible() { addWindow(TYPE_STATUS_BAR, "statusBar").mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR; addStatusBar().mAttrs.privateFlags |= PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR; addWindow(TYPE_NAVIGATION_BAR, "navBar"); final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch(); Loading @@ -123,7 +125,7 @@ public class InsetsPolicyTest extends WindowTestsBase { public void testControlsForDispatch_statusBarForceShowNavigation() { addWindow(TYPE_NOTIFICATION_SHADE, "notificationShade").mAttrs.privateFlags |= PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION; addWindow(TYPE_STATUS_BAR, "statusBar"); addStatusBar(); addWindow(TYPE_NAVIGATION_BAR, "navBar"); final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch(); Loading Loading @@ -152,7 +154,7 @@ public class InsetsPolicyTest extends WindowTestsBase { public void testControlsForDispatch_remoteInsetsControllerControlsBars_appHasNoControl() { mDisplayContent.setRemoteInsetsController(createDisplayWindowInsetsController()); mDisplayContent.getInsetsPolicy().setRemoteInsetsControllerControlsSystemBars(true); addWindow(TYPE_STATUS_BAR, "statusBar"); addStatusBar(); addWindow(TYPE_NAVIGATION_BAR, "navBar"); final InsetsSourceControl[] controls = addAppWindowAndGetControlsForDispatch(); Loading @@ -163,7 +165,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @Test public void testControlsForDispatch_topAppHidesStatusBar() { addWindow(TYPE_STATUS_BAR, "statusBar"); addStatusBar(); addWindow(TYPE_NAVIGATION_BAR, "navBar"); // Add a fullscreen (MATCH_PARENT x MATCH_PARENT) app window which hides status bar. Loading Loading @@ -256,7 +258,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @SetupWindows(addWindows = W_ACTIVITY) @Test public void testShowTransientBars_bothCanBeTransient_appGetsBothFakeControls() { final WindowState statusBar = addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar"); final WindowState statusBar = addStatusBar(); statusBar.setHasSurface(true); statusBar.getControllableInsetProvider().setServerVisible(true); final WindowState navBar = addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar"); Loading Loading @@ -298,8 +300,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @SetupWindows(addWindows = W_ACTIVITY) @Test public void testShowTransientBars_statusBarCanBeTransient_appGetsStatusBarFakeControl() { addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar") .getControllableInsetProvider().getSource().setVisible(false); addStatusBar().getControllableInsetProvider().getSource().setVisible(false); addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar") .getControllableInsetProvider().setServerVisible(true); Loading Loading @@ -328,8 +329,8 @@ public class InsetsPolicyTest extends WindowTestsBase { @SetupWindows(addWindows = W_ACTIVITY) @Test public void testAbortTransientBars_bothCanBeAborted_appGetsBothRealControls() { final InsetsSource statusBarSource = addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar") .getControllableInsetProvider().getSource(); final InsetsSource statusBarSource = addStatusBar().getControllableInsetProvider().getSource(); final InsetsSource navBarSource = addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar") .getControllableInsetProvider().getSource(); statusBarSource.setVisible(false); Loading Loading @@ -381,8 +382,7 @@ public class InsetsPolicyTest extends WindowTestsBase { @Test public void testShowTransientBars_abortsWhenControlTargetChanges() { addNonFocusableWindow(TYPE_STATUS_BAR, "statusBar") .getControllableInsetProvider().getSource().setVisible(false); addStatusBar().getControllableInsetProvider().getSource().setVisible(false); addNonFocusableWindow(TYPE_NAVIGATION_BAR, "navBar") .getControllableInsetProvider().getSource().setVisible(false); final WindowState app = addWindow(TYPE_APPLICATION, "app"); Loading @@ -406,6 +406,18 @@ public class InsetsPolicyTest extends WindowTestsBase { return win; } private WindowState addStatusBar() { final WindowState win = createWindow(null, TYPE_STATUS_BAR, "statusBar"); win.mAttrs.flags |= FLAG_NOT_FOCUSABLE; win.mAttrs.providedInsets = new InsetsFrameProvider[] { new InsetsFrameProvider(ITYPE_STATUS_BAR), new InsetsFrameProvider(ITYPE_TOP_TAPPABLE_ELEMENT), new InsetsFrameProvider(ITYPE_TOP_MANDATORY_GESTURES) }; mDisplayContent.getDisplayPolicy().addWindowLw(win, win.mAttrs); return win; } private WindowState addWindow(int type, String name) { final WindowState win = createWindow(null, type, name); mDisplayContent.getDisplayPolicy().addWindowLw(win, win.mAttrs); Loading
services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java +8 −0 Original line number Diff line number Diff line Loading @@ -26,6 +26,8 @@ import static android.content.res.Configuration.ORIENTATION_LANDSCAPE; import static android.content.res.Configuration.ORIENTATION_PORTRAIT; import static android.provider.DeviceConfig.NAMESPACE_CONSTRAIN_DISPLAY_APIS; import static android.view.InsetsState.ITYPE_STATUS_BAR; import static android.view.InsetsState.ITYPE_TOP_MANDATORY_GESTURES; import static android.view.InsetsState.ITYPE_TOP_TAPPABLE_ELEMENT; import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_180; import static android.view.Surface.ROTATION_270; Loading Loading @@ -84,6 +86,7 @@ import android.os.UserHandle; import android.platform.test.annotations.Presubmit; import android.provider.DeviceConfig; import android.provider.DeviceConfig.Properties; import android.view.InsetsFrameProvider; import android.view.InsetsVisibilities; import android.view.WindowManager; Loading Loading @@ -3079,6 +3082,11 @@ public class SizeCompatTests extends WindowTestsBase { attrs.layoutInDisplayCutoutMode = WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; attrs.setFitInsetsTypes(0 /* types */); attrs.providedInsets = new InsetsFrameProvider[] { new InsetsFrameProvider(ITYPE_STATUS_BAR), new InsetsFrameProvider(ITYPE_TOP_TAPPABLE_ELEMENT), new InsetsFrameProvider(ITYPE_TOP_MANDATORY_GESTURES) }; final TestWindowState statusBar = new TestWindowState( displayContent.mWmService, mock(Session.class), new TestIWindow(), attrs, token); token.addWindow(statusBar); Loading