Call into shell for recent tasks
- No change in behavior from today until groups are actually returned from the shell Bug: 202740477 Test: atest RecentTasksListTest Change-Id: I4ac7b472ce2e0a3b2574dc6d8f4c1761a0ad993a
This commit is contained in:
@@ -22,35 +22,33 @@ import android.annotation.TargetApi;
|
|||||||
import android.app.ActivityManager;
|
import android.app.ActivityManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.util.Log;
|
import android.os.RemoteException;
|
||||||
import android.util.SparseBooleanArray;
|
import android.util.SparseBooleanArray;
|
||||||
|
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import com.android.launcher3.testing.TestProtocol;
|
|
||||||
import com.android.launcher3.util.LooperExecutor;
|
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.recents.model.Task;
|
||||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
|
||||||
import com.android.systemui.shared.system.KeyguardManagerCompat;
|
import com.android.systemui.shared.system.KeyguardManagerCompat;
|
||||||
import com.android.systemui.shared.system.TaskStackChangeListener;
|
import com.android.wm.shell.recents.IRecentTasksListener;
|
||||||
import com.android.systemui.shared.system.TaskStackChangeListeners;
|
import com.android.wm.shell.util.GroupedRecentTaskInfo;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manages the recent task list from the system, caching it as necessary.
|
* Manages the recent task list from the system, caching it as necessary.
|
||||||
*/
|
*/
|
||||||
@TargetApi(Build.VERSION_CODES.R)
|
@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 static final TaskLoadResult INVALID_RESULT = new TaskLoadResult(-1, false, 0);
|
||||||
|
|
||||||
private final KeyguardManagerCompat mKeyguardManager;
|
private final KeyguardManagerCompat mKeyguardManager;
|
||||||
private final LooperExecutor mMainThreadExecutor;
|
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
|
// The list change id, increments as the task list changes in the system
|
||||||
private int mChangeId;
|
private int mChangeId;
|
||||||
@@ -62,12 +60,17 @@ public class RecentTasksList extends TaskStackChangeListener {
|
|||||||
private TaskLoadResult mResultsUi = INVALID_RESULT;
|
private TaskLoadResult mResultsUi = INVALID_RESULT;
|
||||||
|
|
||||||
public RecentTasksList(LooperExecutor mainThreadExecutor,
|
public RecentTasksList(LooperExecutor mainThreadExecutor,
|
||||||
KeyguardManagerCompat keyguardManager, ActivityManagerWrapper activityManagerWrapper) {
|
KeyguardManagerCompat keyguardManager, SystemUiProxy sysUiProxy) {
|
||||||
mMainThreadExecutor = mainThreadExecutor;
|
mMainThreadExecutor = mainThreadExecutor;
|
||||||
mKeyguardManager = keyguardManager;
|
mKeyguardManager = keyguardManager;
|
||||||
mChangeId = 1;
|
mChangeId = 1;
|
||||||
mActivityManagerWrapper = activityManagerWrapper;
|
mSysUiProxy = sysUiProxy;
|
||||||
TaskStackChangeListeners.getInstance().registerTaskStackListener(this);
|
sysUiProxy.registerRecentTasksListener(new IRecentTasksListener.Stub() {
|
||||||
|
@Override
|
||||||
|
public void onRecentTasksChanged() throws RemoteException {
|
||||||
|
mMainThreadExecutor.execute(RecentTasksList.this::onRecentTasksChanged);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -78,10 +81,11 @@ public class RecentTasksList extends TaskStackChangeListener {
|
|||||||
/**
|
/**
|
||||||
* Fetches the task keys skipping any local cache.
|
* 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
|
// Kick off task loading in the background
|
||||||
UI_HELPER_EXECUTOR.execute(() -> {
|
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));
|
mMainThreadExecutor.execute(() -> callback.accept(tasks));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -93,14 +97,15 @@ public class RecentTasksList extends TaskStackChangeListener {
|
|||||||
* @param callback The callback to receive the list of recent tasks
|
* @param callback The callback to receive the list of recent tasks
|
||||||
* @return The change id of the current task list
|
* @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;
|
final int requestLoadId = mChangeId;
|
||||||
if (mResultsUi.isValidForRequest(requestLoadId, loadKeysOnly)) {
|
if (mResultsUi.isValidForRequest(requestLoadId, loadKeysOnly)) {
|
||||||
// The list is up to date, send the callback on the next frame,
|
// The list is up to date, send the callback on the next frame,
|
||||||
// so that requestID can be returned first.
|
// so that requestID can be returned first.
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
// Copy synchronously as the changeId might change by next frame
|
// Copy synchronously as the changeId might change by next frame
|
||||||
ArrayList<Task> result = copyOf(mResultsUi);
|
ArrayList<GroupTask> result = copyOf(mResultsUi);
|
||||||
mMainThreadExecutor.post(() -> {
|
mMainThreadExecutor.post(() -> {
|
||||||
callback.accept(result);
|
callback.accept(result);
|
||||||
});
|
});
|
||||||
@@ -120,7 +125,7 @@ public class RecentTasksList extends TaskStackChangeListener {
|
|||||||
mLoadingTasksInBackground = false;
|
mLoadingTasksInBackground = false;
|
||||||
mResultsUi = loadResult;
|
mResultsUi = loadResult;
|
||||||
if (callback != null) {
|
if (callback != null) {
|
||||||
ArrayList<Task> result = copyOf(mResultsUi);
|
ArrayList<GroupTask> result = copyOf(mResultsUi);
|
||||||
callback.accept(result);
|
callback.accept(result);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -136,35 +141,7 @@ public class RecentTasksList extends TaskStackChangeListener {
|
|||||||
return mChangeId == changeId;
|
return mChangeId == changeId;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void onRecentTasksChanged() {
|
||||||
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() {
|
|
||||||
invalidateLoadedTasks();
|
invalidateLoadedTasks();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -180,8 +157,8 @@ public class RecentTasksList extends TaskStackChangeListener {
|
|||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
TaskLoadResult loadTasksInBackground(int numTasks, int requestId, boolean loadKeysOnly) {
|
TaskLoadResult loadTasksInBackground(int numTasks, int requestId, boolean loadKeysOnly) {
|
||||||
int currentUserId = Process.myUserHandle().getIdentifier();
|
int currentUserId = Process.myUserHandle().getIdentifier();
|
||||||
List<ActivityManager.RecentTaskInfo> rawTasks =
|
ArrayList<GroupedRecentTaskInfo> rawTasks =
|
||||||
mActivityManagerWrapper.getRecentTasks(numTasks, currentUserId);
|
mSysUiProxy.getRecentTasks(numTasks, currentUserId);
|
||||||
// The raw tasks are given in most-recent to least-recent order, we need to reverse it
|
// The raw tasks are given in most-recent to least-recent order, we need to reverse it
|
||||||
Collections.reverse(rawTasks);
|
Collections.reverse(rawTasks);
|
||||||
|
|
||||||
@@ -197,45 +174,53 @@ public class RecentTasksList extends TaskStackChangeListener {
|
|||||||
};
|
};
|
||||||
|
|
||||||
TaskLoadResult allTasks = new TaskLoadResult(requestId, loadKeysOnly, rawTasks.size());
|
TaskLoadResult allTasks = new TaskLoadResult(requestId, loadKeysOnly, rawTasks.size());
|
||||||
for (ActivityManager.RecentTaskInfo rawTask : rawTasks) {
|
for (GroupedRecentTaskInfo rawTask : rawTasks) {
|
||||||
Task.TaskKey taskKey = new Task.TaskKey(rawTask);
|
ActivityManager.RecentTaskInfo taskInfo1 = rawTask.mTaskInfo1;
|
||||||
Task task;
|
ActivityManager.RecentTaskInfo taskInfo2 = rawTask.mTaskInfo2;
|
||||||
if (!loadKeysOnly) {
|
Task.TaskKey task1Key = new Task.TaskKey(taskInfo1);
|
||||||
boolean isLocked = tmpLockedUsers.get(taskKey.userId);
|
Task task1 = loadKeysOnly
|
||||||
task = Task.from(taskKey, rawTask, isLocked);
|
? new Task(task1Key)
|
||||||
} else {
|
: Task.from(task1Key, taskInfo1,
|
||||||
task = new Task(taskKey);
|
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(new GroupTask(task1, task2));
|
||||||
allTasks.add(task);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return allTasks;
|
return allTasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<Task> copyOf(ArrayList<Task> tasks) {
|
private ArrayList<GroupTask> copyOf(ArrayList<GroupTask> tasks) {
|
||||||
ArrayList<Task> newTasks = new ArrayList<>();
|
ArrayList<GroupTask> newTasks = new ArrayList<>();
|
||||||
for (int i = 0; i < tasks.size(); i++) {
|
for (int i = 0; i < tasks.size(); i++) {
|
||||||
newTasks.add(new Task(tasks.get(i)));
|
newTasks.add(new GroupTask(tasks.get(i)));
|
||||||
}
|
}
|
||||||
return newTasks;
|
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
|
// If the result was loaded with keysOnly = true
|
||||||
final boolean mKeysOnly;
|
final boolean mKeysOnly;
|
||||||
|
|
||||||
TaskLoadResult(int id, boolean keysOnly, int size) {
|
TaskLoadResult(int requestId, boolean keysOnly, int size) {
|
||||||
super(size);
|
super(size);
|
||||||
mId = id;
|
mRequestId = requestId;
|
||||||
mKeysOnly = keysOnly;
|
mKeysOnly = keysOnly;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isValidForRequest(int requestId, boolean loadKeysOnly) {
|
boolean isValidForRequest(int requestId, boolean loadKeysOnly) {
|
||||||
return mId == requestId && (!mKeysOnly || loadKeysOnly);
|
return mRequestId == requestId && (!mKeysOnly || loadKeysOnly);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -34,6 +34,7 @@ import com.android.launcher3.icons.IconProvider;
|
|||||||
import com.android.launcher3.icons.IconProvider.IconChangeListener;
|
import com.android.launcher3.icons.IconProvider.IconChangeListener;
|
||||||
import com.android.launcher3.util.Executors.SimpleThreadFactory;
|
import com.android.launcher3.util.Executors.SimpleThreadFactory;
|
||||||
import com.android.launcher3.util.MainThreadInitializedObject;
|
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.Task;
|
||||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||||
@@ -70,7 +71,7 @@ public class RecentsModel extends TaskStackChangeListener implements IconChangeL
|
|||||||
private RecentsModel(Context context) {
|
private RecentsModel(Context context) {
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mTaskList = new RecentTasksList(MAIN_EXECUTOR,
|
mTaskList = new RecentTasksList(MAIN_EXECUTOR,
|
||||||
new KeyguardManagerCompat(context), ActivityManagerWrapper.getInstance());
|
new KeyguardManagerCompat(context), SystemUiProxy.INSTANCE.get(context));
|
||||||
|
|
||||||
IconProvider iconProvider = new IconProvider(context);
|
IconProvider iconProvider = new IconProvider(context);
|
||||||
mIconCache = new TaskIconCache(context, RECENTS_MODEL_EXECUTOR, iconProvider);
|
mIconCache = new TaskIconCache(context, RECENTS_MODEL_EXECUTOR, iconProvider);
|
||||||
@@ -95,7 +96,7 @@ public class RecentsModel extends TaskStackChangeListener implements IconChangeL
|
|||||||
* always called on the UI thread.
|
* always called on the UI thread.
|
||||||
* @return the request id associated with this call.
|
* @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);
|
return mTaskList.getTasks(false /* loadKeysOnly */, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,9 +121,9 @@ public class RecentsModel extends TaskStackChangeListener implements IconChangeL
|
|||||||
* @param callback Receives true if task is removed, false otherwise
|
* @param callback Receives true if task is removed, false otherwise
|
||||||
*/
|
*/
|
||||||
public void isTaskRemoved(int taskId, Consumer<Boolean> callback) {
|
public void isTaskRemoved(int taskId, Consumer<Boolean> callback) {
|
||||||
mTaskList.getTasks(true /* loadKeysOnly */, (tasks) -> {
|
mTaskList.getTasks(true /* loadKeysOnly */, (taskGroups) -> {
|
||||||
for (Task task : tasks) {
|
for (GroupTask group : taskGroups) {
|
||||||
if (task.key.id == taskId) {
|
if (group.containsTask(taskId)) {
|
||||||
callback.accept(false);
|
callback.accept(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -148,14 +149,15 @@ public class RecentsModel extends TaskStackChangeListener implements IconChangeL
|
|||||||
ActivityManager.RunningTaskInfo runningTask =
|
ActivityManager.RunningTaskInfo runningTask =
|
||||||
ActivityManagerWrapper.getInstance().getRunningTask();
|
ActivityManagerWrapper.getInstance().getRunningTask();
|
||||||
int runningTaskId = runningTask != null ? runningTask.id : -1;
|
int runningTaskId = runningTask != null ? runningTask.id : -1;
|
||||||
mTaskList.getTaskKeys(mThumbnailCache.getCacheSize(), tasks -> {
|
mTaskList.getTaskKeys(mThumbnailCache.getCacheSize(), taskGroups -> {
|
||||||
for (Task task : tasks) {
|
for (GroupTask group : taskGroups) {
|
||||||
if (task.key.id == runningTaskId) {
|
if (group.containsTask(runningTaskId)) {
|
||||||
// Skip the running task, it's not going to have an up-to-date snapshot by the
|
// Skip the running task, it's not going to have an up-to-date snapshot by the
|
||||||
// time the user next enters overview
|
// time the user next enters overview
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
mThumbnailCache.updateThumbnailInCache(task);
|
mThumbnailCache.updateThumbnailInCache(group.task1);
|
||||||
|
mThumbnailCache.updateThumbnailInCache(group.task2);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@
|
|||||||
*/
|
*/
|
||||||
package com.android.quickstep;
|
package com.android.quickstep;
|
||||||
|
|
||||||
|
import static android.app.ActivityManager.RECENT_IGNORE_UNAVAILABLE;
|
||||||
|
|
||||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||||
|
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
@@ -47,6 +49,9 @@ import com.android.systemui.shared.system.smartspace.ISmartspaceTransitionContro
|
|||||||
import com.android.wm.shell.onehanded.IOneHanded;
|
import com.android.wm.shell.onehanded.IOneHanded;
|
||||||
import com.android.wm.shell.pip.IPip;
|
import com.android.wm.shell.pip.IPip;
|
||||||
import com.android.wm.shell.pip.IPipAnimationListener;
|
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.ISplitScreen;
|
||||||
import com.android.wm.shell.splitscreen.ISplitScreenListener;
|
import com.android.wm.shell.splitscreen.ISplitScreenListener;
|
||||||
import com.android.wm.shell.startingsurface.IStartingWindow;
|
import com.android.wm.shell.startingsurface.IStartingWindow;
|
||||||
@@ -54,6 +59,7 @@ import com.android.wm.shell.startingsurface.IStartingWindowListener;
|
|||||||
import com.android.wm.shell.transition.IShellTransitions;
|
import com.android.wm.shell.transition.IShellTransitions;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the reference to SystemUI.
|
* Holds the reference to SystemUI.
|
||||||
@@ -72,6 +78,7 @@ public class SystemUiProxy implements ISystemUiProxy,
|
|||||||
private IOneHanded mOneHanded;
|
private IOneHanded mOneHanded;
|
||||||
private IShellTransitions mShellTransitions;
|
private IShellTransitions mShellTransitions;
|
||||||
private IStartingWindow mStartingWindow;
|
private IStartingWindow mStartingWindow;
|
||||||
|
private IRecentTasks mRecentTasks;
|
||||||
private final DeathRecipient mSystemUiProxyDeathRecipient = () -> {
|
private final DeathRecipient mSystemUiProxyDeathRecipient = () -> {
|
||||||
MAIN_EXECUTOR.execute(() -> clearProxy());
|
MAIN_EXECUTOR.execute(() -> clearProxy());
|
||||||
};
|
};
|
||||||
@@ -82,6 +89,7 @@ public class SystemUiProxy implements ISystemUiProxy,
|
|||||||
private ISplitScreenListener mPendingSplitScreenListener;
|
private ISplitScreenListener mPendingSplitScreenListener;
|
||||||
private IStartingWindowListener mPendingStartingWindowListener;
|
private IStartingWindowListener mPendingStartingWindowListener;
|
||||||
private ISmartspaceCallback mPendingSmartspaceCallback;
|
private ISmartspaceCallback mPendingSmartspaceCallback;
|
||||||
|
private IRecentTasksListener mPendingRecentTasksListener;
|
||||||
private final ArrayList<RemoteTransitionCompat> mPendingRemoteTransitions = new ArrayList<>();
|
private final ArrayList<RemoteTransitionCompat> mPendingRemoteTransitions = new ArrayList<>();
|
||||||
|
|
||||||
// Used to dedupe calls to SystemUI
|
// Used to dedupe calls to SystemUI
|
||||||
@@ -135,7 +143,7 @@ public class SystemUiProxy implements ISystemUiProxy,
|
|||||||
|
|
||||||
public void setProxy(ISystemUiProxy proxy, IPip pip, ISplitScreen splitScreen,
|
public void setProxy(ISystemUiProxy proxy, IPip pip, ISplitScreen splitScreen,
|
||||||
IOneHanded oneHanded, IShellTransitions shellTransitions,
|
IOneHanded oneHanded, IShellTransitions shellTransitions,
|
||||||
IStartingWindow startingWindow,
|
IStartingWindow startingWindow, IRecentTasks recentTasks,
|
||||||
ISmartspaceTransitionController smartSpaceTransitionController) {
|
ISmartspaceTransitionController smartSpaceTransitionController) {
|
||||||
unlinkToDeath();
|
unlinkToDeath();
|
||||||
mSystemUiProxy = proxy;
|
mSystemUiProxy = proxy;
|
||||||
@@ -145,6 +153,7 @@ public class SystemUiProxy implements ISystemUiProxy,
|
|||||||
mShellTransitions = shellTransitions;
|
mShellTransitions = shellTransitions;
|
||||||
mStartingWindow = startingWindow;
|
mStartingWindow = startingWindow;
|
||||||
mSmartspaceTransitionController = smartSpaceTransitionController;
|
mSmartspaceTransitionController = smartSpaceTransitionController;
|
||||||
|
mRecentTasks = recentTasks;
|
||||||
linkToDeath();
|
linkToDeath();
|
||||||
// re-attach the listeners once missing due to setProxy has not been initialized yet.
|
// re-attach the listeners once missing due to setProxy has not been initialized yet.
|
||||||
if (mPendingPipAnimationListener != null && mPip != null) {
|
if (mPendingPipAnimationListener != null && mPip != null) {
|
||||||
@@ -167,6 +176,10 @@ public class SystemUiProxy implements ISystemUiProxy,
|
|||||||
registerRemoteTransition(mPendingRemoteTransitions.get(i));
|
registerRemoteTransition(mPendingRemoteTransitions.get(i));
|
||||||
}
|
}
|
||||||
mPendingRemoteTransitions.clear();
|
mPendingRemoteTransitions.clear();
|
||||||
|
if (mPendingRecentTasksListener != null && mRecentTasks != null) {
|
||||||
|
registerRecentTasksListener(mPendingRecentTasksListener);
|
||||||
|
mPendingRecentTasksListener = null;
|
||||||
|
}
|
||||||
|
|
||||||
if (mPendingSetNavButtonAlpha != null) {
|
if (mPendingSetNavButtonAlpha != null) {
|
||||||
mPendingSetNavButtonAlpha.run();
|
mPendingSetNavButtonAlpha.run();
|
||||||
@@ -175,7 +188,7 @@ public class SystemUiProxy implements ISystemUiProxy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void clearProxy() {
|
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
|
// TODO(141886704): Find a way to remove this
|
||||||
@@ -745,7 +758,6 @@ public class SystemUiProxy implements ISystemUiProxy,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// SmartSpace transitions
|
// SmartSpace transitions
|
||||||
//
|
//
|
||||||
@@ -761,4 +773,43 @@ public class SystemUiProxy implements ISystemUiProxy,
|
|||||||
mPendingSmartspaceCallback = callback;
|
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<>();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,6 +104,9 @@ public class TaskThumbnailCache {
|
|||||||
* Synchronously fetches the thumbnail for the given {@param task} and puts it in the cache.
|
* Synchronously fetches the thumbnail for the given {@param task} and puts it in the cache.
|
||||||
*/
|
*/
|
||||||
public void updateThumbnailInCache(Task task) {
|
public void updateThumbnailInCache(Task task) {
|
||||||
|
if (task == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
Preconditions.assertUIThread();
|
Preconditions.assertUIThread();
|
||||||
// Fetch the thumbnail for this task and put it in the cache
|
// Fetch the thumbnail for this task and put it in the cache
|
||||||
if (task.thumbnail == null) {
|
if (task.thumbnail == null) {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TI
|
|||||||
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
|
||||||
import static com.android.quickstep.GestureState.DEFAULT_STATE;
|
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.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_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_PIP;
|
||||||
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_SHELL_TRANSITIONS;
|
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_SHELL_TRANSITIONS;
|
||||||
@@ -107,6 +108,7 @@ import com.android.systemui.shared.system.smartspace.ISmartspaceTransitionContro
|
|||||||
import com.android.systemui.shared.tracing.ProtoTraceable;
|
import com.android.systemui.shared.tracing.ProtoTraceable;
|
||||||
import com.android.wm.shell.onehanded.IOneHanded;
|
import com.android.wm.shell.onehanded.IOneHanded;
|
||||||
import com.android.wm.shell.pip.IPip;
|
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.splitscreen.ISplitScreen;
|
||||||
import com.android.wm.shell.startingsurface.IStartingWindow;
|
import com.android.wm.shell.startingsurface.IStartingWindow;
|
||||||
import com.android.wm.shell.transition.IShellTransitions;
|
import com.android.wm.shell.transition.IShellTransitions;
|
||||||
@@ -162,9 +164,11 @@ public class TouchInteractionService extends Service
|
|||||||
ISmartspaceTransitionController smartspaceTransitionController =
|
ISmartspaceTransitionController smartspaceTransitionController =
|
||||||
ISmartspaceTransitionController.Stub.asInterface(
|
ISmartspaceTransitionController.Stub.asInterface(
|
||||||
bundle.getBinder(KEY_EXTRA_SMARTSPACE_TRANSITION_CONTROLLER));
|
bundle.getBinder(KEY_EXTRA_SMARTSPACE_TRANSITION_CONTROLLER));
|
||||||
|
IRecentTasks recentTasks = IRecentTasks.Stub.asInterface(
|
||||||
|
bundle.getBinder(KEY_EXTRA_RECENT_TASKS));
|
||||||
MAIN_EXECUTOR.execute(() -> {
|
MAIN_EXECUTOR.execute(() -> {
|
||||||
SystemUiProxy.INSTANCE.get(TouchInteractionService.this).setProxy(proxy, pip,
|
SystemUiProxy.INSTANCE.get(TouchInteractionService.this).setProxy(proxy, pip,
|
||||||
splitscreen, onehanded, shellTransitions, startingWindow,
|
splitscreen, onehanded, shellTransitions, startingWindow, recentTasks,
|
||||||
smartspaceTransitionController);
|
smartspaceTransitionController);
|
||||||
TouchInteractionService.this.initInputMonitor();
|
TouchInteractionService.this.initInputMonitor();
|
||||||
preloadOverview(true /* fromInit */);
|
preloadOverview(true /* fromInit */);
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import com.android.quickstep.util.TaskViewSimulator;
|
|||||||
import com.android.quickstep.views.OverviewActionsView;
|
import com.android.quickstep.views.OverviewActionsView;
|
||||||
import com.android.quickstep.views.RecentsView;
|
import com.android.quickstep.views.RecentsView;
|
||||||
import com.android.quickstep.views.TaskView;
|
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;
|
||||||
import com.android.systemui.shared.recents.model.Task.TaskKey;
|
import com.android.systemui.shared.recents.model.Task.TaskKey;
|
||||||
|
|
||||||
@@ -153,29 +154,32 @@ public class FallbackRecentsView extends RecentsView<RecentsActivity, RecentsSta
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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
|
// 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
|
// 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.
|
// 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
|
// TODO(b/195607777) Confirm home task info is front-most task and not mixed in with others
|
||||||
int runningTaskId = getTaskIdsForRunningTaskView()[0];
|
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
|
// Check if the task list has running task
|
||||||
boolean found = false;
|
boolean found = false;
|
||||||
for (Task t : tasks) {
|
for (GroupTask group : taskGroups) {
|
||||||
if (t.key.id == runningTaskId) {
|
if (group.containsTask(runningTaskId)) {
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
if (!found) {
|
||||||
ArrayList<Task> newList = new ArrayList<>(tasks.size() + 1);
|
ArrayList<GroupTask> newList = new ArrayList<>(taskGroups.size() + 1);
|
||||||
newList.addAll(tasks);
|
newList.addAll(taskGroups);
|
||||||
newList.add(Task.from(new TaskKey(mHomeTaskInfo), mHomeTaskInfo, false));
|
newList.add(new GroupTask(
|
||||||
tasks = newList;
|
Task.from(new TaskKey(mHomeTaskInfo), mHomeTaskInfo, false),
|
||||||
|
null));
|
||||||
|
taskGroups = newList;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
super.applyLoadPlan(tasks);
|
super.applyLoadPlan(taskGroups);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -167,6 +167,7 @@ import com.android.quickstep.util.TaskViewSimulator;
|
|||||||
import com.android.quickstep.util.TransformParams;
|
import com.android.quickstep.util.TransformParams;
|
||||||
import com.android.quickstep.util.VibratorWrapper;
|
import com.android.quickstep.util.VibratorWrapper;
|
||||||
import com.android.systemui.plugins.ResourceProvider;
|
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;
|
||||||
import com.android.systemui.shared.recents.model.Task.TaskKey;
|
import com.android.systemui.shared.recents.model.Task.TaskKey;
|
||||||
import com.android.systemui.shared.recents.model.ThumbnailData;
|
import com.android.systemui.shared.recents.model.ThumbnailData;
|
||||||
@@ -1296,13 +1297,13 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
|||||||
updateGridProperties();
|
updateGridProperties();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void applyLoadPlan(ArrayList<Task> tasks) {
|
protected void applyLoadPlan(ArrayList<GroupTask> taskGroups) {
|
||||||
if (mPendingAnimation != null) {
|
if (mPendingAnimation != null) {
|
||||||
mPendingAnimation.addEndListener(success -> applyLoadPlan(tasks));
|
mPendingAnimation.addEndListener(success -> applyLoadPlan(taskGroups));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tasks == null || tasks.isEmpty()) {
|
if (taskGroups == null || taskGroups.isEmpty()) {
|
||||||
removeTasksViewsAndClearAllButton();
|
removeTasksViewsAndClearAllButton();
|
||||||
onTaskStackUpdated();
|
onTaskStackUpdated();
|
||||||
return;
|
return;
|
||||||
@@ -1324,10 +1325,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
|||||||
LauncherSplitScreenListener.INSTANCE.getNoCreate().getPersistentSplitIds();
|
LauncherSplitScreenListener.INSTANCE.getNoCreate().getPersistentSplitIds();
|
||||||
int requiredGroupTaskViews = splitTaskIds.length / 2;
|
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
|
// Subtract half the number of split tasks and not total number because we've already
|
||||||
// added a GroupedTaskView when swipe up gesture happens.
|
// added a GroupedTaskView when swipe up gesture happens.
|
||||||
// This will need to change if we start showing GroupedTaskViews during swipe up from home
|
// 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 (getTaskViewCount() != requiredTaskViewCount) {
|
||||||
if (indexOfChild(mClearAllButton) != -1) {
|
if (indexOfChild(mClearAllButton) != -1) {
|
||||||
@@ -1360,11 +1362,12 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
|||||||
+ " runningTaskViewId: " + mRunningTaskViewId
|
+ " runningTaskViewId: " + mRunningTaskViewId
|
||||||
+ " forTaskView: " + getTaskViewFromTaskViewId(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 >= 0;
|
||||||
taskViewIndex--, taskDataIndex--) {
|
taskViewIndex--, taskDataIndex--) {
|
||||||
final int pageIndex = requiredTaskViewCount - taskViewIndex - 1;
|
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);
|
final TaskView taskView = (TaskView) getChildAt(pageIndex);
|
||||||
if (taskView instanceof GroupedTaskView) {
|
if (taskView instanceof GroupedTaskView) {
|
||||||
Task leftTop;
|
Task leftTop;
|
||||||
@@ -1372,11 +1375,11 @@ public abstract class RecentsView<ACTIVITY_TYPE extends StatefulActivity<STATE_T
|
|||||||
if (task.key.id == splitTaskIds[0]) {
|
if (task.key.id == splitTaskIds[0]) {
|
||||||
leftTop = task;
|
leftTop = task;
|
||||||
taskDataIndex--;
|
taskDataIndex--;
|
||||||
rightBottom = tasks.get(taskDataIndex);
|
rightBottom = taskGroups.get(taskDataIndex).task1;
|
||||||
} else {
|
} else {
|
||||||
rightBottom = task;
|
rightBottom = task;
|
||||||
taskDataIndex--;
|
taskDataIndex--;
|
||||||
leftTop = tasks.get(taskDataIndex);
|
leftTop = taskGroups.get(taskDataIndex).task1;
|
||||||
}
|
}
|
||||||
((GroupedTaskView) taskView).bind(leftTop, rightBottom, mOrientationState,
|
((GroupedTaskView) taskView).bind(leftTop, rightBottom, mOrientationState,
|
||||||
mSplitBoundsConfig);
|
mSplitBoundsConfig);
|
||||||
|
|||||||
@@ -30,70 +30,78 @@ import android.app.ActivityManager;
|
|||||||
import androidx.test.filters.SmallTest;
|
import androidx.test.filters.SmallTest;
|
||||||
|
|
||||||
import com.android.launcher3.util.LooperExecutor;
|
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.recents.model.Task;
|
||||||
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
import com.android.systemui.shared.system.ActivityManagerWrapper;
|
||||||
import com.android.systemui.shared.system.KeyguardManagerCompat;
|
import com.android.systemui.shared.system.KeyguardManagerCompat;
|
||||||
|
import com.android.wm.shell.util.GroupedRecentTaskInfo;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@SmallTest
|
@SmallTest
|
||||||
public class RecentTasksListTest {
|
public class RecentTasksListTest {
|
||||||
|
|
||||||
private ActivityManagerWrapper mockActivityManagerWrapper;
|
@Mock
|
||||||
|
private SystemUiProxy mockSystemUiProxy;
|
||||||
|
|
||||||
// Class under test
|
// Class under test
|
||||||
private RecentTasksList mRecentTasksList;
|
private RecentTasksList mRecentTasksList;
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setup() {
|
public void setup() {
|
||||||
|
MockitoAnnotations.initMocks(this);
|
||||||
LooperExecutor mockMainThreadExecutor = mock(LooperExecutor.class);
|
LooperExecutor mockMainThreadExecutor = mock(LooperExecutor.class);
|
||||||
KeyguardManagerCompat mockKeyguardManagerCompat = mock(KeyguardManagerCompat.class);
|
KeyguardManagerCompat mockKeyguardManagerCompat = mock(KeyguardManagerCompat.class);
|
||||||
mockActivityManagerWrapper = mock(ActivityManagerWrapper.class);
|
|
||||||
mRecentTasksList = new RecentTasksList(mockMainThreadExecutor, mockKeyguardManagerCompat,
|
mRecentTasksList = new RecentTasksList(mockMainThreadExecutor, mockKeyguardManagerCompat,
|
||||||
mockActivityManagerWrapper);
|
mockSystemUiProxy);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void onTaskRemoved_doesNotFetchTasks() {
|
public void onRecentTasksChanged_doesNotFetchTasks() {
|
||||||
mRecentTasksList.onTaskRemoved(0);
|
mRecentTasksList.onRecentTasksChanged();
|
||||||
verify(mockActivityManagerWrapper, times(0))
|
verify(mockSystemUiProxy, times(0))
|
||||||
.getRecentTasks(anyInt(), anyInt());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void onTaskStackChanged_doesNotFetchTasks() {
|
|
||||||
mRecentTasksList.onTaskStackChanged();
|
|
||||||
verify(mockActivityManagerWrapper, times(0))
|
|
||||||
.getRecentTasks(anyInt(), anyInt());
|
.getRecentTasks(anyInt(), anyInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void loadTasksInBackground_onlyKeys_noValidTaskDescription() {
|
public void loadTasksInBackground_onlyKeys_noValidTaskDescription() {
|
||||||
ActivityManager.RecentTaskInfo recentTaskInfo = new ActivityManager.RecentTaskInfo();
|
GroupedRecentTaskInfo recentTaskInfos = new GroupedRecentTaskInfo(
|
||||||
when(mockActivityManagerWrapper.getRecentTasks(anyInt(), anyInt()))
|
new ActivityManager.RecentTaskInfo(), new ActivityManager.RecentTaskInfo());
|
||||||
.thenReturn(Collections.singletonList(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());
|
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
|
@Test
|
||||||
public void loadTasksInBackground_moreThanKeys_hasValidTaskDescription() {
|
public void loadTasksInBackground_moreThanKeys_hasValidTaskDescription() {
|
||||||
String taskDescription = "Wheeee!";
|
String taskDescription = "Wheeee!";
|
||||||
ActivityManager.RecentTaskInfo recentTaskInfo = new ActivityManager.RecentTaskInfo();
|
ActivityManager.RecentTaskInfo task1 = new ActivityManager.RecentTaskInfo();
|
||||||
recentTaskInfo.taskDescription = new ActivityManager.TaskDescription(taskDescription);
|
task1.taskDescription = new ActivityManager.TaskDescription(taskDescription);
|
||||||
when(mockActivityManagerWrapper.getRecentTasks(anyInt(), anyInt()))
|
ActivityManager.RecentTaskInfo task2 = new ActivityManager.RecentTaskInfo();
|
||||||
.thenReturn(Collections.singletonList(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(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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user