Merge "Keeping task list stable across multiple task switches" into ub-launcher3-master
This commit is contained in:
commit
4225924086
|
@ -44,6 +44,7 @@ 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;
|
||||
|
@ -83,7 +84,7 @@ public class RecentTasksList extends TaskStackChangeListener {
|
|||
final int requestLoadId = mChangeId;
|
||||
Runnable resultCallback = callback == null
|
||||
? () -> { }
|
||||
: () -> callback.accept(mTasks);
|
||||
: () -> callback.accept(mStabilizer.reorder(mTasks));
|
||||
|
||||
if (mLastLoadedId == mChangeId && (!mLastLoadHadKeysOnly || loadKeysOnly)) {
|
||||
// The list is up to date, callback with the same list
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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 static com.android.launcher3.config.FeatureFlags.ENABLE_TASK_STABILIZER;
|
||||
|
||||
import android.os.SystemClock;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.android.launcher3.util.IntArray;
|
||||
import com.android.launcher3.util.IntSet;
|
||||
import com.android.systemui.shared.recents.model.Task;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class TaskListStabilizer {
|
||||
|
||||
private static final long TASK_CACHE_TIMEOUT_MS = 5000;
|
||||
|
||||
private final SparseArray<Task> mTempMap = new SparseArray<>();
|
||||
private final IntArray mTempArray = new IntArray();
|
||||
private final IntSet mTempSet = new IntSet();
|
||||
|
||||
private final IntArray mLastStableOrder = new IntArray();
|
||||
private final IntSet mLastSet = new IntSet();
|
||||
private final IntArray mLastUnstableOrder = new IntArray();
|
||||
|
||||
private long mLastReorderTime;
|
||||
|
||||
public ArrayList<Task> reorder(ArrayList<Task> tasks) {
|
||||
if (!ENABLE_TASK_STABILIZER.get()) {
|
||||
return tasks;
|
||||
}
|
||||
|
||||
// Create task id array
|
||||
int count = tasks.size();
|
||||
mTempArray.clear();
|
||||
mTempSet.clear();
|
||||
mTempMap.clear();
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
Task t = tasks.get(i);
|
||||
mTempMap.put(t.key.id, t);
|
||||
|
||||
mTempSet.add(t.key.id);
|
||||
mTempArray.add(t.key.id);
|
||||
}
|
||||
|
||||
if (mLastSet.equals(mTempSet) && isStabilizationQuickEnough()) {
|
||||
if (mLastStableOrder.equals(mTempArray)) {
|
||||
// Everything is same
|
||||
return tasks;
|
||||
}
|
||||
|
||||
if (!mLastUnstableOrder.equals(mTempArray)) {
|
||||
// Fast reordering, record the current time.
|
||||
mLastUnstableOrder.copyFrom(mTempArray);
|
||||
mLastReorderTime = SystemClock.uptimeMillis();
|
||||
}
|
||||
|
||||
// Reorder the tasks based on the last stable order.
|
||||
ArrayList<Task> sorted = new ArrayList<>(count);
|
||||
for (int i = 0; i < count; i++) {
|
||||
sorted.add(mTempMap.get(mLastStableOrder.get(i)));
|
||||
}
|
||||
return sorted;
|
||||
}
|
||||
|
||||
// Cache the data
|
||||
mLastStableOrder.copyFrom(mTempArray);
|
||||
mLastUnstableOrder.copyFrom(mTempArray);
|
||||
mLastSet.copyFrom(mTempSet);
|
||||
|
||||
mLastReorderTime = SystemClock.uptimeMillis();
|
||||
|
||||
return tasks;
|
||||
}
|
||||
|
||||
private boolean isStabilizationQuickEnough() {
|
||||
return (SystemClock.uptimeMillis() - mLastReorderTime) < TASK_CACHE_TIMEOUT_MS;
|
||||
}
|
||||
}
|
|
@ -751,7 +751,8 @@ public abstract class RecentsView<T extends BaseActivity> extends PagedView impl
|
|||
setRunningTaskIconScaledDown(runningTaskIconScaledDown);
|
||||
setRunningTaskHidden(runningTaskTileHidden);
|
||||
|
||||
setCurrentPage(0);
|
||||
TaskView tv = getRunningTaskView();
|
||||
setCurrentPage(tv == null ? 0 : indexOfChild(tv));
|
||||
|
||||
// Load the tasks (if the loading is already
|
||||
mTaskListChangeId = mModel.getTasks(this::applyLoadPlan);
|
||||
|
|
|
@ -95,6 +95,9 @@ abstract class BaseFlags {
|
|||
public static final TogglableFlag APPLY_CONFIG_AT_RUNTIME = new TogglableFlag(
|
||||
"APPLY_CONFIG_AT_RUNTIME", false, "Apply display changes dynamically");
|
||||
|
||||
public static final TogglableFlag ENABLE_TASK_STABILIZER = new TogglableFlag(
|
||||
"ENABLE_TASK_STABILIZER", true, "Stable task list across fast task switches");
|
||||
|
||||
public static void initialize(Context context) {
|
||||
// Avoid the disk read for user builds
|
||||
if (Utilities.IS_DEBUG_DEVICE) {
|
||||
|
|
|
@ -99,6 +99,14 @@ public class IntArray implements Cloneable {
|
|||
mSize += count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the array to be same as {@param other}
|
||||
*/
|
||||
public void copyFrom(IntArray other) {
|
||||
clear();
|
||||
addAll(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures capacity to append at least <code>count</code> values.
|
||||
*/
|
||||
|
@ -127,6 +135,25 @@ public class IntArray implements Cloneable {
|
|||
return wrap(toArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
if (obj instanceof IntArray) {
|
||||
IntArray arr = (IntArray) obj;
|
||||
if (mSize == arr.mSize) {
|
||||
for (int i = 0; i < mSize; i++) {
|
||||
if (arr.mValues[i] != mValues[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value at the specified position in this array.
|
||||
*/
|
||||
|
|
|
@ -49,10 +49,29 @@ public class IntSet {
|
|||
return mArray.size();
|
||||
}
|
||||
|
||||
public void clear() {
|
||||
mArray.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if (obj == this) {
|
||||
return true;
|
||||
}
|
||||
return (obj instanceof IntSet) && ((IntSet) obj).mArray.equals(mArray);
|
||||
}
|
||||
|
||||
public IntArray getArray() {
|
||||
return mArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets this set to be same as {@param other}
|
||||
*/
|
||||
public void copyFrom(IntSet other) {
|
||||
mArray.copyFrom(other.mArray);
|
||||
}
|
||||
|
||||
public static IntSet wrap(IntArray array) {
|
||||
IntSet set = new IntSet();
|
||||
set.mArray.addAll(array);
|
||||
|
|
Loading…
Reference in New Issue