From 2842bc72fd759bc72387304a6d28da44ce0b1fca Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Fri, 6 Jan 2023 16:33:51 -0800 Subject: [PATCH] Fix bug with Taskbar launches in Overview This patch fixes a bug where Taskbar launches (tapping an icon on the Taskbar) were not executing correctly in Overview. Now that Taskbar is always present in Overview, we need to handle cases where the user taps to launch an app, but the app is already visible to the user in Overview. This was breaking in a noticeable way with split apps, where the Taskbar simply wouldn't respond when the tapped app was already visible as a live tile. Fixed by polling RecentsModel for already-running tasks, checking to see if the associated TaskView is visible to the user or not, and calling launchTasks() on the TaskView if so. If the tile is not visible to the user, the app will launch normally. Fixes: 261952204 Test: Work in progress Change-Id: If761546913bde7451a22456a272ba6c31942c5f8 --- .../popup/QuickstepSystemShortcut.java | 2 +- .../taskbar/TaskbarActivityContext.java | 39 ++++++++++++++++--- .../taskbar/TaskbarUIController.java | 2 +- .../android/quickstep/views/RecentsView.java | 8 ++-- 4 files changed, 39 insertions(+), 12 deletions(-) diff --git a/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java b/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java index 9554bd3d9c..45d1b11c56 100644 --- a/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java +++ b/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java @@ -101,7 +101,7 @@ public interface QuickstepSystemShortcut { RecentsView recentsView = mTarget.getOverviewPanel(); // Check if there is already an instance of this app running, if so, initiate the split // using that. - recentsView.findLastActiveTaskAndDoSplitOperation( + recentsView.findLastActiveTaskAndRunCallback( intent.getComponent(), (Consumer) foundTask -> { SplitSelectSource source = new SplitSelectSource(mOriginalView, diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 731eea78e9..ba1cf9e1d1 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -94,6 +94,7 @@ import com.android.launcher3.util.TraceHelper; import com.android.launcher3.util.ViewCache; import com.android.launcher3.views.ActivityContext; import com.android.quickstep.views.RecentsView; +import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.rotation.RotationButtonController; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -101,6 +102,7 @@ import com.android.systemui.unfold.updates.RotationChangeProvider; import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider; import java.io.PrintWriter; +import java.util.function.Consumer; /** * The {@link ActivityContext} with which we inflate Taskbar-related Views. This allows UI elements @@ -781,12 +783,12 @@ public class TaskbarActivityContext extends BaseTaskbarContext { }); }); } else if (tag instanceof WorkspaceItemInfo) { + // Tapping a launchable icon on Taskbar WorkspaceItemInfo info = (WorkspaceItemInfo) tag; if (!info.isDisabled() || !ItemClickHandler.handleDisabledItemClicked(info, this)) { TaskbarUIController taskbarUIController = mControllers.uiController; RecentsView recents = taskbarUIController.getRecentsView(); - if (recents != null - && taskbarUIController.getRecentsView().isSplitSelectionActive()) { + if (recents != null && recents.isSplitSelectionActive()) { // If we are selecting a second app for split, launch the split tasks taskbarUIController.triggerSecondAppForSplit(info, info.intent, view); } else { @@ -813,7 +815,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { getSystemService(LauncherApps.class) .startShortcut(packageName, id, null, null, info.user); } else { - startItemInfoActivity(info); + launchFromTaskbarPreservingSplitIfVisible(recents, info); } mControllers.uiController.onTaskbarIconLaunched(info); @@ -828,6 +830,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true); } } else if (tag instanceof AppInfo) { + // Tapping an item in AllApps AppInfo info = (AppInfo) tag; TaskbarUIController taskbarUIController = mControllers.uiController; RecentsView recents = taskbarUIController.getRecentsView(); @@ -836,9 +839,8 @@ public class TaskbarActivityContext extends BaseTaskbarContext { // If we are selecting a second app for split, launch the split tasks taskbarUIController.triggerSecondAppForSplit(info, info.intent, view); } else { - // Else launch the selected task - startItemInfoActivity((AppInfo) tag); - mControllers.uiController.onTaskbarIconLaunched((AppInfo) tag); + launchFromTaskbarPreservingSplitIfVisible(recents, info); + mControllers.uiController.onTaskbarIconLaunched(info); } mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true); } else if (tag instanceof ItemClickProxy) { @@ -850,6 +852,31 @@ public class TaskbarActivityContext extends BaseTaskbarContext { AbstractFloatingView.closeAllOpenViews(this); } + /** + * Run when the user taps a Taskbar icon while in Overview. If the tapped app is currently + * visible to the user in Overview, or is part of a visible split pair, we expand the TaskView + * as if the user tapped on it (preserving the split pair). Otherwise, launch it normally + * (potentially breaking a split pair). + */ + private void launchFromTaskbarPreservingSplitIfVisible(RecentsView recents, ItemInfo info) { + recents.findLastActiveTaskAndRunCallback( + info.getTargetComponent(), + (Consumer) foundTask -> { + if (foundTask != null) { + TaskView foundTaskView = + recents.getTaskViewByTaskId(foundTask.key.id); + if (foundTaskView != null + && foundTaskView.isVisibleToUser()) { + TestLogging.recordEvent( + TestProtocol.SEQUENCE_MAIN, "start: taskbarAppIcon"); + foundTaskView.launchTasks(); + return; + } + } + startItemInfoActivity(info); + }); + } + private void startItemInfoActivity(ItemInfo info) { Intent intent = new Intent(info.getIntent()) .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java index 7b0374614c..ebb37a88fc 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java @@ -170,7 +170,7 @@ public class TaskbarUIController { */ public void triggerSecondAppForSplit(ItemInfoWithIcon info, Intent intent, View startingView) { RecentsView recents = getRecentsView(); - recents.findLastActiveTaskAndDoSplitOperation( + recents.findLastActiveTaskAndRunCallback( info.getTargetComponent(), (Consumer) foundTask -> { if (foundTask != null) { diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 5e645ea917..8ac4251951 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1275,14 +1275,14 @@ public abstract class RecentsView callback) { mModel.getTasks(taskGroups -> { Task lastActiveTask = null;