From 7e3c0c224915a67a2dc06b24e9a64cf3bbf98f05 Mon Sep 17 00:00:00 2001 From: Will Osborn Date: Tue, 18 Mar 2025 14:07:33 +0000 Subject: Get top task per display from TopTaskTracker Test: locally tested on tablet Flag: com.android.launcher3.enable_overview_on_connected_displays Bug: 402362465 Change-Id: I0eb66c5c931fe30ce954657ee1b0eb2d87e58943 --- .../taskbar/FallbackTaskbarUIController.java | 3 ++- .../taskbar/TaskbarViewCallbacksFactory.kt | 3 ++- .../quickstep/LauncherActivityInterface.java | 6 ++++-- .../src/com/android/quickstep/RecentTasksList.java | 2 +- .../src/com/android/quickstep/TopTaskTracker.java | 25 ++++++++++++++++------ .../android/quickstep/TouchInteractionService.java | 4 ++-- .../inputconsumers/NavHandleLongPressHandler.java | 4 ++-- .../NavHandleLongPressInputConsumer.java | 7 +++--- .../android/quickstep/util/AppPairsController.java | 19 ++++++++-------- .../quickstep/util/ContextualSearchInvoker.kt | 3 ++- .../util/ContextualSearchStateManager.java | 4 +++- .../com/android/quickstep/util/ExternalDisplays.kt | 16 ++++++++++---- .../quickstep/util/SplitSelectStateController.java | 2 +- .../src/com/android/quickstep/views/TaskView.kt | 4 ++-- 14 files changed, 65 insertions(+), 37 deletions(-) (limited to 'quickstep/src') diff --git a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java index d6327bc3cd..c4679a716e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java @@ -134,7 +134,8 @@ public class FallbackTaskbarUIController private boolean isIn3pHomeOrRecents() { TopTaskTracker.CachedTaskInfo topTask = TopTaskTracker.INSTANCE - .get(mControllers.taskbarActivityContext).getCachedTopTask(true); + .get(mControllers.taskbarActivityContext).getCachedTopTask(true, + mRecentsContainer.asContext().getDisplayId()); return topTask.isHomeTask() || topTask.isRecentsTask(); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacksFactory.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacksFactory.kt index 17da5336f4..6e948894c2 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacksFactory.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacksFactory.kt @@ -42,7 +42,8 @@ open class TaskbarViewCallbacksFactory : ResourceBasedOverride { if (contextualSearchInvoked) { val runningPackage = TopTaskTracker.INSTANCE[activity].getCachedTopTask( - /* filterOnlyVisibleRecents */ true + /* filterOnlyVisibleRecents */ true, + activity.display.displayId, ) .getPackageName() activity.statsLogManager diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java index ac0aa76ad5..6ec2ff3bd9 100644 --- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java +++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java @@ -261,7 +261,8 @@ public final class LauncherActivityInterface extends return launcher != null && launcher.getStateManager().getState() == OVERVIEW && launcher.isStarted() - && TopTaskTracker.INSTANCE.get(launcher).getCachedTopTask(false).isHomeTask(); + && TopTaskTracker.INSTANCE.get(launcher).getCachedTopTask(false, + launcher.getDisplayId()).isHomeTask(); } private boolean isInMinusOne() { @@ -270,7 +271,8 @@ public final class LauncherActivityInterface extends return launcher != null && launcher.getStateManager().getState() == NORMAL && !launcher.isStarted() - && TopTaskTracker.INSTANCE.get(launcher).getCachedTopTask(false).isHomeTask(); + && TopTaskTracker.INSTANCE.get(launcher).getCachedTopTask(false, + launcher.getDisplayId()).isHomeTask(); } @Override diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java index dab78c5df3..a77241549c 100644 --- a/quickstep/src/com/android/quickstep/RecentTasksList.java +++ b/quickstep/src/com/android/quickstep/RecentTasksList.java @@ -504,7 +504,7 @@ public class RecentTasksList implements WindowManagerProxy.DesktopVisibilityList for (TaskInfo taskInfo : recentTaskInfo.getTaskInfoList()) { Task task = createTask(taskInfo, minimizedTaskIds); List tasks = perDisplayTasks.computeIfAbsent( - ExternalDisplaysKt.getDisplayId(task), + ExternalDisplaysKt.getSafeDisplayId(task), k -> new ArrayList<>()); tasks.add(task); } diff --git a/quickstep/src/com/android/quickstep/TopTaskTracker.java b/quickstep/src/com/android/quickstep/TopTaskTracker.java index 8116a8867d..7e773e3a58 100644 --- a/quickstep/src/com/android/quickstep/TopTaskTracker.java +++ b/quickstep/src/com/android/quickstep/TopTaskTracker.java @@ -22,8 +22,10 @@ import static android.content.Intent.ACTION_CHOOSER; import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS; import static android.view.Display.DEFAULT_DISPLAY; +import static com.android.launcher3.Flags.enableOverviewOnConnectedDisplays; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_TYPE_A; +import static com.android.quickstep.fallback.window.RecentsWindowFlags.enableOverviewOnConnectedDisplays; import static com.android.wm.shell.Flags.enableShellTopTaskTracking; import static com.android.wm.shell.Flags.enableFlexibleSplit; import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_SPLIT; @@ -47,6 +49,7 @@ import com.android.launcher3.util.SplitConfigurationOptions.StageType; import com.android.launcher3.util.TraceHelper; import com.android.quickstep.dagger.QuickstepBaseAppComponent; import com.android.quickstep.util.DesksUtils; +import com.android.quickstep.util.ExternalDisplaysKt; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.Task.TaskKey; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -316,21 +319,26 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta */ @NonNull @UiThread - public CachedTaskInfo getCachedTopTask(boolean filterOnlyVisibleRecents) { + public CachedTaskInfo getCachedTopTask(boolean filterOnlyVisibleRecents, int displayId) { if (enableShellTopTaskTracking()) { // TODO(346588978): Currently ignore filterOnlyVisibleRecents, but perhaps make this an // explicit filter For things to ignore (ie. PIP/Bubbles/Assistant/etc/so that this is // explicit) - // TODO(346588978): This assumes default display as gesture nav is only supported there - return new CachedTaskInfo(mVisibleTasks.get(DEFAULT_DISPLAY)); + return new CachedTaskInfo(mVisibleTasks.get(displayId)); } else { if (filterOnlyVisibleRecents) { // Since we only know about the top most task, any filtering may not be applied on // the cache. The second to top task may change while the top task is still the // same. - RunningTaskInfo[] tasks = TraceHelper.allowIpcs("getCachedTopTask.true", () -> + TaskInfo[] tasks = TraceHelper.allowIpcs("getCachedTopTask.true", () -> ActivityManagerWrapper.getInstance().getRunningTasks(true)); - return new CachedTaskInfo(Arrays.asList(tasks)); + if (enableOverviewOnConnectedDisplays()) { + return new CachedTaskInfo(Arrays.stream(tasks).filter( + info -> ExternalDisplaysKt.getSafeDisplayId(info) + == displayId).toList()); + } else { + return new CachedTaskInfo(Arrays.asList(tasks)); + } } if (mOrderedTaskList.isEmpty()) { @@ -344,7 +352,12 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta // Strip the pinned task and recents task tasks.removeIf(t -> t.taskId == mPinnedTaskId || isRecentsTask(t) || DesksUtils.isDesktopWallpaperTask(t)); - return new CachedTaskInfo(tasks); + if (enableOverviewOnConnectedDisplays()) { + return new CachedTaskInfo(tasks.stream().filter( + info -> ExternalDisplaysKt.getSafeDisplayId(info) == displayId).toList()); + } else { + return new CachedTaskInfo(tasks); + } } } diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 7878e68a94..c187db8055 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -1089,7 +1089,7 @@ public class TouchInteractionService extends Service { // previousTaskInfo can be null iff previousGestureState == GestureState.DEFAULT_STATE taskInfo = previousTaskInfo != null ? previousTaskInfo - : TopTaskTracker.INSTANCE.get(this).getCachedTopTask(false); + : TopTaskTracker.INSTANCE.get(this).getCachedTopTask(false, displayId); gestureState.updateRunningTask(taskInfo); gestureState.updateLastStartedTaskIds(previousGestureState.getLastStartedTaskIds()); gestureState.updatePreviouslyAppearedTaskIds( @@ -1099,7 +1099,7 @@ public class TouchInteractionService extends Service { mOverviewComponentObserver, displayId, ActiveGestureLog.INSTANCE.incrementLogId()); - taskInfo = TopTaskTracker.INSTANCE.get(this).getCachedTopTask(false); + taskInfo = TopTaskTracker.INSTANCE.get(this).getCachedTopTask(false, displayId); gestureState.updateRunningTask(taskInfo); } gestureState.setTrackpadGestureType(trackpadGestureType); diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java index 107babd61e..571a5468d1 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressHandler.java @@ -88,7 +88,7 @@ public class NavHandleLongPressHandler implements ResourceBasedOverride { */ @Nullable @VisibleForTesting - final Runnable getLongPressRunnable(NavHandle navHandle) { + final Runnable getLongPressRunnable(NavHandle navHandle, int displayId) { if (!isContextualSearchEntrypointEnabled(navHandle)) { Log.i(TAG, "Contextual Search invocation failed: entry point disabled"); mVibratorWrapper.cancelVibrate(); @@ -116,7 +116,7 @@ public class NavHandleLongPressHandler implements ResourceBasedOverride { Log.i(TAG, "Contextual Search invocation successful"); String runningPackage = TopTaskTracker.INSTANCE.get(mContext).getCachedTopTask( - /* filterOnlyVisibleRecents */ true).getPackageName(); + /* filterOnlyVisibleRecents */ true, displayId).getPackageName(); mStatsLogManager.logger().withPackageName(runningPackage) .log(LAUNCHER_LAUNCH_ASSISTANT_SUCCESSFUL_NAV_HANDLE); } else { diff --git a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java index baabde884e..af7c975e0b 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/NavHandleLongPressInputConsumer.java @@ -214,7 +214,7 @@ public class NavHandleLongPressInputConsumer extends DelegateInputConsumer { && !mDeepPressLogged) { // Log deep press even if feature is disabled. String runningPackage = mTopTaskTracker.getCachedTopTask( - /* filterOnlyVisibleRecents */ true).getPackageName(); + /* filterOnlyVisibleRecents */ true, getDisplayId()).getPackageName(); mStatsLogManager.logger().withPackageName(runningPackage).log( mNavHandle.isNavHandleStashedTaskbar() ? LAUNCHER_DEEP_PRESS_STASHED_TASKBAR : LAUNCHER_DEEP_PRESS_NAVBAR); @@ -233,12 +233,13 @@ public class NavHandleLongPressInputConsumer extends DelegateInputConsumer { Log.d(TAG, "triggerLongPress"); } String runningPackage = mTopTaskTracker.getCachedTopTask( - /* filterOnlyVisibleRecents */ true).getPackageName(); + /* filterOnlyVisibleRecents */ true, getDisplayId()).getPackageName(); mStatsLogManager.logger().withPackageName(runningPackage).log( mNavHandle.isNavHandleStashedTaskbar() ? LAUNCHER_LONG_PRESS_STASHED_TASKBAR : LAUNCHER_LONG_PRESS_NAVBAR); - Runnable longPressRunnable = mNavHandleLongPressHandler.getLongPressRunnable(mNavHandle); + Runnable longPressRunnable = mNavHandleLongPressHandler.getLongPressRunnable(mNavHandle, + getDisplayId()); if (longPressRunnable == null) { return; } diff --git a/quickstep/src/com/android/quickstep/util/AppPairsController.java b/quickstep/src/com/android/quickstep/util/AppPairsController.java index 8385485253..24c01ae26d 100644 --- a/quickstep/src/com/android/quickstep/util/AppPairsController.java +++ b/quickstep/src/com/android/quickstep/util/AppPairsController.java @@ -32,7 +32,6 @@ import static com.android.wm.shell.shared.split.SplitScreenConstants.SNAP_TO_NON import static com.android.wm.shell.shared.split.SplitScreenConstants.getIndex; import static com.android.wm.shell.shared.split.SplitScreenConstants.isPersistentSnapPosition; -import android.content.Context; import android.content.Intent; import android.content.pm.LauncherApps; import android.util.Log; @@ -93,10 +92,10 @@ public class AppPairsController { private static final int BITMASK_SIZE = 16; private static final int BITMASK_FOR_SNAP_POSITION = (1 << BITMASK_SIZE) - 1; - private Context mContext; + private ActivityContext mContext; private final SplitSelectStateController mSplitSelectStateController; private final StatsLogManager mStatsLogManager; - public AppPairsController(Context context, + public AppPairsController(ActivityContext context, SplitSelectStateController splitSelectStateController, StatsLogManager statsLogManager) { mContext = context; @@ -208,7 +207,7 @@ public class AppPairsController { } AppPairInfo newAppPair = new AppPairInfo(apps); - IconCache iconCache = LauncherAppState.getInstance(mContext).getIconCache(); + IconCache iconCache = LauncherAppState.getInstance(mContext.asContext()).getIconCache(); MODEL_EXECUTOR.execute(() -> { newAppPair.getAppContents().forEach(member -> { member.title = ""; @@ -216,8 +215,8 @@ public class AppPairsController { iconCache.getTitleAndIcon(member, member.getMatchingLookupFlag()); }); MAIN_EXECUTOR.execute(() -> { - LauncherAccessibilityDelegate delegate = - QuickstepLauncher.getLauncher(mContext).getAccessibilityDelegate(); + LauncherAccessibilityDelegate delegate = QuickstepLauncher.getLauncher( + mContext.asContext()).getAccessibilityDelegate(); if (delegate != null) { delegate.addToWorkspace(newAppPair, true, (success) -> { if (success) { @@ -300,7 +299,7 @@ public class AppPairsController { */ @Nullable private AppInfo resolveAppInfoByComponent(@NonNull ComponentKey key) { - AllAppsStore appsStore = ActivityContext.lookupContext(mContext) + AllAppsStore appsStore = ActivityContext.lookupContext(mContext.asContext()) .getAppsView().getAppsStore(); // First look up the app info in order of: @@ -326,7 +325,7 @@ public class AppPairsController { if (appInfo == null) { return null; } - return appInfo.makeWorkspaceItem(mContext); + return appInfo.makeWorkspaceItem(mContext.asContext()); } /** @@ -418,7 +417,7 @@ public class AppPairsController { } else { // Tapped an app pair while in a single app final TopTaskTracker.CachedTaskInfo runningTask = topTaskTracker - .getCachedTopTask(false /* filterOnlyVisibleRecents */); + .getCachedTopTask(false /* filterOnlyVisibleRecents */, context.getDisplayId()); mSplitSelectStateController.findLastActiveTasksAndRunCallback( componentKeys, @@ -548,6 +547,6 @@ public class AppPairsController { */ @VisibleForTesting public TopTaskTracker getTopTaskTracker() { - return TopTaskTracker.INSTANCE.get(mContext); + return TopTaskTracker.INSTANCE.get(mContext.asContext()); } } diff --git a/quickstep/src/com/android/quickstep/util/ContextualSearchInvoker.kt b/quickstep/src/com/android/quickstep/util/ContextualSearchInvoker.kt index 3bc9adcba6..e574cc7cdd 100644 --- a/quickstep/src/com/android/quickstep/util/ContextualSearchInvoker.kt +++ b/quickstep/src/com/android/quickstep/util/ContextualSearchInvoker.kt @@ -87,7 +87,8 @@ internal constructor( if (success) { val runningPackage = TopTaskTracker.INSTANCE[context].getCachedTopTask( - /* filterOnlyVisibleRecents */ true + /* filterOnlyVisibleRecents */ true, + DEFAULT_DISPLAY, ) .getPackageName() statsLogManager diff --git a/quickstep/src/com/android/quickstep/util/ContextualSearchStateManager.java b/quickstep/src/com/android/quickstep/util/ContextualSearchStateManager.java index a8d3c6d5a3..136c496dce 100644 --- a/quickstep/src/com/android/quickstep/util/ContextualSearchStateManager.java +++ b/quickstep/src/com/android/quickstep/util/ContextualSearchStateManager.java @@ -18,6 +18,7 @@ package com.android.quickstep.util; import static android.app.contextualsearch.ContextualSearchManager.ACTION_LAUNCH_CONTEXTUAL_SEARCH; import static android.app.contextualsearch.ContextualSearchManager.ENTRYPOINT_SYSTEM_ACTION; import static android.app.contextualsearch.ContextualSearchManager.FEATURE_CONTEXTUAL_SEARCH; +import static android.view.Display.DEFAULT_DISPLAY; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_LAUNCH_OMNI_SUCCESSFUL_SYSTEM_ACTION; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; @@ -244,7 +245,8 @@ public class ContextualSearchStateManager { ENTRYPOINT_SYSTEM_ACTION); if (contextualSearchInvoked) { String runningPackage = mTopTaskTracker.getCachedTopTask( - /* filterOnlyVisibleRecents */ true).getPackageName(); + /* filterOnlyVisibleRecents */ true, + DEFAULT_DISPLAY).getPackageName(); StatsLogManager.newInstance(mContext).logger() .withPackageName(runningPackage) .log(LAUNCHER_LAUNCH_OMNI_SUCCESSFUL_SYSTEM_ACTION); diff --git a/quickstep/src/com/android/quickstep/util/ExternalDisplays.kt b/quickstep/src/com/android/quickstep/util/ExternalDisplays.kt index 455b3121ec..0aaca31f8b 100644 --- a/quickstep/src/com/android/quickstep/util/ExternalDisplays.kt +++ b/quickstep/src/com/android/quickstep/util/ExternalDisplays.kt @@ -16,6 +16,7 @@ package com.android.quickstep.util +import android.app.TaskInfo import android.view.Display.DEFAULT_DISPLAY import android.view.Display.INVALID_DISPLAY import com.android.systemui.shared.recents.model.Task @@ -24,10 +25,9 @@ import com.android.systemui.shared.recents.model.Task val Int.isExternalDisplay get() = this != DEFAULT_DISPLAY -/** Returns displayId of this [Task], default to [DEFAULT_DISPLAY] */ -val Task?.displayId +val Int?.safeDisplayId get() = - this?.key?.displayId.let { displayId -> + this.let { displayId -> when (displayId) { null -> DEFAULT_DISPLAY INVALID_DISPLAY -> DEFAULT_DISPLAY @@ -35,6 +35,14 @@ val Task?.displayId } } +/** Returns displayId of this [Task], default to [DEFAULT_DISPLAY] */ +val Task?.safeDisplayId + get() = this?.key?.displayId.safeDisplayId + /** Returns if this task belongs tto [DEFAULT_DISPLAY] */ val Task?.isExternalDisplay - get() = displayId.isExternalDisplay + get() = safeDisplayId.isExternalDisplay + +/** Returns displayId of this [TaskInfo], default to [DEFAULT_DISPLAY] */ +val TaskInfo?.safeDisplayId + get() = this?.displayId.safeDisplayId diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java index fd8b356708..08f2552157 100644 --- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java @@ -195,7 +195,7 @@ public class SplitSelectStateController { mRecentTasksModel = recentsModel; mActivityBackCallback = activityBackCallback; mSplitAnimationController = new SplitAnimationController(this); - mAppPairsController = new AppPairsController(mContainer.asContext(), this, statsLogManager); + mAppPairsController = new AppPairsController(mContainer, this, statsLogManager); mSplitSelectDataHolder = new SplitSelectDataHolder(mContainer.asContext()); } diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt index b1561fa769..a108afc34b 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.kt +++ b/quickstep/src/com/android/quickstep/views/TaskView.kt @@ -97,8 +97,8 @@ import com.android.quickstep.util.BorderAnimator.Companion.createSimpleBorderAni import com.android.quickstep.util.RecentsOrientedState import com.android.quickstep.util.TaskCornerRadius import com.android.quickstep.util.TaskRemovedDuringLaunchListener -import com.android.quickstep.util.displayId import com.android.quickstep.util.isExternalDisplay +import com.android.quickstep.util.safeDisplayId import com.android.quickstep.views.IconAppChipView.AppChipStatus import com.android.quickstep.views.OverviewActionsView.DISABLED_NO_THUMBNAIL import com.android.quickstep.views.OverviewActionsView.DISABLED_ROTATED @@ -155,7 +155,7 @@ constructor( get() = this === recentsView?.selectedTaskView open val displayId: Int - get() = taskContainers.firstOrNull()?.task.displayId + get() = taskContainers.firstOrNull()?.task.safeDisplayId val isExternalDisplay: Boolean get() = displayId.isExternalDisplay -- cgit v1.2.3-59-g8ed1b