mirror of
https://github.com/LawnchairLauncher/lawnchair.git
synced 2026-02-20 11:18:21 +00:00
Use system recent tasks stabilization
Bug: 111926330 Test: Swipe to last task, ensure it resets task list on timeout or interaction Change-Id: Id09215a4cfdea63a4be6fb69fced163ad3bc10bd
This commit is contained in:
@@ -851,16 +851,6 @@ public class WindowTransformSwipeHandler<T extends BaseDraggingActivity>
|
||||
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<T extends BaseDraggingActivity>
|
||||
// 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);
|
||||
|
||||
@@ -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<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 @@ 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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user