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

Commit 601dc87b authored by Sergey Pinkevich's avatar Sergey Pinkevich Committed by Android (Google) Code Review
Browse files

Merge "Don't use a custom animation for Notification shader in Desktop Windowing mode" into main

parents 064c170f c38085ac
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -42,6 +42,15 @@ public interface DesktopMode {
    void addVisibleTasksListener(DesktopRepository.VisibleTasksListener listener,
    void addVisibleTasksListener(DesktopRepository.VisibleTasksListener listener,
            Executor callbackExecutor);
            Executor callbackExecutor);


    /**
     * Adds a listener to find out about desk changes.
     *
     * @param listener the listener to add.
     * @param callbackExecutor the executor to call the listener on.
     */
    void addDeskChangeListener(DesktopRepository.DeskChangeListener listener,
            Executor callbackExecutor);

    /**
    /**
     * Adds a consumer to listen for Desktop task corner changes. This is used for gesture
     * Adds a consumer to listen for Desktop task corner changes. This is used for gesture
     * exclusion. The SparseArray contains a list of four corner resize handles mapped to each
     * exclusion. The SparseArray contains a list of four corner resize handles mapped to each
+19 −1
Original line number Original line Diff line number Diff line
@@ -5745,6 +5745,16 @@ class DesktopTasksController(
        userRepositories.current.addVisibleTasksListener(listener, callbackExecutor)
        userRepositories.current.addVisibleTasksListener(listener, callbackExecutor)
    }
    }


    /**
     * Adds a listener to find out about desk changes.
     *
     * @param listener the listener to add.
     * @param callbackExecutor the executor to call the listener on.
     */
    fun addDeskChangeListener(listener: DeskChangeListener, callbackExecutor: Executor) {
        userRepositories.current.addDeskChangeListener(listener, callbackExecutor)
    }

    /**
    /**
     * Adds a listener to track changes to desktop task gesture exclusion regions
     * Adds a listener to track changes to desktop task gesture exclusion regions
     *
     *
@@ -5821,7 +5831,6 @@ class DesktopTasksController(
                ) {
                ) {
                    // Inherit parent's bounds.
                    // Inherit parent's bounds.
                    newWindowBounds.set(taskInfo.configuration.windowConfiguration.bounds)
                    newWindowBounds.set(taskInfo.configuration.windowConfiguration.bounds)

                } else {
                } else {
                    newWindowBounds.set(calculateDefaultDesktopTaskBounds(displayLayout))
                    newWindowBounds.set(calculateDefaultDesktopTaskBounds(displayLayout))
                }
                }
@@ -5988,6 +5997,15 @@ class DesktopTasksController(
            }
            }
        }
        }


        override fun addDeskChangeListener(
            listener: DeskChangeListener,
            callbackExecutor: Executor,
        ) {
            mainExecutor.execute {
                this@DesktopTasksController.addDeskChangeListener(listener, callbackExecutor)
            }
        }

        override fun addDesktopGestureExclusionRegionListener(
        override fun addDesktopGestureExclusionRegionListener(
            listener: Consumer<Region>,
            listener: Consumer<Region>,
            callbackExecutor: Executor,
            callbackExecutor: Executor,
+10 −0
Original line number Original line Diff line number Diff line
@@ -1332,6 +1332,16 @@ flag {
    }
    }
}
}


flag {
    name: "shade_app_launch_animation_skip_in_desktop"
    namespace: "systemui"
    description: "Fixes the animation for notification shade entry points in Desktop Mode"
    bug: "383061244"
    metadata {
        purpose: PURPOSE_BUGFIX
    }
}

flag {
flag {
  namespace: "systemui"
  namespace: "systemui"
  name: "enable_view_capture_tracing"
  name: "enable_view_capture_tracing"
+149 −0
Original line number Original line Diff line number Diff line
@@ -30,6 +30,7 @@ import android.widget.FrameLayout
import android.window.SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR
import android.window.SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.app.displaylib.PerDisplayRepository
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.systemui.ActivityIntentHelper
import com.android.systemui.ActivityIntentHelper
import com.android.systemui.Flags
import com.android.systemui.Flags
@@ -42,6 +43,7 @@ import com.android.systemui.communal.domain.interactor.CommunalSettingsInteracto
import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.KeyguardViewMediator
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.keyguard.WakefulnessLifecycle
import com.android.systemui.kosmos.testScope
import com.android.systemui.kosmos.testScope
import com.android.systemui.model.SysUiState
import com.android.systemui.plugins.ActivityStarter.OnDismissAction
import com.android.systemui.plugins.ActivityStarter.OnDismissAction
import com.android.systemui.settings.UserTracker
import com.android.systemui.settings.UserTracker
import com.android.systemui.shade.ShadeController
import com.android.systemui.shade.ShadeController
@@ -49,6 +51,7 @@ import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.android.systemui.shade.data.repository.ShadeAnimationRepository
import com.android.systemui.shade.data.repository.ShadeAnimationRepository
import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractorLegacyImpl
import com.android.systemui.shade.domain.interactor.ShadeAnimationInteractorLegacyImpl
import com.android.systemui.shade.domain.interactor.ShadeDialogContextInteractor
import com.android.systemui.shade.domain.interactor.ShadeDialogContextInteractor
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.NotificationLockscreenUserManager
import com.android.systemui.statusbar.NotificationShadeWindowController
import com.android.systemui.statusbar.NotificationShadeWindowController
@@ -108,6 +111,8 @@ class LegacyActivityStarterInternalImplTest : SysuiTestCase() {
    @Mock private lateinit var activityIntentHelper: ActivityIntentHelper
    @Mock private lateinit var activityIntentHelper: ActivityIntentHelper
    @Mock private lateinit var communalSceneInteractor: CommunalSceneInteractor
    @Mock private lateinit var communalSceneInteractor: CommunalSceneInteractor
    @Mock private lateinit var communalSettingsInteractor: CommunalSettingsInteractor
    @Mock private lateinit var communalSettingsInteractor: CommunalSettingsInteractor
    @Mock private lateinit var perDisplaySysUiStateRepository: PerDisplayRepository<SysUiState>
    @Mock private lateinit var sysUIState: SysUiState
    private lateinit var underTest: LegacyActivityStarterInternalImpl
    private lateinit var underTest: LegacyActivityStarterInternalImpl
    private val kosmos = testKosmos()
    private val kosmos = testKosmos()
    private val mainExecutor = FakeExecutor(FakeSystemClock())
    private val mainExecutor = FakeExecutor(FakeSystemClock())
@@ -118,6 +123,7 @@ class LegacyActivityStarterInternalImplTest : SysuiTestCase() {
    fun setUp() {
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        MockitoAnnotations.initMocks(this)
        `when`(statusBarWindowControllerStore.defaultDisplay).thenReturn(statusBarWindowController)
        `when`(statusBarWindowControllerStore.defaultDisplay).thenReturn(statusBarWindowController)
        `when`(perDisplaySysUiStateRepository[anyInt()]).thenReturn(sysUIState)
        underTest =
        underTest =
            LegacyActivityStarterInternalImpl(
            LegacyActivityStarterInternalImpl(
                centralSurfacesOptLazy = { Optional.of(centralSurfaces) },
                centralSurfacesOptLazy = { Optional.of(centralSurfaces) },
@@ -145,6 +151,7 @@ class LegacyActivityStarterInternalImplTest : SysuiTestCase() {
                applicationScope = kosmos.testScope,
                applicationScope = kosmos.testScope,
                communalSceneInteractor = communalSceneInteractor,
                communalSceneInteractor = communalSceneInteractor,
                communalSettingsInteractor = communalSettingsInteractor,
                communalSettingsInteractor = communalSettingsInteractor,
                perDisplaySysUiStateRepository = perDisplaySysUiStateRepository,
            )
            )
        `when`(userTracker.userHandle).thenReturn(UserHandle.OWNER)
        `when`(userTracker.userHandle).thenReturn(UserHandle.OWNER)
        `when`(communalSceneInteractor.isCommunalVisible).thenReturn(MutableStateFlow(false))
        `when`(communalSceneInteractor.isCommunalVisible).thenReturn(MutableStateFlow(false))
@@ -945,6 +952,148 @@ class LegacyActivityStarterInternalImplTest : SysuiTestCase() {
        )
        )
    }
    }


    @EnableFlags(
        Flags.FLAG_ANIMATION_LIBRARY_SHELL_MIGRATION,
        Flags.FLAG_SHADE_APP_LAUNCH_ANIMATION_SKIP_IN_DESKTOP,
    )
    @Test
    fun startActivity_skipAnimInDesktop_flagEnabled_inDesktop_noAnimate() {
        setupDesktopMode(enabled = true)
        val (controller, pendingIntent) = setupLaunchWithOccludedKeyguard()

        underTest.startPendingIntentDismissingKeyguard(
            intent = pendingIntent,
            dismissShade = true,
            animationController = controller,
            showOverLockscreen = true,
            skipLockscreenChecks = true,
        )
        mainExecutor.runAllReady()

        // Verify animate parameter is false
        verify(activityTransitionAnimator)
            .startPendingIntentWithAnimation(
                nullable(ActivityTransitionAnimator.Controller::class.java),
                eq(kosmos.testScope),
                /* animate */ eq(false),
                eq(false),
                eq(true),
                any(),
            )
    }

    @EnableFlags(Flags.FLAG_ANIMATION_LIBRARY_SHELL_MIGRATION)
    @DisableFlags(Flags.FLAG_SHADE_APP_LAUNCH_ANIMATION_SKIP_IN_DESKTOP)
    @Test
    fun startActivity_skipAnimInDesktop_flagDisabled_inDesktop_doAnimate() {
        setupDesktopMode(enabled = true)
        val (controller, pendingIntent) = setupLaunchWithOccludedKeyguard()

        underTest.startPendingIntentDismissingKeyguard(
            intent = pendingIntent,
            dismissShade = true,
            animationController = controller,
            showOverLockscreen = true,
            skipLockscreenChecks = true,
        )
        mainExecutor.runAllReady()

        // Verify animate parameter is true
        verify(activityTransitionAnimator)
            .startPendingIntentWithAnimation(
                nullable(ActivityTransitionAnimator.Controller::class.java),
                eq(kosmos.testScope),
                /* animate */ eq(true),
                eq(false),
                eq(true),
                any(),
            )
    }

    @EnableFlags(
        Flags.FLAG_ANIMATION_LIBRARY_SHELL_MIGRATION,
        Flags.FLAG_SHADE_APP_LAUNCH_ANIMATION_SKIP_IN_DESKTOP,
    )
    @Test
    fun startActivity_skipAnimInDesktop_flagEnabled_notInDesktop_doAnimate() {
        setupDesktopMode(enabled = false)
        val (controller, pendingIntent) = setupLaunchWithOccludedKeyguard()

        underTest.startPendingIntentDismissingKeyguard(
            intent = pendingIntent,
            dismissShade = true,
            animationController = controller,
            showOverLockscreen = true,
            skipLockscreenChecks = true,
        )
        mainExecutor.runAllReady()

        // Verify animate parameter is true
        verify(activityTransitionAnimator)
            .startPendingIntentWithAnimation(
                nullable(ActivityTransitionAnimator.Controller::class.java),
                eq(kosmos.testScope),
                /* animate */ eq(true),
                eq(false),
                eq(true),
                any(),
            )
    }

    @EnableFlags(Flags.FLAG_ANIMATION_LIBRARY_SHELL_MIGRATION)
    @DisableFlags(Flags.FLAG_SHADE_APP_LAUNCH_ANIMATION_SKIP_IN_DESKTOP)
    @Test
    fun startActivity_skipAnimInDesktop_flagDisabled_notInDesktop_doAnimate() {
        setupDesktopMode(enabled = false)
        val (controller, pendingIntent) = setupLaunchWithOccludedKeyguard()

        underTest.startPendingIntentDismissingKeyguard(
            intent = pendingIntent,
            dismissShade = true,
            animationController = controller,
            showOverLockscreen = true,
            skipLockscreenChecks = true,
        )
        mainExecutor.runAllReady()

        // Verify animate parameter is true
        verify(activityTransitionAnimator)
            .startPendingIntentWithAnimation(
                nullable(ActivityTransitionAnimator.Controller::class.java),
                eq(kosmos.testScope),
                /* animate */ eq(true),
                eq(false),
                eq(true),
                any(),
            )
    }

    private fun setupDesktopMode(enabled: Boolean) {
        val flags =
            if (enabled) {
                SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE
            } else {
                0L
            }
        `when`(sysUIState.flags).thenReturn(flags)
    }

    private fun setupLaunchWithOccludedKeyguard():
        Pair<ActivityTransitionAnimator.Controller?, PendingIntent> {
        val parent = FrameLayout(context)
        val view =
            object : View(context), LaunchableView {
                override fun setShouldBlockVisibilityChanges(block: Boolean) {}
            }
        parent.addView(view)
        val controller = ActivityTransitionAnimator.Controller.fromView(view)
        val pendingIntent = mock(PendingIntent::class.java)
        `when`(pendingIntent.isActivity).thenReturn(true)
        `when`(keyguardStateController.isShowing).thenReturn(true)
        `when`(keyguardStateController.isOccluded).thenReturn(true)
        return Pair(controller, pendingIntent)
    }

    private companion object {
    private companion object {
        private const val DISPLAY_ID = 0
        private const val DISPLAY_ID = 0
    }
    }
