From a5354e02a2bf2bd8b0907b9e34dfbfddd9e679be Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Tue, 26 Mar 2019 14:36:52 -0700 Subject: [PATCH] Use system recent tasks stabilization Bug: 111926330 Test: Swipe to last task, ensure it resets task list on timeout or interaction Change-Id: Id09215a4cfdea63a4be6fb69fced163ad3bc10bd --- .../WindowTransformSwipeHandler.java | 16 +- .../com/android/quickstep/views/TaskView.java | 25 ++- .../NavBarModeOverlayResourceObserver.java | 7 +- .../android/quickstep/RecentTasksList.java | 11 +- .../com/android/quickstep/RecentsModel.java | 8 - .../android/quickstep/TaskListStabilizer.java | 145 ------------------ 6 files changed, 31 insertions(+), 181 deletions(-) delete mode 100644 quickstep/src/com/android/quickstep/TaskListStabilizer.java 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 e8d4c19a73..15072a254c 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 @@ public class WindowTransformSwipeHandler 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 @@ public class WindowTransformSwipeHandler // 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 eb17e3e820..6ba89c9bce 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 class TaskView extends FrameLayout implements PageCallbacks, Reusable { } 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 class TaskView extends FrameLayout implements PageCallbacks, Reusable { public void launchTask(boolean animate, Consumer resultCallback, Handler resultCallbackHandler) { + launchTask(animate, false /* freezeTaskList */, resultCallback, resultCallbackHandler); + } + + public void launchTask(boolean animate, boolean freezeTaskList, Consumer 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 resultCallback, - Handler resultCallbackHandler) { + private void launchTaskInternal(boolean animate, boolean freezeTaskList, + Consumer 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 @@ public class TaskView extends FrameLayout implements PageCallbacks, Reusable { 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 058b46ffc6..3136632807 100644 --- a/quickstep/src/com/android/quickstep/NavBarModeOverlayResourceObserver.java +++ b/quickstep/src/com/android/quickstep/NavBarModeOverlayResourceObserver.java @@ -70,6 +70,11 @@ public class NavBarModeOverlayResourceObserver extends BroadcastReceiver { 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 @@ public class NavBarModeOverlayResourceObserver extends BroadcastReceiver { 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 e15a3f1ca1..06a36c9f0c 100644 --- a/quickstep/src/com/android/quickstep/RecentTasksList.java +++ b/quickstep/src/com/android/quickstep/RecentTasksList.java @@ -44,7 +44,6 @@ public class RecentTasksList extends TaskStackChangeListener { 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 class RecentTasksList extends TaskStackChangeListener { }); } - 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 @@ public class RecentTasksList extends TaskStackChangeListener { 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 56bc8570f6..a65bc33f14 100644 --- a/quickstep/src/com/android/quickstep/RecentsModel.java +++ b/quickstep/src/com/android/quickstep/RecentsModel.java @@ -90,14 +90,6 @@ public class RecentsModel extends TaskStackChangeListener { 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 4c63f8188f..0000000000 --- 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 mTaskWrappers = new ArrayList<>(); - - private boolean mInStabilizationSession; - private long mSessionStartTime; - - public TaskListStabilizer() { - // Initialize the task ids map - List 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 reorder(ArrayList 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 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 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 { - Task task; - int index; - - @Override - public int compareTo(TaskWrapper other) { - return Integer.compare(index, other.index); - } - } -}