Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2687781 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Ensure external display to be freeform display" into main

parents f25afeda a867d0e5
Loading
Loading
Loading
Loading
+9 −3
Original line number Diff line number Diff line
@@ -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)
@@ -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.
@@ -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()
        }
    }

+31 −12
Original line number Diff line number Diff line
@@ -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()
            }
        }

@@ -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.
@@ -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
@@ -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)
+5 −3
Original line number Diff line number Diff line
@@ -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 {
+19 −2
Original line number Diff line number Diff line
@@ -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>()
@@ -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,
@@ -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) {