+127 −1
Original line number Original line Diff line number Diff line
@@ -19,16 +19,19 @@ import android.content.pm.UserInfo
import android.graphics.Color
import android.graphics.Color
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.DisableFlags
import android.platform.test.annotations.EnableFlags
import android.platform.test.annotations.EnableFlags
import android.view.Display
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.keyguard.keyguardUpdateMonitor
import com.android.keyguard.keyguardUpdateMonitor
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.Flags.FLAG_COMMUNAL_HUB
import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_BLURRED_BACKGROUND
import com.android.systemui.Flags.FLAG_GLANCEABLE_HUB_BLURRED_BACKGROUND
import com.android.systemui.Flags.FLAG_SHADE_APP_LAUNCH_ANIMATION_SKIP_IN_DESKTOP
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.ui.viewmodel.communalTransitionViewModel
import com.android.systemui.communal.ui.viewmodel.communalTransitionViewModel
import com.android.systemui.communal.util.fakeCommunalColors
import com.android.systemui.communal.util.fakeCommunalColors
import com.android.systemui.concurrency.fakeExecutor
import com.android.systemui.concurrency.fakeExecutor
import com.android.systemui.display.data.repository.createPerDisplayInstanceSysUIStateRepository
import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
import com.android.systemui.flags.Flags.COMMUNAL_SERVICE_ENABLED
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.flags.fakeFeatureFlagsClassic
import com.android.systemui.keyguard.ScreenLifecycle
import com.android.systemui.keyguard.ScreenLifecycle
@@ -44,6 +47,7 @@ import com.android.systemui.model.sysUiState
import com.android.systemui.notetask.NoteTaskInitializer
import com.android.systemui.notetask.NoteTaskInitializer
import com.android.systemui.settings.FakeDisplayTracker
import com.android.systemui.settings.FakeDisplayTracker
import com.android.systemui.settings.userTracker
import com.android.systemui.settings.userTracker
import com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.commandQueue
import com.android.systemui.statusbar.commandQueue
import com.android.systemui.statusbar.commandline.commandRegistry
import com.android.systemui.statusbar.commandline.commandRegistry
@@ -53,6 +57,7 @@ import com.android.systemui.testKosmos
import com.android.systemui.user.data.repository.fakeUserRepository
import com.android.systemui.user.data.repository.fakeUserRepository
import com.android.systemui.util.kotlin.javaAdapter
import com.android.systemui.util.kotlin.javaAdapter
import com.android.wm.shell.desktopmode.DesktopMode
import com.android.wm.shell.desktopmode.DesktopMode
import com.android.wm.shell.desktopmode.data.DesktopRepository
import com.android.wm.shell.desktopmode.data.DesktopRepository.VisibleTasksListener
import com.android.wm.shell.desktopmode.data.DesktopRepository.VisibleTasksListener
import com.android.wm.shell.onehanded.OneHanded
import com.android.wm.shell.onehanded.OneHanded
import com.android.wm.shell.onehanded.OneHandedEventCallback
import com.android.wm.shell.onehanded.OneHandedEventCallback
@@ -61,12 +66,13 @@ import com.android.wm.shell.pip.Pip
import com.android.wm.shell.recents.RecentTasks
import com.android.wm.shell.recents.RecentTasks
import com.android.wm.shell.splitscreen.SplitScreen
import com.android.wm.shell.splitscreen.SplitScreen
import com.android.wm.shell.sysui.ShellInterface
import com.android.wm.shell.sysui.ShellInterface
import com.google.common.truth.Truth.assertThat
import java.util.Optional
import java.util.Optional
import java.util.concurrent.Executor
import java.util.concurrent.Executor
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Before
import org.junit.Test
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.any
import org.mockito.ArgumentMatchers.any
import org.mockito.Mockito.never
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.Mockito.verify
@@ -91,6 +97,8 @@ class WMShellTest : SysuiTestCase() {
    private val Kosmos.screenLifecycle by Kosmos.Fixture { mock<ScreenLifecycle>() }
    private val Kosmos.screenLifecycle by Kosmos.Fixture { mock<ScreenLifecycle>() }
    private val Kosmos.displayTracker by Kosmos.Fixture { FakeDisplayTracker(context) }
    private val Kosmos.displayTracker by Kosmos.Fixture { FakeDisplayTracker(context) }
    private val Kosmos.shellInterface by Kosmos.Fixture { mock<ShellInterface>() }
    private val Kosmos.shellInterface by Kosmos.Fixture { mock<ShellInterface>() }
    private val Kosmos.perDisplayRepository by
        Kosmos.Fixture { createPerDisplayInstanceSysUIStateRepository() }


    private val Kosmos.underTest by
    private val Kosmos.underTest by
        Kosmos.Fixture {
        Kosmos.Fixture {
@@ -116,6 +124,7 @@ class WMShellTest : SysuiTestCase() {
                /* communalTransitionViewModel = */ communalTransitionViewModel,
                /* communalTransitionViewModel = */ communalTransitionViewModel,
                /* javaAdapter = */ javaAdapter,
                /* javaAdapter = */ javaAdapter,
                /* sysUiMainExecutor = */ fakeExecutor,
                /* sysUiMainExecutor = */ fakeExecutor,
                /* perDisplayRepository= */ perDisplayRepository,
            )
            )
        }
        }


