Merge "Call into shell for recent tasks" into sc-v2-dev
diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java
index 3080f04..79dd633 100644
--- a/quickstep/src/com/android/quickstep/RecentTasksList.java
+++ b/quickstep/src/com/android/quickstep/RecentTasksList.java
@@ -22,35 +22,33 @@
import android.app.ActivityManager;
import android.os.Build;
import android.os.Process;
-import android.util.Log;
+import android.os.RemoteException;
import android.util.SparseBooleanArray;
import androidx.annotation.VisibleForTesting;
-import com.android.launcher3.testing.TestProtocol;
import com.android.launcher3.util.LooperExecutor;
+import com.android.systemui.shared.recents.model.GroupTask;
import com.android.systemui.shared.recents.model.Task;
-import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.KeyguardManagerCompat;
-import com.android.systemui.shared.system.TaskStackChangeListener;
-import com.android.systemui.shared.system.TaskStackChangeListeners;
+import com.android.wm.shell.recents.IRecentTasksListener;
+import com.android.wm.shell.util.GroupedRecentTaskInfo;
import java.util.ArrayList;
import java.util.Collections;
-import java.util.List;
import java.util.function.Consumer;
/**
* Manages the recent task list from the system, caching it as necessary.
*/
@TargetApi(Build.VERSION_CODES.R)
-public class RecentTasksList extends TaskStackChangeListener {
+public class RecentTasksList {
private static final TaskLoadResult INVALID_RESULT = new TaskLoadResult(-1, false, 0);
private final KeyguardManagerCompat mKeyguardManager;
private final LooperExecutor mMainThreadExecutor;
- private final ActivityManagerWrapper mActivityManagerWrapper;
+ private final SystemUiProxy mSysUiProxy;
// The list change id, increments as the task list changes in the system
private int mChangeId;
@@ -62,12 +60,17 @@
private TaskLoadResult mResultsUi = INVALID_RESULT;
public RecentTasksList(LooperExecutor mainThreadExecutor,
- KeyguardManagerCompat keyguardManager, ActivityManagerWrapper activityManagerWrapper) {
+ KeyguardManagerCompat keyguardManager, SystemUiProxy sysUiProxy) {
mMainThreadExecutor = mainThreadExecutor;
mKeyguardManager = keyguardManager;
mChangeId = 1;
- mActivityManagerWrapper = activityManagerWrapper;
- TaskStackChangeListeners.getInstance().registerTaskStackListener(this);
+ mSysUiProxy = sysUiProxy;
+ sysUiProxy.registerRecentTasksListener(new IRecentTasksListener.Stub() {
+ @Override
+ public void onRecentTasksChanged() throws RemoteException {
+ mMainThreadExecutor.execute(RecentTasksList.this::onRecentTasksChanged);
+ }
+ });
}
@VisibleForTesting
@@ -78,10 +81,11 @@
/**
* Fetches the task keys skipping any local cache.
*/
- public void getTaskKeys(int numTasks, Consumer<ArrayList<Task>> callback) {
+ public void getTaskKeys(int numTasks, Consumer<ArrayList<GroupTask>> callback) {
// Kick off task loading in the background
UI_HELPER_EXECUTOR.execute(() -> {
- ArrayList<Task> tasks = loadTasksInBackground(numTasks, -1, true /* loadKeysOnly */);
+ ArrayList<GroupTask> tasks = loadTasksInBackground(numTasks, -1,
+ true /* loadKeysOnly */);
mMainThreadExecutor.execute(() -> callback.accept(tasks));
});
}
@@ -93,14 +97,15 @@
* @param callback The callback to receive the list of recent tasks
* @return The change id of the current task list
*/
- public synchronized int getTasks(boolean loadKeysOnly, Consumer<ArrayList<Task>> callback) {
+ public synchronized int getTasks(boolean loadKeysOnly,
+ Consumer<ArrayList<GroupTask>> callback) {
final int requestLoadId = mChangeId;
if (mResultsUi.isValidForRequest(requestLoadId, loadKeysOnly)) {
// The list is up to date, send the callback on the next frame,
// so that requestID can be returned first.
if (callback != null) {
// Copy synchronously as the changeId might change by next frame
- ArrayList<Task> result = copyOf(mResultsUi);
+ ArrayList<GroupTask> result = copyOf(mResultsUi);
mMainThreadExecutor.post(() -> {
callback.accept(result);
});
@@ -120,7 +125,7 @@
mLoadingTasksInBackground = false;
mResultsUi = loadResult;
if (callback != null) {
- ArrayList<Task> result = copyOf(mResultsUi);
+ ArrayList<GroupTask> result = copyOf(mResultsUi);
callback.accept(result);
}
});
@@ -136,35 +141,7 @@
return mChangeId == changeId;
}
- @Override
- public void onTaskStackChanged() {
- invalidateLoadedTasks();
- }
-
- @Override
- public void onRecentTaskListUpdated() {
- // In some cases immediately after booting, the tasks in the system recent task list may be
- // loaded, but not in the active task hierarchy in the system. These tasks are displayed in
- // overview, but removing them don't result in a onTaskStackChanged() nor a onTaskRemoved()
- // callback (those are for changes to the active tasks), but the task list is still updated,
- // so we should also invalidate the change id to ensure we load a new list instead of
- // reusing a stale list.
- invalidateLoadedTasks();
- }
-
- @Override
- public void onTaskRemoved(int taskId) {
- invalidateLoadedTasks();
- }
-
-
- @Override
- public void onActivityPinned(String packageName, int userId, int taskId, int stackId) {
- invalidateLoadedTasks();
- }
-
- @Override
- public synchronized void onActivityUnpinned() {
+ public void onRecentTasksChanged() {
invalidateLoadedTasks();
}
@@ -180,8 +157,8 @@
@VisibleForTesting
TaskLoadResult loadTasksInBackground(int numTasks, int requestId, boolean loadKeysOnly) {
int currentUserId = Process.myUserHandle().getIdentifier();
- List<ActivityManager.RecentTaskInfo> rawTasks =
- mActivityManagerWrapper.getRecentTasks(numTasks, currentUserId);
+ ArrayList<GroupedRecentTaskInfo> rawTasks =
+ mSysUiProxy.getRecentTasks(numTasks, currentUserId);
// The raw tasks are given in most-recent to least-recent order, we need to reverse it
Collections.reverse(rawTasks);
@@ -197,45 +174,53 @@
};
TaskLoadResult allTasks = new TaskLoadResult(requestId, loadKeysOnly, rawTasks.size());
- for (ActivityManager.RecentTaskInfo rawTask : rawTasks) {
- Task.TaskKey taskKey = new Task.TaskKey(rawTask);
- Task task;
- if (!loadKeysOnly) {
- boolean isLocked = tmpLockedUsers.get(taskKey.userId);
- task = Task.from(taskKey, rawTask, isLocked);
- } else {
- task = new Task(taskKey);
+ for (GroupedRecentTaskInfo rawTask : rawTasks) {
+ ActivityManager.RecentTaskInfo taskInfo1 = rawTask.mTaskInfo1;
+ ActivityManager.RecentTaskInfo taskInfo2 = rawTask.mTaskInfo2;
+ Task.TaskKey task1Key = new Task.TaskKey(taskInfo1);
+ Task task1 = loadKeysOnly
+ ? new Task(task1Key)
+ : Task.from(task1Key, taskInfo1,
+ tmpLockedUsers.get(task1Key.userId) /* isLocked */);
+ task1.setLastSnapshotData(taskInfo1);
+ Task task2 = null;
+ if (taskInfo2 != null) {
+ Task.TaskKey task2Key = new Task.TaskKey(taskInfo2);
+ task2 = loadKeysOnly
+ ? new Task(task2Key)
+ : Task.from(task2Key, taskInfo2,
+ tmpLockedUsers.get(task2Key.userId) /* isLocked */);
+ task2.setLastSnapshotData(taskInfo2);
}
- task.setLastSnapshotData(rawTask);
- allTasks.add(task);
+ allTasks.add(new GroupTask(task1, task2));
}
return allTasks;
}
- private ArrayList<Task> copyOf(ArrayList<Task> tasks) {
- ArrayList<Task> newTasks = new ArrayList<>();
+ private ArrayList<GroupTask> copyOf(ArrayList<GroupTask> tasks) {
+ ArrayList<GroupTask> newTasks = new ArrayList<>();
for (int i = 0; i < tasks.size(); i++) {
- newTasks.add(new Task(tasks.get(i)));
+ newTasks.add(new GroupTask(tasks.get(i)));
}
return newTasks;
}
- private static class TaskLoadResult extends ArrayList<Task> {
+ private static class TaskLoadResult extends ArrayList<GroupTask> {
- final int mId;
+ final int mRequestId;
// If the result was loaded with keysOnly = true
final boolean mKeysOnly;
- TaskLoadResult(int id, boolean keysOnly, int size) {
+ TaskLoadResult(int requestId, boolean keysOnly, int size) {
super(size);
- mId = id;
+ mRequestId = requestId;
mKeysOnly = keysOnly;
}
boolean isValidForRequest(int requestId, boolean loadKeysOnly) {
- return mId == requestId && (!mKeysOnly || loadKeysOnly);
+ return mRequestId == requestId && (!mKeysOnly || loadKeysOnly);
}
}
}
\ No newline at end of file
diff --git a/quickstep/src/com/android/quickstep/RecentsModel.java b/quickstep/src/com/android/quickstep/RecentsModel.java
index 1e82c8c..71153c6 100644
--- a/quickstep/src/com/android/quickstep/RecentsModel.java
+++ b/quickstep/src/com/android/quickstep/RecentsModel.java
@@ -34,6 +34,7 @@
import com.android.launcher3.icons.IconProvider.IconChangeListener;
import com.android.launcher3.util.Executors.SimpleThreadFactory;
import com.android.launcher3.util.MainThreadInitializedObject;
+import com.android.systemui.shared.recents.model.GroupTask;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -70,7 +71,7 @@
private RecentsModel(Context context) {
mContext = context;
mTaskList = new RecentTasksList(MAIN_EXECUTOR,
- new KeyguardManagerCompat(context), ActivityManagerWrapper.getInstance());
+ new KeyguardManagerCompat(context), SystemUiProxy.INSTANCE.get(context));
IconProvider iconProvider = new IconProvider(context);
mIconCache = new TaskIconCache(context, RECENTS_MODEL_EXECUTOR, iconProvider);
@@ -95,7 +96,7 @@
* always called on the UI thread.
* @return the request id associated with this call.
*/
- public int getTasks(Consumer<ArrayList<Task>> callback) {
+ public int getTasks(Consumer<ArrayList<GroupTask>> callback) {
return mTaskList.getTasks(false /* loadKeysOnly */, callback);
}
@@ -120,9 +121,9 @@
* @param callback Receives true if task is removed, false otherwise
*/
public void isTaskRemoved(int taskId, Consumer<Boolean> callback) {
- mTaskList.getTasks(true /* loadKeysOnly */, (tasks) -> {
- for (Task task : tasks) {
- if (task.key.id == taskId) {
+ mTaskList.getTasks(true /* loadKeysOnly */, (taskGroups) -> {
+ for (GroupTask group : taskGroups) {
+ if (group.containsTask(taskId)) {
callback.accept(false);
return;
}
@@ -148,14 +149,15 @@
ActivityManager.RunningTaskInfo runningTask =
ActivityManagerWrapper.getInstance().getRunningTask();
int runningTaskId = runningTask != null ? runningTask.id : -1;
- mTaskList.getTaskKeys(mThumbnailCache.getCacheSize(), tasks -> {
- for (Task task : tasks) {
- if (task.key.id == runningTaskId) {
+ mTaskList.getTaskKeys(mThumbnailCache.getCacheSize(), taskGroups -> {
+ for (GroupTask group : taskGroups) {
+ if (group.containsTask(runningTaskId)) {
// Skip the running task, it's not going to have an up-to-date snapshot by the
// time the user next enters overview
continue;
}
- mThumbnailCache.updateThumbnailInCache(task);
+ mThumbnailCache.updateThumbnailInCache(group.task1);
+ mThumbnailCache.updateThumbnailInCache(group.task2);
}
});
}
diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java
index 541af76..a875b69 100644
--- a/quickstep/src/com/android/quickstep/SystemUiProxy.java
+++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java
@@ -15,6 +15,8 @@
*/
package com.android.quickstep;
+import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE;
+
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.app.PendingIntent;
@@ -48,6 +50,9 @@
import com.android.wm.shell.onehanded.IOneHanded;
import com.android.wm.shell.pip.IPip;
import com.android.wm.shell.pip.IPipAnimationListener;
+import com.android.wm.shell.recents.IRecentTasks;
+import com.android.wm.shell.recents.IRecentTasksListener;
+import com.android.wm.shell.util.GroupedRecentTaskInfo;
import com.android.wm.shell.splitscreen.ISplitScreen;
import com.android.wm.shell.splitscreen.ISplitScreenListener;
import com.android.wm.shell.startingsurface.IStartingWindow;
@@ -55,6 +60,7 @@
import com.android.wm.shell.transition.IShellTransitions;
import java.util.ArrayList;
+import java.util.Arrays;
/**
* Holds the reference to SystemUI.
@@ -73,6 +79,7 @@
private IOneHanded mOneHanded;
private IShellTransitions mShellTransitions;
private IStartingWindow mStartingWindow;
+ private IRecentTasks mRecentTasks;
private final DeathRecipient mSystemUiProxyDeathRecipient = () -> {
MAIN_EXECUTOR.execute(() -> clearProxy());
};
@@ -83,6 +90,7 @@
private ISplitScreenListener mPendingSplitScreenListener;
private IStartingWindowListener mPendingStartingWindowListener;
private ISmartspaceCallback mPendingSmartspaceCallback;
+ private IRecentTasksListener mPendingRecentTasksListener;
private final ArrayList<RemoteTransitionCompat> mPendingRemoteTransitions = new ArrayList<>();
// Used to dedupe calls to SystemUI
@@ -147,7 +155,7 @@
public void setProxy(ISystemUiProxy proxy, IPip pip, ISplitScreen splitScreen,
IOneHanded oneHanded, IShellTransitions shellTransitions,
- IStartingWindow startingWindow,
+ IStartingWindow startingWindow, IRecentTasks recentTasks,
ISmartspaceTransitionController smartSpaceTransitionController) {
unlinkToDeath();
mSystemUiProxy = proxy;
@@ -157,6 +165,7 @@
mShellTransitions = shellTransitions;
mStartingWindow = startingWindow;
mSmartspaceTransitionController = smartSpaceTransitionController;
+ mRecentTasks = recentTasks;
linkToDeath();
// re-attach the listeners once missing due to setProxy has not been initialized yet.
if (mPendingPipAnimationListener != null && mPip != null) {
@@ -179,6 +188,10 @@
registerRemoteTransition(mPendingRemoteTransitions.get(i));
}
mPendingRemoteTransitions.clear();
+ if (mPendingRecentTasksListener != null && mRecentTasks != null) {
+ registerRecentTasksListener(mPendingRecentTasksListener);
+ mPendingRecentTasksListener = null;
+ }
if (mPendingSetNavButtonAlpha != null) {
mPendingSetNavButtonAlpha.run();
@@ -187,7 +200,7 @@
}
public void clearProxy() {
- setProxy(null, null, null, null, null, null, null);
+ setProxy(null, null, null, null, null, null, null, null);
}
// TODO(141886704): Find a way to remove this
@@ -759,7 +772,6 @@
}
}
-
//
// SmartSpace transitions
//
@@ -775,4 +787,43 @@
mPendingSmartspaceCallback = callback;
}
}
+
+ //
+ // Recents
+ //
+
+ public void registerRecentTasksListener(IRecentTasksListener listener) {
+ if (mRecentTasks != null) {
+ try {
+ mRecentTasks.registerRecentTasksListener(listener);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call registerRecentTasksListener", e);
+ }
+ } else {
+ mPendingRecentTasksListener = listener;
+ }
+ }
+
+ public void unregisterRecentTasksListener(IRecentTasksListener listener) {
+ if (mRecentTasks != null) {
+ try {
+ mRecentTasks.unregisterRecentTasksListener(listener);
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call unregisterRecentTasksListener");
+ }
+ }
+ mPendingRecentTasksListener = null;
+ }
+
+ public ArrayList<GroupedRecentTaskInfo> getRecentTasks(int numTasks, int userId) {
+ if (mRecentTasks != null) {
+ try {
+ return new ArrayList<>(Arrays.asList(mRecentTasks.getRecentTasks(numTasks,
+ RECENT_IGNORE_UNAVAILABLE, userId)));
+ } catch (RemoteException e) {
+ Log.w(TAG, "Failed call getRecentTasks", e);
+ }
+ }
+ return new ArrayList<>();
+ }
}
diff --git a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
index a8a0219..eaa43cf 100644
--- a/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
+++ b/quickstep/src/com/android/quickstep/TaskThumbnailCache.java
@@ -104,6 +104,9 @@
* Synchronously fetches the thumbnail for the given {@param task} and puts it in the cache.
*/
public void updateThumbnailInCache(Task task) {
+ if (task == null) {
+ return;
+ }
Preconditions.assertUIThread();
// Fetch the thumbnail for this task and put it in the cache
if (task.thumbnail == null) {
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index b56c1b7..c037ac4 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -26,6 +26,7 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.quickstep.GestureState.DEFAULT_STATE;
import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS;
+import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_RECENT_TASKS;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_ONE_HANDED;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_PIP;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_SHELL_TRANSITIONS;
@@ -113,6 +114,7 @@
import com.android.systemui.shared.tracing.ProtoTraceable;
import com.android.wm.shell.onehanded.IOneHanded;
import com.android.wm.shell.pip.IPip;
+import com.android.wm.shell.recents.IRecentTasks;
import com.android.wm.shell.splitscreen.ISplitScreen;
import com.android.wm.shell.startingsurface.IStartingWindow;
import com.android.wm.shell.transition.IShellTransitions;
@@ -171,9 +173,11 @@
ISmartspaceTransitionController smartspaceTransitionController =
ISmartspaceTransitionController.Stub.asInterface(
bundle.getBinder(KEY_EXTRA_SMARTSPACE_TRANSITION_CONTROLLER));
+ IRecentTasks recentTasks = IRecentTasks.Stub.asInterface(
+ bundle.getBinder(KEY_EXTRA_RECENT_TASKS));
MAIN_EXECUTOR.execute(() -> {
SystemUiProxy.INSTANCE.get(TouchInteractionService.this).setProxy(proxy, pip,
- splitscreen, onehanded, shellTransitions, startingWindow,
+ splitscreen, onehanded, shellTransitions, startingWindow, recentTasks,
smartspaceTransitionController);
TouchInteractionService.this.initInputMonitor();
preloadOverview(true /* fromInit */);
diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
index 7e8b83e..48315d0 100644
--- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
+++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java
@@ -42,6 +42,7 @@
import com.android.quickstep.views.OverviewActionsView;
import com.android.quickstep.views.RecentsView;
import com.android.quickstep.views.TaskView;
+import com.android.systemui.shared.recents.model.GroupTask;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.Task.TaskKey;
@@ -153,29 +154,31 @@
}
@Override
- protected void applyLoadPlan(ArrayList<Task> tasks) {
+ protected void applyLoadPlan(ArrayList<GroupTask> taskGroups) {
// When quick-switching on 3p-launcher, we add a "stub" tile corresponding to Launcher
// as well. This tile is never shown as we have setCurrentTaskHidden, but allows use to
// track the index of the next task appropriately, as if we are switching on any other app.
// TODO(b/195607777) Confirm home task info is front-most task and not mixed in with others
int runningTaskId = getTaskIdsForRunningTaskView()[0];
- if (mHomeTaskInfo != null && mHomeTaskInfo.taskId == runningTaskId && !tasks.isEmpty()) {
+ if (mHomeTaskInfo != null && mHomeTaskInfo.taskId == runningTaskId && !taskGroups.isEmpty()) {
// Check if the task list has running task
boolean found = false;
- for (Task t : tasks) {
- if (t.key.id == runningTaskId) {
+ for (GroupTask group : taskGroups) {
+ if (group.containsTask(runningTaskId)) {
found = true;
break;
}
}
if (!found) {
- ArrayList<Task> newList = new ArrayList<>(tasks.size() + 1);
- newList.addAll(tasks);
- newList.add(Task.from(new TaskKey(mHomeTaskInfo), mHomeTaskInfo, false));
- tasks = newList;
+ ArrayList<GroupTask> newList = new ArrayList<>(taskGroups.size() + 1);
+ newList.addAll(taskGroups);
+ newList.add(new GroupTask(
+ Task.from(new TaskKey(mHomeTaskInfo), mHomeTaskInfo, false),
+ null));
+ taskGroups = newList;
}
}
- super.applyLoadPlan(tasks);
+ super.applyLoadPlan(taskGroups);
}
@Override
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 96c5561..b5238c6 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -167,6 +167,7 @@
import com.android.quickstep.util.TransformParams;
import com.android.quickstep.util.VibratorWrapper;
import com.android.systemui.plugins.ResourceProvider;
+import com.android.systemui.shared.recents.model.GroupTask;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.Task.TaskKey;
import com.android.systemui.shared.recents.model.ThumbnailData;
@@ -1296,13 +1297,13 @@
updateGridProperties();
}
- protected void applyLoadPlan(ArrayList<Task> tasks) {
+ protected void applyLoadPlan(ArrayList<GroupTask> taskGroups) {
if (mPendingAnimation != null) {
- mPendingAnimation.addEndListener(success -> applyLoadPlan(tasks));
+ mPendingAnimation.addEndListener(success -> applyLoadPlan(taskGroups));
return;
}
- if (tasks == null || tasks.isEmpty()) {
+ if (taskGroups == null || taskGroups.isEmpty()) {
removeTasksViewsAndClearAllButton();
onTaskStackUpdated();
return;
@@ -1324,10 +1325,11 @@
LauncherSplitScreenListener.INSTANCE.getNoCreate().getPersistentSplitIds();
int requiredGroupTaskViews = splitTaskIds.length / 2;
+ // TODO(b/202740477): Update once grouped tasks are returned
// Subtract half the number of split tasks and not total number because we've already
// added a GroupedTaskView when swipe up gesture happens.
// This will need to change if we start showing GroupedTaskViews during swipe up from home
- int requiredTaskViewCount = tasks.size() - requiredGroupTaskViews;
+ int requiredTaskViewCount = taskGroups.size() - requiredGroupTaskViews;
if (getTaskViewCount() != requiredTaskViewCount) {
if (indexOfChild(mClearAllButton) != -1) {
@@ -1360,11 +1362,12 @@
+ " runningTaskViewId: " + mRunningTaskViewId
+ " forTaskView: " + getTaskViewFromTaskViewId(mRunningTaskViewId));
- for (int taskViewIndex = requiredTaskViewCount - 1, taskDataIndex = tasks.size() - 1;
+ for (int taskViewIndex = requiredTaskViewCount - 1, taskDataIndex = taskGroups.size() - 1;
taskViewIndex >= 0;
taskViewIndex--, taskDataIndex--) {
final int pageIndex = requiredTaskViewCount - taskViewIndex - 1;
- final Task task = tasks.get(taskDataIndex);
+ // TODO(b/202740477): Temporary assumption, to be updated once groups are actually used
+ final Task task = taskGroups.get(taskDataIndex).task1;
final TaskView taskView = (TaskView) getChildAt(pageIndex);
if (taskView instanceof GroupedTaskView) {
Task leftTop;
@@ -1372,11 +1375,11 @@
if (task.key.id == splitTaskIds[0]) {
leftTop = task;
taskDataIndex--;
- rightBottom = tasks.get(taskDataIndex);
+ rightBottom = taskGroups.get(taskDataIndex).task1;
} else {
rightBottom = task;
taskDataIndex--;
- leftTop = tasks.get(taskDataIndex);
+ leftTop = taskGroups.get(taskDataIndex).task1;
}
((GroupedTaskView) taskView).bind(leftTop, rightBottom, mOrientationState,
mSplitBoundsConfig);
diff --git a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
index 79ddf7a..6b2d5ed 100644
--- a/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
+++ b/quickstep/tests/src/com/android/quickstep/RecentTasksListTest.java
@@ -30,70 +30,78 @@
import androidx.test.filters.SmallTest;
import com.android.launcher3.util.LooperExecutor;
+import com.android.systemui.shared.recents.model.GroupTask;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.ActivityManagerWrapper;
import com.android.systemui.shared.system.KeyguardManagerCompat;
+import com.android.wm.shell.util.GroupedRecentTaskInfo;
import org.junit.Before;
import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@SmallTest
public class RecentTasksListTest {
- private ActivityManagerWrapper mockActivityManagerWrapper;
+ @Mock
+ private SystemUiProxy mockSystemUiProxy;
// Class under test
private RecentTasksList mRecentTasksList;
@Before
public void setup() {
+ MockitoAnnotations.initMocks(this);
LooperExecutor mockMainThreadExecutor = mock(LooperExecutor.class);
KeyguardManagerCompat mockKeyguardManagerCompat = mock(KeyguardManagerCompat.class);
- mockActivityManagerWrapper = mock(ActivityManagerWrapper.class);
mRecentTasksList = new RecentTasksList(mockMainThreadExecutor, mockKeyguardManagerCompat,
- mockActivityManagerWrapper);
+ mockSystemUiProxy);
}
@Test
- public void onTaskRemoved_doesNotFetchTasks() {
- mRecentTasksList.onTaskRemoved(0);
- verify(mockActivityManagerWrapper, times(0))
- .getRecentTasks(anyInt(), anyInt());
- }
-
- @Test
- public void onTaskStackChanged_doesNotFetchTasks() {
- mRecentTasksList.onTaskStackChanged();
- verify(mockActivityManagerWrapper, times(0))
+ public void onRecentTasksChanged_doesNotFetchTasks() {
+ mRecentTasksList.onRecentTasksChanged();
+ verify(mockSystemUiProxy, times(0))
.getRecentTasks(anyInt(), anyInt());
}
@Test
public void loadTasksInBackground_onlyKeys_noValidTaskDescription() {
- ActivityManager.RecentTaskInfo recentTaskInfo = new ActivityManager.RecentTaskInfo();
- when(mockActivityManagerWrapper.getRecentTasks(anyInt(), anyInt()))
- .thenReturn(Collections.singletonList(recentTaskInfo));
+ GroupedRecentTaskInfo recentTaskInfos = new GroupedRecentTaskInfo(
+ new ActivityManager.RecentTaskInfo(), new ActivityManager.RecentTaskInfo());
+ when(mockSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
+ .thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
- List<Task> taskList = mRecentTasksList.loadTasksInBackground(Integer.MAX_VALUE, -1, true);
+ List<GroupTask> taskList = mRecentTasksList.loadTasksInBackground(Integer.MAX_VALUE, -1,
+ true);
assertEquals(1, taskList.size());
- assertNull(taskList.get(0).taskDescription.getLabel());
+ assertNull(taskList.get(0).task1.taskDescription.getLabel());
+ assertNull(taskList.get(0).task2.taskDescription.getLabel());
}
@Test
public void loadTasksInBackground_moreThanKeys_hasValidTaskDescription() {
String taskDescription = "Wheeee!";
- ActivityManager.RecentTaskInfo recentTaskInfo = new ActivityManager.RecentTaskInfo();
- recentTaskInfo.taskDescription = new ActivityManager.TaskDescription(taskDescription);
- when(mockActivityManagerWrapper.getRecentTasks(anyInt(), anyInt()))
- .thenReturn(Collections.singletonList(recentTaskInfo));
+ ActivityManager.RecentTaskInfo task1 = new ActivityManager.RecentTaskInfo();
+ task1.taskDescription = new ActivityManager.TaskDescription(taskDescription);
+ ActivityManager.RecentTaskInfo task2 = new ActivityManager.RecentTaskInfo();
+ task2.taskDescription = new ActivityManager.TaskDescription();
+ GroupedRecentTaskInfo recentTaskInfos = new GroupedRecentTaskInfo(
+ task1, task2);
+ when(mockSystemUiProxy.getRecentTasks(anyInt(), anyInt()))
+ .thenReturn(new ArrayList<>(Collections.singletonList(recentTaskInfos)));
- List<Task> taskList = mRecentTasksList.loadTasksInBackground(Integer.MAX_VALUE, -1, false);
+ List<GroupTask> taskList = mRecentTasksList.loadTasksInBackground(Integer.MAX_VALUE, -1,
+ false);
assertEquals(1, taskList.size());
- assertEquals(taskDescription, taskList.get(0).taskDescription.getLabel());
+ assertEquals(taskDescription, taskList.get(0).task1.taskDescription.getLabel());
+ assertNull(taskList.get(0).task2.taskDescription.getLabel());
}
}