diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java index 7a63f74d4a..5e116012d5 100644 --- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java @@ -47,7 +47,6 @@ import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import com.android.systemui.shared.system.QuickStepContract; -import com.android.window.flags.Flags; import java.io.PrintWriter; import java.util.List; @@ -247,8 +246,9 @@ public class KeyboardQuickSwitchViewController { return -1; } RemoteTransition remoteTransition = slideInTransition; - if (mOnDesktop && task.task1.isMinimized - && Flags.enableDesktopAppLaunchAlttabTransitions()) { + if (mOnDesktop + && mControllers.taskbarActivityContext.canUnminimizeDesktopTask(task.task1.key.id) + ) { // This app is being unminimized - use our own transition runner. remoteTransition = new RemoteTransition( new DesktopAppLaunchTransition(context, MAIN_EXECUTOR)); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index e22de06374..c9c52b59ad 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -72,6 +72,7 @@ import android.view.WindowInsets; import android.view.WindowManager; import android.widget.FrameLayout; import android.widget.Toast; +import android.window.DesktopModeFlags; import android.window.RemoteTransition; import androidx.annotation.NonNull; @@ -89,6 +90,7 @@ import com.android.launcher3.R; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.apppairs.AppPairIcon; import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.desktop.DesktopAppLaunchTransition; import com.android.launcher3.dot.DotInfo; import com.android.launcher3.folder.Folder; import com.android.launcher3.folder.FolderIcon; @@ -1219,10 +1221,10 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mControllers.keyboardQuickSwitchController.closeQuickSwitchView(false); if (tag instanceof GroupTask groupTask) { - handleGroupTaskLaunch( - groupTask, - /* remoteTransition= */ null, - areDesktopTasksVisible()); + RemoteTransition remoteTransition = + (areDesktopTasksVisible() && canUnminimizeDesktopTask(groupTask.task1.key.id)) + ? createUnminimizeRemoteTransition() : null; + handleGroupTaskLaunch(groupTask, remoteTransition, areDesktopTasksVisible()); mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true); } else if (tag instanceof FolderInfo) { // Tapping an expandable folder icon on Taskbar @@ -1240,9 +1242,11 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true); } } else if (tag instanceof TaskItemInfo info) { + RemoteTransition remoteTransition = canUnminimizeDesktopTask(info.getTaskId()) + ? createUnminimizeRemoteTransition() : null; UI_HELPER_EXECUTOR.execute(() -> SystemUiProxy.INSTANCE.get(this).showDesktopApp( - info.getTaskId(), /* remoteTransition= */ null)); + info.getTaskId(), remoteTransition)); mControllers.taskbarStashController.updateAndAnimateTransientTaskbar( /* stash= */ true); } else if (tag instanceof WorkspaceItemInfo) { @@ -1361,8 +1365,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { return; } if (onDesktop) { - boolean useRemoteTransition = task.task1.isMinimized - && com.android.window.flags.Flags.enableDesktopAppLaunchAlttabTransitions(); + boolean useRemoteTransition = canUnminimizeDesktopTask(task.task1.key.id); UI_HELPER_EXECUTOR.execute(() -> { if (onStartCallback != null) { onStartCallback.run(); @@ -1389,6 +1392,18 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mControllers.uiController.launchSplitTasks(task, remoteTransition); } + /** Returns whether the given task is minimized and can be unminimized. */ + public boolean canUnminimizeDesktopTask(int taskId) { + BubbleTextView.RunningAppState runningAppState = + mControllers.taskbarRecentAppsController.getRunningAppState(taskId); + return runningAppState == BubbleTextView.RunningAppState.MINIMIZED + && DesktopModeFlags.ENABLE_DESKTOP_APP_LAUNCH_ALTTAB_TRANSITIONS.isTrue(); + } + + private RemoteTransition createUnminimizeRemoteTransition() { + return new RemoteTransition(new DesktopAppLaunchTransition(this, getMainExecutor())); + } + /** * Runs when the user taps a Taskbar icon in TaskbarActivityContext (Overview or inside an app), * and calls the appropriate method to animate and launch. diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java index bdefea6b22..c20617de01 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java @@ -42,7 +42,6 @@ import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.function.Predicate; /** @@ -196,26 +195,21 @@ public class TaskbarModelCallbacks implements final TaskbarRecentAppsController recentAppsController = mControllers.taskbarRecentAppsController; hotseatItemInfos = recentAppsController.updateHotseatItemInfos(hotseatItemInfos); - Set runningTaskIds = recentAppsController.getRunningTaskIds(); - Set minimizedTaskIds = recentAppsController.getMinimizedTaskIds(); if (mDeferUpdatesForSUW) { ItemInfo[] finalHotseatItemInfos = hotseatItemInfos; mDeferredUpdates = () -> commitHotseatItemUpdates(finalHotseatItemInfos, - recentAppsController.getShownTasks(), runningTaskIds, - minimizedTaskIds); + recentAppsController.getShownTasks()); } else { - commitHotseatItemUpdates(hotseatItemInfos, - recentAppsController.getShownTasks(), runningTaskIds, minimizedTaskIds); + commitHotseatItemUpdates(hotseatItemInfos, recentAppsController.getShownTasks()); } } - private void commitHotseatItemUpdates(ItemInfo[] hotseatItemInfos, List recentTasks, - Set runningTaskIds, Set minimizedTaskIds) { + private void commitHotseatItemUpdates( + ItemInfo[] hotseatItemInfos, List recentTasks) { mContainer.updateHotseatItems(hotseatItemInfos, recentTasks); - mControllers.taskbarViewController.updateIconViewsRunningStates( - runningTaskIds, minimizedTaskIds); + mControllers.taskbarViewController.updateIconViewsRunningStates(); } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt index 3e8b615b69..7b0504323e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarRecentAppsController.kt @@ -18,6 +18,7 @@ package com.android.launcher3.taskbar import android.content.Context import android.window.DesktopModeFlags import androidx.annotation.VisibleForTesting +import com.android.launcher3.BubbleTextView.RunningAppState import com.android.launcher3.Flags.enableRecentsInTaskbar import com.android.launcher3.model.data.ItemInfo import com.android.launcher3.model.data.TaskItemInfo @@ -72,6 +73,16 @@ class TaskbarRecentAppsController(context: Context, private val recentsModel: Re var shownTasks: List = emptyList() private set + /** Get the [RunningAppState] for the given task. */ + fun getRunningAppState(taskId: Int): RunningAppState { + return when (taskId) { + in minimizedTaskIds -> RunningAppState.MINIMIZED + in runningTaskIds -> RunningAppState.RUNNING + else -> RunningAppState.NOT_RUNNING + } + } + + @VisibleForTesting val runningTaskIds: Set /** * Returns the task IDs of apps that should be indicated as "running" to the user. @@ -88,6 +99,7 @@ class TaskbarRecentAppsController(context: Context, private val recentsModel: Re return tasks.map { task -> task.key.id }.toSet() } + @VisibleForTesting val minimizedTaskIds: Set /** * Returns the task IDs for the tasks that should be indicated as "minimized" to the user. diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 87e19be6de..494c472cc9 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -623,12 +623,10 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar * Updates which icons are marked as running or minimized given the Sets of currently running * and minimized tasks. */ - public void updateIconViewsRunningStates(Set runningTaskIds, - Set minimizedTaskIds) { + public void updateIconViewsRunningStates() { for (View iconView : getIconViews()) { if (iconView instanceof BubbleTextView btv) { - btv.updateRunningState( - getRunningAppState(btv, runningTaskIds, minimizedTaskIds)); + btv.updateRunningState(getRunningAppState(btv)); } } } @@ -651,26 +649,15 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar return pinnedAppsWithTasks; } - private BubbleTextView.RunningAppState getRunningAppState( - BubbleTextView btv, - Set runningTaskIds, - Set minimizedTaskIds) { + private BubbleTextView.RunningAppState getRunningAppState(BubbleTextView btv) { Object tag = btv.getTag(); if (tag instanceof TaskItemInfo itemInfo) { - if (minimizedTaskIds.contains(itemInfo.getTaskId())) { - return BubbleTextView.RunningAppState.MINIMIZED; - } - if (runningTaskIds.contains(itemInfo.getTaskId())) { - return BubbleTextView.RunningAppState.RUNNING; - } + return mControllers.taskbarRecentAppsController.getRunningAppState( + itemInfo.getTaskId()); } if (tag instanceof GroupTask groupTask && !groupTask.hasMultipleTasks()) { - if (minimizedTaskIds.contains(groupTask.task1.key.id)) { - return BubbleTextView.RunningAppState.MINIMIZED; - } - if (runningTaskIds.contains(groupTask.task1.key.id)) { - return BubbleTextView.RunningAppState.RUNNING; - } + return mControllers.taskbarRecentAppsController.getRunningAppState( + groupTask.task1.key.id); } return BubbleTextView.RunningAppState.NOT_RUNNING; } diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt index b67bc5a952..59413d3500 100644 --- a/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt +++ b/quickstep/tests/src/com/android/launcher3/taskbar/TaskbarRecentAppsControllerTest.kt @@ -26,6 +26,7 @@ import android.os.UserHandle import android.platform.test.rule.TestWatcher import android.testing.AndroidTestingRunner import com.android.internal.R +import com.android.launcher3.BubbleTextView.RunningAppState import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT import com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION import com.android.launcher3.model.data.AppInfo @@ -147,6 +148,37 @@ class TaskbarRecentAppsControllerTest : TaskbarBaseTestCase() { verify(mockRecentsModel, times(1)).getTasks(any>>()) } + @Test + fun getRunningAppState_taskNotRunningOrMinimized_returnsNotRunning() { + setInDesktopMode(true) + updateRecentTasks(runningTasks = emptyList(), recentTaskPackages = emptyList()) + + assertThat(recentAppsController.getRunningAppState(taskId = 1)) + .isEqualTo(RunningAppState.NOT_RUNNING) + } + + @Test + fun getRunningAppState_taskNotVisible_returnsMinimized() { + setInDesktopMode(true) + val task1 = createTask(id = 1, packageName = RUNNING_APP_PACKAGE_1, isVisible = false) + val task2 = createTask(id = 2, packageName = RUNNING_APP_PACKAGE_1, isVisible = true) + updateRecentTasks(runningTasks = listOf(task1, task2), recentTaskPackages = emptyList()) + + assertThat(recentAppsController.getRunningAppState(taskId = 1)) + .isEqualTo(RunningAppState.MINIMIZED) + } + + @Test + fun getRunningAppState_taskVisible_returnsRunning() { + setInDesktopMode(true) + val task1 = createTask(id = 1, packageName = RUNNING_APP_PACKAGE_1, isVisible = false) + val task2 = createTask(id = 2, packageName = RUNNING_APP_PACKAGE_1, isVisible = true) + updateRecentTasks(runningTasks = listOf(task1, task2), recentTaskPackages = emptyList()) + + assertThat(recentAppsController.getRunningAppState(taskId = 2)) + .isEqualTo(RunningAppState.RUNNING) + } + @Test fun updateHotseatItemInfos_cantShowRunning_inDesktopMode_returnsAllHotseatItems() { recentAppsController.canShowRunningApps = false