@@ -152,6 +161,123 @@ class WMShellTest : SysuiTestCase() {
                    any(VisibleTasksListener::class.java),
                    any(VisibleTasksListener::class.java),
                    any(Executor::class.java),
                    any(Executor::class.java),
                )
                )
            verify(desktopMode)
                .addDeskChangeListener(
                    any(DesktopRepository.DeskChangeListener::class.java),
                    any(Executor::class.java),
                )
        }

    @Test
    @EnableFlags(FLAG_SHADE_APP_LAUNCH_ANIMATION_SKIP_IN_DESKTOP)
    fun onActiveDeskChanged_enterDesktop_desktopStateIsActive() =
        kosmos.runTest {
            val displayId = Display.DEFAULT_DISPLAY
            val displaySysUiState = perDisplayRepository[displayId]
            underTest.initDesktopMode(desktopMode)
            val listenerCaptor =
                ArgumentCaptor.forClass(DesktopRepository.DeskChangeListener::class.java)
            verify(desktopMode)
                .addDeskChangeListener(listenerCaptor.capture(), any(Executor::class.java))
            val listener = listenerCaptor.value
            displaySysUiState
                ?.setFlag(SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE, false)
                ?.commitUpdate()

            listener.onActiveDeskChanged(
                displayId,
                newActiveDeskId = 1,
                oldActiveDeskId = DesktopRepository.INVALID_DESK_ID,
            )
            fakeExecutor.runAllReady()

            assertThat(
                    displaySysUiState?.isFlagEnabled(SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE)
                )
                .isTrue()
        }

    @Test
    @EnableFlags(FLAG_SHADE_APP_LAUNCH_ANIMATION_SKIP_IN_DESKTOP)
    fun onActiveDeskChanged_exitDesktop_desktopStateIsNotActive() =
        kosmos.runTest {
            val displayId = Display.DEFAULT_DISPLAY
            val displaySysUiState = perDisplayRepository[displayId]
            underTest.initDesktopMode(desktopMode)
            val listenerCaptor =
                ArgumentCaptor.forClass(DesktopRepository.DeskChangeListener::class.java)
            verify(desktopMode)
                .addDeskChangeListener(listenerCaptor.capture(), any(Executor::class.java))
            val listener = listenerCaptor.value
            displaySysUiState
                ?.setFlag(SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE, true)
                ?.commitUpdate()

            listener.onActiveDeskChanged(
                displayId,
                newActiveDeskId = DesktopRepository.INVALID_DESK_ID,
                oldActiveDeskId = 1,
            )
            fakeExecutor.runAllReady()

            assertThat(
                    displaySysUiState?.isFlagEnabled(SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE)
                )
                .isFalse()
        }

    @Test
    @EnableFlags(FLAG_SHADE_APP_LAUNCH_ANIMATION_SKIP_IN_DESKTOP)
    fun onActiveDeskChanged_stayInDesktop_desktopStateIsActive() =
        kosmos.runTest {
            val displayId = Display.DEFAULT_DISPLAY
            val displaySysUiState = perDisplayRepository[displayId]
            underTest.initDesktopMode(desktopMode)
            val listenerCaptor =
                ArgumentCaptor.forClass(DesktopRepository.DeskChangeListener::class.java)
            verify(desktopMode)
                .addDeskChangeListener(listenerCaptor.capture(), any(Executor::class.java))
            val listener = listenerCaptor.value
            displaySysUiState
                ?.setFlag(SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE, true)
                ?.commitUpdate()

            listener.onActiveDeskChanged(displayId, newActiveDeskId = 2, oldActiveDeskId = 1)
            fakeExecutor.runAllReady()

            assertThat(
                    displaySysUiState?.isFlagEnabled(SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE)
                )
                .isTrue()
        }

    @Test
    @EnableFlags(FLAG_SHADE_APP_LAUNCH_ANIMATION_SKIP_IN_DESKTOP)
    fun onActiveDeskChanged_stayOutsideDesktop_desktopStateIsNotActive() =
        kosmos.runTest {
            val displayId = Display.DEFAULT_DISPLAY
            val displaySysUiState = perDisplayRepository[displayId]
            underTest.initDesktopMode(desktopMode)
            val listenerCaptor =
                ArgumentCaptor.forClass(DesktopRepository.DeskChangeListener::class.java)
            verify(desktopMode)
                .addDeskChangeListener(listenerCaptor.capture(), any(Executor::class.java))
            val listener = listenerCaptor.value
            displaySysUiState
                ?.setFlag(SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE, false)
                ?.commitUpdate()

            listener.onActiveDeskChanged(
                displayId,
                newActiveDeskId = DesktopRepository.INVALID_DESK_ID,
                oldActiveDeskId = DesktopRepository.INVALID_DESK_ID,
            )
            fakeExecutor.runAllReady()

            assertThat(
                    displaySysUiState?.isFlagEnabled(SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE)
                )
                .isFalse()
        }
        }


    @Test
    @Test
Loading