Merge "Change Stack to have generic WindowContainer children (76/n)"
diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java
index 84152e8..35b64e7 100644
--- a/services/core/java/com/android/server/wm/ActivityDisplay.java
+++ b/services/core/java/com/android/server/wm/ActivityDisplay.java
@@ -468,7 +468,7 @@
if (resumedActivity == null || resumedActivity.app == null) {
// If previously resumed activity doesn't work either - find the topmost running
// activity that can be focused.
- resumedActivity = focusedStack.topRunningActivityLocked(true /* focusableOnly */);
+ resumedActivity = focusedStack.topRunningActivity(true /* focusableOnly */);
}
}
return resumedActivity;
@@ -832,7 +832,7 @@
ActivityRecord topRunning = null;
final ActivityStack focusedStack = getFocusedStack();
if (focusedStack != null) {
- topRunning = focusedStack.topRunningActivityLocked();
+ topRunning = focusedStack.topRunningActivity();
}
// Look in other focusable stacks.
@@ -843,7 +843,7 @@
if (stack == focusedStack || !stack.isFocusable()) {
continue;
}
- topRunning = stack.topRunningActivityLocked();
+ topRunning = stack.topRunningActivity();
if (topRunning != null) {
break;
}
@@ -961,12 +961,6 @@
super.onConfigurationChanged(newParentConfig);
}
- void onLockTaskPackagesUpdated() {
- for (int i = getStackCount() - 1; i >= 0; --i) {
- getStackAt(i).onLockTaskPackagesUpdated();
- }
- }
-
/** Checks whether the given activity is in size compatibility mode and notifies the change. */
void handleActivitySizeCompatModeIfNeeded(ActivityRecord r) {
if (!r.isState(RESUMED) || r.getWindowingMode() != WINDOWING_MODE_FULLSCREEN) {
@@ -1082,7 +1076,7 @@
}
final ActivityStack stack = getStackCount() == 1 ? getStackAt(0) : null;
- if (stack != null && stack.isActivityTypeHome() && stack.getAllTasks().isEmpty()) {
+ if (stack != null && stack.isActivityTypeHome() && !stack.hasChild()) {
// Release this display if an empty home stack is the only thing left.
// Since it is the last stack, this display will be released along with the stack
// removal.
@@ -1318,13 +1312,7 @@
@VisibleForTesting
void removeAllTasks() {
- for (int i = getStackCount() - 1; i >= 0; --i) {
- final ActivityStack stack = getStackAt(i);
- final ArrayList<Task> tasks = stack.getAllTasks();
- for (int j = tasks.size() - 1; j >= 0; --j) {
- stack.removeChild(tasks.get(j), "removeAllTasks");
- }
- }
+ mDisplayContent.forAllTasks((t) -> { t.getStack().removeChild(t, "removeAllTasks"); });
}
public void dump(PrintWriter pw, String prefix) {
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 25079ec..092a844 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -2406,7 +2406,7 @@
// We are finishing the top focused activity and its stack has nothing to be focused so
// the next focusable stack should be focused.
if (mayAdjustTop
- && (stack.topRunningActivityLocked() == null || !stack.isFocusable())) {
+ && (stack.topRunningActivity() == null || !stack.isFocusable())) {
if (shouldAdjustGlobalFocus) {
// Move the entire hierarchy to top with updating global top resumed activity
// and focused application if needed.
@@ -3440,7 +3440,8 @@
}
@Override
- ActivityRecord getActivity(Predicate<ActivityRecord> callback, boolean traverseTopToBottom) {
+ ActivityRecord getActivity(Predicate<ActivityRecord> callback, boolean traverseTopToBottom,
+ WindowContainer boundary) {
return callback.test(this) ? this : null;
}
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index cc45671..eb1f638 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_BOTTOM_OR_RIGHT;
import static android.app.ActivityTaskManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT;
import static android.app.ITaskStackListener.FORCED_RESIZEABLE_REASON_SPLIT_SCREEN;
@@ -191,7 +192,7 @@
/**
* State and management of a single stack of activities.
*/
-class ActivityStack extends WindowContainer<Task> implements BoundsAnimationTarget {
+class ActivityStack extends WindowContainer<WindowContainer> implements BoundsAnimationTarget {
private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityStack" : TAG_ATM;
static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
private static final String TAG_APP = TAG + POSTFIX_APP;
@@ -583,7 +584,7 @@
return true;
}
- final ActivityRecord topActivity = topRunningActivityLocked();
+ final ActivityRecord topActivity = topRunningActivity();
final PooledFunction f = PooledLambda.obtainFunction(
CheckBehindFullscreenActivityHelper::processActivity, this,
PooledLambda.__(ActivityRecord.class), topActivity);
@@ -870,7 +871,7 @@
final boolean isMinimizedDock =
display.mDisplayContent.getDockedDividerController().isMinimizedDock();
if (isMinimizedDock) {
- Task topTask = display.getSplitScreenPrimaryStack().topTask();
+ Task topTask = display.getSplitScreenPrimaryStack().getTopMostTask();
if (topTask != null) {
dockedBounds = topTask.getBounds();
}
@@ -946,7 +947,7 @@
final int currentMode = getWindowingMode();
final int currentOverrideMode = getRequestedOverrideWindowingMode();
final ActivityDisplay display = getDisplay();
- final Task topTask = topTask();
+ final Task topTask = getTopMostTask();
final ActivityStack splitScreenStack = display.getSplitScreenPrimaryStack();
int windowingMode = preferredWindowingMode;
if (preferredWindowingMode == WINDOWING_MODE_UNDEFINED
@@ -1174,11 +1175,11 @@
return false;
}
- ActivityRecord topRunningActivityLocked() {
- return topRunningActivityLocked(false /* focusableOnly */);
+ ActivityRecord topRunningActivity() {
+ return topRunningActivity(false /* focusableOnly */);
}
- ActivityRecord topRunningActivityLocked(boolean focusableOnly) {
+ ActivityRecord topRunningActivity(boolean focusableOnly) {
// Split into 2 to avoid object creation due to variable capture.
if (focusableOnly) {
return getActivity((r) -> r.canBeTopRunning() && r.isFocusable());
@@ -1212,7 +1213,7 @@
*
* @return Returns the HistoryRecord of the next activity on the stack.
*/
- final ActivityRecord topRunningActivityLocked(IBinder token, int taskId) {
+ ActivityRecord topRunningActivity(IBinder token, int taskId) {
final PooledPredicate p = PooledLambda.obtainPredicate(ActivityStack::isTopRunning,
PooledLambda.__(ActivityRecord.class), taskId, token);
final ActivityRecord r = getActivity(p);
@@ -1221,31 +1222,13 @@
}
private static boolean isTopRunning(ActivityRecord r, int taskId, IBinder notTop) {
- return r.getTask().mTaskId == taskId && r.appToken != notTop && r.canBeTopRunning();
+ return r.getTask().mTaskId != taskId && r.appToken != notTop && r.canBeTopRunning();
}
ActivityRecord getTopNonFinishingActivity() {
return getTopActivity(false /*includeFinishing*/, true /*includeOverlays*/);
}
- final Task topTask() {
- final int size = getChildCount();
- if (size > 0) {
- return getChildAt(size - 1);
- }
- return null;
- }
-
- Task taskForIdLocked(int id) {
- for (int taskNdx = getChildCount() - 1; taskNdx >= 0; --taskNdx) {
- final Task task = getChildAt(taskNdx);
- if (task.mTaskId == id) {
- return task;
- }
- }
- return null;
- }
-
ActivityRecord isInStackLocked(IBinder token) {
final ActivityRecord r = ActivityRecord.forTokenLocked(token);
return isInStackLocked(r);
@@ -1292,9 +1275,7 @@
}
private boolean returnsToHomeStack() {
- return !inMultiWindowMode()
- && hasChild()
- && getChildAt(0).returnsToHomeStack();
+ return !inMultiWindowMode() && hasChild() && getBottomMostTask().returnsToHomeStack();
}
void moveToFront(String reason) {
@@ -1367,7 +1348,7 @@
}
boolean isFocusable() {
- final ActivityRecord r = topRunningActivityLocked();
+ final ActivityRecord r = topRunningActivity();
return mRootActivityContainer.isFocusable(this, r != null && r.isFocusable());
}
@@ -1390,15 +1371,12 @@
mCurrentUser = userId;
super.switchUser(userId);
- int top = mChildren.size();
- for (int taskNdx = 0; taskNdx < top; ++taskNdx) {
- Task task = mChildren.get(taskNdx);
- if (mWmService.isCurrentProfileLocked(task.mUserId) || task.showForAllUsers()) {
- mChildren.remove(taskNdx);
- mChildren.add(task);
- --top;
+ forAllTasks((t) -> {
+ if (t.mWmService.isCurrentProfileLocked(t.mUserId) || t.showForAllUsers()) {
+ mChildren.remove(t);
+ mChildren.add(t);
}
- }
+ });
}
void minimalResumeActivityLocked(ActivityRecord r) {
@@ -1719,7 +1697,7 @@
mRootActivityContainer.resumeFocusedStacksTopActivities(topStack, prev, null);
} else {
checkReadyForSleep();
- ActivityRecord top = topStack.topRunningActivityLocked();
+ ActivityRecord top = topStack.topRunningActivity();
if (top == null || (prev != null && top != prev)) {
// If there are no more activities available to run, do resume anyway to start
// something. Also if the top activity on the stack is not the just paused
@@ -1849,7 +1827,7 @@
final boolean isAssistantType = isActivityTypeAssistant();
for (int i = display.getStackCount() - 1; i >= 0; --i) {
final ActivityStack other = display.getStackAt(i);
- final boolean hasRunningActivities = other.topRunningActivityLocked() != null;
+ final boolean hasRunningActivities = other.topRunningActivity() != null;
if (other == this) {
// Should be visible if there is no other stack occluding it, unless it doesn't
// have any running activities, not starting one and not home stack.
@@ -2001,7 +1979,7 @@
@Override
public boolean supportsSplitScreenWindowingMode() {
- final Task topTask = topTask();
+ final Task topTask = getTopMostTask();
return super.supportsSplitScreenWindowingMode()
&& (topTask == null || topTask.supportsSplitScreenWindowingMode());
}
@@ -2185,7 +2163,7 @@
// to ensure any necessary pause logic occurs. In the case where the Activity will be
// shown regardless of the lock screen, the call to
// {@link ActivityStackSupervisor#checkReadyForSleepLocked} is skipped.
- final ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
+ final ActivityRecord next = topRunningActivity(true /* focusableOnly */);
if (next == null || !next.canTurnScreenOn()) {
checkReadyForSleep();
}
@@ -2224,7 +2202,7 @@
// Find the next top-most activity to resume in this stack that is not finishing and is
// focusable. If it is not focusable, we will fall into the case below to resume the
// top activity in the next focusable task.
- ActivityRecord next = topRunningActivityLocked(true /* focusableOnly */);
+ ActivityRecord next = topRunningActivity(true /* focusableOnly */);
final boolean hasRunningActivity = next != null;
@@ -2535,7 +2513,7 @@
// We should be all done, but let's just make sure our activity
// is still at the top and schedule another run if something
// weird happened.
- ActivityRecord nextNext = topRunningActivityLocked();
+ ActivityRecord nextNext = topRunningActivity();
if (DEBUG_SWITCH || DEBUG_STATES) Slog.i(TAG_STATES,
"Activity config changed during resume: " + next
+ ", new next: " + nextNext);
@@ -2672,41 +2650,28 @@
void startActivityLocked(ActivityRecord r, ActivityRecord focusedTopActivity,
boolean newTask, boolean keepCurTransition, ActivityOptions options) {
Task rTask = r.getTask();
- final int taskId = rTask.mTaskId;
final boolean allowMoveToFront = options == null || !options.getAvoidMoveToFront();
+ final boolean hasTask = hasChild(rTask);
// mLaunchTaskBehind tasks get placed at the back of the task stack.
- if (!r.mLaunchTaskBehind && allowMoveToFront
- && (taskForIdLocked(taskId) == null || newTask)) {
+ if (!r.mLaunchTaskBehind && allowMoveToFront && (!hasTask || newTask)) {
// Last activity in task had been removed or ActivityManagerService is reusing task.
// Insert or replace.
// Might not even be in.
positionChildAtTop(rTask);
}
Task task = null;
- if (!newTask) {
- // If starting in an existing task, find where that is...
- boolean isOccluded = false;
- for (int taskNdx = getChildCount() - 1; taskNdx >= 0; --taskNdx) {
- task = getChildAt(taskNdx);
- if (task.getTopNonFinishingActivity() == null) {
- // All activities in task are finishing.
- continue;
- }
- if (task == rTask) {
- // Here it is! Now, if this is not yet visible (occluded by another task) to
- // the user, then just add it without starting; it will get started when the
- // user navigates back to it.
- if (isOccluded) {
- if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
- + task, new RuntimeException("here").fillInStackTrace());
- rTask.positionChildAtTop(r);
- ActivityOptions.abort(options);
- return;
- }
- break;
- } else if (!isOccluded) {
- isOccluded = task.getActivity(ActivityRecord::occludesParent) != null;
- }
+ if (!newTask && hasTask) {
+ final ActivityRecord occludingActivity = getActivity(
+ (ar) -> !ar.finishing && ar.occludesParent(), true, rTask);
+ if (occludingActivity != null) {
+ // Here it is! Now, if this is not yet visible (occluded by another task) to the
+ // user, then just add it without starting; it will get started when the user
+ // navigates back to it.
+ if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task " + task,
+ new RuntimeException("here").fillInStackTrace());
+ rTask.positionChildAtTop(r);
+ ActivityOptions.abort(options);
+ return;
}
}
@@ -2892,7 +2857,7 @@
return null;
}
- final ActivityRecord top = stack.topRunningActivityLocked();
+ final ActivityRecord top = stack.topRunningActivity();
if (stack.isActivityTypeHome() && (top == null || !top.mVisibleRequested)) {
// If we will be focusing on the home stack next and its current top activity isn't
@@ -2922,7 +2887,7 @@
* not belong to the crashed app.
*/
final Task finishTopCrashedActivityLocked(WindowProcessController app, String reason) {
- ActivityRecord r = topRunningActivityLocked();
+ final ActivityRecord r = topRunningActivity();
if (r == null || r.app != app) {
return null;
}
@@ -3033,12 +2998,11 @@
return true;
}
// We now need to get the task below it to determine what to do.
- int taskIdx = mChildren.indexOf(task);
- if (taskIdx <= 0) {
+ final Task prevTask = getTaskBelow(task);
+ if (prevTask == null) {
Slog.w(TAG, "shouldUpRecreateTask: task not in history for " + srec);
return false;
}
- final Task prevTask = getChildAt(taskIdx);
if (!task.affinity.equals(prevTask.affinity)) {
// These are different apps, so need to recreate.
return true;
@@ -3073,7 +3037,7 @@
// We should consolidate.
IActivityController controller = mService.mController;
if (controller != null) {
- ActivityRecord next = topRunningActivityLocked(srec.appToken, 0);
+ ActivityRecord next = topRunningActivity(srec.appToken, INVALID_TASK_ID);
if (next != null) {
// ask watcher if this is allowed
boolean resumeOK = true;
@@ -3287,7 +3251,7 @@
private void updateTransitLocked(int transit, ActivityOptions options) {
if (options != null) {
- ActivityRecord r = topRunningActivityLocked();
+ ActivityRecord r = topRunningActivity();
if (r != null && !r.isState(RESUMED)) {
r.updateOptionsLocked(options);
} else {
@@ -3344,7 +3308,7 @@
}
// Set focus to the top running activity of this stack.
- final ActivityRecord r = topRunningActivityLocked();
+ final ActivityRecord r = topRunningActivity();
if (r != null) {
r.moveFocusableActivityToTop(reason);
}
@@ -3386,15 +3350,10 @@
* If a watcher is installed, the action is preflighted and the watcher has an opportunity
* to premeptively cancel the move.
*
- * @param taskId The taskId to collect and move to the bottom.
+ * @param tr The task to collect and move to the bottom.
* @return Returns true if the move completed, false if not.
*/
- final boolean moveTaskToBackLocked(int taskId) {
- final Task tr = taskForIdLocked(taskId);
- if (tr == null) {
- Slog.i(TAG, "moveTaskToBack: bad taskId=" + taskId);
- return false;
- }
+ boolean moveTaskToBack(Task tr) {
Slog.i(TAG, "moveTaskToBack: " + tr);
// In LockTask mode, moving a locked task to the back of the stack may expose unlocked
@@ -3407,9 +3366,9 @@
// for *other* available tasks, but if none are available, then try again allowing the
// current task to be selected.
if (isTopStackOnDisplay() && mService.mController != null) {
- ActivityRecord next = topRunningActivityLocked(null, taskId);
+ ActivityRecord next = topRunningActivity(null, tr.mTaskId);
if (next == null) {
- next = topRunningActivityLocked(null, 0);
+ next = topRunningActivity(null, INVALID_TASK_ID);
}
if (next != null) {
// ask watcher if this is allowed
@@ -3426,7 +3385,8 @@
}
}
- if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task=" + taskId);
+ if (DEBUG_TRANSITION) Slog.v(TAG_TRANSITION, "Prepare to back transition: task="
+ + tr.mTaskId);
getDisplay().mDisplayContent.prepareAppTransition(TRANSIT_TASK_TO_BACK, false);
moveToBack("moveTaskToBackLocked", tr);
@@ -3471,24 +3431,16 @@
try {
// Update override configurations of all tasks in the stack.
final Rect taskBounds = tempTaskBounds != null ? tempTaskBounds : bounds;
- for (int i = getChildCount() - 1; i >= 0; i--) {
- final Task task = getChildAt(i);
- if (task.isResizeable()) {
- if (tempTaskInsetBounds != null && !tempTaskInsetBounds.isEmpty()) {
- task.setOverrideDisplayedBounds(taskBounds);
- task.setBounds(tempTaskInsetBounds);
- } else {
- task.setOverrideDisplayedBounds(null);
- task.setBounds(taskBounds);
- }
- }
- }
+ final PooledConsumer c = PooledLambda.obtainConsumer(
+ ActivityStack::processTaskResizeBounds, PooledLambda.__(Task.class),
+ taskBounds, tempTaskInsetBounds);
+ forAllTasks(c);
+ c.recycle();
setBounds(bounds);
if (!deferResume) {
- ensureVisibleActivitiesConfiguration(
- topRunningActivityLocked(), preserveWindows);
+ ensureVisibleActivitiesConfiguration(topRunningActivity(), preserveWindows);
}
} finally {
mService.continueWindowLayout();
@@ -3496,39 +3448,51 @@
}
}
+ private static void processTaskResizeBounds(Task task, Rect bounds, Rect insetBounds) {
+ if (!task.isResizeable()) return;
+
+ if (insetBounds != null && !insetBounds.isEmpty()) {
+ task.setOverrideDisplayedBounds(bounds);
+ task.setBounds(insetBounds);
+ } else {
+ task.setOverrideDisplayedBounds(null);
+ task.setBounds(bounds);
+ }
+ }
+
/**
* Until we can break this "set task bounds to same as stack bounds" behavior, this
* basically resizes both stack and task bounds to the same bounds.
*/
- void setTaskBounds(Rect bounds) {
+ private void setTaskBounds(Rect bounds) {
if (!updateBoundsAllowed(bounds)) {
return;
}
- for (int i = getChildCount() - 1; i >= 0; i--) {
- final Task task = getChildAt(i);
- if (task.isResizeable()) {
- task.setBounds(bounds);
- } else {
- task.setBounds(null);
- }
- }
+ final PooledConsumer c = PooledLambda.obtainConsumer(ActivityStack::setTaskBounds,
+ PooledLambda.__(Task.class), bounds);
+ forAllTasks(c);
+ c.recycle();
+ }
+
+ private static void setTaskBounds(Task task, Rect bounds) {
+ task.setBounds(task.isResizeable() ? bounds : null);
}
/** Helper to setDisplayedBounds on all child tasks */
- void setTaskDisplayedBounds(Rect bounds) {
+ private void setTaskDisplayedBounds(Rect bounds) {
if (!updateDisplayedBoundsAllowed(bounds)) {
return;
}
- for (int i = getChildCount() - 1; i >= 0; i--) {
- final Task task = getChildAt(i);
- if (bounds == null || bounds.isEmpty()) {
- task.setOverrideDisplayedBounds(null);
- } else if (task.isResizeable()) {
- task.setOverrideDisplayedBounds(bounds);
- }
- }
+ final PooledConsumer c = PooledLambda.obtainConsumer(ActivityStack::setTaskDisplayedBounds,
+ PooledLambda.__(Task.class), bounds);
+ forAllTasks(c);
+ c.recycle();
+ }
+
+ private static void setTaskDisplayedBounds(Task task, Rect bounds) {
+ task.setOverrideDisplayedBounds(bounds == null || bounds.isEmpty() ? null : bounds);
}
boolean willActivityBeVisible(IBinder token) {
@@ -3548,56 +3512,6 @@
return !r.finishing;
}
- /**
- * @return The set of running tasks through {@param tasksOut} that are available to the caller.
- * If {@param ignoreActivityType} or {@param ignoreWindowingMode} are not undefined,
- * then skip running tasks that match those types.
- */
- void getRunningTasks(List<Task> tasksOut, @ActivityType int ignoreActivityType,
- @WindowingMode int ignoreWindowingMode, int callingUid, boolean allowed,
- boolean crossUser, ArraySet<Integer> profileIds) {
- boolean focusedStack = mRootActivityContainer.getTopDisplayFocusedStack() == this;
- boolean topTask = true;
- int userId = UserHandle.getUserId(callingUid);
- for (int taskNdx = getChildCount() - 1; taskNdx >= 0; --taskNdx) {
- final Task task = getChildAt(taskNdx);
- if (task.getTopNonFinishingActivity() == null) {
- // Skip if there are no activities in the task
- continue;
- }
- if (task.effectiveUid != callingUid) {
- if (task.mUserId != userId && !crossUser && !profileIds.contains(task.mUserId)) {
- // Skip if the caller does not have cross user permission or cannot access
- // the task's profile
- continue;
- }
- if (!allowed && !task.isActivityTypeHome()) {
- // Skip if the caller isn't allowed to fetch this task, except for the home
- // task which we always return.
- continue;
- }
- }
- if (ignoreActivityType != ACTIVITY_TYPE_UNDEFINED
- && task.getActivityType() == ignoreActivityType) {
- // Skip ignored activity type
- continue;
- }
- if (ignoreWindowingMode != WINDOWING_MODE_UNDEFINED
- && task.getWindowingMode() == ignoreWindowingMode) {
- // Skip ignored windowing mode
- continue;
- }
- if (focusedStack && topTask) {
- // For the focused stack top task, update the last stack active time so that it can
- // be used to determine the order of the tasks (it may not be set for newly created
- // tasks)
- task.touchActiveTime();
- topTask = false;
- }
- tasksOut.add(task);
- }
- }
-
void unhandledBackLocked() {
final ActivityRecord topActivity = getTopMostActivity();
if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
@@ -3717,7 +3631,7 @@
}
ActivityRecord restartPackage(String packageName) {
- ActivityRecord starting = topRunningActivityLocked();
+ ActivityRecord starting = topRunningActivity();
// All activities that came from the package must be
// restarted as if there was a config change.
@@ -3745,7 +3659,7 @@
* @param child to remove.
* @param reason for removal.
*/
- void removeChild(Task child, String reason) {
+ void removeChild(WindowContainer child, String reason) {
if (!mChildren.contains(child)) {
// Not really in this stack anymore...
return;
@@ -3757,7 +3671,7 @@
super.removeChild(child);
- EventLogTags.writeWmRemoveTask(child.mTaskId, mStackId);
+ EventLogTags.writeWmRemoveTask(((Task) child).mTaskId, mStackId);
if (display.isSingleTaskInstance()) {
mService.notifySingleTaskDisplayEmpty(display.mDisplayId);
@@ -3767,15 +3681,15 @@
if (!hasChild()) {
// Stack is now empty...
- removeIfPossible();
+ removeIfPossible();
}
moveHomeStackToFrontIfNeeded(topFocused, display, reason);
}
@Override
- void removeChild(Task task) {
- removeChild(task, "removeChild");
+ void removeChild(WindowContainer child) {
+ removeChild(child, "removeChild");
}
void moveHomeStackToFrontIfNeeded(
@@ -3816,10 +3730,6 @@
return task;
}
- ArrayList<Task> getAllTasks() {
- return new ArrayList<>(mChildren);
- }
-
void addChild(final Task task, final boolean toTop, boolean showForAllUsers) {
if (isSingleTaskInstance() && hasChild()) {
throw new IllegalStateException("Can only have one child on stack=" + this);
@@ -4015,7 +3925,7 @@
}
mWindowManager.inSurfaceTransaction(() -> {
- final Task task = mChildren.get(0);
+ final Task task = getBottomMostTask();
setWindowingMode(WINDOWING_MODE_UNDEFINED);
getDisplay().positionStackAtTop(this, false /* includingParents */);
@@ -4026,7 +3936,7 @@
});
}
- void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds,
+ private void updatePictureInPictureModeForPinnedStackAnimation(Rect targetStackBounds,
boolean forceUpdate) {
// It is guaranteed that the activities requiring the update will be in the pinned stack at
// this point (either reparented before the animation into PiP, or before reparenting after
@@ -4034,29 +3944,19 @@
if (!isAttached()) {
return;
}
- ArrayList<Task> tasks = getAllTasks();
- for (int i = 0; i < tasks.size(); i++) {
- mStackSupervisor.updatePictureInPictureMode(tasks.get(i), targetStackBounds,
- forceUpdate);
- }
+ final PooledConsumer c = PooledLambda.obtainConsumer(
+ ActivityStackSupervisor::updatePictureInPictureMode, mStackSupervisor,
+ PooledLambda.__(Task.class), targetStackBounds, forceUpdate);
+ forAllTasks(c);
+ c.recycle();
}
public int getStackId() {
return mStackId;
}
- Task findHomeTask() {
- if (!isActivityTypeHome() || mChildren.isEmpty()) {
- return null;
- }
- return mChildren.get(mChildren.size() - 1);
- }
-
void prepareFreezingTaskBounds() {
- for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
- final Task task = mChildren.get(taskNdx);
- task.prepareFreezingBounds();
- }
+ forAllTasks(Task::prepareFreezingBounds);
}
/**
@@ -4082,26 +3982,19 @@
insetBounds = mFullyAdjustedImeBounds;
}
}
- alignTasksToAdjustedBounds(adjusted ? mAdjustedBounds : getRawBounds(), insetBounds);
+
+ if (!matchParentBounds()) {
+ final boolean alignBottom = mAdjustedForIme && getDockSide() == DOCKED_TOP;
+ final PooledConsumer c = PooledLambda.obtainConsumer(Task::alignToAdjustedBounds,
+ PooledLambda.__(Task.class), adjusted ? mAdjustedBounds : getRawBounds(),
+ insetBounds, alignBottom);
+ c.recycle();
+ }
+
mDisplayContent.setLayoutNeeded();
-
updateSurfaceBounds();
}
- private void alignTasksToAdjustedBounds(Rect adjustedBounds, Rect tempInsetBounds) {
- if (matchParentBounds()) {
- return;
- }
-
- final boolean alignBottom = mAdjustedForIme && getDockSide() == DOCKED_TOP;
-
- // Update bounds of containing tasks.
- for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; --taskNdx) {
- final Task task = mChildren.get(taskNdx);
- task.alignToAdjustedBounds(adjustedBounds, tempInsetBounds, alignBottom);
- }
- }
-
@Override
public int setBounds(Rect bounds) {
return setBounds(getRequestedOverrideBounds(), bounds);
@@ -4366,17 +4259,17 @@
* @param position Target position to add the task to.
* @param showForAllUsers Whether to show the task regardless of the current user.
*/
- void addChild(Task task, int position, boolean showForAllUsers, boolean moveParents) {
+ private void addChild(Task task, int position, boolean showForAllUsers, boolean moveParents) {
// Add child task.
addChild(task, null);
// Move child to a proper position, as some restriction for position might apply.
- position = positionChildAt(
- position, task, moveParents /* includingParents */, showForAllUsers);
+ positionChildAt(position, task, moveParents /* includingParents */, showForAllUsers);
}
@Override
- void addChild(Task task, int position) {
+ void addChild(WindowContainer child, int position) {
+ final Task task = (Task) child;
addChild(task, position, task.showForAllUsers(), false /* includingParents */);
}
@@ -4415,14 +4308,15 @@
}
@Override
- void positionChildAt(int position, Task child, boolean includingParents) {
- positionChildAt(position, child, includingParents, child.showForAllUsers());
+ void positionChildAt(int position, WindowContainer child, boolean includingParents) {
+ final Task task = (Task) child;
+ positionChildAt(position, task, includingParents, task.showForAllUsers());
}
/**
- * Overridden version of {@link ActivityStack#positionChildAt(int, Task, boolean)}. Used in
- * {@link ActivityStack#addChild(Task, int, boolean showForAllUsers, boolean)}, as it can
- * receive showForAllUsers param from {@link ActivityRecord} instead of
+ * Overridden version of {@link ActivityStack#positionChildAt(int, WindowContainer, boolean)}.
+ * Used in {@link ActivityStack#addChild(Task, int, boolean showForAllUsers, boolean)}, as it
+ * can receive showForAllUsers param from {@link ActivityRecord} instead of
* {@link Task#showForAllUsers()}.
*/
private int positionChildAt(int position, Task child, boolean includingParents,
@@ -4538,9 +4432,10 @@
* We will start adjusting up from here.
* @param size The size of the current task list.
*/
+ // TODO(task-hierarchy): Move user to their own window container.
private int computeMinPosition(int minPosition, int size) {
while (minPosition < size) {
- final Task tmpTask = mChildren.get(minPosition);
+ final Task tmpTask = (Task) mChildren.get(minPosition);
final boolean canShowTmpTask =
tmpTask.showForAllUsers()
|| mWmService.isCurrentProfileLocked(tmpTask.mUserId);
@@ -4557,9 +4452,10 @@
* @param maxPosition The maximum position the caller is suggesting.
* We will start adjusting down from here.
*/
+ // TODO(task-hierarchy): Move user to their own window container.
private int computeMaxPosition(int maxPosition) {
while (maxPosition > 0) {
- final Task tmpTask = mChildren.get(maxPosition);
+ final Task tmpTask = (Task) mChildren.get(maxPosition);
final boolean canShowTmpTask =
tmpTask.showForAllUsers()
|| mWmService.isCurrentProfileLocked(tmpTask.mUserId);
@@ -4664,7 +4560,7 @@
// When the home stack is resizable, should always have the same stack and task bounds
if (isActivityTypeHome()) {
- final Task homeTask = findHomeTask();
+ final Task homeTask = getTopMostTask();
if (homeTask == null || homeTask.isResizeable()) {
// Calculate the home stack bounds when in docked mode and the home stack is
// resizeable.
@@ -4894,25 +4790,20 @@
* to the list of to be drawn windows the service is waiting for.
*/
void beginImeAdjustAnimation() {
- for (int j = mChildren.size() - 1; j >= 0; j--) {
- final Task task = mChildren.get(j);
- if (task.hasContentToDisplay()) {
- task.setDragResizing(true, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
- task.setWaitingForDrawnIfResizingChanged();
+ forAllTasks((t) -> {
+ if (t.hasContentToDisplay()) {
+ t.setDragResizing(true, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
+ t.setWaitingForDrawnIfResizingChanged();
}
- }
+ });
}
- /**
- * Resets the resizing state of all windows.
- */
+ /** Resets the resizing state of all windows. */
void endImeAdjustAnimation() {
- for (int j = mChildren.size() - 1; j >= 0; j--) {
- mChildren.get(j).setDragResizing(false, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
- }
+ forAllTasks((t) -> { t.setDragResizing(false, DRAG_RESIZE_MODE_DOCKED_DIVIDER); });
}
- int getMinTopStackBottom(final Rect displayContentRect, int originalStackBottom) {
+ private int getMinTopStackBottom(final Rect displayContentRect, int originalStackBottom) {
return displayContentRect.top + (int)
((originalStackBottom - displayContentRect.top) * ADJUSTED_STACK_FRACTION_MIN);
}
@@ -5024,7 +4915,7 @@
return true;
}
- private boolean isMinimizedDockAndHomeStackResizable() {
+ boolean isMinimizedDockAndHomeStackResizable() {
return mDisplayContent.mDividerControllerLocked.isMinimizedDock()
&& mDisplayContent.mDividerControllerLocked.isHomeStackResizable();
}
@@ -5092,13 +4983,7 @@
* recents animation); {@code false} otherwise.
*/
boolean isTaskAnimating() {
- for (int j = mChildren.size() - 1; j >= 0; j--) {
- final Task task = mChildren.get(j);
- if (task.isTaskAnimating()) {
- return true;
- }
- }
- return false;
+ return getTask(Task::isTaskAnimating) != null;
}
@Override
@@ -5173,102 +5058,11 @@
}
boolean hasTaskForUser(int userId) {
- for (int i = mChildren.size() - 1; i >= 0; i--) {
- final Task task = mChildren.get(i);
- if (task.mUserId == userId) {
- return true;
- }
- }
- return false;
- }
-
- void findTaskForResizePoint(int x, int y, int delta,
- DisplayContent.TaskForResizePointSearchResult results) {
- if (!getWindowConfiguration().canResizeTask()) {
- results.searchDone = true;
- return;
- }
-
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final Task task = mChildren.get(i);
- if (task.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
- results.searchDone = true;
- return;
- }
-
- // We need to use the task's dim bounds (which is derived from the visible bounds of
- // its apps windows) for any touch-related tests. Can't use the task's original
- // bounds because it might be adjusted to fit the content frame. One example is when
- // the task is put to top-left quadrant, the actual visible area would not start at
- // (0,0) after it's adjusted for the status bar.
- task.getDimBounds(mTmpRect);
- mTmpRect.inset(-delta, -delta);
- if (mTmpRect.contains(x, y)) {
- mTmpRect.inset(delta, delta);
-
- results.searchDone = true;
-
- if (!mTmpRect.contains(x, y)) {
- results.taskForResize = task;
- return;
- }
- // User touched inside the task. No need to look further,
- // focus transfer will be handled in ACTION_UP.
- return;
- }
- }
- }
-
- void setTouchExcludeRegion(Task focusedTask, int delta, Region touchExcludeRegion,
- Rect contentRect, Rect postExclude) {
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final Task task = mChildren.get(i);
- ActivityRecord topVisibleActivity = task.getTopVisibleActivity();
- if (topVisibleActivity == null || !topVisibleActivity.hasContentToDisplay()) {
- continue;
- }
-
- /**
- * Exclusion region is the region that TapDetector doesn't care about.
- * Here we want to remove all non-focused tasks from the exclusion region.
- * We also remove the outside touch area for resizing for all freeform
- * tasks (including the focused).
- *
- * We save the focused task region once we find it, and add it back at the end.
- *
- * If the task is home stack and it is resizable in the minimized state, we want to
- * exclude the docked stack from touch so we need the entire screen area and not just a
- * small portion which the home stack currently is resized to.
- */
-
- if (task.isActivityTypeHome() && isMinimizedDockAndHomeStackResizable()) {
- mDisplayContent.getBounds(mTmpRect);
- } else {
- task.getDimBounds(mTmpRect);
- }
-
- if (task == focusedTask) {
- // Add the focused task rect back into the exclude region once we are done
- // processing stacks.
- postExclude.set(mTmpRect);
- }
-
- final boolean isFreeformed = task.inFreeformWindowingMode();
- if (task != focusedTask || isFreeformed) {
- if (isFreeformed) {
- // If the task is freeformed, enlarge the area to account for outside
- // touch area for resize.
- mTmpRect.inset(-delta, -delta);
- // Intersect with display content rect. If we have system decor (status bar/
- // navigation bar), we want to exclude that from the tap detection.
- // Otherwise, if the app is partially placed under some system button (eg.
- // Recents, Home), pressing that button would cause a full series of
- // unwanted transfer focus/resume/pause, before we could go home.
- mTmpRect.intersect(contentRect);
- }
- touchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE);
- }
- }
+ final PooledPredicate p = PooledLambda.obtainPredicate(
+ Task::isTaskForUser, PooledLambda.__(Task.class), userId);
+ final Task task = getTask(p);
+ p.recycle();
+ return task != null;
}
public boolean setPinnedStackSize(Rect stackBounds, Rect tempTaskBounds) {
@@ -5429,10 +5223,7 @@
/** Called immediately prior to resizing the tasks at the end of the pinned stack animation. */
void onPipAnimationEndResize() {
mBoundsAnimating = false;
- for (int i = 0; i < mChildren.size(); i++) {
- final Task t = mChildren.get(i);
- t.clearPreserveNonFloatingState();
- }
+ forAllTasks(Task::clearPreserveNonFloatingState, false);
mWmService.requestTraversal();
}
@@ -5453,7 +5244,7 @@
if (homeStack == null) {
return true;
}
- final Task homeTask = homeStack.getTopChild();
+ final Task homeTask = homeStack.getTopMostTask();
if (homeTask == null) {
return true;
}
@@ -5585,7 +5376,7 @@
@Override
void getAnimationFrames(Rect outFrame, Rect outInsets, Rect outStableInsets,
Rect outSurfaceInsets) {
- final Task task = getTopChild();
+ final Task task = getTopMostTask();
if (task != null) {
task.getAnimationFrames(outFrame, outInsets, outStableInsets, outSurfaceInsets);
} else {
@@ -5596,7 +5387,7 @@
@Override
RemoteAnimationTarget createRemoteAnimationTarget(
RemoteAnimationController.RemoteAnimationRecord record) {
- final Task task = getTopChild();
+ final Task task = getTopMostTask();
return task != null ? task.createRemoteAnimationTarget(record) : null;
}
@@ -5611,12 +5402,6 @@
+ getChildCount() + " tasks}";
}
- void onLockTaskPackagesUpdated() {
- for (int taskNdx = getChildCount() - 1; taskNdx >= 0; --taskNdx) {
- getChildAt(taskNdx).setLockTaskAuth();
- }
- }
-
void executeAppTransition(ActivityOptions options) {
getDisplay().mDisplayContent.executeAppTransition();
ActivityOptions.abort(options);
@@ -5644,10 +5429,10 @@
final long token = proto.start(fieldId);
dumpDebugInnerStackOnly(proto, STACK, logLevel);
proto.write(com.android.server.am.ActivityStackProto.ID, mStackId);
- for (int taskNdx = getChildCount() - 1; taskNdx >= 0; --taskNdx) {
- final Task task = getChildAt(taskNdx);
- task.dumpDebug(proto, com.android.server.am.ActivityStackProto.TASKS, logLevel);
- }
+
+ forAllTasks((t) -> {
+ t.dumpDebug(proto, com.android.server.am.ActivityStackProto.TASKS, logLevel);
+ });
if (mResumedActivity != null) {
mResumedActivity.writeIdentifierToProto(proto, RESUMED_ACTIVITY);
}
@@ -5672,9 +5457,7 @@
final long token = proto.start(fieldId);
super.dumpDebug(proto, WINDOW_CONTAINER, logLevel);
proto.write(StackProto.ID, mStackId);
- for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; taskNdx--) {
- mChildren.get(taskNdx).dumpDebugInnerTaskOnly(proto, StackProto.TASKS, logLevel);
- }
+ forAllTasks((t) -> { t.dumpDebugInnerTaskOnly(proto, StackProto.TASKS, logLevel); });
proto.write(FILLS_PARENT, matchParentBounds());
getRawBounds().dumpDebug(proto, StackProto.BOUNDS);
proto.write(DEFER_REMOVAL, mDeferRemoval);
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index 7356368..8c5fd8c 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -165,28 +165,28 @@
static final String TAG_TASKS = TAG + POSTFIX_TASKS;
/** How long we wait until giving up on the last activity telling us it is idle. */
- static final int IDLE_TIMEOUT = 10 * 1000;
+ private static final int IDLE_TIMEOUT = 10 * 1000;
/** How long we can hold the sleep wake lock before giving up. */
- static final int SLEEP_TIMEOUT = 5 * 1000;
+ private static final int SLEEP_TIMEOUT = 5 * 1000;
// How long we can hold the launch wake lock before giving up.
- static final int LAUNCH_TIMEOUT = 10 * 1000;
+ private static final int LAUNCH_TIMEOUT = 10 * 1000;
/** How long we wait until giving up on the activity telling us it released the top state. */
- static final int TOP_RESUMED_STATE_LOSS_TIMEOUT = 500;
+ private static final int TOP_RESUMED_STATE_LOSS_TIMEOUT = 500;
- static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
- static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
- static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
- static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
- static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
- static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 12;
- static final int RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 13;
- static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 14;
- static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 15;
- static final int REPORT_HOME_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 16;
- static final int TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 17;
+ private static final int IDLE_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG;
+ private static final int IDLE_NOW_MSG = FIRST_SUPERVISOR_STACK_MSG + 1;
+ private static final int RESUME_TOP_ACTIVITY_MSG = FIRST_SUPERVISOR_STACK_MSG + 2;
+ private static final int SLEEP_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 3;
+ private static final int LAUNCH_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 4;
+ private static final int LAUNCH_TASK_BEHIND_COMPLETE = FIRST_SUPERVISOR_STACK_MSG + 12;
+ private static final int RESTART_ACTIVITY_PROCESS_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 13;
+ private static final int REPORT_MULTI_WINDOW_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 14;
+ private static final int REPORT_PIP_MODE_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 15;
+ private static final int REPORT_HOME_CHANGED_MSG = FIRST_SUPERVISOR_STACK_MSG + 16;
+ private static final int TOP_RESUMED_STATE_LOSS_TIMEOUT_MSG = FIRST_SUPERVISOR_STACK_MSG + 17;
// Used to indicate that windows of activities should be preserved during the resize.
static final boolean PRESERVE_WINDOWS = true;
@@ -237,7 +237,7 @@
// For debugging to make sure the caller when acquiring/releasing our
// wake lock is the system process.
- static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
+ private static final boolean VALIDATE_WAKE_LOCK_CALLER = false;
/** The number of distinct task ids that can be assigned to the tasks of a single user */
private static final int MAX_TASK_IDS_PER_USER = UserHandle.PER_USER_RANGE;
@@ -250,11 +250,11 @@
/** Helper class to abstract out logic for fetching the set of currently running tasks */
private RunningTasks mRunningTasks;
- final ActivityStackSupervisorHandler mHandler;
+ private final ActivityStackSupervisorHandler mHandler;
final Looper mLooper;
/** Short cut */
- WindowManagerService mWindowManager;
+ private WindowManagerService mWindowManager;
/** Common synchronization logic used to save things to disks. */
PersisterQueue mPersisterQueue;
@@ -286,11 +286,11 @@
/** List of activities whose multi-window mode changed that we need to report to the
* application */
- final ArrayList<ActivityRecord> mMultiWindowModeChangedActivities = new ArrayList<>();
+ private final ArrayList<ActivityRecord> mMultiWindowModeChangedActivities = new ArrayList<>();
/** List of activities whose picture-in-picture mode changed that we need to report to the
* application */
- final ArrayList<ActivityRecord> mPipModeChangedActivities = new ArrayList<>();
+ private final ArrayList<ActivityRecord> mPipModeChangedActivities = new ArrayList<>();
/**
* Animations that for the current transition have requested not to
@@ -312,7 +312,7 @@
/** The target stack bounds for the picture-in-picture mode changed that we need to report to
* the application */
- Rect mPipModeChangedTargetStackBounds;
+ private Rect mPipModeChangedTargetStackBounds;
/** Used on user changes */
final ArrayList<UserState> mStartingUsers = new ArrayList<>();
@@ -398,6 +398,52 @@
private boolean mInitialized;
+ private final MoveTaskToFullscreenHelper mMoveTaskToFullscreenHelper =
+ new MoveTaskToFullscreenHelper();
+ private class MoveTaskToFullscreenHelper {
+ private ActivityDisplay mToDisplay;
+ private boolean mOnTop;
+ private Task mTopTask;
+ private boolean mSchedulePictureInPictureModeChange;
+
+ void process(ActivityStack fromStack, ActivityDisplay toDisplay, boolean onTop,
+ boolean schedulePictureInPictureModeChange) {
+ mSchedulePictureInPictureModeChange = schedulePictureInPictureModeChange;
+ mToDisplay = toDisplay;
+ mOnTop = onTop;
+ mTopTask = fromStack.getTopMostTask();
+
+ final PooledConsumer c = PooledLambda.obtainConsumer(
+ MoveTaskToFullscreenHelper::processTask, this, PooledLambda.__(Task.class));
+ fromStack.forAllTasks(c, false);
+ c.recycle();
+ mToDisplay = null;
+ mTopTask = null;
+ }
+
+ private void processTask(Task task) {
+ final ActivityStack toStack = mToDisplay.getOrCreateStack(
+ null, mTmpOptions, task, task.getActivityType(), mOnTop);
+
+ if (mOnTop) {
+ final boolean isTopTask = task == mTopTask;
+ // Defer resume until all the tasks have been moved to the fullscreen stack
+ task.reparent(toStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT, isTopTask /*animate*/,
+ DEFER_RESUME, mSchedulePictureInPictureModeChange,
+ "moveTasksToFullscreenStack - onTop");
+ MetricsLoggerWrapper.logPictureInPictureFullScreen(mService.mContext,
+ task.effectiveUid, task.realActivity.flattenToString());
+ } else {
+ // Position the tasks in the fullscreen stack in order at the bottom of the
+ // stack. Also defer resume until all the tasks have been moved to the
+ // fullscreen stack.
+ task.reparent(toStack, ON_TOP, REPARENT_LEAVE_STACK_IN_PLACE,
+ !ANIMATE, DEFER_RESUME, mSchedulePictureInPictureModeChange,
+ "moveTasksToFullscreenStack - NOT_onTop");
+ }
+ }
+ }
+
/**
* Description of a request to start a new activity, which has been held
* due to app switches being disabled.
@@ -1522,35 +1568,11 @@
// the picture-in-picture mode.
final boolean schedulePictureInPictureModeChange =
windowingMode == WINDOWING_MODE_PINNED;
- final ArrayList<Task> tasks = fromStack.getAllTasks();
- if (!tasks.isEmpty()) {
+ if (fromStack.hasChild()) {
mTmpOptions.setLaunchWindowingMode(WINDOWING_MODE_FULLSCREEN);
- final int size = tasks.size();
- for (int i = 0; i < size; ++i) {
- final Task task = tasks.get(i);
- final ActivityStack toStack = toDisplay.getOrCreateStack(
- null, mTmpOptions, task, task.getActivityType(), onTop);
-
- if (onTop) {
- final boolean isTopTask = i == (size - 1);
- // Defer resume until all the tasks have been moved to the fullscreen stack
- task.reparent(toStack, ON_TOP, REPARENT_MOVE_STACK_TO_FRONT,
- isTopTask /* animate */, DEFER_RESUME,
- schedulePictureInPictureModeChange,
- "moveTasksToFullscreenStack - onTop");
- MetricsLoggerWrapper.logPictureInPictureFullScreen(mService.mContext,
- task.effectiveUid, task.realActivity.flattenToString());
- } else {
- // Position the tasks in the fullscreen stack in order at the bottom of the
- // stack. Also defer resume until all the tasks have been moved to the
- // fullscreen stack.
- task.reparent(toStack, ON_TOP,
- REPARENT_LEAVE_STACK_IN_PLACE, !ANIMATE, DEFER_RESUME,
- schedulePictureInPictureModeChange,
- "moveTasksToFullscreenStack - NOT_onTop");
- }
- }
+ mMoveTaskToFullscreenHelper.process(
+ fromStack, toDisplay, onTop, schedulePictureInPictureModeChange);
}
mRootActivityContainer.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
@@ -1562,12 +1584,8 @@
}
void moveTasksToFullscreenStackLocked(ActivityStack fromStack, boolean onTop) {
- moveTasksToFullscreenStackLocked(fromStack, DEFAULT_DISPLAY, onTop);
- }
-
- void moveTasksToFullscreenStackLocked(ActivityStack fromStack, int toDisplayId, boolean onTop) {
mWindowManager.inSurfaceTransaction(() ->
- moveTasksToFullscreenStackInSurfaceTransaction(fromStack, toDisplayId, onTop));
+ moveTasksToFullscreenStackInSurfaceTransaction(fromStack, DEFAULT_DISPLAY, onTop));
}
void setSplitScreenResizing(boolean resizing) {
@@ -1630,7 +1648,7 @@
try {
// Don't allow re-entry while resizing. E.g. due to docked stack detaching.
mAllowDockedStackResize = false;
- ActivityRecord r = stack.topRunningActivityLocked();
+ ActivityRecord r = stack.topRunningActivity();
stack.resize(dockedBounds, tempDockedTaskBounds, tempDockedTaskInsetBounds,
!PRESERVE_WINDOWS, DEFER_RESUME);
@@ -1731,7 +1749,6 @@
}
private void removeStackInSurfaceTransaction(ActivityStack stack) {
- final ArrayList<Task> tasks = stack.getAllTasks();
if (stack.getWindowingMode() == WINDOWING_MODE_PINNED) {
/**
* Workaround: Force-stop all the activities in the pinned stack before we reparent them
@@ -1746,18 +1763,22 @@
stack.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
stack.mForceHidden = false;
activityIdleInternalLocked(null, false /* fromTimeout */,
- true /* processPausingActivites */, null /* configuration */);
+ true /* processPausingActivities */, null /* configuration */);
// Move all the tasks to the bottom of the fullscreen stack
moveTasksToFullscreenStackLocked(stack, !ON_TOP);
} else {
- for (int i = tasks.size() - 1; i >= 0; i--) {
- removeTaskByIdLocked(tasks.get(i).mTaskId, true /* killProcess */,
- REMOVE_FROM_RECENTS, "remove-stack");
- }
+ final PooledConsumer c = PooledLambda.obtainConsumer(
+ ActivityStackSupervisor::processRemoveTask, this, PooledLambda.__(Task.class));
+ stack.forAllTasks(c);
+ c.recycle();
}
}
+ private void processRemoveTask(Task task) {
+ removeTask(task, true /* killProcess */, REMOVE_FROM_RECENTS, "remove-stack");
+ }
+
/**
* Removes the stack associated with the given {@param stack}. If the {@param stack} is the
* pinned stack, then its tasks are not explicitly removed when the stack is destroyed, but
@@ -1775,24 +1796,28 @@
* @param removeFromRecents Whether to also remove the task from recents.
* @return Returns true if the given task was found and removed.
*/
- boolean removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents,
+ boolean removeTaskById(int taskId, boolean killProcess, boolean removeFromRecents,
String reason) {
final Task task =
mRootActivityContainer.anyTaskForId(taskId, MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
if (task != null) {
- task.removeTaskActivitiesLocked(reason);
- cleanUpRemovedTaskLocked(task, killProcess, removeFromRecents);
- mService.getLockTaskController().clearLockedTask(task);
- mService.getTaskChangeNotificationController().notifyTaskStackChanged();
- if (task.isPersistable) {
- mService.notifyTaskPersisterLocked(null, true);
- }
+ removeTask(task, killProcess, removeFromRecents, reason);
return true;
}
Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
return false;
}
+ void removeTask(Task task, boolean killProcess, boolean removeFromRecents, String reason) {
+ task.removeTaskActivitiesLocked(reason);
+ cleanUpRemovedTaskLocked(task, killProcess, removeFromRecents);
+ mService.getLockTaskController().clearLockedTask(task);
+ mService.getTaskChangeNotificationController().notifyTaskStackChanged();
+ if (task.isPersistable) {
+ mService.notifyTaskPersisterLocked(null, true);
+ }
+ }
+
void cleanUpRemovedTaskLocked(Task task, boolean killProcess, boolean removeFromRecents) {
if (removeFromRecents) {
mRecentTasks.remove(task);
@@ -1899,7 +1924,7 @@
if (wasTrimmed) {
// Task was trimmed from the recent tasks list -- remove the active task record as well
// since the user won't really be able to go back to it
- removeTaskByIdLocked(task.mTaskId, killProcess, false /* removeFromRecents */,
+ removeTaskById(task.mTaskId, killProcess, false /* removeFromRecents */,
"recent-task-trimmed");
}
task.removedFromRecents();
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index baa2955..23083c9 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1434,7 +1434,7 @@
// If there is no state change (e.g. a resumed activity is reparented to top of
// another display) to trigger a visibility/configuration checking, we have to
// update the configuration for changing to different display.
- final ActivityRecord currentTop = startedActivityStack.topRunningActivityLocked();
+ final ActivityRecord currentTop = startedActivityStack.topRunningActivity();
if (currentTop != null && currentTop.shouldUpdateConfigForDisplayChanged()) {
mRootActivityContainer.ensureVisibilityAndConfig(
currentTop, currentTop.getDisplayId(),
@@ -2307,7 +2307,7 @@
? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
final Task topTask = curTop != null ? curTop.getTask() : null;
differentTopTask = topTask != intentActivity.getTask()
- || (focusStack != null && topTask != focusStack.topTask());
+ || (focusStack != null && topTask != focusStack.getTopMostTask());
} else {
// The existing task should always be different from those in other displays.
differentTopTask = true;
@@ -2371,7 +2371,7 @@
mMovedToFront = true;
}
- if (launchStack != null && launchStack.topTask() == null) {
+ if (launchStack != null && launchStack.getTopMostTask() == null) {
// The task does not need to be reparented to the launch stack. Remove the
// launch stack if there is no activity in it.
Slog.w(TAG, "Removing an empty stack: " + launchStack);
@@ -2588,7 +2588,7 @@
// If task's parent stack is not focused - use it during adjacent launch.
return parentStack;
} else {
- if (focusedStack != null && task == focusedStack.topTask()) {
+ if (focusedStack != null && task == focusedStack.getTopMostTask()) {
// If task is already on top of focused stack - use it. We don't want to move the
// existing focused task to adjacent stack, just deliver new intent in this case.
return focusedStack;
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index efd21ec..46c4d87 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -698,7 +698,7 @@
private final Runnable mUpdateOomAdjRunnable = new Runnable() {
@Override
- public void run() {
+ public void run() {
mAmInternal.updateOomAdj();
}
};
@@ -1591,7 +1591,8 @@
// We should consolidate.
if (mController != null) {
// Find the first activity that is not finishing.
- final ActivityRecord next = r.getActivityStack().topRunningActivityLocked(token, 0);
+ final ActivityRecord next =
+ r.getActivityStack().topRunningActivity(token, INVALID_TASK_ID);
if (next != null) {
// ask watcher if this is allowed
boolean resumeOK = true;
@@ -1628,11 +1629,9 @@
// because we don't support returning them across task boundaries. Also, to
// keep backwards compatibility we remove the task from recents when finishing
// task with root activity.
- res = mStackSupervisor.removeTaskByIdLocked(tr.mTaskId, false /* killProcess */,
+ mStackSupervisor.removeTask(tr, false /*killProcess*/,
finishWithRootActivity, "finish-activity");
- if (!res) {
- Slog.i(TAG, "Removing task failed to finish activity");
- }
+ res = true;
// Explicitly dismissing the activity so reset its relaunch flag.
r.mRelaunchReason = RELAUNCH_REASON_NONE;
} else {
@@ -1901,7 +1900,7 @@
public boolean isTopActivityImmersive() {
enforceNotIsolatedCaller("isTopActivityImmersive");
synchronized (mGlobalLock) {
- final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
+ final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivity();
return (r != null) ? r.immersive : false;
}
}
@@ -1931,7 +1930,7 @@
public int getFrontActivityScreenCompatMode() {
enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
synchronized (mGlobalLock) {
- final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
+ final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivity();
if (r == null) {
return ActivityManager.COMPAT_MODE_UNKNOWN;
}
@@ -1945,7 +1944,7 @@
"setFrontActivityScreenCompatMode");
ApplicationInfo ai;
synchronized (mGlobalLock) {
- final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivityLocked();
+ final ActivityRecord r = getTopDisplayFocusedStack().topRunningActivity();
if (r == null) {
Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
return;
@@ -2078,7 +2077,7 @@
Slog.w(TAG, "setFocusedStack: No stack with id=" + stackId);
return;
}
- final ActivityRecord r = stack.topRunningActivityLocked();
+ final ActivityRecord r = stack.topRunningActivity();
if (r != null && r.moveFocusableActivityToTop("setFocusedStack")) {
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
@@ -2133,7 +2132,7 @@
synchronized (mGlobalLock) {
final long ident = Binder.clearCallingIdentity();
try {
- return mStackSupervisor.removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS,
+ return mStackSupervisor.removeTaskById(taskId, true, REMOVE_FROM_RECENTS,
"remove-task");
} finally {
Binder.restoreCallingIdentity(ident);
@@ -2207,7 +2206,7 @@
int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
final Task task = mRootActivityContainer.anyTaskForId(taskId);
if (task != null) {
- return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
+ return ActivityRecord.getStackLocked(token).moveTaskToBack(task);
}
} finally {
Binder.restoreCallingIdentity(origId);
@@ -2918,7 +2917,7 @@
}
final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack();
- if (stack == null || task != stack.topTask()) {
+ if (stack == null || task != stack.getTopMostTask()) {
throw new IllegalArgumentException("Invalid task, not in foreground");
}
@@ -5787,7 +5786,7 @@
// If the configuration changed, and the caller is not already
// in the process of starting an activity, then find the top
// activity to check if its configuration needs to change.
- starting = mainStack.topRunningActivityLocked();
+ starting = mainStack.topRunningActivity();
}
if (starting != null) {
diff --git a/services/core/java/com/android/server/wm/AppTaskImpl.java b/services/core/java/com/android/server/wm/AppTaskImpl.java
index 93a22ca..6d9584c 100644
--- a/services/core/java/com/android/server/wm/AppTaskImpl.java
+++ b/services/core/java/com/android/server/wm/AppTaskImpl.java
@@ -62,7 +62,7 @@
long origId = Binder.clearCallingIdentity();
try {
// We remove the task from recents to preserve backwards
- if (!mService.mStackSupervisor.removeTaskByIdLocked(mTaskId, false,
+ if (!mService.mStackSupervisor.removeTaskById(mTaskId, false,
REMOVE_FROM_RECENTS, "finish-and-remove-task")) {
throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
}
diff --git a/services/core/java/com/android/server/wm/AppTransition.java b/services/core/java/com/android/server/wm/AppTransition.java
index e0c5fd05..3a33a3d 100644
--- a/services/core/java/com/android/server/wm/AppTransition.java
+++ b/services/core/java/com/android/server/wm/AppTransition.java
@@ -130,6 +130,7 @@
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.DumpUtils.Dump;
import com.android.internal.util.function.pooled.PooledLambda;
+import com.android.internal.util.function.pooled.PooledPredicate;
import com.android.server.AttributeCache;
import com.android.server.protolog.common.ProtoLog;
import com.android.server.wm.animation.ClipRectLRAnimation;
@@ -1897,7 +1898,10 @@
for (int i = 0; i < specs.length; i++) {
AppTransitionAnimationSpec spec = specs[i];
if (spec != null) {
- final WindowContainer container = findTask(spec.taskId);
+ final PooledPredicate p = PooledLambda.obtainPredicate(
+ Task::isTaskId, PooledLambda.__(Task.class), spec.taskId);
+ final WindowContainer container = mDisplayContent.getTask(p);
+ p.recycle();
if (container == null) {
continue;
}
@@ -1918,21 +1922,6 @@
}
}
- private Task findTask(int taskId) {
- if (taskId < 0) {
- return null;
- }
- final ArrayList<Task> tasks = new ArrayList<>();
- mDisplayContent.forAllTasks(task -> {
- if (task.mTaskId == taskId) {
- tasks.add(task);
- return true;
- }
- return false;
- });
- return tasks.size() == 1 ? tasks.get(0) : null;
- }
-
void overridePendingAppTransitionMultiThumbFuture(
IAppTransitionAnimationSpecsFuture specsFuture, IRemoteCallback callback,
boolean scaleUp) {
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index f85fba0..bc8e718 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -196,6 +196,7 @@
import com.android.internal.util.ToBooleanFunction;
import com.android.internal.util.function.TriConsumer;
import com.android.internal.util.function.pooled.PooledConsumer;
+import com.android.internal.util.function.pooled.PooledFunction;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.AnimationThread;
import com.android.server.policy.WindowManagerPolicy;
@@ -2255,19 +2256,7 @@
*/
Task findTaskForResizePoint(int x, int y) {
final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
- mTmpTaskForResizePointSearchResult.reset();
- for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = mTaskStackContainers.getChildAt(stackNdx);
- if (!stack.getWindowConfiguration().canResizeTask()) {
- return null;
- }
-
- stack.findTaskForResizePoint(x, y, delta, mTmpTaskForResizePointSearchResult);
- if (mTmpTaskForResizePointSearchResult.searchDone) {
- return mTmpTaskForResizePointSearchResult.taskForResize;
- }
- }
- return null;
+ return mTmpTaskForResizePointSearchResult.process(mTaskStackContainers, x, y, delta);
}
void updateTouchExcludeRegion() {
@@ -2277,13 +2266,15 @@
} else {
mTouchExcludeRegion.set(mBaseDisplayRect);
final int delta = dipToPixel(RESIZE_HANDLE_WIDTH_IN_DP, mDisplayMetrics);
+ mTmpRect.setEmpty();
mTmpRect2.setEmpty();
- for (int stackNdx = mTaskStackContainers.getChildCount() - 1; stackNdx >= 0;
- --stackNdx) {
- final ActivityStack stack = mTaskStackContainers.getChildAt(stackNdx);
- stack.setTouchExcludeRegion(focusedTask, delta, mTouchExcludeRegion,
- mDisplayFrames.mContent, mTmpRect2);
- }
+
+ final PooledConsumer c = PooledLambda.obtainConsumer(
+ DisplayContent::processTaskForTouchExcludeRegion, this,
+ PooledLambda.__(Task.class), focusedTask, delta);
+ mTaskStackContainers.forAllTasks(c);
+ c.recycle();
+
// If we removed the focused task above, add it back and only leave its
// outside touch area in the exclusion. TapDetector is not interested in
// any touch inside the focused task itself.
@@ -2313,12 +2304,56 @@
mTapDetector.setTouchExcludeRegion(mTouchExcludeRegion);
}
+ private void processTaskForTouchExcludeRegion(Task task, Task focusedTask, int delta) {
+ final ActivityRecord topVisibleActivity = task.getTopVisibleActivity();
+
+ if (topVisibleActivity == null || !topVisibleActivity.hasContentToDisplay()) {
+ return;
+ }
+
+ // Exclusion region is the region that TapDetector doesn't care about.
+ // Here we want to remove all non-focused tasks from the exclusion region.
+ // We also remove the outside touch area for resizing for all freeform
+ // tasks (including the focused).
+ // We save the focused task region once we find it, and add it back at the end.
+ // If the task is home stack and it is resizable in the minimized state, we want to
+ // exclude the docked stack from touch so we need the entire screen area and not just a
+ // small portion which the home stack currently is resized to.
+ if (task.isActivityTypeHome() && task.getStack().isMinimizedDockAndHomeStackResizable()) {
+ mDisplayContent.getBounds(mTmpRect);
+ } else {
+ task.getDimBounds(mTmpRect);
+ }
+
+ if (task == focusedTask) {
+ // Add the focused task rect back into the exclude region once we are done
+ // processing stacks.
+ mTmpRect2.set(mTmpRect);
+ }
+
+ final boolean isFreeformed = task.inFreeformWindowingMode();
+ if (task != focusedTask || isFreeformed) {
+ if (isFreeformed) {
+ // If the task is freeformed, enlarge the area to account for outside
+ // touch area for resize.
+ mTmpRect.inset(-delta, -delta);
+ // Intersect with display content rect. If we have system decor (status bar/
+ // navigation bar), we want to exclude that from the tap detection.
+ // Otherwise, if the app is partially placed under some system button (eg.
+ // Recents, Home), pressing that button would cause a full series of
+ // unwanted transfer focus/resume/pause, before we could go home.
+ mTmpRect.intersect(mDisplayFrames.mContent);
+ }
+ mTouchExcludeRegion.op(mTmpRect, Region.Op.DIFFERENCE);
+ }
+ }
+
/**
* Union the region with all the tap exclude region provided by windows on this display.
*
* @param inOutRegion The region to be amended.
*/
- void amendWindowTapExcludeRegion(Region inOutRegion) {
+ private void amendWindowTapExcludeRegion(Region inOutRegion) {
for (int i = mTapExcludeProvidingWindows.size() - 1; i >= 0; i--) {
final WindowState win = mTapExcludeProvidingWindows.valueAt(i);
win.amendTapExcludeRegion(inOutRegion);
@@ -3830,12 +3865,56 @@
}
static final class TaskForResizePointSearchResult {
- boolean searchDone;
- Task taskForResize;
+ private Task taskForResize;
+ private int x;
+ private int y;
+ private int delta;
+ private Rect mTmpRect = new Rect();
- void reset() {
- searchDone = false;
+ Task process(WindowContainer root, int x, int y, int delta) {
taskForResize = null;
+ this.x = x;
+ this.y = y;
+ this.delta = delta;
+ mTmpRect.setEmpty();
+
+ final PooledFunction f = PooledLambda.obtainFunction(
+ TaskForResizePointSearchResult::processTask, this, PooledLambda.__(Task.class));
+ root.forAllTasks(f);
+ f.recycle();
+
+ return taskForResize;
+ }
+
+ private boolean processTask(Task task) {
+ if (!task.getStack().getWindowConfiguration().canResizeTask()) {
+ return true;
+ }
+
+ if (task.getWindowingMode() == WINDOWING_MODE_FULLSCREEN) {
+ return true;
+ }
+
+ // We need to use the task's dim bounds (which is derived from the visible bounds of
+ // its apps windows) for any touch-related tests. Can't use the task's original
+ // bounds because it might be adjusted to fit the content frame. One example is when
+ // the task is put to top-left quadrant, the actual visible area would not start at
+ // (0,0) after it's adjusted for the status bar.
+ task.getDimBounds(mTmpRect);
+ mTmpRect.inset(-delta, -delta);
+ if (mTmpRect.contains(x, y)) {
+ mTmpRect.inset(delta, delta);
+
+ if (!mTmpRect.contains(x, y)) {
+ taskForResize = task;
+ return true;
+ }
+ // User touched inside the task. No need to look further,
+ // focus transfer will be handled in ACTION_UP.
+ return true;
+ }
+
+ return false;
}
}
diff --git a/services/core/java/com/android/server/wm/DockedStackDividerController.java b/services/core/java/com/android/server/wm/DockedStackDividerController.java
index 1a1a7d4..6b5859d 100644
--- a/services/core/java/com/android/server/wm/DockedStackDividerController.java
+++ b/services/core/java/com/android/server/wm/DockedStackDividerController.java
@@ -259,7 +259,7 @@
if (homeStack == null) {
return false;
}
- final Task homeTask = homeStack.findHomeTask();
+ final Task homeTask = homeStack.getTopMostTask();
return homeTask != null && homeTask.isResizeable();
}
@@ -708,7 +708,7 @@
if (homeStack == null) {
return;
}
- final Task homeTask = homeStack.findHomeTask();
+ final Task homeTask = homeStack.getTopMostTask();
if (homeTask == null || !isWithinDisplay(homeTask)) {
return;
}
diff --git a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
index 3aae1b1..949ff19 100644
--- a/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
+++ b/services/core/java/com/android/server/wm/EnsureActivitiesVisibleHelper.java
@@ -45,7 +45,7 @@
void reset(ActivityRecord starting, int configChanges, boolean preserveWindows,
boolean notifyClients) {
mStarting = starting;
- mTop = mContiner.topRunningActivityLocked();
+ mTop = mContiner.topRunningActivity();
// If the top activity is not fullscreen, then we need to make sure any activities under it
// are now visible.
mAboveTop = mTop != null;
diff --git a/services/core/java/com/android/server/wm/KeyguardController.java b/services/core/java/com/android/server/wm/KeyguardController.java
index ac5c96b..3a0696f 100644
--- a/services/core/java/com/android/server/wm/KeyguardController.java
+++ b/services/core/java/com/android/server/wm/KeyguardController.java
@@ -494,7 +494,7 @@
if (stack != null) {
final ActivityRecord topDismissing = stack.getTopDismissingKeyguardActivity();
mOccluded = stack.topActivityOccludesKeyguard() || (topDismissing != null
- && stack.topRunningActivityLocked() == topDismissing
+ && stack.topRunningActivity() == topDismissing
&& controller.canShowWhileOccluded(
true /* dismissKeyguard */,
false /* showWhenLocked */));
diff --git a/services/core/java/com/android/server/wm/LockTaskController.java b/services/core/java/com/android/server/wm/LockTaskController.java
index 2ece6e2..7a72b43 100644
--- a/services/core/java/com/android/server/wm/LockTaskController.java
+++ b/services/core/java/com/android/server/wm/LockTaskController.java
@@ -150,7 +150,7 @@
* The first task in the list, which started the current LockTask session, is called the root
* task. It coincides with the Home task in a typical multi-app kiosk deployment. When there are
* more than one locked tasks, the root task can't be finished. Nor can it be moved to the back
- * of the stack by {@link ActivityStack#moveTaskToBackLocked(int)};
+ * of the stack by {@link ActivityStack#moveTaskToBack(Task)};
*
* Calling {@link Activity#stopLockTask()} on the root task will finish all tasks but itself in
* this list, and the device will exit LockTask mode.
@@ -251,7 +251,7 @@
/**
* @return whether the given task can be moved to the back of the stack with
- * {@link ActivityStack#moveTaskToBackLocked(int)}
+ * {@link ActivityStack#moveTaskToBack(Task)}
* @see #mLockTaskModeTasks
*/
boolean canMoveTaskToBack(Task task) {
@@ -653,10 +653,7 @@
taskChanged = true;
}
- for (int displayNdx = mSupervisor.mRootActivityContainer.getChildCount() - 1;
- displayNdx >= 0; --displayNdx) {
- mSupervisor.mRootActivityContainer.getChildAt(displayNdx).onLockTaskPackagesUpdated();
- }
+ mSupervisor.mRootActivityContainer.mRootWindowContainer.forAllTasks(Task::setLockTaskAuth);
final ActivityRecord r = mSupervisor.mRootActivityContainer.topRunningActivity();
final Task task = (r != null) ? r.getTask() : null;
diff --git a/services/core/java/com/android/server/wm/RecentTasks.java b/services/core/java/com/android/server/wm/RecentTasks.java
index f0e441f..c54fbd6 100644
--- a/services/core/java/com/android/server/wm/RecentTasks.java
+++ b/services/core/java/com/android/server/wm/RecentTasks.java
@@ -211,7 +211,7 @@
final DisplayContent dc = rac.getActivityDisplay(displayId).mDisplayContent;
if (dc.pointWithinAppWindow(x, y)) {
final ActivityStack stack = mService.getTopDisplayFocusedStack();
- final Task topTask = stack != null ? stack.topTask() : null;
+ final Task topTask = stack != null ? stack.getTopMostTask() : null;
resetFreezeTaskListReordering(topTask);
}
}
@@ -319,7 +319,7 @@
void resetFreezeTaskListReorderingOnTimeout() {
synchronized (mService.mGlobalLock) {
final ActivityStack focusedStack = mService.getTopDisplayFocusedStack();
- final Task topTask = focusedStack != null ? focusedStack.topTask() : null;
+ final Task topTask = focusedStack != null ? focusedStack.getTopMostTask() : null;
resetFreezeTaskListReordering(topTask);
}
}
@@ -630,8 +630,7 @@
&& task.realActivitySuspended != suspended) {
task.realActivitySuspended = suspended;
if (suspended) {
- mSupervisor.removeTaskByIdLocked(task.mTaskId, false,
- REMOVE_FROM_RECENTS, "suspended-package");
+ mSupervisor.removeTask(task, false, REMOVE_FROM_RECENTS, "suspended-package");
}
notifyTaskPersisterLocked(task, false);
}
@@ -658,8 +657,7 @@
if (task.mUserId != userId) continue;
if (!taskPackageName.equals(packageName)) continue;
- mSupervisor.removeTaskByIdLocked(task.mTaskId, true, REMOVE_FROM_RECENTS,
- "remove-package-task");
+ mSupervisor.removeTask(task, true, REMOVE_FROM_RECENTS, "remove-package-task");
}
}
@@ -687,8 +685,7 @@
final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
&& (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
if (sameComponent) {
- mSupervisor.removeTaskByIdLocked(task.mTaskId, false,
- REMOVE_FROM_RECENTS, "disabled-package");
+ mSupervisor.removeTask(task, false, REMOVE_FROM_RECENTS, "disabled-package");
}
}
}
@@ -1306,9 +1303,9 @@
case WINDOWING_MODE_PINNED:
return false;
case WINDOWING_MODE_SPLIT_SCREEN_PRIMARY:
- if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\ttop=" + task.getStack().topTask());
+ if (DEBUG_RECENTS_TRIM_TASKS) Slog.d(TAG, "\ttop=" + task.getStack().getTopMostTask());
final ActivityStack stack = task.getStack();
- if (stack != null && stack.topTask() == task) {
+ if (stack != null && stack.getTopMostTask() == task) {
// Only the non-top task of the primary split screen mode is visible
return false;
}
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index d5bbe6b..b398626 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -216,7 +216,7 @@
// and default launchers coexisting), then move the task to the top as a part of
// moving the stack to the front
final Task task = targetActivity.getTask();
- if (targetStack.topTask() != task) {
+ if (targetStack.getTopMostTask() != task) {
targetStack.positionChildAtTop(task);
}
} else {
@@ -432,7 +432,7 @@
// cases:
// 1) The next launching task is not being animated by the recents animation
// 2) The next task is home activity. (i.e. pressing home key to back home in recents).
- if ((!controller.isAnimatingTask(stack.getTopChild())
+ if ((!controller.isAnimatingTask(stack.getTopMostTask())
|| controller.isTargetApp(stack.getTopNonFinishingActivity()))
&& controller.shouldDeferCancelUntilNextTransition()) {
// Always prepare an app transition since we rely on the transition callbacks to cleanup
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index 5653ec0..704a4b7 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -129,6 +129,7 @@
import java.util.List;
import java.util.Objects;
import java.util.Set;
+import java.util.function.Function;
/**
* Root node for activity containers.
@@ -168,8 +169,8 @@
WindowManagerService mWindowManager;
DisplayManager mDisplayManager;
private DisplayManagerInternal mDisplayManagerInternal;
- // TODO: Remove after object merge with RootWindowContainer.
- private RootWindowContainer mRootWindowContainer;
+ // TODO(root-unify): Remove after object merge with RootWindowContainer.
+ RootWindowContainer mRootWindowContainer;
/**
* List of displays which contain activities, sorted by z-order.
@@ -214,7 +215,7 @@
private RemoteException mTmpRemoteException;
private final FindTaskResult mTmpFindTaskResult = new FindTaskResult();
- static class FindTaskResult implements ToBooleanFunction<Task> {
+ static class FindTaskResult implements Function<Task, Boolean> {
ActivityRecord mRecord;
boolean mIdealMatch;
@@ -259,7 +260,7 @@
}
@Override
- public boolean apply(Task task) {
+ public Boolean apply(Task task) {
if (task.voiceSession != null) {
// We never match voice sessions; those always run independently.
if (DEBUG_TASKS) Slog.d(TAG_TASKS, "Skipping " + task + ": voice session");
@@ -899,7 +900,7 @@
mTmpBoolean = false; // Set to true if an activity was started.
final PooledFunction c = PooledLambda.obtainFunction(
RootActivityContainer::startActivityForAttachedApplicationIfNeeded, this,
- PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivityLocked());
+ PooledLambda.__(ActivityRecord.class), app, stack.topRunningActivity());
stack.forAllActivities(c);
c.recycle();
if (mTmpRemoteException != null) {
@@ -992,7 +993,7 @@
for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = display.getStackAt(stackNdx);
stack.switchUser(userId);
- Task task = stack.topTask();
+ Task task = stack.getTopMostTask();
if (task != null) {
stack.positionChildAtTop(task);
}
@@ -1075,7 +1076,7 @@
"moveTopStackActivityToPinnedStack: Unknown stackId=" + stackId);
}
- final ActivityRecord r = stack.topRunningActivityLocked();
+ final ActivityRecord r = stack.topRunningActivity();
if (r == null) {
Slog.w(TAG, "moveTopStackActivityToPinnedStack: No top running activity"
+ " in stack=" + stack);
@@ -1263,7 +1264,7 @@
final ActivityDisplay display = mActivityDisplays.get(displayNdx);
for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
final ActivityStack stack = display.getStackAt(stackNdx);
- final ActivityRecord topRunningActivity = stack.topRunningActivityLocked();
+ final ActivityRecord topRunningActivity = stack.topRunningActivity();
if (!stack.isFocusableAndVisible() || topRunningActivity == null) {
continue;
}
@@ -1401,32 +1402,37 @@
info.position = display != null ? display.getIndexOf(stack) : 0;
info.configuration.setTo(stack.getConfiguration());
- ArrayList<Task> tasks = stack.getAllTasks();
- final int numTasks = tasks.size();
- int[] taskIds = new int[numTasks];
- String[] taskNames = new String[numTasks];
- Rect[] taskBounds = new Rect[numTasks];
- int[] taskUserIds = new int[numTasks];
- for (int i = 0; i < numTasks; ++i) {
- final Task task = tasks.get(i);
- taskIds[i] = task.mTaskId;
- taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
- : task.realActivity != null ? task.realActivity.flattenToString()
- : task.getTopNonFinishingActivity() != null
- ? task.getTopNonFinishingActivity().packageName : "unknown";
- taskBounds[i] = mService.getTaskBounds(task.mTaskId);
- taskUserIds[i] = task.mUserId;
- }
- info.taskIds = taskIds;
- info.taskNames = taskNames;
- info.taskBounds = taskBounds;
- info.taskUserIds = taskUserIds;
+ final int numTasks = stack.getChildCount();
+ info.taskIds = new int[numTasks];
+ info.taskNames = new String[numTasks];
+ info.taskBounds = new Rect[numTasks];
+ info.taskUserIds = new int[numTasks];
+ final int[] currenIndex = {0};
- final ActivityRecord top = stack.topRunningActivityLocked();
+ final PooledConsumer c = PooledLambda.obtainConsumer(
+ RootActivityContainer::processTaskForStackInfo, PooledLambda.__(Task.class), info,
+ currenIndex);
+ stack.forAllTasks(c, false);
+ c.recycle();
+
+ final ActivityRecord top = stack.topRunningActivity();
info.topActivity = top != null ? top.intent.getComponent() : null;
return info;
}
+ private static void processTaskForStackInfo(
+ Task task, ActivityManager.StackInfo info, int[] currentIndex) {
+ int i = currentIndex[0];
+ info.taskIds[i] = task.mTaskId;
+ info.taskNames[i] = task.origActivity != null ? task.origActivity.flattenToString()
+ : task.realActivity != null ? task.realActivity.flattenToString()
+ : task.getTopNonFinishingActivity() != null
+ ? task.getTopNonFinishingActivity().packageName : "unknown";
+ info.taskBounds[i] = task.mAtmService.getTaskBounds(task.mTaskId);
+ info.taskUserIds[i] = task.mUserId;
+ currentIndex[0] = ++i;
+ }
+
ActivityManager.StackInfo getStackInfo(int stackId) {
ActivityStack stack = getStack(stackId);
if (stack != null) {
@@ -1905,7 +1911,7 @@
}
if (windowingMode == WINDOWING_MODE_FULLSCREEN_OR_SPLIT_SCREEN_SECONDARY
&& display.getSplitScreenPrimaryStack() == stack
- && candidateTask == stack.topTask()) {
+ && candidateTask == stack.getTopMostTask()) {
// This is a special case when we try to launch an activity that is currently on
// top of split-screen primary stack, but is targeting split-screen secondary.
// In this case we don't want to move it to another stack.
@@ -2338,24 +2344,11 @@
void lockAllProfileTasks(@UserIdInt int userId) {
mService.deferWindowLayout();
try {
- for (int displayNdx = mActivityDisplays.size() - 1; displayNdx >= 0; --displayNdx) {
- final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getStackAt(stackNdx);
- final List<Task> tasks = stack.getAllTasks();
- for (int taskNdx = tasks.size() - 1; taskNdx >= 0; taskNdx--) {
- final Task task = tasks.get(taskNdx);
-
- // Check the task for a top activity belonging to userId, or returning a
- // result to an activity belonging to userId. Example case: a document
- // picker for personal files, opened by a work app, should still get locked.
- if (taskTopActivityIsUser(task, userId)) {
- mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
- task.mTaskId, userId);
- }
- }
- }
- }
+ final PooledConsumer c = PooledLambda.obtainConsumer(
+ RootActivityContainer::taskTopActivityIsUser, this, PooledLambda.__(Task.class),
+ userId);
+ mRootWindowContainer.forAllTasks(c);
+ c.recycle();
} finally {
mService.continueWindowLayout();
}
@@ -2372,13 +2365,19 @@
*
* @return {@code true} if the top activity looks like it belongs to {@param userId}.
*/
- private boolean taskTopActivityIsUser(Task task, @UserIdInt int userId) {
+ private void taskTopActivityIsUser(Task task, @UserIdInt int userId) {
// To handle the case that work app is in the task but just is not the top one.
final ActivityRecord activityRecord = task.getTopNonFinishingActivity();
final ActivityRecord resultTo = (activityRecord != null ? activityRecord.resultTo : null);
- return (activityRecord != null && activityRecord.mUserId == userId)
- || (resultTo != null && resultTo.mUserId == userId);
+ // Check the task for a top activity belonging to userId, or returning a
+ // result to an activity belonging to userId. Example case: a document
+ // picker for personal files, opened by a work app, should still get locked.
+ if ((activityRecord != null && activityRecord.mUserId == userId)
+ || (resultTo != null && resultTo.mUserId == userId)) {
+ mService.getTaskChangeNotificationController().notifyTaskProfileLocked(
+ task.mTaskId, userId);
+ }
}
void cancelInitializingActivities() {
@@ -2414,29 +2413,25 @@
+ " lookup");
}
- int numDisplays = mActivityDisplays.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final ActivityDisplay display = mActivityDisplays.get(displayNdx);
- for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getStackAt(stackNdx);
- final Task task = stack.taskForIdLocked(id);
- if (task == null) {
- continue;
+ final PooledPredicate p = PooledLambda.obtainPredicate(
+ Task::isTaskId, PooledLambda.__(Task.class), id);
+ Task task = mRootWindowContainer.getTask(p);
+ p.recycle();
+
+ if (task != null) {
+ if (aOptions != null) {
+ // Resolve the stack the task should be placed in now based on options
+ // and reparent if needed.
+ final ActivityStack launchStack =
+ getLaunchStack(null, aOptions, task, onTop);
+ if (launchStack != null && task.getStack() != launchStack) {
+ final int reparentMode = onTop
+ ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE;
+ task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME,
+ "anyTaskForId");
}
- if (aOptions != null) {
- // Resolve the stack the task should be placed in now based on options
- // and reparent if needed.
- final ActivityStack launchStack =
- getLaunchStack(null, aOptions, task, onTop);
- if (launchStack != null && stack != launchStack) {
- final int reparentMode = onTop
- ? REPARENT_MOVE_STACK_TO_FRONT : REPARENT_LEAVE_STACK_IN_PLACE;
- task.reparent(launchStack, onTop, reparentMode, ANIMATE, DEFER_RESUME,
- "anyTaskForId");
- }
- }
- return task;
}
+ return task;
}
// If we are matching stack tasks only, return now
@@ -2447,7 +2442,7 @@
// Otherwise, check the recent tasks and return if we find it there and we are not restoring
// the task from recents
if (DEBUG_RECENTS) Slog.v(TAG_RECENTS, "Looking for task id=" + id + " in recents");
- final Task task = mStackSupervisor.mRecentTasks.getTask(id);
+ task = mStackSupervisor.mRecentTasks.getTask(id);
if (task == null) {
if (DEBUG_RECENTS) {
@@ -2492,7 +2487,7 @@
@WindowConfiguration.WindowingMode int ignoreWindowingMode, int callingUid,
boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
mStackSupervisor.getRunningTasks().getTasks(maxNum, list, ignoreActivityType,
- ignoreWindowingMode, mActivityDisplays, callingUid, allowed, crossUser, profileIds);
+ ignoreWindowingMode, this, callingUid, allowed, crossUser, profileIds);
}
void sendPowerHintForLaunchStartIfNeeded(boolean forceSend, ActivityRecord targetActivity) {
diff --git a/services/core/java/com/android/server/wm/RunningTasks.java b/services/core/java/com/android/server/wm/RunningTasks.java
index ca9d91e..5783713 100644
--- a/services/core/java/com/android/server/wm/RunningTasks.java
+++ b/services/core/java/com/android/server/wm/RunningTasks.java
@@ -16,11 +16,18 @@
package com.android.server.wm;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
+import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+
import android.app.ActivityManager.RunningTaskInfo;
import android.app.WindowConfiguration.ActivityType;
import android.app.WindowConfiguration.WindowingMode;
+import android.os.UserHandle;
import android.util.ArraySet;
+import com.android.internal.util.function.pooled.PooledConsumer;
+import com.android.internal.util.function.pooled.PooledLambda;
+
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Iterator;
@@ -39,8 +46,17 @@
private final TreeSet<Task> mTmpSortedSet = new TreeSet<>(LAST_ACTIVE_TIME_COMPARATOR);
private final ArrayList<Task> mTmpStackTasks = new ArrayList<>();
+ private int mCallingUid;
+ private int mUserId;
+ private boolean mCrossUser;
+ private ArraySet<Integer> mProfileIds;
+ private boolean mAllowed;
+ private int mIgnoreActivityType;
+ private int mIgnoreWindowingMode;
+ private ActivityStack mTopDisplayFocusStack;
+
void getTasks(int maxNum, List<RunningTaskInfo> list, @ActivityType int ignoreActivityType,
- @WindowingMode int ignoreWindowingMode, ArrayList<ActivityDisplay> activityDisplays,
+ @WindowingMode int ignoreWindowingMode, RootActivityContainer root,
int callingUid, boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
// Return early if there are no tasks to fetch
if (maxNum <= 0) {
@@ -49,17 +65,19 @@
// Gather all of the tasks across all of the tasks, and add them to the sorted set
mTmpSortedSet.clear();
- final int numDisplays = activityDisplays.size();
- for (int displayNdx = 0; displayNdx < numDisplays; ++displayNdx) {
- final ActivityDisplay display = activityDisplays.get(displayNdx);
- for (int stackNdx = display.getStackCount() - 1; stackNdx >= 0; --stackNdx) {
- final ActivityStack stack = display.getStackAt(stackNdx);
- mTmpStackTasks.clear();
- stack.getRunningTasks(mTmpStackTasks, ignoreActivityType, ignoreWindowingMode,
- callingUid, allowed, crossUser, profileIds);
- mTmpSortedSet.addAll(mTmpStackTasks);
- }
- }
+ mCallingUid = callingUid;
+ mUserId = UserHandle.getUserId(callingUid);
+ mCrossUser = crossUser;
+ mProfileIds = profileIds;
+ mAllowed = allowed;
+ mIgnoreActivityType = ignoreActivityType;
+ mIgnoreWindowingMode = ignoreWindowingMode;
+ mTopDisplayFocusStack = root.getTopDisplayFocusedStack();
+
+ final PooledConsumer c = PooledLambda.obtainConsumer(RunningTasks::processTask, this,
+ PooledLambda.__(Task.class));
+ root.mRootWindowContainer.forAllTasks(c, false);
+ c.recycle();
// Take the first {@param maxNum} tasks and create running task infos for them
final Iterator<Task> iter = mTmpSortedSet.iterator();
@@ -74,9 +92,45 @@
}
}
- /**
- * Constructs a {@link RunningTaskInfo} from a given {@param task}.
- */
+ private void processTask(Task task) {
+ if (task.getTopNonFinishingActivity() == null) {
+ // Skip if there are no activities in the task
+ return;
+ }
+ if (task.effectiveUid != mCallingUid) {
+ if (task.mUserId != mUserId && !mCrossUser && !mProfileIds.contains(task.mUserId)) {
+ // Skip if the caller does not have cross user permission or cannot access
+ // the task's profile
+ return;
+ }
+ if (!mAllowed && !task.isActivityTypeHome()) {
+ // Skip if the caller isn't allowed to fetch this task, except for the home
+ // task which we always return.
+ return;
+ }
+ }
+ if (mIgnoreActivityType != ACTIVITY_TYPE_UNDEFINED
+ && task.getActivityType() == mIgnoreActivityType) {
+ // Skip ignored activity type
+ return;
+ }
+ if (mIgnoreWindowingMode != WINDOWING_MODE_UNDEFINED
+ && task.getWindowingMode() == mIgnoreWindowingMode) {
+ // Skip ignored windowing mode
+ return;
+ }
+
+ final ActivityStack stack = task.getStack();
+ if (stack == mTopDisplayFocusStack && stack.getTopMostTask() == task) {
+ // For the focused stack top task, update the last stack active time so that it can be
+ // used to determine the order of the tasks (it may not be set for newly created tasks)
+ task.touchActiveTime();
+ }
+
+ mTmpSortedSet.add(task);
+ }
+
+ /** Constructs a {@link RunningTaskInfo} from a given {@param task}. */
private RunningTaskInfo createRunningTaskInfo(Task task) {
final RunningTaskInfo rti = new RunningTaskInfo();
task.fillTaskInfo(rti);
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index b1d0692..0e07e52 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -155,6 +155,7 @@
import java.util.ArrayList;
import java.util.Objects;
import java.util.function.Consumer;
+import java.util.function.Function;
import java.util.function.Predicate;
class Task extends WindowContainer<WindowContainer> {
@@ -684,7 +685,7 @@
final boolean toTopOfStack = position == MAX_VALUE;
if (toTopOfStack && toStack.getResumedActivity() != null
- && toStack.topRunningActivityLocked() != null) {
+ && toStack.topRunningActivity() != null) {
// Pause the resumed activity on the target stack while re-parenting task on top of it.
toStack.startPausingLocked(false /* userLeaving */, false /* uiSleeping */,
null /* resuming */);
@@ -720,7 +721,7 @@
// Whenever we are moving the top activity from the front stack we want to make sure to
// move the stack to the front.
final boolean wasFront = r != null && sourceStack.isTopStackOnDisplay()
- && (sourceStack.topRunningActivityLocked() == r);
+ && (sourceStack.topRunningActivity() == r);
final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
|| (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
@@ -1256,7 +1257,7 @@
// work.
// TODO: If the callers to removeChild() changes such that we have multiple places
// where we are destroying the task, move this back into removeChild()
- mAtmService.mStackSupervisor.removeTaskByIdLocked(mTaskId, false /* killProcess */,
+ mAtmService.mStackSupervisor.removeTask(this, false /* killProcess */,
!REMOVE_FROM_RECENTS, reason);
}
} else if (!mReuseTask) {
@@ -2659,12 +2660,13 @@
}
@Override
- void forAllTasks(Consumer<Task> callback) {
+ void forAllTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
+ // TODO(task-hierarchy): Change to traverse children when tasks can contain other tasks.
callback.accept(this);
}
@Override
- boolean forAllTasks(ToBooleanFunction<Task> callback) {
+ boolean forAllTasks(Function<Task, Boolean> callback) {
return callback.apply(this);
}
@@ -2707,6 +2709,10 @@
return mDimmer;
}
+ boolean isTaskForUser(int userId) {
+ return mUserId == userId;
+ }
+
@Override
void prepareSurfaces() {
mDimmer.resetDimStates();
@@ -2800,6 +2806,10 @@
return info;
}
+ boolean isTaskId(int taskId) {
+ return mTaskId == taskId;
+ }
+
void dump(PrintWriter pw, String prefix) {
pw.print(prefix); pw.print("userId="); pw.print(mUserId);
pw.print(" effectiveUid="); UserHandle.formatUid(pw, effectiveUid);
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index e80f3b8..d73cb50f 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -1202,9 +1202,17 @@
}
ActivityRecord getActivity(Predicate<ActivityRecord> callback, boolean traverseTopToBottom) {
+ return getActivity(callback, traverseTopToBottom, null /*boundary*/);
+ }
+
+ ActivityRecord getActivity(Predicate<ActivityRecord> callback, boolean traverseTopToBottom,
+ WindowContainer boundary) {
if (traverseTopToBottom) {
for (int i = mChildren.size() - 1; i >= 0; --i) {
- final ActivityRecord r = mChildren.get(i).getActivity(callback, traverseTopToBottom);
+ final WindowContainer wc = mChildren.get(i);
+ if (wc == boundary) return null;
+
+ final ActivityRecord r = wc.getActivity(callback, traverseTopToBottom, boundary);
if (r != null) {
return r;
}
@@ -1212,7 +1220,10 @@
} else {
final int count = mChildren.size();
for (int i = 0; i < count; i++) {
- final ActivityRecord r = mChildren.get(i).getActivity(callback, traverseTopToBottom);
+ final WindowContainer wc = mChildren.get(i);
+ if (wc == boundary) return null;
+
+ final ActivityRecord r = wc.getActivity(callback, traverseTopToBottom, boundary);
if (r != null) {
return r;
}
@@ -1320,14 +1331,57 @@
/**
* For all tasks at or below this container call the callback.
*
+ * @param callback Calls the {@link ToBooleanFunction#apply} method for each task found and
+ * stops the search if {@link ToBooleanFunction#apply} returns {@code true}.
+ */
+ boolean forAllTasks(Function<Task, Boolean> callback) {
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ if (mChildren.get(i).forAllTasks(callback)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * For all tasks at or below this container call the callback.
+ *
* @param callback Callback to be called for every task.
*/
void forAllTasks(Consumer<Task> callback) {
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- mChildren.get(i).forAllTasks(callback);
+ forAllTasks(callback, true /*traverseTopToBottom*/);
+ }
+
+ void forAllTasks(Consumer<Task> callback, boolean traverseTopToBottom) {
+ final int count = mChildren.size();
+ if (traverseTopToBottom) {
+ for (int i = count - 1; i >= 0; --i) {
+ mChildren.get(i).forAllTasks(callback, traverseTopToBottom);
+ }
+ } else {
+ for (int i = 0; i < count; i++) {
+ mChildren.get(i).forAllTasks(callback, traverseTopToBottom);
+ }
}
}
+ Task getTaskAbove(Task t) {
+ return getTask(
+ (above) -> true, t, false /*includeBoundary*/, false /*traverseTopToBottom*/);
+ }
+
+ Task getTaskBelow(Task t) {
+ return getTask((below) -> true, t, false /*includeBoundary*/, true /*traverseTopToBottom*/);
+ }
+
+ Task getBottomMostTask() {
+ return getTask((t) -> true, false /*traverseTopToBottom*/);
+ }
+
+ Task getTopMostTask() {
+ return getTask((t) -> true, true /*traverseTopToBottom*/);
+ }
+
Task getTask(Predicate<Task> callback) {
return getTask(callback, true /*traverseTopToBottom*/);
}
@@ -1354,18 +1408,59 @@
}
/**
- * For all tasks at or below this container call the callback.
+ * Gets an task in a branch of the tree.
*
- * @param callback Calls the {@link ToBooleanFunction#apply} method for each task found and
- * stops the search if {@link ToBooleanFunction#apply} returns {@code true}.
+ * @param callback called to test if this is the task that should be returned.
+ * @param boundary We don't return tasks via {@param callback} until we get to this node in
+ * the tree.
+ * @param includeBoundary If the boundary from be processed to return tasks.
+ * @param traverseTopToBottom direction to traverse the tree.
+ * @return The task if found or null.
*/
- boolean forAllTasks(ToBooleanFunction<Task> callback) {
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- if (mChildren.get(i).forAllTasks(callback)) {
- return true;
+ final Task getTask(Predicate<Task> callback, WindowContainer boundary, boolean includeBoundary,
+ boolean traverseTopToBottom) {
+ return getTask(callback, boundary, includeBoundary, traverseTopToBottom, new boolean[1]);
+ }
+
+ private Task getTask(Predicate<Task> callback,
+ WindowContainer boundary, boolean includeBoundary, boolean traverseTopToBottom,
+ boolean[] boundaryFound) {
+ if (traverseTopToBottom) {
+ for (int i = mChildren.size() - 1; i >= 0; --i) {
+ final Task t = processGetTaskWithBoundary(callback, boundary,
+ includeBoundary, traverseTopToBottom, boundaryFound, mChildren.get(i));
+ if (t != null) {
+ return t;
+ }
+ }
+ } else {
+ final int count = mChildren.size();
+ for (int i = 0; i < count; i++) {
+ final Task t = processGetTaskWithBoundary(callback, boundary,
+ includeBoundary, traverseTopToBottom, boundaryFound, mChildren.get(i));
+ if (t != null) {
+ return t;
+ }
}
}
- return false;
+
+ return null;
+ }
+
+ private Task processGetTaskWithBoundary(Predicate<Task> callback,
+ WindowContainer boundary, boolean includeBoundary, boolean traverseTopToBottom,
+ boolean[] boundaryFound, WindowContainer wc) {
+ if (wc == boundary || boundary == null) {
+ boundaryFound[0] = true;
+ if (!includeBoundary) return null;
+ }
+
+ if (boundaryFound[0]) {
+ return wc.getTask(callback, traverseTopToBottom);
+ }
+
+ return wc.getTask(
+ callback, boundary, includeBoundary, traverseTopToBottom, boundaryFound);
}
WindowState getWindow(Predicate<WindowState> callback) {
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
index de2bba2..5928641 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityDisplayTests.java
@@ -144,7 +144,7 @@
// Put a finishing standard activity which will be reparented.
final ActivityStack stack = createFullscreenStackWithSimpleActivityAt(display);
- stack.topRunningActivityLocked().makeFinishingLocked();
+ stack.topRunningActivity().makeFinishingLocked();
clearInvocations(homeStack);
display.remove();
@@ -301,24 +301,18 @@
doAnswer(invocation -> {
display.positionStackAtTop(stack3, false);
return true;
- }).when(mSupervisor).removeTaskByIdLocked(eq(task4.mTaskId), anyBoolean(), anyBoolean(),
- any());
+ }).when(mSupervisor).removeTask(eq(task4), anyBoolean(), anyBoolean(), any());
// Removing stacks from the display while removing stacks.
doAnswer(invocation -> {
display.removeStack(stack2);
return true;
- }).when(mSupervisor).removeTaskByIdLocked(eq(task2.mTaskId), anyBoolean(), anyBoolean(),
- any());
+ }).when(mSupervisor).removeTask(eq(task2), anyBoolean(), anyBoolean(), any());
runnable.run();
- verify(mSupervisor).removeTaskByIdLocked(eq(task4.mTaskId), anyBoolean(), anyBoolean(),
- any());
- verify(mSupervisor).removeTaskByIdLocked(eq(task3.mTaskId), anyBoolean(), anyBoolean(),
- any());
- verify(mSupervisor).removeTaskByIdLocked(eq(task2.mTaskId), anyBoolean(), anyBoolean(),
- any());
- verify(mSupervisor).removeTaskByIdLocked(eq(task1.mTaskId), anyBoolean(), anyBoolean(),
- any());
+ verify(mSupervisor).removeTask(eq(task4), anyBoolean(), anyBoolean(), any());
+ verify(mSupervisor).removeTask(eq(task3), anyBoolean(), anyBoolean(), any());
+ verify(mSupervisor).removeTask(eq(task2), anyBoolean(), anyBoolean(), any());
+ verify(mSupervisor).removeTask(eq(task1), anyBoolean(), anyBoolean(), any());
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
index dbcfa94..7a449b3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -107,7 +107,7 @@
@Before
public void setUp() throws Exception {
mStack = new StackBuilder(mRootActivityContainer).build();
- mTask = mStack.getChildAt(0);
+ mTask = mStack.getBottomMostTask();
mActivity = mTask.getTopNonFinishingActivity();
doReturn(false).when(mService).isBooting();
@@ -640,7 +640,7 @@
// stacks. Then when mActivity is finishing, its stack will be invisible (no running
// activities in the stack) that is the key condition to verify.
final ActivityStack stack2 = new StackBuilder(mRootActivityContainer).build();
- stack2.moveToBack("test", stack2.getChildAt(0));
+ stack2.moveToBack("test", stack2.getBottomMostTask());
assertTrue(mStack.isTopStackOnDisplay());
@@ -948,9 +948,7 @@
public void testDestroyIfPossible_lastActivityAboveEmptyHomeStack() {
// Empty the home stack.
final ActivityStack homeStack = mActivity.getDisplay().getHomeStack();
- for (Task t : homeStack.getAllTasks()) {
- homeStack.removeChild(t, "test");
- }
+ homeStack.forAllTasks((t) -> { homeStack.removeChild(t, "test"); });
mActivity.finishing = true;
doReturn(false).when(mRootActivityContainer).resumeFocusedStacksTopActivities();
spyOn(mStack);
@@ -974,9 +972,7 @@
public void testCompleteFinishing_lastActivityAboveEmptyHomeStack() {
// Empty the home stack.
final ActivityStack homeStack = mActivity.getDisplay().getHomeStack();
- for (Task t : homeStack.getAllTasks()) {
- homeStack.removeChild(t, "test");
- }
+ homeStack.forAllTasks((t) -> { homeStack.removeChild(t, "test"); });
mActivity.finishing = true;
spyOn(mStack);
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
index 7806d40..47f454e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStackTests.java
@@ -286,12 +286,12 @@
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_STANDARD, true /* onTop */);
// Do not move display to back because there is still another stack.
- stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.topTask());
+ stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.getTopMostTask());
verify(stack2).positionChildAtBottom(any(), eq(false) /* includingParents */);
// Also move display to back because there is only one stack left.
display.removeStack(stack1);
- stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.topTask());
+ stack2.moveToBack("testMoveStackToBackIncludingParent", stack2.getTopMostTask());
verify(stack2).positionChildAtBottom(any(), eq(true) /* includingParents */);
}
@@ -545,7 +545,7 @@
public void testShouldBeVisible_Finishing() {
final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
- ActivityRecord topRunningHomeActivity = homeStack.topRunningActivityLocked();
+ ActivityRecord topRunningHomeActivity = homeStack.topRunningActivity();
if (topRunningHomeActivity == null) {
topRunningHomeActivity = new ActivityBuilder(mService)
.setStack(homeStack)
@@ -563,7 +563,7 @@
topRunningHomeActivity.finishing = true;
final ActivityRecord topRunningTranslucentActivity =
- translucentStack.topRunningActivityLocked();
+ translucentStack.topRunningActivity();
topRunningTranslucentActivity.finishing = true;
// Home stack should be visible even there are no running activities.
@@ -883,7 +883,7 @@
// removed from the task. Since the overlay activity should be removed as well, the task
// should be empty.
assertFalse(mTask.hasChild());
- assertThat(mStack.getAllTasks()).isEmpty();
+ assertFalse(mStack.hasChild());
}
@Test
@@ -905,7 +905,7 @@
mStack.handleAppDiedLocked(secondActivity.app);
assertFalse(mTask.hasChild());
- assertThat(mStack.getAllTasks()).isEmpty();
+ assertFalse(mStack.hasChild());
}
@Test
@@ -919,7 +919,7 @@
mStack.handleAppDiedLocked(activity.app);
assertEquals(1, mTask.getChildCount());
- assertEquals(1, mStack.getAllTasks().size());
+ assertEquals(1, mStack.getChildCount());
}
@Test
@@ -933,7 +933,7 @@
mStack.handleAppDiedLocked(activity.app);
assertFalse(mTask.hasChild());
- assertThat(mStack.getAllTasks()).isEmpty();
+ assertFalse(mStack.hasChild());
}
@Test
@@ -947,7 +947,7 @@
mStack.handleAppDiedLocked(activity.app);
assertEquals(1, mTask.getChildCount());
- assertEquals(1, mStack.getAllTasks().size());
+ assertEquals(1, mStack.getChildCount());
}
@Test
@@ -961,7 +961,7 @@
mStack.handleAppDiedLocked(activity.app);
assertFalse(mTask.hasChild());
- assertThat(mStack.getAllTasks()).isEmpty();
+ assertFalse(mStack.hasChild());
}
@Test
@@ -982,7 +982,7 @@
final ActivityStack homeStack = createStackForShouldBeVisibleTest(mDefaultDisplay,
WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME, true /* onTop */);
- ActivityRecord activity = homeStack.topRunningActivityLocked();
+ ActivityRecord activity = homeStack.topRunningActivity();
if (activity == null) {
activity = new ActivityBuilder(mService)
.setStack(homeStack)
@@ -1020,7 +1020,7 @@
}
private ActivityRecord finishTopActivity(ActivityStack stack) {
- final ActivityRecord activity = stack.topRunningActivityLocked();
+ final ActivityRecord activity = stack.topRunningActivity();
assertNotNull(activity);
activity.setState(STOPPED, "finishTopActivity");
activity.makeFinishingLocked();
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
index d5fdf98..018c10a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityStarterTests.java
@@ -54,6 +54,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -519,7 +520,7 @@
private void assertNoTasks(ActivityDisplay display) {
for (int i = display.getStackCount() - 1; i >= 0; --i) {
final ActivityStack stack = display.getStackAt(i);
- assertThat(stack.getAllTasks()).isEmpty();
+ assertFalse(stack.hasChild());
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
index dae1052..07b7cf4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskManagerServiceTests.java
@@ -59,7 +59,7 @@
@Test
public void testActivityFinish() {
final ActivityStack stack = new StackBuilder(mRootActivityContainer).build();
- final ActivityRecord activity = stack.getChildAt(0).getTopNonFinishingActivity();
+ final ActivityRecord activity = stack.getBottomMostTask().getTopNonFinishingActivity();
assertTrue("Activity must be finished", mService.finishActivity(activity.appToken,
0 /* resultCode */, null /* resultData */,
Activity.DONT_FINISH_TASK_WITH_ACTIVITY));
@@ -75,7 +75,7 @@
removeGlobalMinSizeRestriction();
final ActivityStack stack = new StackBuilder(mRootActivityContainer)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
- final Task task = stack.topTask();
+ final Task task = stack.getTopMostTask();
WindowContainerTransaction t = new WindowContainerTransaction();
Rect newBounds = new Rect(10, 10, 100, 100);
t.setBounds(task.mRemoteToken, new Rect(10, 10, 100, 100));
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
index a29c8cb..14c09eb 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayContentTests.java
@@ -742,7 +742,7 @@
final ActivityStack stack =
new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
.setDisplay(dc).build();
- final ActivityRecord activity = stack.topTask().getTopNonFinishingActivity();
+ final ActivityRecord activity = stack.getTopMostTask().getTopNonFinishingActivity();
activity.setRequestedOrientation(newOrientation);
@@ -764,7 +764,7 @@
final ActivityStack stack =
new ActivityTestsBase.StackBuilder(mWm.mAtmService.mRootActivityContainer)
.setDisplay(dc).build();
- final ActivityRecord activity = stack.topTask().getTopNonFinishingActivity();
+ final ActivityRecord activity = stack.getTopMostTask().getTopNonFinishingActivity();
activity.setRequestedOrientation(newOrientation);
diff --git a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
index 6ced816..0cc2626 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LockTaskControllerTest.java
@@ -106,6 +106,7 @@
@Mock private ActivityStackSupervisor mSupervisor;
@Mock private RootActivityContainer mRootActivityContainer;
+ @Mock private RootWindowContainer mRootWindowContainer;
@Mock private IDevicePolicyManager mDevicePolicyManager;
@Mock private IStatusBarService mStatusBarService;
@Mock private WindowManagerService mWindowManager;
@@ -134,6 +135,7 @@
mSupervisor.mRecentTasks = mRecentTasks;
mSupervisor.mRootActivityContainer = mRootActivityContainer;
+ mRootActivityContainer.mRootWindowContainer = mRootWindowContainer;
mLockTaskController = new LockTaskController(mContext, mSupervisor,
new ImmediatelyExecuteHandler());
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
index 9f97c48..b1cd931 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentTasksTest.java
@@ -1282,10 +1282,10 @@
@Override
void getTasks(int maxNum, List<RunningTaskInfo> list, int ignoreActivityType,
- int ignoreWindowingMode, ArrayList<ActivityDisplay> activityDisplays,
+ int ignoreWindowingMode, RootActivityContainer root,
int callingUid, boolean allowed, boolean crossUser, ArraySet<Integer> profileIds) {
mLastAllowed = allowed;
- super.getTasks(maxNum, list, ignoreActivityType, ignoreWindowingMode, activityDisplays,
+ super.getTasks(maxNum, list, ignoreActivityType, ignoreWindowingMode, root,
callingUid, allowed, crossUser, profileIds);
}
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
index 4abab63..8fbb16c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RecentsAnimationTest.java
@@ -120,7 +120,7 @@
final ActivityStack homeStack =
defaultDisplay.getStack(WINDOWING_MODE_FULLSCREEN, ACTIVITY_TYPE_HOME);
defaultDisplay.positionStackAtTop(homeStack, false /* includingParents */);
- ActivityRecord topRunningHomeActivity = homeStack.topRunningActivityLocked();
+ ActivityRecord topRunningHomeActivity = homeStack.topRunningActivity();
if (topRunningHomeActivity == null) {
topRunningHomeActivity = new ActivityBuilder(mService)
.setStack(homeStack)
diff --git a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
index 59c7c02..5417ade 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RootActivityContainerTests.java
@@ -147,7 +147,7 @@
}
private static void ensureStackPlacement(ActivityStack stack, ActivityRecord... activities) {
- final Task task = stack.getAllTasks().get(0);
+ final Task task = stack.getBottomMostTask();
final ArrayList<ActivityRecord> stackActivities = new ArrayList<>();
task.forAllActivities((Consumer<ActivityRecord>) stackActivities::add, false);
@@ -320,7 +320,7 @@
.setWindowingMode(WINDOWING_MODE_SPLIT_SCREEN_PRIMARY)
.setOnTop(true)
.build();
- final Task task = primaryStack.topTask();
+ final Task task = primaryStack.getTopMostTask();
// Resize dock stack.
mService.resizeDockedStack(stackSize, taskSize, null, null, null);
@@ -340,7 +340,7 @@
final ActivityStack targetStack = new StackBuilder(mRootActivityContainer)
.setOnTop(false)
.build();
- final Task targetTask = targetStack.getChildAt(0);
+ final Task targetTask = targetStack.getBottomMostTask();
// Create Recents on top of the display.
final ActivityStack stack = new StackBuilder(mRootActivityContainer).setActivityType(
diff --git a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
index 5c9ccae..66f4d2a 100644
--- a/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/RunningTasksTest.java
@@ -82,8 +82,8 @@
final int numFetchTasks = 5;
ArrayList<RunningTaskInfo> tasks = new ArrayList<>();
mRunningTasks.getTasks(5, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED,
- displays, -1 /* callingUid */, true /* allowed */, true /*crossUser */,
- PROFILE_IDS);
+ mRootActivityContainer, -1 /* callingUid */, true /* allowed */,
+ true /*crossUser */, PROFILE_IDS);
assertThat(tasks).hasSize(numFetchTasks);
for (int i = 0; i < numFetchTasks; i++) {
assertEquals(numTasks - i - 1, tasks.get(i).id);
@@ -93,8 +93,8 @@
// and does not crash
tasks.clear();
mRunningTasks.getTasks(100, tasks, ACTIVITY_TYPE_UNDEFINED, WINDOWING_MODE_UNDEFINED,
- displays, -1 /* callingUid */, true /* allowed */, true /* crossUser */,
- PROFILE_IDS);
+ mRootActivityContainer, -1 /* callingUid */, true /* allowed */,
+ true /* crossUser */, PROFILE_IDS);
assertThat(tasks).hasSize(numTasks);
for (int i = 0; i < numTasks; i++) {
assertEquals(numTasks - i - 1, tasks.get(i).id);
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 8953cd4..46f95ed 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -69,7 +69,7 @@
private void setUpApp(ActivityDisplay display) {
mStack = new StackBuilder(mRootActivityContainer).setDisplay(display).build();
- mTask = mStack.getChildAt(0);
+ mTask = mStack.getBottomMostTask();
mActivity = mTask.getTopNonFinishingActivity();
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
index 599edb1..39e7885 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskRecordTests.java
@@ -235,7 +235,7 @@
ActivityDisplay display = mService.mRootActivityContainer.getDefaultDisplay();
ActivityStack stack = new StackBuilder(mRootActivityContainer).setDisplay(display)
.setWindowingMode(WINDOWING_MODE_FREEFORM).build();
- Task task = stack.getChildAt(0);
+ Task task = stack.getBottomMostTask();
task.getRootActivity().setOrientation(SCREEN_ORIENTATION_UNSPECIFIED);
DisplayInfo info = new DisplayInfo();
display.mDisplay.getDisplayInfo(info);
@@ -276,7 +276,7 @@
ActivityStack stack = new StackBuilder(mRootActivityContainer)
.setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
- Task task = stack.getChildAt(0);
+ Task task = stack.getBottomMostTask();
ActivityRecord root = task.getTopNonFinishingActivity();
assertEquals(fullScreenBounds, task.getBounds());
@@ -337,7 +337,7 @@
display.getRequestedOverrideConfiguration());
ActivityStack stack = new StackBuilder(mRootActivityContainer)
.setWindowingMode(WINDOWING_MODE_FULLSCREEN).setDisplay(display).build();
- Task task = stack.getChildAt(0);
+ Task task = stack.getBottomMostTask();
ActivityRecord root = task.getTopNonFinishingActivity();
final WindowContainer parentWindowContainer =
@@ -803,7 +803,7 @@
private Task getTestTask() {
final ActivityStack stack = new StackBuilder(mRootActivityContainer).build();
- return stack.getChildAt(0);
+ return stack.getBottomMostTask();
}
private void testStackBoundsConfiguration(int windowingMode, Rect parentBounds, Rect bounds,