diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java index c4ba2d52bb..f093f62cdf 100644 --- a/quickstep/src/com/android/quickstep/GestureState.java +++ b/quickstep/src/com/android/quickstep/GestureState.java @@ -361,7 +361,8 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL * @return the single top-most running taskId for this gesture */ public int getTopRunningTaskId() { - return getRunningTaskIds(false /*getMultipleTasks*/)[0]; + var taskIds = getRunningTaskIds(/* getMultipleTasks = */ false); + return taskIds.length != 0 ? taskIds[0] : INVALID_TASK_ID; } /** diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java index a77241549c..b481fe8ede 100644 --- a/quickstep/src/com/android/quickstep/RecentTasksList.java +++ b/quickstep/src/com/android/quickstep/RecentTasksList.java @@ -417,6 +417,7 @@ public class RecentTasksList implements WindowManagerProxy.DesktopVisibilityList continue; } + // [getTaskInfo1] will not be null for types below beside [TYPE_DESK]. if (Flags.enableShellTopTaskTracking()) { final TaskInfo taskInfo1 = rawTask.getBaseGroupedTask().getTaskInfo1(); final Task.TaskKey task1Key = new Task.TaskKey(taskInfo1); diff --git a/quickstep/src/com/android/quickstep/TopTaskTracker.java b/quickstep/src/com/android/quickstep/TopTaskTracker.java index 2b83311052..53344a1408 100644 --- a/quickstep/src/com/android/quickstep/TopTaskTracker.java +++ b/quickstep/src/com/android/quickstep/TopTaskTracker.java @@ -26,12 +26,13 @@ import static android.view.Display.INVALID_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_DESK; import static com.android.wm.shell.shared.GroupedTaskInfo.TYPE_SPLIT; import static com.android.launcher3.statehandlers.DesktopVisibilityController.INACTIVE_DESK_ID; import static com.android.wm.shell.shared.desktopmode.DesktopModeStatus.canEnterDesktopMode; +import static com.android.wm.shell.shared.desktopmode.DesktopModeStatus.enableMultipleDesktops; import android.app.ActivityManager.RunningTaskInfo; import android.app.TaskInfo; @@ -46,6 +47,7 @@ import androidx.annotation.UiThread; import com.android.launcher3.dagger.ApplicationContext; import com.android.launcher3.dagger.LauncherAppSingleton; +import com.android.launcher3.statehandlers.DesktopVisibilityController; import com.android.launcher3.util.DaggerSingletonObject; import com.android.launcher3.util.DaggerSingletonTracker; import com.android.launcher3.util.SplitConfigurationOptions; @@ -96,7 +98,7 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta // most. private ArrayMap mVisibleTasks = new ArrayMap<>(); - private final boolean mCanEnterDesktopMode; + private final Context mContext; @Inject public TopTaskTracker(@ApplicationContext Context context, DaggerSingletonTracker tracker, @@ -118,7 +120,7 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta systemUiProxy.unregisterSplitScreenListener(this); }); - mCanEnterDesktopMode = canEnterDesktopMode(context); + mContext = context; } @Override @@ -201,7 +203,13 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta Log.d(TAG, "onVisibleTasksChanged:"); for (GroupedTaskInfo groupedTask : visibleTasks) { Log.d(TAG, "\t" + groupedTask); - final int displayId = groupedTask.getBaseGroupedTask().getTaskInfo1().getDisplayId(); + GroupedTaskInfo baseGroupedTask = groupedTask.getBaseGroupedTask(); + int displayId; + if (enableMultipleDesktops(mContext) && baseGroupedTask.isBaseType(TYPE_DESK)) { + displayId = baseGroupedTask.getDeskDisplayId(); + } else { + displayId = baseGroupedTask.getTaskInfo1().getDisplayId(); + } mVisibleTasks.put(displayId, groupedTask); } } @@ -344,9 +352,9 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta if (enableOverviewOnConnectedDisplays()) { return new CachedTaskInfo(Arrays.stream(tasks).filter( info -> ExternalDisplaysKt.getSafeDisplayId(info) - == displayId).toList(), mCanEnterDesktopMode, displayId); + == displayId).toList(), mContext, displayId); } else { - return new CachedTaskInfo(Arrays.asList(tasks), mCanEnterDesktopMode, + return new CachedTaskInfo(Arrays.asList(tasks), mContext, displayId); } } @@ -358,17 +366,21 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta Collections.addAll(mOrderedTaskList, tasks); } - ArrayList tasks = new ArrayList<>(mOrderedTaskList); - // Strip the pinned task and recents task - tasks.removeIf(t -> t.taskId == mPinnedTaskId || isRecentsTask(t) - || DesksUtils.isDesktopWallpaperTask(t)); + List tasks = new ArrayList<>(mOrderedTaskList); + // Strip the pinned task and recents task. + tasks.removeIf(t -> t.taskId == mPinnedTaskId || isRecentsTask(t)); if (enableOverviewOnConnectedDisplays()) { - return new CachedTaskInfo(tasks.stream().filter( - info -> ExternalDisplaysKt.getSafeDisplayId(info) == displayId).toList(), - mCanEnterDesktopMode, displayId); - } else { - return new CachedTaskInfo(tasks, mCanEnterDesktopMode, displayId); + tasks = tasks.stream().filter( + info -> ExternalDisplaysKt.getSafeDisplayId(info) == displayId).toList(); } + if (enableMultipleDesktops(mContext)) { + tasks = tasks.stream().takeWhile( + taskInfo -> !DesksUtils.isDesktopWallpaperTask(taskInfo)).toList(); + } else { + tasks.removeIf(taskInfo -> DesksUtils.isDesktopWallpaperTask(taskInfo)); + } + + return new CachedTaskInfo(tasks, mContext, displayId); } } @@ -399,7 +411,7 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta @Nullable private final GroupedTaskInfo mVisibleTasks; - private boolean mCanEnterDesktopMode = false; + private Context mContext; // Only used when enableShellTopTaskTracking() is enabled CachedTaskInfo(@Nullable GroupedTaskInfo visibleTasks) { @@ -409,13 +421,13 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta } // Only used when enableShellTopTaskTracking() is disabled - CachedTaskInfo(@NonNull List allCachedTasks, boolean canEnterDesktopMode, + CachedTaskInfo(@NonNull List allCachedTasks, Context context, int displayId) { + mDisplayId = displayId; mVisibleTasks = null; mAllCachedTasks = allCachedTasks; mTopTask = allCachedTasks.isEmpty() ? null : allCachedTasks.get(0); - mCanEnterDesktopMode = canEnterDesktopMode; - mDisplayId = displayId; + mContext = context; } /** @@ -525,7 +537,7 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta && t.getActivityType() != ACTIVITY_TYPE_RECENTS) .toList(); return visibleNonExcludedTasks.isEmpty() ? null - : new CachedTaskInfo(visibleNonExcludedTasks, mCanEnterDesktopMode, mDisplayId); + : new CachedTaskInfo(visibleNonExcludedTasks, mContext, mDisplayId); } /** @@ -551,7 +563,7 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta } private boolean isDesktopTask(TaskInfo taskInfo) { - return mCanEnterDesktopMode + return canEnterDesktopMode(mContext) && taskInfo.configuration.windowConfiguration.getWindowingMode() == WindowConfiguration.WINDOWING_MODE_FREEFORM; } @@ -572,10 +584,6 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta } return mVisibleTasks.getBaseGroupedTask(); } else { - final TaskInfo baseTaskInfo = getLegacyBaseTask(); - if (baseTaskInfo == null) { - return null; - } if (splitTaskIds != null && splitTaskIds.length >= 2) { TaskInfo[] splitTasksInfo = getSplitPlaceholderTasksInfo(splitTaskIds); if (splitTasksInfo[0] == null || splitTasksInfo[1] == null) { @@ -583,12 +591,23 @@ public class TopTaskTracker extends ISplitScreenListener.Stub implements TaskSta } return GroupedTaskInfo.forSplitTasks(splitTasksInfo[0], splitTasksInfo[1], /* splitBounds = */ null); - } else if (isDesktopTask(baseTaskInfo)) { - return GroupedTaskInfo.forDeskTasks(INACTIVE_DESK_ID, mDisplayId, - Collections.singletonList( - baseTaskInfo), /* minimizedFreeformTaskIds = */ - Collections.emptySet()); } else { + final TaskInfo baseTaskInfo = getLegacyBaseTask(); + if (enableMultipleDesktops(mContext)) { + DesktopVisibilityController desktopVisibilityController = + DesktopVisibilityController.INSTANCE.get(mContext); + if (desktopVisibilityController.isInDesktopMode(mDisplayId)) { + return GroupedTaskInfo.forDeskTasks( + desktopVisibilityController.getActiveDeskId(mDisplayId), + mDisplayId, mAllCachedTasks, + /* minimizedFreeformTaskIds = */ Collections.emptySet()); + } + } else if (isDesktopTask(baseTaskInfo)) { + return GroupedTaskInfo.forDeskTasks(INACTIVE_DESK_ID, mDisplayId, + Collections.singletonList( + baseTaskInfo), /* minimizedFreeformTaskIds = */ + Collections.emptySet()); + } return GroupedTaskInfo.forFullscreenTasks(baseTaskInfo); } } diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java index be9b4a1fc5..d2b62b1f13 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -190,10 +190,8 @@ public class FallbackRecentsView taskInfo.taskId).toArray(); - } else { - runningTaskIds = new int[0]; - } - TaskView matchingTaskView = null; - if (groupedTaskInfo != null && groupedTaskInfo.isBaseType(GroupedTaskInfo.TYPE_DESK) - && runningTaskIds.length == 1) { - // TODO(b/342635213): Unsure if it's expected, desktop runningTasks only have a single - // taskId, therefore we match any DesktopTaskView that contains the runningTaskId. - TaskView taskview = getTaskViewByTaskId(runningTaskIds[0]); - if (taskview instanceof DesktopTaskView) { - matchingTaskView = taskview; - } - } else { - matchingTaskView = getTaskViewByTaskIds(runningTaskIds); - } - return matchingTaskView == null; + return mUtils.shouldAddStubTaskView(groupedTaskInfo); } /** @@ -3156,7 +3137,13 @@ public abstract class RecentsView< makeMeasureSpec(getMeasuredHeight(), EXACTLY)); layout(getLeft(), getTop(), getRight(), getBottom()); } else { - var runningTaskView = getTaskViewByTaskId(groupedTaskInfo.getTaskInfo1().taskId); + TaskView runningTaskView; + if (DesktopModeStatus.enableMultipleDesktops(mContext) && groupedTaskInfo.isBaseType( + GroupedTaskInfo.TYPE_DESK)) { + runningTaskView = mUtils.getDesktopTaskViewForDeskId(groupedTaskInfo.getDeskId()); + } else { + runningTaskView = getTaskViewByTaskId(groupedTaskInfo.getTaskInfo1().taskId); + } if (runningTaskView != null) { runningTaskViewId = runningTaskView.getTaskViewId(); } diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt b/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt index 4f862da802..67f5e9589b 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt +++ b/quickstep/src/com/android/quickstep/views/RecentsViewUtils.kt @@ -45,6 +45,7 @@ import com.android.quickstep.views.RecentsView.TAG import com.android.systemui.shared.recents.model.Task import com.android.systemui.shared.recents.model.ThumbnailData import com.android.wm.shell.shared.GroupedTaskInfo +import com.android.wm.shell.shared.desktopmode.DesktopModeStatus.enableMultipleDesktops import java.util.function.BiConsumer import kotlin.math.min import kotlin.reflect.KMutableProperty1 @@ -115,16 +116,19 @@ class RecentsViewUtils(private val recentsView: RecentsView<*, *>) : DesktopVisi taskViews.filter { recentsView.mTopRowIdSet.contains(it.taskViewId) } /** Returns all the task Ids in the top row, without the focused task */ - fun getTopRowIdArray(): IntArray = getTopRowTaskViews().map { it.taskViewId }.toIntArray() + fun getTopRowIdArray(): IntArray = + getTopRowTaskViews().map { it.taskViewId }.toLauncher3IntArray() /** Returns all the TaskViews in the bottom row, without the focused task */ fun getBottomRowTaskViews(): List = taskViews.filter { !recentsView.mTopRowIdSet.contains(it.taskViewId) && !it.isLargeTile } /** Returns all the task Ids in the bottom row, without the focused task */ - fun getBottomRowIdArray(): IntArray = getBottomRowTaskViews().map { it.taskViewId }.toIntArray() + fun getBottomRowIdArray(): IntArray = + getBottomRowTaskViews().map { it.taskViewId }.toLauncher3IntArray() - private fun List.toIntArray() = IntArray(size).apply { this@toIntArray.forEach(::add) } + private fun List.toLauncher3IntArray() = + IntArray(size).apply { this@toLauncher3IntArray.forEach(::add) } /** Counts [TaskView]s that are large tiles. */ fun getLargeTileCount(): Int = taskViews.count { it.isLargeTile } @@ -539,6 +543,26 @@ class RecentsViewUtils(private val recentsView: RecentsView<*, *>) : DesktopVisi return desktopTaskView } + fun shouldAddStubTaskView(groupedTaskInfo: GroupedTaskInfo): Boolean { + val matchingTaskView = + when { + groupedTaskInfo.isBaseType(GroupedTaskInfo.TYPE_DESK) && + enableMultipleDesktops(recentsView.context) -> + getDesktopTaskViewForDeskId(groupedTaskInfo.deskDisplayId) + + groupedTaskInfo.isBaseType(GroupedTaskInfo.TYPE_DESK) && + groupedTaskInfo.taskInfoList.size == 1 -> + recentsView.getTaskViewByTaskId(groupedTaskInfo.taskInfo1!!.taskId) + as? DesktopTaskView + + else -> { + val runningTaskIds = groupedTaskInfo.taskInfoList.map { it.taskId }.toIntArray() + recentsView.getTaskViewByTaskIds(runningTaskIds) + } + } + return matchingTaskView == null + } + companion object { class RecentsViewFloatProperty( private val utilsProperty: KMutableProperty1 diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java index 6adb7b4052..85ad1e4a31 100644 --- a/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java @@ -51,7 +51,6 @@ import android.os.SystemClock; import android.platform.test.annotations.DisableFlags; import android.platform.test.annotations.EnableFlags; import android.platform.test.flag.junit.SetFlagsRule; -import android.view.Display; import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.ViewTreeObserver; @@ -104,8 +103,7 @@ public abstract class AbsSwipeUpHandlerTestCase< new ActivityManager.RunningTaskInfo(); protected final TopTaskTracker.CachedTaskInfo mCachedTaskInfo = new TopTaskTracker.CachedTaskInfo( - Collections.singletonList(mRunningTaskInfo), /* canEnterDesktop = */ false, - DEFAULT_DISPLAY); + Collections.singletonList(mRunningTaskInfo), mContext, DEFAULT_DISPLAY); protected final RemoteAnimationTarget mRemoteAnimationTarget = new RemoteAnimationTarget( /* taskId= */ 0, /* mode= */ RemoteAnimationTarget.MODE_CLOSING,