Use system recent tasks stabilization
Bug: 111926330
Test: Swipe to last task, ensure it resets task list on timeout or interaction
Change-Id: Id09215a4cfdea63a4be6fb69fced163ad3bc10bd
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
index e8d4c19..15072a2 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/WindowTransformSwipeHandler.java
@@ -851,16 +851,6 @@
Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) {
mGestureEndTarget = target;
- if (mGestureEndTarget.canBeContinued) {
- // Because we might continue this gesture, e.g. for consecutive quick switch, we need to
- // stabilize the task list so that tasks don't rearrange in the middle of the gesture.
- RecentsModel.INSTANCE.get(mContext).startStabilizationSession();
- } else if (mGestureEndTarget.isLauncher) {
- // Otherwise, if we're going to home or overview,
- // we reset the tasks to a consistent start state.
- RecentsModel.INSTANCE.get(mContext).endStabilizationSession();
- }
-
if (mGestureEndTarget == HOME) {
HomeAnimationFactory homeAnimFactory;
if (mActivity != null) {
@@ -1003,10 +993,12 @@
// Launch the task user scrolled to (mRecentsView.getNextPage()).
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
// We finish recents animation inside launchTask() when live tile is enabled.
- mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).launchTask(false);
+ mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).launchTask(false /* animate */,
+ true /* freezeTaskList */);
} else {
mRecentsAnimationWrapper.finish(true /* toRecents */, () -> {
- mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).launchTask(false);
+ mRecentsView.getTaskViewAt(mRecentsView.getNextPage()).launchTask(
+ false /* animate */, true /* freezeTaskList */);
});
}
TOUCH_INTERACTION_LOG.addLog("finishRecentsAnimation", false);
diff --git a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
index eb17e3e..6ba89c9 100644
--- a/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
+++ b/quickstep/recents_ui_overrides/src/com/android/quickstep/views/TaskView.java
@@ -250,7 +250,11 @@
}
public void launchTask(boolean animate) {
- launchTask(animate, (result) -> {
+ launchTask(animate, false /* freezeTaskList */);
+ }
+
+ public void launchTask(boolean animate, boolean freezeTaskList) {
+ launchTask(animate, freezeTaskList, (result) -> {
if (!result) {
notifyTaskLaunchFailed(TAG);
}
@@ -259,25 +263,33 @@
public void launchTask(boolean animate, Consumer<Boolean> resultCallback,
Handler resultCallbackHandler) {
+ launchTask(animate, false /* freezeTaskList */, resultCallback, resultCallbackHandler);
+ }
+
+ public void launchTask(boolean animate, boolean freezeTaskList, Consumer<Boolean> resultCallback,
+ Handler resultCallbackHandler) {
if (ENABLE_QUICKSTEP_LIVE_TILE.get()) {
if (isRunningTask()) {
getRecentsView().finishRecentsAnimation(false /* toRecents */,
() -> resultCallbackHandler.post(() -> resultCallback.accept(true)));
} else {
- launchTaskInternal(animate, resultCallback, resultCallbackHandler);
+ launchTaskInternal(animate, freezeTaskList, resultCallback, resultCallbackHandler);
}
} else {
- launchTaskInternal(animate, resultCallback, resultCallbackHandler);
+ launchTaskInternal(animate, freezeTaskList, resultCallback, resultCallbackHandler);
}
}
- private void launchTaskInternal(boolean animate, Consumer<Boolean> resultCallback,
- Handler resultCallbackHandler) {
+ private void launchTaskInternal(boolean animate, boolean freezeTaskList,
+ Consumer<Boolean> resultCallback, Handler resultCallbackHandler) {
if (mTask != null) {
final ActivityOptions opts;
if (animate) {
opts = ((BaseDraggingActivity) fromContext(getContext()))
.getActivityLaunchOptions(this);
+ if (freezeTaskList) {
+ ActivityOptionsCompat.setFreezeRecentTasksList(opts);
+ }
ActivityManagerWrapper.getInstance().startActivityFromRecentsAsync(mTask.key,
opts, resultCallback, resultCallbackHandler);
} else {
@@ -288,6 +300,9 @@
resultCallbackHandler.post(() -> resultCallback.accept(true));
}
}, resultCallbackHandler);
+ if (freezeTaskList) {
+ ActivityOptionsCompat.setFreezeRecentTasksList(opts);
+ }
ActivityManagerWrapper.getInstance().startActivityFromRecentsAsync(mTask.key,
opts, (success) -> {
if (resultCallback != null && !success) {
diff --git a/quickstep/src/com/android/quickstep/NavBarModeOverlayResourceObserver.java b/quickstep/src/com/android/quickstep/NavBarModeOverlayResourceObserver.java
index 058b46f..3136632 100644
--- a/quickstep/src/com/android/quickstep/NavBarModeOverlayResourceObserver.java
+++ b/quickstep/src/com/android/quickstep/NavBarModeOverlayResourceObserver.java
@@ -70,6 +70,11 @@
NAV_BAR_INTERACTION_MODE_RES_NAME));
}
+ public static boolean isLegacyModeEnabled(Context context) {
+ return QuickStepContract.isLegacyMode(getSystemIntegerRes(context,
+ NAV_BAR_INTERACTION_MODE_RES_NAME));
+ }
+
private static int getSystemIntegerRes(Context context, String resName) {
Resources res = context.getResources();
int resId = res.getIdentifier(resName, "integer", "android");
@@ -81,4 +86,4 @@
return -1;
}
}
-}
+}
\ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index e15a3f1..06a36c9 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -44,7 +44,6 @@
private final KeyguardManagerCompat mKeyguardManager;
private final MainThreadExecutor mMainThreadExecutor;
private final BackgroundExecutor mBgThreadExecutor;
- private final TaskListStabilizer mStabilizer = new TaskListStabilizer();
// The list change id, increments as the task list changes in the system
private int mChangeId;
@@ -74,14 +73,6 @@
});
}
- public void startStabilizationSession() {
- mStabilizer.startStabilizationSession();
- }
-
- public void endStabilizationSession() {
- mStabilizer.endStabilizationSession();
- }
-
/**
* Asynchronously fetches the list of recent tasks, reusing cached list if available.
*
@@ -93,7 +84,7 @@
final int requestLoadId = mChangeId;
Runnable resultCallback = callback == null
? () -> { }
- : () -> callback.accept(mStabilizer.reorder(mTasks));
+ : () -> callback.accept(mTasks);
if (mLastLoadedId == mChangeId && (!mLastLoadHadKeysOnly || loadKeysOnly)) {
// The list is up to date, callback with the same list
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 56bc8570..a65bc33 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -90,14 +90,6 @@
return mThumbnailCache;
}
- public void startStabilizationSession() {
- mTaskList.startStabilizationSession();
- }
-
- public void endStabilizationSession() {
- mTaskList.endStabilizationSession();
- }
-
/**
* Fetches the list of recent tasks.
*
diff --git a/quickstep/src/com/android/quickstep/TaskListStabilizer.java b/quickstep/src/com/android/quickstep/TaskListStabilizer.java
deleted file mode 100644
index 4c63f81..0000000
--- a/quickstep/src/com/android/quickstep/TaskListStabilizer.java
+++ /dev/null
@@ -1,145 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.quickstep;
-
-import android.app.ActivityManager.RecentTaskInfo;
-import android.content.ComponentName;
-import android.os.Process;
-import android.os.SystemClock;
-
-import com.android.launcher3.util.IntArray;
-import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.recents.model.Task.TaskKey;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
-import com.android.systemui.shared.system.TaskStackChangeListener;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Keeps the task list stable during quick switch gestures. So if you swipe right to switch from app
- * A to B, you can then swipe right again to get to app C or left to get back to A.
- */
-public class TaskListStabilizer {
-
- private static final long TASK_CACHE_TIMEOUT_MS = 5000;
-
- private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() {
-
- @Override
- public void onTaskCreated(int taskId, ComponentName componentName) {
- endStabilizationSession();
- }
-
- @Override
- public void onTaskRemoved(int taskId) {
- endStabilizationSession();
- }
- };
-
- // Task ids ordered based on recency, 0th index is the least recent task
- private final IntArray mSystemOrder;
- private final IntArray mStabilizedOrder;
-
- // Wrapper objects used for sorting tasks
- private final ArrayList<TaskWrapper> mTaskWrappers = new ArrayList<>();
-
- private boolean mInStabilizationSession;
- private long mSessionStartTime;
-
- public TaskListStabilizer() {
- // Initialize the task ids map
- List<RecentTaskInfo> rawTasks = ActivityManagerWrapper.getInstance().getRecentTasks(
- Integer.MAX_VALUE, Process.myUserHandle().getIdentifier());
- mSystemOrder = new IntArray(rawTasks.size());
- for (RecentTaskInfo info : rawTasks) {
- mSystemOrder.add(new TaskKey(info).id);
- }
- // We will lazily copy the task id's from mSystemOrder when a stabilization session starts.
- mStabilizedOrder = new IntArray(rawTasks.size());
-
- ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
- }
-
- public synchronized void startStabilizationSession() {
- if (!mInStabilizationSession) {
- mStabilizedOrder.clear();
- mStabilizedOrder.addAll(mSystemOrder);
- }
- mInStabilizationSession = true;
- mSessionStartTime = SystemClock.uptimeMillis();
- }
-
- public synchronized void endStabilizationSession() {
- mInStabilizationSession = false;
- }
-
- public synchronized ArrayList<Task> reorder(ArrayList<Task> tasks) {
- mSystemOrder.clear();
- for (Task task : tasks) {
- mSystemOrder.add(task.key.id);
- }
-
- if ((SystemClock.uptimeMillis() - mSessionStartTime) > TASK_CACHE_TIMEOUT_MS) {
- endStabilizationSession();
- }
-
- if (!mInStabilizationSession) {
- return tasks;
- }
-
- // Ensure that we have enough wrappers
- int taskCount = tasks.size();
- for (int i = taskCount - mTaskWrappers.size(); i > 0; i--) {
- mTaskWrappers.add(new TaskWrapper());
- }
-
- List<TaskWrapper> listToSort = mTaskWrappers.size() == taskCount
- ? mTaskWrappers : mTaskWrappers.subList(0, taskCount);
- int missingTaskIndex = -taskCount;
-
- for (int i = 0; i < taskCount; i++){
- TaskWrapper wrapper = listToSort.get(i);
- wrapper.task = tasks.get(i);
- wrapper.index = mStabilizedOrder.indexOf(wrapper.task.key.id);
-
- // Ensure that missing tasks are put in the front, in the order they appear in the
- // original list
- if (wrapper.index < 0) {
- wrapper.index = missingTaskIndex;
- missingTaskIndex++;
- }
- }
- Collections.sort(listToSort);
-
- ArrayList<Task> result = new ArrayList<>(taskCount);
- for (int i = 0; i < taskCount; i++) {
- result.add(listToSort.get(i).task);
- }
- return result;
- }
-
- private static class TaskWrapper implements Comparable<TaskWrapper> {
- Task task;
- int index;
-
- @Override
- public int compareTo(TaskWrapper other) {
- return Integer.compare(index, other.index);
- }
- }
-}