diff options
| author | 2025-02-26 19:36:51 +0900 | |
|---|---|---|
| committer | 2025-03-11 19:56:30 +0900 | |
| commit | 31bf29576a6be72fa22e6426019944c32f452b9c (patch) | |
| tree | e433b28507b9c50e9dc1c9f3634fe91a369cd359 | |
| parent | 0131dc875ab3182127abb3d26a0608bbdf1f2c06 (diff) | |
Add projected mode check in DesktopDisplayModeCtrl
This CL adds a projected mode check in DesktopDisplayModeController.
If the projected mode is explicitly enabled, we don’t need to switch the
default display’s windowing mode.
Flag: com.android.window.flags.enable_projected_display_desktop_mode
Flag: com.android.window.flags.enable_display_windowing_mode_switching
Bug: 399240355
Test: DesktopDisplayModeControllerTest
Change-Id: I9f8801a237f616847250dcf339b2810ad08ec7b9
2 files changed, 241 insertions, 35 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt index 6dcc0deb1da1..489e4f0aed01 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/DesktopDisplayModeController.kt @@ -114,21 +114,36 @@ class DesktopDisplayModeController( transitions.startTransition(TRANSIT_CHANGE, wct, /* handler= */ null) } + // Do not directly use this method to check the state of desktop-first mode. Check the display + // windowing mode instead. + private fun canDesktopFirstModeBeEnabledOnDefaultDisplay(): Boolean { + if (isDefaultDisplayDesktopEligible()) { + if (isExtendedDisplayEnabled() && hasExternalDisplay()) { + return true + } + if (DesktopExperienceFlags.FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH.isTrue) { + if (isInClamshellMode()) { + return true + } + } + } + return false + } + @VisibleForTesting fun getTargetWindowingModeForDefaultDisplay(): Int { - if (isExtendedDisplayEnabled() && hasExternalDisplay()) { + if (canDesktopFirstModeBeEnabledOnDefaultDisplay()) { return WINDOWING_MODE_FREEFORM } - if (DesktopExperienceFlags.FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH.isTrue) { - if (isInClamshellMode()) { - return WINDOWING_MODE_FREEFORM - } - return WINDOWING_MODE_FULLSCREEN - } - // If form factor-based desktop first switch is disabled, use the default display windowing - // mode here to keep the freeform mode for some form factors (e.g., FEATURE_PC). - return windowManager.getWindowingMode(DEFAULT_DISPLAY) + return if (DesktopExperienceFlags.FORM_FACTOR_BASED_DESKTOP_FIRST_SWITCH.isTrue) { + WINDOWING_MODE_FULLSCREEN + } else { + // If form factor-based desktop first switch is disabled, use the default display + // windowing mode here to keep the freeform mode for some form factors (e.g., + // FEATURE_PC). + windowManager.getWindowingMode(DEFAULT_DISPLAY) + } } private fun isExtendedDisplayEnabled(): Boolean { @@ -156,6 +171,13 @@ class DesktopDisplayModeController( private fun isInClamshellMode() = inputManager.isInTabletMode() == InputManager.SWITCH_STATE_OFF + private fun isDefaultDisplayDesktopEligible(): Boolean { + val display = requireNotNull(displayController.getDisplay(DEFAULT_DISPLAY)) { + "Display object of DEFAULT_DISPLAY must be non-null." + } + return DesktopModeStatus.isDesktopModeSupportedOnDisplay(context, display) + } + private fun logV(msg: String, vararg arguments: Any?) { ProtoLog.v(WM_SHELL_DESKTOP_MODE, "%s: $msg", TAG, *arguments) } diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt index 105941079095..da6a67c679ff 100644 --- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt +++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/DesktopDisplayModeControllerTest.kt @@ -37,7 +37,6 @@ import android.view.WindowManager.TRANSIT_CHANGE import android.window.DisplayAreaInfo import android.window.WindowContainerTransaction import androidx.test.filters.SmallTest -import com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn import com.android.dx.mockito.inline.extended.ExtendedMockito.mockitoSession import com.android.dx.mockito.inline.extended.ExtendedMockito.never import com.android.dx.mockito.inline.extended.StaticMockitoSession @@ -102,6 +101,7 @@ class DesktopDisplayModeControllerTest( TestRunningTaskInfoBuilder().setWindowingMode(WINDOWING_MODE_FULLSCREEN).build() private val defaultTDA = DisplayAreaInfo(MockToken().token(), DEFAULT_DISPLAY, 0) private val wallpaperToken = MockToken().token() + private val defaultDisplay = mock<Display>() private val externalDisplay = mock<Display>() private lateinit var extendedDisplaySettingsRestoreSession: @@ -118,7 +118,7 @@ class DesktopDisplayModeControllerTest( mockitoSession = mockitoSession() .strictness(Strictness.LENIENT) - .spyStatic(DesktopModeStatus::class.java) + .mockStatic(DesktopModeStatus::class.java) .startMocking() extendedDisplaySettingsRestoreSession = ExtendedDisplaySettingsRestoreSession(context.contentResolver) @@ -141,8 +141,15 @@ class DesktopDisplayModeControllerTest( runningTasks.add(fullscreenTask) whenever(shellTaskOrganizer.getRunningTasks(anyInt())).thenReturn(ArrayList(runningTasks)) whenever(desktopWallpaperActivityTokenProvider.getToken()).thenReturn(wallpaperToken) + whenever(displayController.getDisplay(DEFAULT_DISPLAY)).thenReturn(defaultDisplay) whenever(displayController.getDisplay(EXTERNAL_DISPLAY_ID)).thenReturn(externalDisplay) setTabletModeStatus(SwitchState.UNKNOWN) + whenever( + DesktopModeStatus.isDesktopModeSupportedOnDisplay( + context, + defaultDisplay + ) + ).thenReturn(true) } @After @@ -210,6 +217,12 @@ class DesktopDisplayModeControllerTest( } setTabletModeStatus(tabletModeStatus) setExtendedMode(param.extendedDisplayEnabled) + whenever( + DesktopModeStatus.isDesktopModeSupportedOnDisplay( + context, + defaultDisplay + ) + ).thenReturn(param.isDefaultDisplayDesktopEligible) assertThat(controller.getTargetWindowingModeForDefaultDisplay()) .isEqualTo(param.expectedWindowingMode) @@ -228,6 +241,12 @@ class DesktopDisplayModeControllerTest( } setTabletModeStatus(param.tabletModeStatus) setExtendedMode(param.extendedDisplayEnabled) + whenever( + DesktopModeStatus.isDesktopModeSupportedOnDisplay( + context, + defaultDisplay + ) + ).thenReturn(param.isDefaultDisplayDesktopEligible) assertThat(controller.getTargetWindowingModeForDefaultDisplay()) .isEqualTo(param.expectedWindowingMode) @@ -287,9 +306,12 @@ class DesktopDisplayModeControllerTest( private fun setExtendedMode(enabled: Boolean) { if (DisplayFlags.enableDisplayContentModeManagement()) { - doReturn(enabled).`when` { - DesktopModeStatus.isDesktopModeSupportedOnDisplay(context, externalDisplay) - } + whenever( + DesktopModeStatus.isDesktopModeSupportedOnDisplay( + context, + externalDisplay + ) + ).thenReturn(enabled) } else { Settings.Global.putInt( context.contentResolver, @@ -334,54 +356,119 @@ class DesktopDisplayModeControllerTest( val defaultWindowingMode: Int, val hasExternalDisplay: Boolean, val extendedDisplayEnabled: Boolean, + val isDefaultDisplayDesktopEligible: Boolean, val expectedWindowingMode: Int, ) { - FREEFORM_EXTERNAL_EXTENDED( + FREEFORM_EXTERNAL_EXTENDED_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FREEFORM, hasExternalDisplay = true, extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - FULLSCREEN_EXTERNAL_EXTENDED( + FULLSCREEN_EXTERNAL_EXTENDED_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, hasExternalDisplay = true, extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - FREEFORM_NO_EXTERNAL_EXTENDED( + FREEFORM_NO_EXTERNAL_EXTENDED_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FREEFORM, hasExternalDisplay = false, extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - FULLSCREEN_NO_EXTERNAL_EXTENDED( + FULLSCREEN_NO_EXTERNAL_EXTENDED_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, hasExternalDisplay = false, extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), - FREEFORM_EXTERNAL_MIRROR( + FREEFORM_EXTERNAL_MIRROR_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FREEFORM, hasExternalDisplay = true, extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - FULLSCREEN_EXTERNAL_MIRROR( + FULLSCREEN_EXTERNAL_MIRROR_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, hasExternalDisplay = true, extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), - FREEFORM_NO_EXTERNAL_MIRROR( + FREEFORM_NO_EXTERNAL_MIRROR_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FREEFORM, hasExternalDisplay = false, extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - FULLSCREEN_NO_EXTERNAL_MIRROR( + FULLSCREEN_NO_EXTERNAL_MIRROR_NO_PROJECTED( defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, hasExternalDisplay = false, extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = true, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + FREEFORM_EXTERNAL_EXTENDED_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FREEFORM, + hasExternalDisplay = true, + extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + FULLSCREEN_EXTERNAL_EXTENDED_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, + hasExternalDisplay = true, + extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + FREEFORM_NO_EXTERNAL_EXTENDED_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FREEFORM, + hasExternalDisplay = false, + extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + FULLSCREEN_NO_EXTERNAL_EXTENDED_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, + hasExternalDisplay = false, + extendedDisplayEnabled = true, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + FREEFORM_EXTERNAL_MIRROR_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FREEFORM, + hasExternalDisplay = true, + extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + FULLSCREEN_EXTERNAL_MIRROR_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, + hasExternalDisplay = true, + extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + FREEFORM_NO_EXTERNAL_MIRROR_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FREEFORM, + hasExternalDisplay = false, + extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FREEFORM, + ), + FULLSCREEN_NO_EXTERNAL_MIRROR_PROJECTED( + defaultWindowingMode = WINDOWING_MODE_FULLSCREEN, + hasExternalDisplay = false, + extendedDisplayEnabled = false, + isDefaultDisplayDesktopEligible = false, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), } @@ -390,78 +477,175 @@ class DesktopDisplayModeControllerTest( val hasExternalDisplay: Boolean, val extendedDisplayEnabled: Boolean, val tabletModeStatus: SwitchState, + val isDefaultDisplayDesktopEligible: Boolean, val expectedWindowingMode: Int, ) { - EXTERNAL_EXTENDED_TABLET( + EXTERNAL_EXTENDED_TABLET_NO_PROJECTED( hasExternalDisplay = true, extendedDisplayEnabled = true, tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - NO_EXTERNAL_EXTENDED_TABLET( + NO_EXTERNAL_EXTENDED_TABLET_NO_PROJECTED( hasExternalDisplay = false, extendedDisplayEnabled = true, tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), - EXTERNAL_MIRROR_TABLET( + EXTERNAL_MIRROR_TABLET_NO_PROJECTED( hasExternalDisplay = true, extendedDisplayEnabled = false, tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), - NO_EXTERNAL_MIRROR_TABLET( + NO_EXTERNAL_MIRROR_TABLET_NO_PROJECTED( hasExternalDisplay = false, extendedDisplayEnabled = false, tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), - EXTERNAL_EXTENDED_CLAMSHELL( + EXTERNAL_EXTENDED_CLAMSHELL_NO_PROJECTED( hasExternalDisplay = true, extendedDisplayEnabled = true, tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - NO_EXTERNAL_EXTENDED_CLAMSHELL( + NO_EXTERNAL_EXTENDED_CLAMSHELL_NO_PROJECTED( hasExternalDisplay = false, extendedDisplayEnabled = true, tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - EXTERNAL_MIRROR_CLAMSHELL( + EXTERNAL_MIRROR_CLAMSHELL_NO_PROJECTED( hasExternalDisplay = true, extendedDisplayEnabled = false, tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - NO_EXTERNAL_MIRROR_CLAMSHELL( + NO_EXTERNAL_MIRROR_CLAMSHELL_NO_PROJECTED( hasExternalDisplay = false, extendedDisplayEnabled = false, tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - EXTERNAL_EXTENDED_UNKNOWN( + EXTERNAL_EXTENDED_UNKNOWN_NO_PROJECTED( hasExternalDisplay = true, extendedDisplayEnabled = true, tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = true, expectedWindowingMode = WINDOWING_MODE_FREEFORM, ), - NO_EXTERNAL_EXTENDED_UNKNOWN( + NO_EXTERNAL_EXTENDED_UNKNOWN_NO_PROJECTED( + hasExternalDisplay = false, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = true, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_MIRROR_UNKNOWN_NO_PROJECTED( + hasExternalDisplay = true, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = true, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_MIRROR_UNKNOWN_NO_PROJECTED( + hasExternalDisplay = false, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = true, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_EXTENDED_TABLET_PROJECTED( + hasExternalDisplay = true, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_EXTENDED_TABLET_PROJECTED( + hasExternalDisplay = false, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_MIRROR_TABLET_PROJECTED( + hasExternalDisplay = true, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_MIRROR_TABLET_PROJECTED( + hasExternalDisplay = false, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.ON, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_EXTENDED_CLAMSHELL_PROJECTED( + hasExternalDisplay = true, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_EXTENDED_CLAMSHELL_PROJECTED( + hasExternalDisplay = false, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_MIRROR_CLAMSHELL_PROJECTED( + hasExternalDisplay = true, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_MIRROR_CLAMSHELL_PROJECTED( + hasExternalDisplay = false, + extendedDisplayEnabled = false, + tabletModeStatus = SwitchState.OFF, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + EXTERNAL_EXTENDED_UNKNOWN_PROJECTED( + hasExternalDisplay = true, + extendedDisplayEnabled = true, + tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = false, + expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, + ), + NO_EXTERNAL_EXTENDED_UNKNOWN_PROJECTED( hasExternalDisplay = false, extendedDisplayEnabled = true, tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = false, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), - EXTERNAL_MIRROR_UNKNOWN( + EXTERNAL_MIRROR_UNKNOWN_PROJECTED( hasExternalDisplay = true, extendedDisplayEnabled = false, tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = false, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), - NO_EXTERNAL_MIRROR_UNKNOWN( + NO_EXTERNAL_MIRROR_UNKNOWN_PROJECTED( hasExternalDisplay = false, extendedDisplayEnabled = false, tabletModeStatus = SwitchState.UNKNOWN, + isDefaultDisplayDesktopEligible = false, expectedWindowingMode = WINDOWING_MODE_FULLSCREEN, ), } |