Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandler.kt +9 −3 Original line number Diff line number Diff line Loading @@ -72,7 +72,10 @@ class DesktopDisplayEventHandler( override fun onDisplayAdded(displayId: Int) { if (displayId != DEFAULT_DISPLAY) { desktopDisplayModeController.refreshDisplayWindowingMode() desktopDisplayModeController.updateExternalDisplayWindowingMode(displayId) // The default display's windowing mode depends on the availability of the external // display. So updating the default display's windowing mode here. desktopDisplayModeController.updateDefaultDisplayWindowingMode() } createDefaultDesksIfNeeded(displayIds = setOf(displayId), userId = null) Loading @@ -80,7 +83,7 @@ class DesktopDisplayEventHandler( override fun onDisplayRemoved(displayId: Int) { if (displayId != DEFAULT_DISPLAY) { desktopDisplayModeController.refreshDisplayWindowingMode() desktopDisplayModeController.updateDefaultDisplayWindowingMode() } // TODO: b/362720497 - move desks in closing display to the remaining desk. Loading @@ -91,7 +94,10 @@ class DesktopDisplayEventHandler( DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue && displayId != DEFAULT_DISPLAY ) { desktopDisplayModeController.refreshDisplayWindowingMode() desktopDisplayModeController.updateExternalDisplayWindowingMode(displayId) // The default display's windowing mode depends on the desktop eligibility of the // external display. So updating the default display's windowing mode here. desktopDisplayModeController.updateDefaultDisplayWindowingMode() } } Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt +31 −12 Original line number Diff line number Diff line Loading @@ -59,15 +59,15 @@ class DesktopDisplayModeController( private val inputDeviceListener = object : InputManager.InputDeviceListener { override fun onInputDeviceAdded(deviceId: Int) { refreshDisplayWindowingMode() updateDefaultDisplayWindowingMode() } override fun onInputDeviceChanged(deviceId: Int) { refreshDisplayWindowingMode() updateDefaultDisplayWindowingMode() } override fun onInputDeviceRemoved(deviceId: Int) { refreshDisplayWindowingMode() updateDefaultDisplayWindowingMode() } } Loading @@ -77,12 +77,30 @@ class DesktopDisplayModeController( } } fun refreshDisplayWindowingMode() { fun updateExternalDisplayWindowingMode(displayId: Int) { if (!DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue) return val desktopModeSupported = displayController.getDisplay(displayId)?.let { display -> DesktopModeStatus.isDesktopModeSupportedOnDisplay(context, display) } ?: false if (!desktopModeSupported) return // An external display should always be a freeform display when desktop mode is enabled. updateDisplayWindowingMode(displayId, WINDOWING_MODE_FREEFORM) } fun updateDefaultDisplayWindowingMode() { if (!DesktopExperienceFlags.ENABLE_DISPLAY_WINDOWING_MODE_SWITCHING.isTrue) return val targetDisplayWindowingMode = getTargetWindowingModeForDefaultDisplay() val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY) requireNotNull(tdaInfo) { "DisplayAreaInfo of DEFAULT_DISPLAY must be non-null." } updateDisplayWindowingMode(DEFAULT_DISPLAY, getTargetWindowingModeForDefaultDisplay()) } private fun updateDisplayWindowingMode(displayId: Int, targetDisplayWindowingMode: Int) { val tdaInfo = requireNotNull(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId)) { "DisplayAreaInfo of display#$displayId must be non-null." } val currentDisplayWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode if (currentDisplayWindowingMode == targetDisplayWindowingMode) { // Already in the target mode. Loading @@ -90,15 +108,16 @@ class DesktopDisplayModeController( } logV( "As an external display is connected, changing default display's windowing mode from" + " ${windowingModeToString(currentDisplayWindowingMode)}" + " to ${windowingModeToString(targetDisplayWindowingMode)}" "Changing display#%d's windowing mode from %s to %s", displayId, windowingModeToString(currentDisplayWindowingMode), windowingModeToString(targetDisplayWindowingMode), ) val wct = WindowContainerTransaction() wct.setWindowingMode(tdaInfo.token, targetDisplayWindowingMode) shellTaskOrganizer .getRunningTasks(DEFAULT_DISPLAY) .getRunningTasks(displayId) .filter { it.activityType == ACTIVITY_TYPE_STANDARD } .forEach { // TODO: b/391965153 - Reconsider the logic under multi-desk window hierarchy Loading @@ -114,7 +133,7 @@ class DesktopDisplayModeController( // The override windowing mode of DesktopWallpaper can be UNDEFINED on fullscreen-display // right after the first launch while its resolved windowing mode is FULLSCREEN. We here // it has the FULLSCREEN override windowing mode. desktopWallpaperActivityTokenProvider.getToken(DEFAULT_DISPLAY)?.let { token -> desktopWallpaperActivityTokenProvider.getToken(displayId)?.let { token -> wct.setWindowingMode(token, WINDOWING_MODE_FULLSCREEN) } transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ null) Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandlerTest.kt +5 −3 Original line number Diff line number Diff line Loading @@ -242,20 +242,22 @@ class DesktopDisplayEventHandlerTest : ShellTestCase() { @Test fun testConnectExternalDisplay() { onDisplaysChangedListenerCaptor.lastValue.onDisplayAdded(externalDisplayId) verify(desktopDisplayModeController).refreshDisplayWindowingMode() verify(desktopDisplayModeController).updateExternalDisplayWindowingMode(externalDisplayId) verify(desktopDisplayModeController).updateDefaultDisplayWindowingMode() } @Test fun testDisconnectExternalDisplay() { onDisplaysChangedListenerCaptor.lastValue.onDisplayRemoved(externalDisplayId) verify(desktopDisplayModeController).refreshDisplayWindowingMode() verify(desktopDisplayModeController).updateDefaultDisplayWindowingMode() } @Test @EnableFlags(DisplayFlags.FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT) fun testDesktopModeEligibleChanged() { onDisplaysChangedListenerCaptor.lastValue.onDesktopModeEligibleChanged(externalDisplayId) verify(desktopDisplayModeController).refreshDisplayWindowingMode() verify(desktopDisplayModeController).updateExternalDisplayWindowingMode(externalDisplayId) verify(desktopDisplayModeController).updateDefaultDisplayWindowingMode() } private class FakeDesktopRepositoryInitializer : DesktopRepositoryInitializer { Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt +19 −2 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ class DesktopDisplayModeControllerTest( private val fullscreenTask = TestRunningTaskInfoBuilder().setWindowingMode(WINDOWING_MODE_FULLSCREEN).build() private val defaultTDA = DisplayAreaInfo(MockToken().token(), DEFAULT_DISPLAY, 0) private val externalTDA = DisplayAreaInfo(MockToken().token(), EXTERNAL_DISPLAY_ID, 0) private val wallpaperToken = MockToken().token() private val defaultDisplay = mock<Display>() private val externalDisplay = mock<Display>() Loading Loading @@ -129,6 +130,8 @@ class DesktopDisplayModeControllerTest( whenever(transitions.startTransition(anyInt(), any(), isNull())).thenReturn(Binder()) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)) .thenReturn(defaultTDA) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(EXTERNAL_DISPLAY_ID)) .thenReturn(externalTDA) controller = DesktopDisplayModeController( context, Loading Loading @@ -292,16 +295,30 @@ class DesktopDisplayModeControllerTest( .isEqualTo(WINDOWING_MODE_UNDEFINED) } @Test @EnableFlags(DisplayFlags.FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT) fun externalDisplayWindowingMode() { externalTDA.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN setExtendedMode(true) controller.updateExternalDisplayWindowingMode(EXTERNAL_DISPLAY_ID) val arg = argumentCaptor<WindowContainerTransaction>() verify(transitions, times(1)).startTransition(eq(TRANSIT_CHANGE), arg.capture(), isNull()) assertThat(arg.firstValue.changes[externalTDA.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_FREEFORM) } private fun connectExternalDisplay() { whenever(rootTaskDisplayAreaOrganizer.getDisplayIds()) .thenReturn(intArrayOf(DEFAULT_DISPLAY, EXTERNAL_DISPLAY_ID)) controller.refreshDisplayWindowingMode() controller.updateDefaultDisplayWindowingMode() } private fun disconnectExternalDisplay() { whenever(rootTaskDisplayAreaOrganizer.getDisplayIds()) .thenReturn(intArrayOf(DEFAULT_DISPLAY)) controller.refreshDisplayWindowingMode() controller.updateDefaultDisplayWindowingMode() } private fun setExtendedMode(enabled: Boolean) { Loading Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandler.kt +9 −3 Original line number Diff line number Diff line Loading @@ -72,7 +72,10 @@ class DesktopDisplayEventHandler( override fun onDisplayAdded(displayId: Int) { if (displayId != DEFAULT_DISPLAY) { desktopDisplayModeController.refreshDisplayWindowingMode() desktopDisplayModeController.updateExternalDisplayWindowingMode(displayId) // The default display's windowing mode depends on the availability of the external // display. So updating the default display's windowing mode here. desktopDisplayModeController.updateDefaultDisplayWindowingMode() } createDefaultDesksIfNeeded(displayIds = setOf(displayId), userId = null) Loading @@ -80,7 +83,7 @@ class DesktopDisplayEventHandler( override fun onDisplayRemoved(displayId: Int) { if (displayId != DEFAULT_DISPLAY) { desktopDisplayModeController.refreshDisplayWindowingMode() desktopDisplayModeController.updateDefaultDisplayWindowingMode() } // TODO: b/362720497 - move desks in closing display to the remaining desk. Loading @@ -91,7 +94,10 @@ class DesktopDisplayEventHandler( DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue && displayId != DEFAULT_DISPLAY ) { desktopDisplayModeController.refreshDisplayWindowingMode() desktopDisplayModeController.updateExternalDisplayWindowingMode(displayId) // The default display's windowing mode depends on the desktop eligibility of the // external display. So updating the default display's windowing mode here. desktopDisplayModeController.updateDefaultDisplayWindowingMode() } } Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt +31 −12 Original line number Diff line number Diff line Loading @@ -59,15 +59,15 @@ class DesktopDisplayModeController( private val inputDeviceListener = object : InputManager.InputDeviceListener { override fun onInputDeviceAdded(deviceId: Int) { refreshDisplayWindowingMode() updateDefaultDisplayWindowingMode() } override fun onInputDeviceChanged(deviceId: Int) { refreshDisplayWindowingMode() updateDefaultDisplayWindowingMode() } override fun onInputDeviceRemoved(deviceId: Int) { refreshDisplayWindowingMode() updateDefaultDisplayWindowingMode() } } Loading @@ -77,12 +77,30 @@ class DesktopDisplayModeController( } } fun refreshDisplayWindowingMode() { fun updateExternalDisplayWindowingMode(displayId: Int) { if (!DesktopExperienceFlags.ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT.isTrue) return val desktopModeSupported = displayController.getDisplay(displayId)?.let { display -> DesktopModeStatus.isDesktopModeSupportedOnDisplay(context, display) } ?: false if (!desktopModeSupported) return // An external display should always be a freeform display when desktop mode is enabled. updateDisplayWindowingMode(displayId, WINDOWING_MODE_FREEFORM) } fun updateDefaultDisplayWindowingMode() { if (!DesktopExperienceFlags.ENABLE_DISPLAY_WINDOWING_MODE_SWITCHING.isTrue) return val targetDisplayWindowingMode = getTargetWindowingModeForDefaultDisplay() val tdaInfo = rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY) requireNotNull(tdaInfo) { "DisplayAreaInfo of DEFAULT_DISPLAY must be non-null." } updateDisplayWindowingMode(DEFAULT_DISPLAY, getTargetWindowingModeForDefaultDisplay()) } private fun updateDisplayWindowingMode(displayId: Int, targetDisplayWindowingMode: Int) { val tdaInfo = requireNotNull(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(displayId)) { "DisplayAreaInfo of display#$displayId must be non-null." } val currentDisplayWindowingMode = tdaInfo.configuration.windowConfiguration.windowingMode if (currentDisplayWindowingMode == targetDisplayWindowingMode) { // Already in the target mode. Loading @@ -90,15 +108,16 @@ class DesktopDisplayModeController( } logV( "As an external display is connected, changing default display's windowing mode from" + " ${windowingModeToString(currentDisplayWindowingMode)}" + " to ${windowingModeToString(targetDisplayWindowingMode)}" "Changing display#%d's windowing mode from %s to %s", displayId, windowingModeToString(currentDisplayWindowingMode), windowingModeToString(targetDisplayWindowingMode), ) val wct = WindowContainerTransaction() wct.setWindowingMode(tdaInfo.token, targetDisplayWindowingMode) shellTaskOrganizer .getRunningTasks(DEFAULT_DISPLAY) .getRunningTasks(displayId) .filter { it.activityType == ACTIVITY_TYPE_STANDARD } .forEach { // TODO: b/391965153 - Reconsider the logic under multi-desk window hierarchy Loading @@ -114,7 +133,7 @@ class DesktopDisplayModeController( // The override windowing mode of DesktopWallpaper can be UNDEFINED on fullscreen-display // right after the first launch while its resolved windowing mode is FULLSCREEN. We here // it has the FULLSCREEN override windowing mode. desktopWallpaperActivityTokenProvider.getToken(DEFAULT_DISPLAY)?.let { token -> desktopWallpaperActivityTokenProvider.getToken(displayId)?.let { token -> wct.setWindowingMode(token, WINDOWING_MODE_FULLSCREEN) } transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ null) Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayEventHandlerTest.kt +5 −3 Original line number Diff line number Diff line Loading @@ -242,20 +242,22 @@ class DesktopDisplayEventHandlerTest : ShellTestCase() { @Test fun testConnectExternalDisplay() { onDisplaysChangedListenerCaptor.lastValue.onDisplayAdded(externalDisplayId) verify(desktopDisplayModeController).refreshDisplayWindowingMode() verify(desktopDisplayModeController).updateExternalDisplayWindowingMode(externalDisplayId) verify(desktopDisplayModeController).updateDefaultDisplayWindowingMode() } @Test fun testDisconnectExternalDisplay() { onDisplaysChangedListenerCaptor.lastValue.onDisplayRemoved(externalDisplayId) verify(desktopDisplayModeController).refreshDisplayWindowingMode() verify(desktopDisplayModeController).updateDefaultDisplayWindowingMode() } @Test @EnableFlags(DisplayFlags.FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT) fun testDesktopModeEligibleChanged() { onDisplaysChangedListenerCaptor.lastValue.onDesktopModeEligibleChanged(externalDisplayId) verify(desktopDisplayModeController).refreshDisplayWindowingMode() verify(desktopDisplayModeController).updateExternalDisplayWindowingMode(externalDisplayId) verify(desktopDisplayModeController).updateDefaultDisplayWindowingMode() } private class FakeDesktopRepositoryInitializer : DesktopRepositoryInitializer { Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt +19 −2 Original line number Diff line number Diff line Loading @@ -101,6 +101,7 @@ class DesktopDisplayModeControllerTest( private val fullscreenTask = TestRunningTaskInfoBuilder().setWindowingMode(WINDOWING_MODE_FULLSCREEN).build() private val defaultTDA = DisplayAreaInfo(MockToken().token(), DEFAULT_DISPLAY, 0) private val externalTDA = DisplayAreaInfo(MockToken().token(), EXTERNAL_DISPLAY_ID, 0) private val wallpaperToken = MockToken().token() private val defaultDisplay = mock<Display>() private val externalDisplay = mock<Display>() Loading Loading @@ -129,6 +130,8 @@ class DesktopDisplayModeControllerTest( whenever(transitions.startTransition(anyInt(), any(), isNull())).thenReturn(Binder()) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(DEFAULT_DISPLAY)) .thenReturn(defaultTDA) whenever(rootTaskDisplayAreaOrganizer.getDisplayAreaInfo(EXTERNAL_DISPLAY_ID)) .thenReturn(externalTDA) controller = DesktopDisplayModeController( context, Loading Loading @@ -292,16 +295,30 @@ class DesktopDisplayModeControllerTest( .isEqualTo(WINDOWING_MODE_UNDEFINED) } @Test @EnableFlags(DisplayFlags.FLAG_ENABLE_DISPLAY_CONTENT_MODE_MANAGEMENT) fun externalDisplayWindowingMode() { externalTDA.configuration.windowConfiguration.windowingMode = WINDOWING_MODE_FULLSCREEN setExtendedMode(true) controller.updateExternalDisplayWindowingMode(EXTERNAL_DISPLAY_ID) val arg = argumentCaptor<WindowContainerTransaction>() verify(transitions, times(1)).startTransition(eq(TRANSIT_CHANGE), arg.capture(), isNull()) assertThat(arg.firstValue.changes[externalTDA.token.asBinder()]?.windowingMode) .isEqualTo(WINDOWING_MODE_FREEFORM) } private fun connectExternalDisplay() { whenever(rootTaskDisplayAreaOrganizer.getDisplayIds()) .thenReturn(intArrayOf(DEFAULT_DISPLAY, EXTERNAL_DISPLAY_ID)) controller.refreshDisplayWindowingMode() controller.updateDefaultDisplayWindowingMode() } private fun disconnectExternalDisplay() { whenever(rootTaskDisplayAreaOrganizer.getDisplayIds()) .thenReturn(intArrayOf(DEFAULT_DISPLAY)) controller.refreshDisplayWindowingMode() controller.updateDefaultDisplayWindowingMode() } private fun setExtendedMode(enabled: Boolean) { Loading