Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java +39 −7 Original line number Diff line number Diff line Loading @@ -211,8 +211,12 @@ public class DisplayController { final Context context = (displayId == Display.DEFAULT_DISPLAY) ? mContext : mContext.createDisplayContext(display); final DisplayRecord record = new DisplayRecord(displayId); DisplayLayout displayLayout = new DisplayLayout(context, display); boolean hasStatusAndNavBars = false; if (DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue()) { hasStatusAndNavBars = mDesktopState.isDesktopModeSupportedOnDisplay(displayId); } final DisplayRecord record = new DisplayRecord(displayId, hasStatusAndNavBars); DisplayLayout displayLayout = record.createLayout(context, display); if (DesktopExperienceFlags.ENABLE_CONNECTED_DISPLAYS_WINDOW_DRAG.isTrue() && mUnpopulatedDisplayBounds.containsKey(displayId)) { displayLayout.setGlobalBoundsDp(mUnpopulatedDisplayBounds.get(displayId)); Loading @@ -225,7 +229,6 @@ public class DisplayController { } } /** Called when a display rotate requested. */ public void onDisplayChangeRequested(WindowContainerTransaction wct, int displayId, Rect startAbsBounds, Rect endAbsBounds, int fromRotation, int toRotation) { Loading Loading @@ -298,7 +301,7 @@ public class DisplayController { ? mContext : mContext.createDisplayContext(display); final Context context = perDisplayContext.createConfigurationContext(newConfig); final DisplayLayout displayLayout = new DisplayLayout(context, display); final DisplayLayout displayLayout = dr.createLayout(context, display); if (mDisplayTopology != null) { displayLayout.setGlobalBoundsDp( mDisplayTopology.getAbsoluteBounds().get( Loading Loading @@ -368,11 +371,17 @@ public class DisplayController { private void onDesktopModeEligibleChanged(int displayId) { synchronized (mDisplays) { if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) { DisplayRecord r = mDisplays.get(displayId); Display display = getDisplay(displayId); if (r == null || display == null) { Slog.w(TAG, "Skipping onDesktopModeEligibleChanged on unknown" + " display, displayId=" + displayId); return; } if (DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue()) { r.updateHasStatusAndNavBars(display, mDesktopState.isDesktopModeSupportedOnDisplay(display)); } for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) { mDisplayChangedListeners.get(i).onDesktopModeEligibleChanged(displayId); } Loading @@ -380,13 +389,36 @@ public class DisplayController { } private static class DisplayRecord { private int mDisplayId; private final int mDisplayId; private Context mContext; private DisplayLayout mDisplayLayout; private InsetsState mInsetsState = new InsetsState(); private boolean mHasStatusAndNavBars; private DisplayRecord(int displayId) { private DisplayRecord(int displayId, boolean hasStatusAndNavBars) { mDisplayId = displayId; mHasStatusAndNavBars = hasStatusAndNavBars; } private DisplayLayout createLayout(Context context, Display display) { if (mDisplayId != Display.DEFAULT_DISPLAY && mHasStatusAndNavBars) { return new DisplayLayout(context, display, true /* hasNavigationBar */, true /* hasTaskBar */); } else { return new DisplayLayout(context, display); } } private void updateHasStatusAndNavBars(Display display, boolean hasStatusAndNavBars) { if (mHasStatusAndNavBars == hasStatusAndNavBars) { return; } mHasStatusAndNavBars = hasStatusAndNavBars; // Don't change how DEFAULT_DISPLAY is handled: the default heuristic is correct. if (mDisplayId != Display.DEFAULT_DISPLAY) { setDisplayLayout(mContext, createLayout(mContext, display)); } } private void setDisplayLayout(Context context, DisplayLayout displayLayout) { Loading libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java +14 −0 Original line number Diff line number Diff line Loading @@ -155,6 +155,20 @@ public class DisplayLayout { init(info, res, hasNavigationBar, hasStatusBar); } /** * Construct a display layout based on a live display. * @param context Used for resources. * @param rawDisplay Display object for the layout * @param hasNavigationBar whether the navigation bar is visible on that display * @param hasStatusBar whether the status bar is visible on that display */ public DisplayLayout(@NonNull Context context, @NonNull Display rawDisplay, boolean hasNavigationBar, boolean hasStatusBar) { DisplayInfo info = new DisplayInfo(); rawDisplay.getDisplayInfo(info); init(info, context.getResources(), hasNavigationBar, hasStatusBar); } /** * Construct a display layout based on a live display. * @param context Used for resources. Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java +31 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.wm.shell.common; import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; Loading Loading @@ -79,7 +81,8 @@ public class DisplayControllerTests extends ShellTestCase { private TestSyncExecutor mMainExecutor; private IDisplayWindowListener mDisplayContainerListener; private Consumer<DisplayTopology> mCapturedTopologyListener; private Display mMockDisplay; private Display mMockDisplay0; private Display mMockDisplay1; private DisplayController mController; private FakeDesktopState mDesktopState; private static final int DISPLAY_ID_0 = 0; Loading @@ -101,10 +104,18 @@ public class DisplayControllerTests extends ShellTestCase { mController = new DisplayController( mContext, mWM, mShellInit, mMainExecutor, mDisplayManager, mDesktopState); mMockDisplay = mock(Display.class); when(mMockDisplay.getDisplayAdjustments()).thenReturn( mMockDisplay0 = mock(Display.class); when(mMockDisplay0.getDisplayAdjustments()).thenReturn( new DisplayAdjustments(new Configuration())); when(mMockDisplay0.getDisplayId()).thenReturn(DISPLAY_ID_0); when(mDisplayManager.getDisplay(eq(DISPLAY_ID_0))).thenReturn(mMockDisplay0); mMockDisplay1 = mock(Display.class); when(mMockDisplay1.getDisplayAdjustments()).thenReturn( new DisplayAdjustments(new Configuration())); when(mDisplayManager.getDisplay(anyInt())).thenReturn(mMockDisplay); when(mMockDisplay1.getDisplayId()).thenReturn(DISPLAY_ID_1); when(mDisplayManager.getDisplay(eq(DISPLAY_ID_1))).thenReturn(mMockDisplay1); when(mDisplayManager.getDisplayTopology()).thenReturn(mMockTopology); doAnswer(invocation -> { mDisplayContainerListener = invocation.getArgument(0); Loading @@ -114,6 +125,7 @@ public class DisplayControllerTests extends ShellTestCase { mCapturedTopologyListener = invocation.getArgument(1); return null; }).when(mDisplayManager).registerTopologyListener(any(), any()); when(mWM.isEligibleForDesktopMode(anyInt())).thenReturn(false); SparseArray<RectF> absoluteBounds = new SparseArray<>(); absoluteBounds.put(DISPLAY_ID_0, DISPLAY_ABS_BOUNDS_0); absoluteBounds.put(DISPLAY_ID_1, DISPLAY_ABS_BOUNDS_1); Loading Loading @@ -180,7 +192,7 @@ public class DisplayControllerTests extends ShellTestCase { verify(mListener).onDisplayAdded(eq(DISPLAY_ID_0)); verify(mListener).onDisplayAdded(eq(DISPLAY_ID_1)); assertNotNull(mController.getDisplayContext(DISPLAY_ID_1)); verify(mContext).createDisplayContext(eq(mMockDisplay)); verify(mContext).createDisplayContext(eq(mMockDisplay1)); mDisplayContainerListener.onDisplayRemoved(DISPLAY_ID_1); Loading Loading @@ -242,4 +254,18 @@ public class DisplayControllerTests extends ShellTestCase { assertEquals(DISPLAY_ABS_BOUNDS_0, mController.getDisplayLayout(DISPLAY_ID_0).globalBoundsDp()); } @Test @EnableFlags(FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT) public void onEligibleForDesktopModeChanged_recreateLayout() throws RemoteException { mController.onInit(); mDesktopState.getOverrideDesktopModeSupportPerDisplay().put(DISPLAY_ID_1, false); mDisplayContainerListener.onDisplayAdded(DISPLAY_ID_1); mDesktopState.getOverrideDesktopModeSupportPerDisplay().put(DISPLAY_ID_1, true); DisplayLayout initialLayout = mController.getDisplayLayout(DISPLAY_ID_1); mDisplayContainerListener.onDesktopModeEligibleChanged(DISPLAY_ID_1); assertNotSame(initialLayout, mController.getDisplayLayout(DISPLAY_ID_1)); } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayController.java +39 −7 Original line number Diff line number Diff line Loading @@ -211,8 +211,12 @@ public class DisplayController { final Context context = (displayId == Display.DEFAULT_DISPLAY) ? mContext : mContext.createDisplayContext(display); final DisplayRecord record = new DisplayRecord(displayId); DisplayLayout displayLayout = new DisplayLayout(context, display); boolean hasStatusAndNavBars = false; if (DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue()) { hasStatusAndNavBars = mDesktopState.isDesktopModeSupportedOnDisplay(displayId); } final DisplayRecord record = new DisplayRecord(displayId, hasStatusAndNavBars); DisplayLayout displayLayout = record.createLayout(context, display); if (DesktopExperienceFlags.ENABLE_CONNECTED_DISPLAYS_WINDOW_DRAG.isTrue() && mUnpopulatedDisplayBounds.containsKey(displayId)) { displayLayout.setGlobalBoundsDp(mUnpopulatedDisplayBounds.get(displayId)); Loading @@ -225,7 +229,6 @@ public class DisplayController { } } /** Called when a display rotate requested. */ public void onDisplayChangeRequested(WindowContainerTransaction wct, int displayId, Rect startAbsBounds, Rect endAbsBounds, int fromRotation, int toRotation) { Loading Loading @@ -298,7 +301,7 @@ public class DisplayController { ? mContext : mContext.createDisplayContext(display); final Context context = perDisplayContext.createConfigurationContext(newConfig); final DisplayLayout displayLayout = new DisplayLayout(context, display); final DisplayLayout displayLayout = dr.createLayout(context, display); if (mDisplayTopology != null) { displayLayout.setGlobalBoundsDp( mDisplayTopology.getAbsoluteBounds().get( Loading Loading @@ -368,11 +371,17 @@ public class DisplayController { private void onDesktopModeEligibleChanged(int displayId) { synchronized (mDisplays) { if (mDisplays.get(displayId) == null || getDisplay(displayId) == null) { DisplayRecord r = mDisplays.get(displayId); Display display = getDisplay(displayId); if (r == null || display == null) { Slog.w(TAG, "Skipping onDesktopModeEligibleChanged on unknown" + " display, displayId=" + displayId); return; } if (DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue()) { r.updateHasStatusAndNavBars(display, mDesktopState.isDesktopModeSupportedOnDisplay(display)); } for (int i = mDisplayChangedListeners.size() - 1; i >= 0; --i) { mDisplayChangedListeners.get(i).onDesktopModeEligibleChanged(displayId); } Loading @@ -380,13 +389,36 @@ public class DisplayController { } private static class DisplayRecord { private int mDisplayId; private final int mDisplayId; private Context mContext; private DisplayLayout mDisplayLayout; private InsetsState mInsetsState = new InsetsState(); private boolean mHasStatusAndNavBars; private DisplayRecord(int displayId) { private DisplayRecord(int displayId, boolean hasStatusAndNavBars) { mDisplayId = displayId; mHasStatusAndNavBars = hasStatusAndNavBars; } private DisplayLayout createLayout(Context context, Display display) { if (mDisplayId != Display.DEFAULT_DISPLAY && mHasStatusAndNavBars) { return new DisplayLayout(context, display, true /* hasNavigationBar */, true /* hasTaskBar */); } else { return new DisplayLayout(context, display); } } private void updateHasStatusAndNavBars(Display display, boolean hasStatusAndNavBars) { if (mHasStatusAndNavBars == hasStatusAndNavBars) { return; } mHasStatusAndNavBars = hasStatusAndNavBars; // Don't change how DEFAULT_DISPLAY is handled: the default heuristic is correct. if (mDisplayId != Display.DEFAULT_DISPLAY) { setDisplayLayout(mContext, createLayout(mContext, display)); } } private void setDisplayLayout(Context context, DisplayLayout displayLayout) { Loading
libs/WindowManager/Shell/src/com/android/wm/shell/common/DisplayLayout.java +14 −0 Original line number Diff line number Diff line Loading @@ -155,6 +155,20 @@ public class DisplayLayout { init(info, res, hasNavigationBar, hasStatusBar); } /** * Construct a display layout based on a live display. * @param context Used for resources. * @param rawDisplay Display object for the layout * @param hasNavigationBar whether the navigation bar is visible on that display * @param hasStatusBar whether the status bar is visible on that display */ public DisplayLayout(@NonNull Context context, @NonNull Display rawDisplay, boolean hasNavigationBar, boolean hasStatusBar) { DisplayInfo info = new DisplayInfo(); rawDisplay.getDisplayInfo(info); init(info, context.getResources(), hasNavigationBar, hasStatusBar); } /** * Construct a display layout based on a live display. * @param context Used for resources. Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/DisplayControllerTests.java +31 −5 Original line number Diff line number Diff line Loading @@ -16,6 +16,8 @@ package com.android.wm.shell.common; import static com.android.server.display.feature.flags.Flags.FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNotSame; Loading Loading @@ -79,7 +81,8 @@ public class DisplayControllerTests extends ShellTestCase { private TestSyncExecutor mMainExecutor; private IDisplayWindowListener mDisplayContainerListener; private Consumer<DisplayTopology> mCapturedTopologyListener; private Display mMockDisplay; private Display mMockDisplay0; private Display mMockDisplay1; private DisplayController mController; private FakeDesktopState mDesktopState; private static final int DISPLAY_ID_0 = 0; Loading @@ -101,10 +104,18 @@ public class DisplayControllerTests extends ShellTestCase { mController = new DisplayController( mContext, mWM, mShellInit, mMainExecutor, mDisplayManager, mDesktopState); mMockDisplay = mock(Display.class); when(mMockDisplay.getDisplayAdjustments()).thenReturn( mMockDisplay0 = mock(Display.class); when(mMockDisplay0.getDisplayAdjustments()).thenReturn( new DisplayAdjustments(new Configuration())); when(mMockDisplay0.getDisplayId()).thenReturn(DISPLAY_ID_0); when(mDisplayManager.getDisplay(eq(DISPLAY_ID_0))).thenReturn(mMockDisplay0); mMockDisplay1 = mock(Display.class); when(mMockDisplay1.getDisplayAdjustments()).thenReturn( new DisplayAdjustments(new Configuration())); when(mDisplayManager.getDisplay(anyInt())).thenReturn(mMockDisplay); when(mMockDisplay1.getDisplayId()).thenReturn(DISPLAY_ID_1); when(mDisplayManager.getDisplay(eq(DISPLAY_ID_1))).thenReturn(mMockDisplay1); when(mDisplayManager.getDisplayTopology()).thenReturn(mMockTopology); doAnswer(invocation -> { mDisplayContainerListener = invocation.getArgument(0); Loading @@ -114,6 +125,7 @@ public class DisplayControllerTests extends ShellTestCase { mCapturedTopologyListener = invocation.getArgument(1); return null; }).when(mDisplayManager).registerTopologyListener(any(), any()); when(mWM.isEligibleForDesktopMode(anyInt())).thenReturn(false); SparseArray<RectF> absoluteBounds = new SparseArray<>(); absoluteBounds.put(DISPLAY_ID_0, DISPLAY_ABS_BOUNDS_0); absoluteBounds.put(DISPLAY_ID_1, DISPLAY_ABS_BOUNDS_1); Loading Loading @@ -180,7 +192,7 @@ public class DisplayControllerTests extends ShellTestCase { verify(mListener).onDisplayAdded(eq(DISPLAY_ID_0)); verify(mListener).onDisplayAdded(eq(DISPLAY_ID_1)); assertNotNull(mController.getDisplayContext(DISPLAY_ID_1)); verify(mContext).createDisplayContext(eq(mMockDisplay)); verify(mContext).createDisplayContext(eq(mMockDisplay1)); mDisplayContainerListener.onDisplayRemoved(DISPLAY_ID_1); Loading Loading @@ -242,4 +254,18 @@ public class DisplayControllerTests extends ShellTestCase { assertEquals(DISPLAY_ABS_BOUNDS_0, mController.getDisplayLayout(DISPLAY_ID_0).globalBoundsDp()); } @Test @EnableFlags(FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT) public void onEligibleForDesktopModeChanged_recreateLayout() throws RemoteException { mController.onInit(); mDesktopState.getOverrideDesktopModeSupportPerDisplay().put(DISPLAY_ID_1, false); mDisplayContainerListener.onDisplayAdded(DISPLAY_ID_1); mDesktopState.getOverrideDesktopModeSupportPerDisplay().put(DISPLAY_ID_1, true); DisplayLayout initialLayout = mController.getDisplayLayout(DISPLAY_ID_1); mDisplayContainerListener.onDesktopModeEligibleChanged(DISPLAY_ID_1); assertNotSame(initialLayout, mController.getDisplayLayout(DISPLAY_ID_1)); } }