Loading core/java/android/window/DesktopExperienceFlags.java +3 −0 Original line number Diff line number Diff line Loading @@ -230,6 +230,9 @@ public enum DesktopExperienceFlags { RESPECT_FULLSCREEN_ACTIVITY_OPTION_IN_DESKTOP_LAUNCH_PARAMS( Flags::respectFullscreenActivityOptionInDesktopLaunchParams, true, Flags.FLAG_RESPECT_FULLSCREEN_ACTIVITY_OPTION_IN_DESKTOP_LAUNCH_PARAMS), SKIP_DEACTIVATION_OF_DESK_WITH_NOTHING_IN_FRONT( Flags::skipDeactivationOfDeskWithNothingInFront, false, Flags.FLAG_SKIP_DEACTIVATION_OF_DESK_WITH_NOTHING_IN_FRONT), USE_RESOURCES_FROM_CONTEXT_TO_CREATE_DRAWABLE_ICONS( com.android.graphics.flags.Flags::useResourcesFromContextToCreateDrawableIcons, true, Loading core/java/android/window/flags/lse_desktop_experience.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -1390,6 +1390,16 @@ flag { } } flag { name: "skip_deactivation_of_desk_with_nothing_in_front" namespace: "lse_desktop_experience" description: "Keep the desk active on TO_BACK transitions without nothing else in front" bug: "421124396" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "skip_decor_view_relayout_when_closing_bugfix" namespace: "lse_desktop_experience" Loading libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserver.kt +23 −4 Original line number Diff line number Diff line Loading @@ -268,6 +268,7 @@ class DesksTransitionObserver( } val wct = WindowContainerTransaction() var hasSeenDesk = false var hasSeenOpeningTask = false val openingUserIds = mutableListOf<Int>() val desksToActivate = mutableListOf<Int>() // Visit all task changes, not just desk/wallpaper changes because we're interested in Loading @@ -276,17 +277,19 @@ class DesksTransitionObserver( val taskInfo = checkNotNull(change.taskInfo) { "Expected non-null task info" } val taskId = taskInfo.taskId logD("Handle change for taskId=%d:", taskId) if (TransitionUtil.isOpeningMode(change.mode) || change.isToTop()) { if (change.isOpeningOrToTop()) { logD("Opening/to-top change for userId=%d", taskInfo.userId) openingUserIds += taskInfo.userId } if (change in deskChanges) { hasSeenDesk = true } else if (change.isOpeningOrToTop()) { hasSeenOpeningTask = true } if (change !in deskChanges && change !in desktopWallpaperChanges) { logD("Not desk or wallpaper, skipping") continue } if (change in deskChanges) { hasSeenDesk = true } val changeUserId = taskInfo.userId val userSwitch = getUserSwitch(change, openingUserIds) logD( Loading Loading @@ -393,6 +396,19 @@ class DesksTransitionObserver( ) when { change.isToBack() -> { if ( !hasSeenOpeningTask && DesktopExperienceFlags.SKIP_DEACTIVATION_OF_DESK_WITH_NOTHING_IN_FRONT .isTrue ) { // In cases such as minimizing the last app, where we want to remain // in an empty desk, WM core may report BOTH the minimizing task and its // (former) parent root as TO_BACK changes. However, the root will still // remain in front (as it should), so do not interpret TO_BACK as it having // to be deactivated unless something else actually showed up in front. logD("desk=%d moved to back but nothing moved to front, skipping", deskId) continue } if ( desksToActivate.contains(deskId) && DesktopExperienceFlags.ENABLE_EMPTY_DESK_ON_MINIMIZE.isTrue Loading Loading @@ -503,6 +519,9 @@ class DesksTransitionObserver( private fun TransitionInfo.Change.isToBack(): Boolean = mode == TRANSIT_TO_BACK private fun TransitionInfo.Change.isOpeningOrToTop(): Boolean = TransitionUtil.isOpeningMode(mode) || isToTop() private fun TransitionInfo.taskChanges(): List<TransitionInfo.Change> = changes.filter { c -> val taskId = c.taskInfo?.taskId Loading libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserverTest.kt +49 −2 Original line number Diff line number Diff line Loading @@ -690,7 +690,10 @@ class DesksTransitionObserverTest : ShellTestCase() { } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) @EnableFlags( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Flags.FLAG_SKIP_DEACTIVATION_OF_DESK_WITH_NOTHING_IN_FRONT, ) fun independentDeskTransition_deskToBack_deactivatesSkippingReorder() = testScope.runTest { val deskId = 5 Loading @@ -703,6 +706,11 @@ class DesksTransitionObserverTest : ShellTestCase() { transition = Binder(), info = buildTransitionInfo() .addHomeChange( mode = TRANSIT_TO_FRONT, userId = repository.userId, displayId = displayId, ) .addDeskChange( deskId = deskId, mode = TRANSIT_TO_BACK, Loading @@ -721,7 +729,10 @@ class DesksTransitionObserverTest : ShellTestCase() { } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) @EnableFlags( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Flags.FLAG_SKIP_DEACTIVATION_OF_DESK_WITH_NOTHING_IN_FRONT, ) fun independentDeskTransition_deskToBack_userSwitch_deactivatesKeepingRepoActive() = testScope.runTest { val deskId = 5 Loading @@ -735,6 +746,11 @@ class DesksTransitionObserverTest : ShellTestCase() { transition = Binder(), info = buildTransitionInfo() .addHomeChange( mode = TRANSIT_TO_FRONT, userId = newUserRepository.userId, displayId = displayId, ) .addDeskChange( deskId = deskId, mode = TRANSIT_TO_BACK, Loading @@ -757,6 +773,37 @@ class DesksTransitionObserverTest : ShellTestCase() { assertThat(oldUserRepository.getActiveDeskId(displayId)).isEqualTo(deskId) } @Test @EnableFlags( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Flags.FLAG_SKIP_DEACTIVATION_OF_DESK_WITH_NOTHING_IN_FRONT, ) fun independentDeskTransition_deskToBackWithNothingInFront_keepsDeskActive() = testScope.runTest { val deskId = 5 val displayId = DEFAULT_DISPLAY val repository = desktopUserRepositories.getProfile(USER_ID_1) repository.addDesk(displayId, deskId) repository.setActiveDesk(displayId, deskId) observer.onTransitionReady( transition = Binder(), info = buildTransitionInfo() .addDeskChange( deskId = deskId, mode = TRANSIT_TO_BACK, userId = repository.userId, displayId = displayId, ), ) runCurrent() verify(mockDesksOrganizer, never()) .deactivateDesk(any(), deskId = eq(5), skipReorder = any()) assertThat(repository.getActiveDeskId(displayId)).isEqualTo(deskId) } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun independentDeskTransition_emptyDeskToBackHomeToFront_userSwitch_deactivatesKeepingRepoActive() = Loading Loading
core/java/android/window/DesktopExperienceFlags.java +3 −0 Original line number Diff line number Diff line Loading @@ -230,6 +230,9 @@ public enum DesktopExperienceFlags { RESPECT_FULLSCREEN_ACTIVITY_OPTION_IN_DESKTOP_LAUNCH_PARAMS( Flags::respectFullscreenActivityOptionInDesktopLaunchParams, true, Flags.FLAG_RESPECT_FULLSCREEN_ACTIVITY_OPTION_IN_DESKTOP_LAUNCH_PARAMS), SKIP_DEACTIVATION_OF_DESK_WITH_NOTHING_IN_FRONT( Flags::skipDeactivationOfDeskWithNothingInFront, false, Flags.FLAG_SKIP_DEACTIVATION_OF_DESK_WITH_NOTHING_IN_FRONT), USE_RESOURCES_FROM_CONTEXT_TO_CREATE_DRAWABLE_ICONS( com.android.graphics.flags.Flags::useResourcesFromContextToCreateDrawableIcons, true, Loading
core/java/android/window/flags/lse_desktop_experience.aconfig +10 −0 Original line number Diff line number Diff line Loading @@ -1390,6 +1390,16 @@ flag { } } flag { name: "skip_deactivation_of_desk_with_nothing_in_front" namespace: "lse_desktop_experience" description: "Keep the desk active on TO_BACK transitions without nothing else in front" bug: "421124396" metadata { purpose: PURPOSE_BUGFIX } } flag { name: "skip_decor_view_relayout_when_closing_bugfix" namespace: "lse_desktop_experience" Loading
libs/WindowManager/Shell/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserver.kt +23 −4 Original line number Diff line number Diff line Loading @@ -268,6 +268,7 @@ class DesksTransitionObserver( } val wct = WindowContainerTransaction() var hasSeenDesk = false var hasSeenOpeningTask = false val openingUserIds = mutableListOf<Int>() val desksToActivate = mutableListOf<Int>() // Visit all task changes, not just desk/wallpaper changes because we're interested in Loading @@ -276,17 +277,19 @@ class DesksTransitionObserver( val taskInfo = checkNotNull(change.taskInfo) { "Expected non-null task info" } val taskId = taskInfo.taskId logD("Handle change for taskId=%d:", taskId) if (TransitionUtil.isOpeningMode(change.mode) || change.isToTop()) { if (change.isOpeningOrToTop()) { logD("Opening/to-top change for userId=%d", taskInfo.userId) openingUserIds += taskInfo.userId } if (change in deskChanges) { hasSeenDesk = true } else if (change.isOpeningOrToTop()) { hasSeenOpeningTask = true } if (change !in deskChanges && change !in desktopWallpaperChanges) { logD("Not desk or wallpaper, skipping") continue } if (change in deskChanges) { hasSeenDesk = true } val changeUserId = taskInfo.userId val userSwitch = getUserSwitch(change, openingUserIds) logD( Loading Loading @@ -393,6 +396,19 @@ class DesksTransitionObserver( ) when { change.isToBack() -> { if ( !hasSeenOpeningTask && DesktopExperienceFlags.SKIP_DEACTIVATION_OF_DESK_WITH_NOTHING_IN_FRONT .isTrue ) { // In cases such as minimizing the last app, where we want to remain // in an empty desk, WM core may report BOTH the minimizing task and its // (former) parent root as TO_BACK changes. However, the root will still // remain in front (as it should), so do not interpret TO_BACK as it having // to be deactivated unless something else actually showed up in front. logD("desk=%d moved to back but nothing moved to front, skipping", deskId) continue } if ( desksToActivate.contains(deskId) && DesktopExperienceFlags.ENABLE_EMPTY_DESK_ON_MINIMIZE.isTrue Loading Loading @@ -503,6 +519,9 @@ class DesksTransitionObserver( private fun TransitionInfo.Change.isToBack(): Boolean = mode == TRANSIT_TO_BACK private fun TransitionInfo.Change.isOpeningOrToTop(): Boolean = TransitionUtil.isOpeningMode(mode) || isToTop() private fun TransitionInfo.taskChanges(): List<TransitionInfo.Change> = changes.filter { c -> val taskId = c.taskInfo?.taskId Loading
libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/desktopmode/multidesks/DesksTransitionObserverTest.kt +49 −2 Original line number Diff line number Diff line Loading @@ -690,7 +690,10 @@ class DesksTransitionObserverTest : ShellTestCase() { } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) @EnableFlags( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Flags.FLAG_SKIP_DEACTIVATION_OF_DESK_WITH_NOTHING_IN_FRONT, ) fun independentDeskTransition_deskToBack_deactivatesSkippingReorder() = testScope.runTest { val deskId = 5 Loading @@ -703,6 +706,11 @@ class DesksTransitionObserverTest : ShellTestCase() { transition = Binder(), info = buildTransitionInfo() .addHomeChange( mode = TRANSIT_TO_FRONT, userId = repository.userId, displayId = displayId, ) .addDeskChange( deskId = deskId, mode = TRANSIT_TO_BACK, Loading @@ -721,7 +729,10 @@ class DesksTransitionObserverTest : ShellTestCase() { } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) @EnableFlags( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Flags.FLAG_SKIP_DEACTIVATION_OF_DESK_WITH_NOTHING_IN_FRONT, ) fun independentDeskTransition_deskToBack_userSwitch_deactivatesKeepingRepoActive() = testScope.runTest { val deskId = 5 Loading @@ -735,6 +746,11 @@ class DesksTransitionObserverTest : ShellTestCase() { transition = Binder(), info = buildTransitionInfo() .addHomeChange( mode = TRANSIT_TO_FRONT, userId = newUserRepository.userId, displayId = displayId, ) .addDeskChange( deskId = deskId, mode = TRANSIT_TO_BACK, Loading @@ -757,6 +773,37 @@ class DesksTransitionObserverTest : ShellTestCase() { assertThat(oldUserRepository.getActiveDeskId(displayId)).isEqualTo(deskId) } @Test @EnableFlags( Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND, Flags.FLAG_SKIP_DEACTIVATION_OF_DESK_WITH_NOTHING_IN_FRONT, ) fun independentDeskTransition_deskToBackWithNothingInFront_keepsDeskActive() = testScope.runTest { val deskId = 5 val displayId = DEFAULT_DISPLAY val repository = desktopUserRepositories.getProfile(USER_ID_1) repository.addDesk(displayId, deskId) repository.setActiveDesk(displayId, deskId) observer.onTransitionReady( transition = Binder(), info = buildTransitionInfo() .addDeskChange( deskId = deskId, mode = TRANSIT_TO_BACK, userId = repository.userId, displayId = displayId, ), ) runCurrent() verify(mockDesksOrganizer, never()) .deactivateDesk(any(), deskId = eq(5), skipReorder = any()) assertThat(repository.getActiveDeskId(displayId)).isEqualTo(deskId) } @Test @EnableFlags(Flags.FLAG_ENABLE_MULTIPLE_DESKTOPS_BACKEND) fun independentDeskTransition_emptyDeskToBackHomeToFront_userSwitch_deactivatesKeepingRepoActive() = Loading