Merge Task level of window hierarchy (58/n)
Bug: 80414790
Fixes: 143491035
Test: Existing tests pass
Change-Id: I1b39a70afce86f9807ee7b257e10b7e9d6b6e95b
diff --git a/services/core/java/com/android/server/wm/ActivityDisplay.java b/services/core/java/com/android/server/wm/ActivityDisplay.java
index 48a7b73..1268113 100644
--- a/services/core/java/com/android/server/wm/ActivityDisplay.java
+++ b/services/core/java/com/android/server/wm/ActivityDisplay.java
@@ -41,7 +41,6 @@
import static com.android.server.am.ActivityDisplayProto.SINGLE_TASK_INSTANCE;
import static com.android.server.am.ActivityDisplayProto.STACKS;
import static com.android.server.wm.ActivityStack.ActivityState.RESUMED;
-import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static com.android.server.wm.ActivityStack.STACK_VISIBILITY_VISIBLE;
import static com.android.server.wm.ActivityStackSupervisor.TAG_TASKS;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_STACK;
@@ -1523,7 +1522,7 @@
final ActivityStack stack = getChildAt(i);
final ArrayList<TaskRecord> tasks = stack.getAllTasks();
for (int j = tasks.size() - 1; j >= 0; --j) {
- stack.removeTask(tasks.get(j), "removeAllTasks", REMOVE_TASK_MODE_DESTROYING);
+ stack.removeChild(tasks.get(j), "removeAllTasks");
}
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index d4dd033..b95d327 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -1148,56 +1148,11 @@
}
}
- // TODO(task-unify): Remove once TaskRecord and Task are unified.
TaskRecord getTaskRecord() {
return task;
}
/**
- * Sets reference to the {@link TaskRecord} the {@link ActivityRecord} will treat as its parent.
- * Note that this does not actually add the {@link ActivityRecord} as a {@link TaskRecord}
- * children. However, this method will clean up references to this {@link ActivityRecord} in
- * {@link ActivityStack}.
- * @param task The new parent {@link TaskRecord}.
- */
- // TODO(task-unify): Can be remove after task level unification. Callers can just use addChild
- void setTask(TaskRecord task) {
- // Do nothing if the {@link TaskRecord} is the same as the current {@link getTaskRecord}.
- if (task != null && task == getTaskRecord()) {
- return;
- }
-
- final ActivityStack oldStack = getActivityStack();
- final ActivityStack newStack = task != null ? task.getStack() : null;
-
- // Inform old stack (if present) of activity removal and new stack (if set) of activity
- // addition.
- if (oldStack != newStack) {
- if (oldStack != null) {
- oldStack.onActivityRemovedFromStack(this);
- }
-
- if (newStack != null) {
- newStack.onActivityAddedToStack(this);
- }
- }
-
- final TaskRecord oldTask = this.task;
- this.task = task;
-
- // This is attaching the activity to the task which we only want to do once.
- // TODO(task-unify): Need to re-work after unifying the task level since it will already
- // have a parent then. Just need to restructure the re-parent case not to do this. NOTE that
- // the reparenting flag passed in can't be used directly for this as it isn't set in
- // ActivityRecord#reparent() case that ends up calling this method.
- if (task != null && getParent() == null) {
- task.addChild(this);
- } else {
- onParentChanged(task, oldTask);
- }
- }
-
- /**
* Sets the Task on this activity for the purposes of re-use during launch where we will
* re-use another activity instead of this one for the launch.
*/
@@ -1220,8 +1175,8 @@
@Override
void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
- final TaskRecord oldTask = (oldParent != null) ? ((Task) oldParent).mTaskRecord : null;
- final TaskRecord newTask = (newParent != null) ? ((Task) newParent).mTaskRecord : null;
+ final TaskRecord oldTask = oldParent != null ? (TaskRecord) oldParent : null;
+ final TaskRecord newTask = newParent != null ? (TaskRecord) newParent : null;
this.task = newTask;
super.onParentChanged(newParent, oldParent);
@@ -1230,14 +1185,12 @@
if (oldParent == null && newParent != null) {
// First time we are adding the activity to the system.
- // TODO(task-unify): See if mVoiceInteraction variable is really needed after task level
- // unification.
- mVoiceInteraction = task.mTaskRecord != null && task.mTaskRecord.voiceSession != null;
+ mVoiceInteraction = newTask.voiceSession != null;
mInputDispatchingTimeoutNanos = getInputDispatchingTimeoutLocked(this) * 1000000L;
onDisplayChanged(task.getDisplayContent());
- if (task.mTaskRecord != null) {
- task.mTaskRecord.updateOverrideConfigurationFromLaunchBounds();
- }
+ // TODO(b/36505427): Maybe this call should be moved inside
+ // updateOverrideConfiguration()
+ newTask.updateOverrideConfigurationFromLaunchBounds();
// Make sure override configuration is up-to-date before using to create window
// controller.
updateSizeCompatMode();
@@ -1279,8 +1232,6 @@
// Inform old stack (if present) of activity removal and new stack (if set) of activity
// addition.
if (oldStack != newStack) {
- // TODO(task-unify): Might be better to use onChildAdded and onChildRemoved signal for
- // this once task level is unified.
if (oldStack != null) {
oldStack.onActivityRemovedFromStack(this);
}
@@ -1964,15 +1915,7 @@
ProtoLog.i(WM_DEBUG_ADD_REMOVE, "reparent: moving activity=%s"
+ " to task=%d at %d", this, task.mTaskId, position);
-
- reparent(newTask.getTask(), position);
- }
-
- // TODO(task-unify): Remove once Task level is unified.
- void onParentChanged(TaskRecord newParent, TaskRecord oldParent) {
- onParentChanged(
- newParent != null ? newParent.mTask : null,
- oldParent != null ? oldParent.mTask : null);
+ reparent(newTask, position);
}
private boolean isHomeIntent(Intent intent) {
@@ -2051,7 +1994,7 @@
/**
* @return Stack value from current task, null if there is no task.
*/
- // TODO: Remove once ActivityStack and TaskStack are unified.
+ // TODO(stack-unify): Remove once ActivityStack and TaskStack are unified.
<T extends ActivityStack> T getActivityStack() {
return task != null ? (T) task.getStack() : null;
}
@@ -2339,7 +2282,7 @@
/** Finish all activities in the task with the same affinity as this one. */
void finishActivityAffinity() {
- final ArrayList<ActivityRecord> activities = getTaskRecord().mActivities;
+ final ArrayList<ActivityRecord> activities = getTaskRecord().mChildren;
for (int index = activities.indexOf(this); index >= 0; --index) {
final ActivityRecord cur = activities.get(index);
if (!Objects.equals(cur.taskAffinity, taskAffinity)) {
@@ -2451,7 +2394,7 @@
EventLog.writeEvent(EventLogTags.AM_FINISH_ACTIVITY,
mUserId, System.identityHashCode(this),
task.mTaskId, shortComponentName, reason);
- final ArrayList<ActivityRecord> activities = task.mActivities;
+ final ArrayList<ActivityRecord> activities = task.mChildren;
final int index = activities.indexOf(this);
if (index < (task.getChildCount() - 1)) {
if ((intent.getFlags() & Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET) != 0) {
@@ -2505,7 +2448,7 @@
// When finishing the activity preemptively take the snapshot before the app window
// is marked as hidden and any configuration changes take place
if (mAtmService.mWindowManager.mTaskSnapshotController != null) {
- final ArraySet<Task> tasks = Sets.newArraySet(task.mTask);
+ final ArraySet<Task> tasks = Sets.newArraySet(task);
mAtmService.mWindowManager.mTaskSnapshotController.snapshotTasks(tasks);
mAtmService.mWindowManager.mTaskSnapshotController
.addSkipClosingAppSnapshotTasks(tasks);
@@ -2547,7 +2490,8 @@
// In this case, we can set the visibility of all the task overlay activities when
// we detect the last one is finishing to keep them in sync.
if (task.onlyHasTaskOverlayActivities(true /* excludeFinishing */)) {
- for (ActivityRecord taskOverlay : task.mActivities) {
+ for (int i = task.getChildCount() - 1; i >= 0 ; --i) {
+ final ActivityRecord taskOverlay = task.getChildAt(i);
if (!taskOverlay.mTaskOverlay) {
continue;
}
@@ -2819,8 +2763,6 @@
}
/** Note: call {@link #cleanUp(boolean, boolean)} before this method. */
- // TODO(task-unify): Look into consolidating this with TaskRecord.removeChild once we unify
- // task level.
void removeFromHistory(String reason) {
finishActivityResults(Activity.RESULT_CANCELED, null /* resultData */);
makeFinishingLocked();
@@ -4659,7 +4601,7 @@
}
// Check if position in task allows to become paused
- final int positionInTask = task.mActivities.indexOf(this);
+ final int positionInTask = task.mChildren.indexOf(this);
if (positionInTask == -1) {
throw new IllegalStateException("Activity not found in its task");
}
@@ -5387,7 +5329,7 @@
return INVALID_TASK_ID;
}
final TaskRecord task = r.task;
- final int activityNdx = task.mActivities.indexOf(r);
+ final int activityNdx = task.mChildren.indexOf(r);
if (activityNdx < 0
|| (onlyRoot && activityNdx > task.findRootIndex(true /* effectiveRoot */))) {
return INVALID_TASK_ID;
@@ -5751,7 +5693,7 @@
@Override
boolean isWaitingForTransitionStart() {
final DisplayContent dc = getDisplayContent();
- // TODO: Test for null can be removed once unification is done.
+ // TODO(display-unify): Test for null can be removed once unification is done.
if (dc == null) return false;
return dc.mAppTransition.isTransitionSet()
&& (dc.mOpeningApps.contains(this)
@@ -6559,8 +6501,7 @@
// If the changes come from change-listener, the incoming parent configuration is
// still the old one. Make sure their orientations are the same to reduce computing
// the compatibility bounds for the intermediate state.
- && (task.mTaskRecord == null || task.mTaskRecord
- .getConfiguration().orientation == newParentConfig.orientation)) {
+ && (task.getConfiguration().orientation == newParentConfig.orientation)) {
final Rect taskBounds = task.getBounds();
// Since we only center the activity horizontally, if only the fixed height is smaller
// than its container, the override bounds don't need to take effect.
@@ -6878,8 +6819,7 @@
preserveWindow &= isResizeOnlyChange(changes);
final boolean hasResizeChange = hasResizeChange(changes & ~info.getRealConfigChanged());
if (hasResizeChange) {
- final boolean isDragResizing =
- getTaskRecord().getTask().isDragResizing();
+ final boolean isDragResizing = getTaskRecord().isDragResizing();
mRelaunchReason = isDragResizing ? RELAUNCH_REASON_FREE_RESIZE
: RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
} else {
diff --git a/services/core/java/com/android/server/wm/ActivityStack.java b/services/core/java/com/android/server/wm/ActivityStack.java
index 8e3995bf..9dade2c 100644
--- a/services/core/java/com/android/server/wm/ActivityStack.java
+++ b/services/core/java/com/android/server/wm/ActivityStack.java
@@ -254,7 +254,11 @@
@Override
protected void onParentChanged(
ConfigurationContainer newParent, ConfigurationContainer oldParent) {
- ActivityDisplay display = getParent();
+ if (oldParent != null) {
+ mPrevDisplayId = ((ActivityDisplay) oldParent).mDisplayId;
+ }
+
+ final ActivityDisplay display = getParent();
if (display != null) {
// Rotations are relative to the display. This means if there are 2 displays rotated
// differently (eg. 2 monitors with one landscape and one portrait), moving a stack
@@ -292,18 +296,6 @@
RESTARTING_PROCESS
}
- @VisibleForTesting
- /* The various modes for the method {@link #removeTask}. */
- // Task is being completely removed from all stacks in the system.
- protected static final int REMOVE_TASK_MODE_DESTROYING = 0;
- // Task is being removed from this stack so we can add it to another stack. In the case we are
- // moving we don't want to perform some operations on the task like removing it from window
- // manager or recents.
- static final int REMOVE_TASK_MODE_MOVING = 1;
- // Similar to {@link #REMOVE_TASK_MODE_MOVING} and the task will be added to the top of its new
- // stack and the new stack will be on top of all stacks.
- static final int REMOVE_TASK_MODE_MOVING_TO_TOP = 2;
-
final ActivityTaskManagerService mService;
final WindowManagerService mWindowManager;
@@ -381,6 +373,8 @@
final int mStackId;
/** The attached Display's unique identifier, or -1 if detached */
int mDisplayId;
+ // Id of the previous display the stack was on.
+ int mPrevDisplayId = INVALID_DISPLAY;
/** Stores the override windowing-mode from before a transient mode change (eg. split) */
private int mRestoreOverrideWindowingMode = WINDOWING_MODE_UNDEFINED;
@@ -962,7 +956,7 @@
void positionChildWindowContainerAtTop(TaskRecord child) {
if (mTaskStack != null) {
// TODO: Remove after unification. This cannot be false after that.
- mTaskStack.positionChildAtTop(child.getTask(), true /* includingParents */);
+ mTaskStack.positionChildAtTop(child, true /* includingParents */);
}
}
@@ -974,7 +968,7 @@
child.getStack(), true /* ignoreCurrent */);
if (mTaskStack != null) {
// TODO: Remove after unification. This cannot be false after that.
- mTaskStack.positionChildAtBottom(child.getTask(),
+ mTaskStack.positionChildAtBottom(child,
nextFocusableStack == null /* includingParents */);
}
}
@@ -1168,7 +1162,7 @@
}
final TaskRecord task = r.getTaskRecord();
final ActivityStack stack = r.getActivityStack();
- if (stack != null && task.mActivities.contains(r) && mTaskHistory.contains(task)) {
+ if (stack != null && task.mChildren.contains(r) && mTaskHistory.contains(task)) {
if (stack != this) Slog.w(TAG,
"Illegal state! task does not point to stack it is in.");
return r;
@@ -1183,7 +1177,8 @@
/** Checks if there are tasks with specific UID in the stack. */
boolean isUidPresent(int uid) {
for (TaskRecord task : mTaskHistory) {
- for (ActivityRecord r : task.mActivities) {
+ for (int i = task.getChildCount() - 1; i >= 0 ; --i) {
+ final ActivityRecord r = task.getChildAt(i);
if (r.getUid() == uid) {
return true;
}
@@ -1195,7 +1190,8 @@
/** Get all UIDs that are present in the stack. */
void getPresentUIDs(IntArray presentUIDs) {
for (TaskRecord task : mTaskHistory) {
- for (ActivityRecord r : task.mActivities) {
+ for (int i = task.getChildCount() - 1; i >= 0 ; --i) {
+ final ActivityRecord r = task.getChildAt(i);
presentUIDs.add(r.getUid());
}
}
@@ -1207,12 +1203,6 @@
return display != null && display.isSingleTaskInstance();
}
- private void removeActivitiesFromLRUList(TaskRecord task) {
- for (ActivityRecord r : task.mActivities) {
- mLRUActivities.remove(r);
- }
- }
-
/** @return {@code true} if LRU list contained the specified activity. */
final boolean removeActivityFromLRUList(ActivityRecord activity) {
return mLRUActivities.remove(activity);
@@ -3016,19 +3006,19 @@
mTaskHistory.remove(task);
mTaskHistory.add(position, task);
if (mTaskStack != null) {
- // TODO: this could not be false after unification.
- mTaskStack.positionChildAt(task.getTask(), position);
+ // TODO: this can not be false after unification Stack.
+ mTaskStack.positionChildAt(task, position);
}
- updateTaskMovement(task, true);
+ task.updateTaskMovement(true);
}
- private void insertTaskAtTop(TaskRecord task, ActivityRecord starting) {
- // TODO: Better place to put all the code below...may be addTask...
+ void insertTaskAtTop(TaskRecord task, ActivityRecord starting) {
+ // TODO: Better place to put all the code below...may be addChild...
mTaskHistory.remove(task);
// Now put task at top.
final int position = getAdjustedPositionForTask(task, mTaskHistory.size(), starting);
mTaskHistory.add(position, task);
- updateTaskMovement(task, true);
+ task.updateTaskMovement(true);
positionChildWindowContainerAtTop(task);
}
@@ -3036,7 +3026,7 @@
mTaskHistory.remove(task);
final int position = getAdjustedPositionForTask(task, 0, null);
mTaskHistory.add(position, task);
- updateTaskMovement(task, true);
+ task.updateTaskMovement(true);
positionChildWindowContainerAtBottom(task);
}
@@ -3070,7 +3060,7 @@
if (!startIt) {
if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to task "
+ task, new RuntimeException("here").fillInStackTrace());
- r.setTask(rTask);
+ rTask.positionChildAtTop(r);
ActivityOptions.abort(options);
return;
}
@@ -3097,7 +3087,7 @@
// Slot the activity into the history stack and proceed
if (DEBUG_ADD_REMOVE) Slog.i(TAG, "Adding activity " + r + " to stack to task " + task,
new RuntimeException("here").fillInStackTrace());
- r.setTask(task);
+ task.positionChildAtTop(r);
// The transition animation and starting window are not needed if {@code allowMoveToFront}
// is false, because the activity won't be visible.
@@ -3272,7 +3262,7 @@
// with the same affinity is unlikely to be in the same stack.
final TaskRecord targetTask;
final ActivityRecord bottom =
- !mTaskHistory.isEmpty() && !mTaskHistory.get(0).mActivities.isEmpty() ?
+ !mTaskHistory.isEmpty() && mTaskHistory.get(0).hasChild() ?
mTaskHistory.get(0).getChildAt(0) : null;
if (bottom != null && target.taskAffinity.equals(bottom.getTaskRecord().affinity)) {
// If the activity currently at the bottom has the
@@ -3483,7 +3473,7 @@
// instance of the same activity? Then we drop the instance
// below so it remains singleTop.
if (target.info.launchMode == ActivityInfo.LAUNCH_SINGLE_TOP) {
- final ArrayList<ActivityRecord> taskActivities = task.mActivities;
+ final ArrayList<ActivityRecord> taskActivities = task.mChildren;
final int targetNdx = taskActivities.indexOf(target);
if (targetNdx > 0) {
final ActivityRecord p = taskActivities.get(targetNdx - 1);
@@ -3637,7 +3627,7 @@
finishedTask = r.getTaskRecord();
int taskNdx = mTaskHistory.indexOf(finishedTask);
final TaskRecord task = finishedTask;
- int activityNdx = task.mActivities.indexOf(r);
+ int activityNdx = task.mChildren.indexOf(r);
getDisplay().mDisplayContent.prepareAppTransition(
TRANSIT_CRASHING_ACTIVITY_CLOSE, false /* alwaysKeepCurrent */);
r.finishIfPossible(reason, false /* oomAdj */);
@@ -3774,7 +3764,7 @@
final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode,
Intent resultData) {
final TaskRecord task = srec.getTaskRecord();
- final ArrayList<ActivityRecord> activities = task.mActivities;
+ final ArrayList<ActivityRecord> activities = task.mChildren;
final int start = activities.indexOf(srec);
if (!mTaskHistory.contains(task) || (start < 0)) {
return false;
@@ -3868,8 +3858,16 @@
* an activity moves away from the stack.
*/
void onActivityRemovedFromStack(ActivityRecord r) {
+ removeActivityFromLRUList(r);
removeTimeoutsForActivity(r);
+ // TODO(stack-unify): null check will no longer be needed.
+ if (mTaskStack != null) {
+ mTaskStack.mExitingActivities.remove(r);
+ }
+ // TODO(stack-unify): Remove if no bugs showed up...
+ //r.mIsExiting = false;
+
if (mResumedActivity != null && mResumedActivity == r) {
setResumedActivity(null, "onActivityRemovedFromStack");
}
@@ -4062,7 +4060,7 @@
if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
"Removing app " + app + " from history with " + i + " entries");
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
- final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+ final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mChildren;
mTmpActivities.clear();
mTmpActivities.addAll(activities);
@@ -4151,19 +4149,6 @@
getDisplay().mDisplayContent.prepareAppTransition(transit, false);
}
- private void updateTaskMovement(TaskRecord task, boolean toFront) {
- if (task.isPersistable) {
- task.mLastTimeMoved = System.currentTimeMillis();
- // Sign is used to keep tasks sorted when persisted. Tasks sent to the bottom most
- // recently will be most negative, tasks sent to the bottom before that will be less
- // negative. Similarly for recent tasks moved to the top which will be most positive.
- if (!toFront) {
- task.mLastTimeMoved *= -1;
- }
- }
- mRootActivityContainer.invalidateTaskLayers();
- }
-
final void moveTaskToFrontLocked(TaskRecord tr, boolean noAnimation, ActivityOptions options,
AppTimeTracker timeTracker, String reason) {
if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "moveTaskToFront: " + tr);
@@ -4296,7 +4281,7 @@
mTaskHistory.remove(tr);
mTaskHistory.add(0, tr);
- updateTaskMovement(tr, false);
+ tr.updateTaskMovement(false);
getDisplay().mDisplayContent.prepareAppTransition(TRANSIT_TASK_TO_BACK, false);
moveToBack("moveTaskToBackLocked", tr);
@@ -4335,7 +4320,7 @@
for (int taskIndex = mTaskHistory.indexOf(startTask); taskIndex >= 0; --taskIndex) {
final TaskRecord task = mTaskHistory.get(taskIndex);
- final ArrayList<ActivityRecord> activities = task.mActivities;
+ final ArrayList<ActivityRecord> activities = task.mChildren;
int activityIndex = (start.getTaskRecord() == task)
? activities.indexOf(start) : activities.size() - 1;
for (; activityIndex >= 0; --activityIndex) {
@@ -4375,10 +4360,10 @@
final TaskRecord task = mTaskHistory.get(i);
if (task.isResizeable()) {
if (tempTaskInsetBounds != null && !tempTaskInsetBounds.isEmpty()) {
- task.setDisplayedBounds(taskBounds);
+ task.setOverrideDisplayedBounds(taskBounds);
task.setBounds(tempTaskInsetBounds);
} else {
- task.setDisplayedBounds(null);
+ task.setOverrideDisplayedBounds(null);
task.setBounds(taskBounds);
}
}
@@ -4430,9 +4415,9 @@
for (int i = mTaskHistory.size() - 1; i >= 0; i--) {
final TaskRecord task = mTaskHistory.get(i);
if (bounds == null || bounds.isEmpty()) {
- task.setDisplayedBounds(null);
+ task.setOverrideDisplayedBounds(null);
} else if (task.isResizeable()) {
- task.setDisplayedBounds(bounds);
+ task.setOverrideDisplayedBounds(bounds);
}
}
}
@@ -4477,7 +4462,7 @@
TaskRecord lastTask = null;
ComponentName homeActivity = null;
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
- final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
+ final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mChildren;
mTmpActivities.clear();
mTmpActivities.addAll(activities);
@@ -4675,7 +4660,7 @@
pw.println(prefix + "mLastNonFullscreenBounds=" + task.mLastNonFullscreenBounds);
pw.println(prefix + "* " + task);
task.dump(pw, prefix + " ");
- dumpHistoryList(fd, pw, mTaskHistory.get(taskNdx).mActivities,
+ dumpHistoryList(fd, pw, mTaskHistory.get(taskNdx).mChildren,
prefix, "Hist", true, !dumpAll, dumpClient, dumpPackage, false, null, task);
}
return true;
@@ -4686,15 +4671,15 @@
if ("all".equals(name)) {
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
- activities.addAll(mTaskHistory.get(taskNdx).mActivities);
+ activities.addAll(mTaskHistory.get(taskNdx).mChildren);
}
} else if ("top".equals(name)) {
final int top = mTaskHistory.size() - 1;
if (top >= 0) {
- final ArrayList<ActivityRecord> list = mTaskHistory.get(top).mActivities;
- int listTop = list.size() - 1;
+ final TaskRecord task = mTaskHistory.get(top);
+ int listTop = task.getChildCount() - 1;
if (listTop >= 0) {
- activities.add(list.get(listTop));
+ activities.add(task.getChildAt(listTop));
}
}
} else {
@@ -4702,7 +4687,9 @@
matcher.build(name);
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
- for (ActivityRecord r1 : mTaskHistory.get(taskNdx).mActivities) {
+ final TaskRecord task = mTaskHistory.get(taskNdx);
+ for (int activityNdx = task.getChildCount() - 1; activityNdx >= 0; --activityNdx) {
+ final ActivityRecord r1 = task.getChildAt(activityNdx);
if (matcher.match(r1, r1.intent.getComponent())) {
activities.add(r1);
}
@@ -4734,57 +4721,50 @@
return starting;
}
+ // TODO(stack-unify): Merge into removeChild method below.
+ void onChildRemoved(TaskRecord child, DisplayContent dc) {
+ mTaskHistory.remove(child);
+ EventLog.writeEvent(EventLogTags.AM_REMOVE_TASK, child.mTaskId, mStackId);
+
+ ActivityDisplay display = getDisplay();
+ if (display == null && dc != null) {
+ display = dc.mActivityDisplay;
+ }
+
+ if (display.isSingleTaskInstance()) {
+ mService.notifySingleTaskDisplayEmpty(display.mDisplayId);
+ }
+
+ display.mDisplayContent.setLayoutNeeded();
+
+ if (mTaskHistory.isEmpty()) {
+ // Stack is now empty...
+ remove();
+ }
+ }
+
/**
* Removes the input task from this stack.
*
* @param task to remove.
* @param reason for removal.
- * @param mode task removal mode. Either {@link #REMOVE_TASK_MODE_DESTROYING},
- * {@link #REMOVE_TASK_MODE_MOVING}, {@link #REMOVE_TASK_MODE_MOVING_TO_TOP}.
*/
- void removeTask(TaskRecord task, String reason, int mode) {
- if (!mTaskHistory.remove(task)) {
- // Not really in this stack anymore...
- return;
- }
-
- EventLog.writeEvent(EventLogTags.AM_REMOVE_TASK, task.mTaskId, getStackId());
-
- removeActivitiesFromLRUList(task);
- updateTaskMovement(task, true);
-
- if (mode == REMOVE_TASK_MODE_DESTROYING) {
- task.cleanUpResourcesForDestroy();
- }
-
+ void removeChild(TaskRecord task, String reason) {
final ActivityDisplay display = getDisplay();
- if (mTaskHistory.isEmpty()) {
- if (DEBUG_STACK) Slog.i(TAG_STACK, "removeTask: removing stack=" + this);
+ final boolean topFocused = mRootActivityContainer.isTopDisplayFocusedStack(this);
+ mTaskStack.removeChild(task);
+ moveHomeStackToFrontIfNeeded(topFocused, display, reason);
+ }
+
+ void moveHomeStackToFrontIfNeeded(
+ boolean wasTopFocusedStack, ActivityDisplay display, String reason) {
+ if (mTaskHistory.isEmpty() && wasTopFocusedStack) {
// We only need to adjust focused stack if this stack is in focus and we are not in the
// process of moving the task to the top of the stack that will be focused.
- if (mode != REMOVE_TASK_MODE_MOVING_TO_TOP
- && mRootActivityContainer.isTopDisplayFocusedStack(this)) {
- String myReason = reason + " leftTaskHistoryEmpty";
- if (!inMultiWindowMode() || adjustFocusToNextFocusableStack(myReason) == null) {
- display.moveHomeStackToFront(myReason);
- }
+ String myReason = reason + " leftTaskHistoryEmpty";
+ if (!inMultiWindowMode() || adjustFocusToNextFocusableStack(myReason) == null) {
+ display.moveHomeStackToFront(myReason);
}
- if (isAttached()) {
- display.positionChildAtBottom(this);
- }
- if (!isActivityTypeHome() || !isAttached()) {
- remove();
- }
- }
-
- task.setStack(null);
-
- // Notify if a task from the pinned stack is being removed (or moved depending on the mode)
- if (inPinnedWindowingMode()) {
- mService.getTaskChangeNotificationController().notifyActivityUnpinned();
- }
- if (display != null && display.isSingleTaskInstance()) {
- mService.notifySingleTaskDisplayEmpty(display.mDisplayId);
}
}
@@ -4800,9 +4780,9 @@
boolean toTop, ActivityRecord activity, ActivityRecord source,
ActivityOptions options) {
final TaskRecord task = TaskRecord.create(
- mService, taskId, info, intent, voiceSession, voiceInteractor);
+ mService, taskId, info, intent, voiceSession, voiceInteractor, this);
// add the task to stack first, mTaskPositioner might need the stack association
- addTask(task, toTop, "createTaskRecord");
+ addChild(task, toTop, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
final int displayId = mDisplayId != INVALID_DISPLAY ? mDisplayId : DEFAULT_DISPLAY;
final boolean isLockscreenShown = mService.mStackSupervisor.getKeyguardController()
.isKeyguardOrAodShowing(displayId);
@@ -4811,7 +4791,6 @@
&& !matchParentBounds() && task.isResizeable() && !isLockscreenShown) {
task.setBounds(getRequestedOverrideBounds());
}
- task.createTask(toTop, (info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
return task;
}
@@ -4819,34 +4798,31 @@
return new ArrayList<>(mTaskHistory);
}
- void addTask(final TaskRecord task, final boolean toTop, String reason) {
- addTask(task, toTop ? MAX_VALUE : 0, true /* schedulePictureInPictureModeChange */, reason);
- if (toTop) {
- // TODO: figure-out a way to remove this call.
- positionChildWindowContainerAtTop(task);
- }
+ // TODO(stack-unify): Merge with addChild below.
+ void onChildAdded(TaskRecord task, int position) {
+ final boolean toTop = position >= mTaskHistory.size();
+ mTaskHistory.add(position, task);
+
+ // TODO: Feels like this should go in TaskRecord#onParentChanged
+ task.updateTaskMovement(toTop);
}
- // TODO: This shouldn't allow automatic reparenting. Remove the call to preAddTask and deal
- // with the fall-out...
- void addTask(final TaskRecord task, int position, boolean schedulePictureInPictureModeChange,
- String reason) {
- // TODO: Is this remove really needed? Need to look into the call path for the other addTask
- mTaskHistory.remove(task);
+ void addChild(final TaskRecord task, final boolean toTop, boolean showForAllUsers) {
if (isSingleTaskInstance() && !mTaskHistory.isEmpty()) {
throw new IllegalStateException("Can only have one child on stack=" + this);
}
- position = getAdjustedPositionForTask(task, position, null /* starting */);
- final boolean toTop = position >= mTaskHistory.size();
- final ActivityStack prevStack = preAddTask(task, reason, toTop);
+ final int position =
+ getAdjustedPositionForTask(task, toTop ? MAX_VALUE : 0, null /* starting */);
- mTaskHistory.add(position, task);
- task.setStack(this);
+ // We only want to move the parents to the parents if we are creating this task at the
+ // top of its stack.
+ mTaskStack.addChild(task, position, showForAllUsers, toTop /*moveParents*/);
- updateTaskMovement(task, toTop);
-
- postAddTask(task, prevStack, schedulePictureInPictureModeChange);
+ if (toTop) {
+ // TODO: figure-out a way to remove this call.
+ positionChildWindowContainerAtTop(task);
+ }
}
void positionChildAt(TaskRecord task, int index) {
@@ -4861,8 +4837,14 @@
final ActivityRecord topRunningActivity = task.topRunningActivityLocked();
final boolean wasResumed = topRunningActivity == task.getStack().mResumedActivity;
insertTaskAtPosition(task, index);
- task.setStack(this);
- postAddTask(task, null /* prevStack */, true /* schedulePictureInPictureModeChange */);
+
+ // TODO: Investigate if this random code is really needed.
+ if (task.voiceSession != null) {
+ try {
+ task.voiceSession.taskStarted(task.intent, task.mTaskId);
+ } catch (RemoteException e) {
+ }
+ }
if (wasResumed) {
if (mResumedActivity != null) {
@@ -4879,32 +4861,6 @@
mRootActivityContainer.resumeFocusedStacksTopActivities();
}
- private ActivityStack preAddTask(TaskRecord task, String reason, boolean toTop) {
- final ActivityStack prevStack = task.getStack();
- if (prevStack != null && prevStack != this) {
- prevStack.removeTask(task, reason,
- toTop ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
- }
- return prevStack;
- }
-
- /**
- * @param schedulePictureInPictureModeChange specifies whether or not to schedule the PiP mode
- * change. Callers may set this to false if they are explicitly scheduling PiP mode
- * changes themselves, like during the PiP animation
- */
- private void postAddTask(TaskRecord task, ActivityStack prevStack,
- boolean schedulePictureInPictureModeChange) {
- if (schedulePictureInPictureModeChange && prevStack != null) {
- mStackSupervisor.scheduleUpdatePictureInPictureModeIfNeeded(task, prevStack);
- } else if (task.voiceSession != null) {
- try {
- task.voiceSession.taskStarted(task.intent, task.mTaskId);
- } catch (RemoteException e) {
- }
- }
- }
-
public void setAlwaysOnTop(boolean alwaysOnTop) {
if (isAlwaysOnTop() == alwaysOnTop) {
return;
diff --git a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
index dc3d263..f8a7397 100644
--- a/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/wm/ActivityStackSupervisor.java
@@ -52,7 +52,6 @@
import static com.android.server.wm.ActivityStack.ActivityState.PAUSED;
import static com.android.server.wm.ActivityStack.ActivityState.PAUSING;
-import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_ALL;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_IDLE;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_PAUSE;
@@ -83,6 +82,7 @@
import static com.android.server.wm.TaskRecord.REPARENT_LEAVE_STACK_IN_PLACE;
import static com.android.server.wm.TaskRecord.REPARENT_MOVE_STACK_TO_FRONT;
import static com.android.server.wm.WindowContainer.AnimationFlags.TRANSITION;
+import static com.android.server.wm.WindowContainer.POSITION_TOP;
import android.Manifest;
import android.app.Activity;
@@ -1420,7 +1420,7 @@
// WM resizeTask must be done after the task is moved to the correct stack,
// because Task's setBounds() also updates dim layer's bounds, but that has
// dependency on the stack.
- task.resizeWindowContainer();
+ task.resize(false /* relayout */, false /* forced */);
}
}
@@ -1885,26 +1885,22 @@
final ActivityStack stack =
mRootActivityContainer.getLaunchStack(null, aOptions, task, onTop);
final ActivityStack currentStack = task.getStack();
- if (currentStack != null) {
- // Task has already been restored once. See if we need to do anything more
- if (currentStack == stack) {
- // Nothing else to do since it is already restored in the right stack.
- return true;
- }
- // Remove current stack association, so we can re-associate the task with the
- // right stack below.
- currentStack.removeTask(task, "restoreRecentTaskLocked", REMOVE_TASK_MODE_MOVING);
+
+ if (currentStack == stack) {
+ // Nothing else to do since it is already restored in the right stack.
+ return true;
}
- stack.addTask(task, onTop, "restoreRecentTask");
- // TODO: move call for creation here and other place into Stack.addTask()
- task.createTask(onTop, true /* showForAllUsers */);
+ if (currentStack != null) {
+ // Task has already been restored once. Just re-parent it to the new stack.
+ task.reparent(stack.mTaskStack,
+ POSITION_TOP, true /*moveParents*/, "restoreRecentTaskLocked");
+ return true;
+ }
+
+ stack.addChild(task, onTop, true /* showForAllUsers */);
if (DEBUG_RECENTS) Slog.v(TAG_RECENTS,
"Added restored task=" + task + " to stack=" + stack);
- for (int activityNdx = task.getChildCount() - 1; activityNdx >= 0; --activityNdx) {
- final ActivityRecord r = task.getChildAt(activityNdx);
- r.setTask(task);
- }
return true;
}
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index d1bb255..6edcb02 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -50,6 +50,7 @@
import static android.content.Intent.FLAG_ACTIVITY_SINGLE_TOP;
import static android.content.Intent.FLAG_ACTIVITY_TASK_ON_HOME;
import static android.content.pm.ActivityInfo.DOCUMENT_LAUNCH_ALWAYS;
+import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
import static android.content.pm.ActivityInfo.LAUNCH_MULTIPLE;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_INSTANCE;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TASK;
@@ -1842,7 +1843,7 @@
// {@code ActivityRecord} removing its reference to the {@code TaskRecord}. The task
// reference is needed in the call below to {@link setTargetStackAndMoveToFrontIfNeeded}
if (targetTaskTop.getTaskRecord() == null) {
- targetTaskTop.setTask(targetTask);
+ targetTask.addChild(targetTaskTop);
}
if (top != null) {
@@ -1862,8 +1863,8 @@
// Go ahead and reset it.
mTargetStack = computeStackFocus(mSourceRecord, false /* newTask */,
mLaunchFlags, mOptions);
- mTargetStack.addTask(targetTask,
- !mLaunchTaskBehind /* toTop */, "complyActivityFlags");
+ mTargetStack.addChild(targetTask, !mLaunchTaskBehind /* toTop */,
+ (mStartActivity.info.flags & FLAG_SHOW_FOR_ALL_USERS) != 0);
}
}
} else if ((mLaunchFlags & FLAG_ACTIVITY_CLEAR_TOP) == 0 && !mAddingToTask
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 222f26e..da7af5f 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -85,7 +85,6 @@
import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE;
import static com.android.server.wm.ActivityStack.ActivityState.DESTROYED;
import static com.android.server.wm.ActivityStack.ActivityState.DESTROYING;
-import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
import static com.android.server.wm.ActivityStackSupervisor.DEFER_RESUME;
import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
@@ -1996,7 +1995,7 @@
return false;
}
final TaskRecord task = r.getTaskRecord();
- int index = task.mActivities.lastIndexOf(r);
+ int index = task.mChildren.lastIndexOf(r);
if (index > 0) {
ActivityRecord under = task.getChildAt(index - 1);
under.returningOptions = safeOptions != null ? safeOptions.getOptions(r) : null;
@@ -2221,18 +2220,10 @@
Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
return rect;
}
- if (task.getStack() != null) {
- // Return the bounds from window manager since it will be adjusted for various
- // things like the presense of a docked stack for tasks that aren't resizeable.
- task.getWindowContainerBounds(rect);
- } else {
- // Task isn't in window manager yet since it isn't associated with a stack.
- // Return the persist value from activity manager
- if (!task.matchParentBounds()) {
- rect.set(task.getBounds());
- } else if (task.mLastNonFullscreenBounds != null) {
- rect.set(task.mLastNonFullscreenBounds);
- }
+ if (task.getParent() != null) {
+ rect.set(task.getBounds());
+ } else if (task.mLastNonFullscreenBounds != null) {
+ rect.set(task.mLastNonFullscreenBounds);
}
}
} finally {
@@ -2249,7 +2240,7 @@
final TaskRecord tr = mRootActivityContainer.anyTaskForId(id,
MATCH_TASK_IN_STACKS_OR_RECENT_TASKS);
if (tr != null) {
- return tr.mTaskDescription;
+ return tr.getTaskDescription();
}
}
return null;
@@ -3168,10 +3159,10 @@
null /* voiceSession */, null /* voiceInteractor */, !ON_TOP);
if (!mRecentTasks.addToBottom(task)) {
// The app has too many tasks already and we can't add any more
- stack.removeTask(task, "addAppTask", REMOVE_TASK_MODE_DESTROYING);
+ stack.removeChild(task, "addAppTask");
return INVALID_TASK_ID;
}
- task.mTaskDescription.copyFrom(description);
+ task.getTaskDescription().copyFrom(description);
// TODO: Send the thumbnail to WM to store it.
@@ -4489,7 +4480,7 @@
Slog.w(TAG, "cancelTaskWindowTransition: taskId=" + taskId + " not found");
return;
}
- task.cancelWindowTransition();
+ task.cancelTaskWindowTransition();
}
} finally {
Binder.restoreCallingIdentity(ident);
diff --git a/services/core/java/com/android/server/wm/ConfigurationContainer.java b/services/core/java/com/android/server/wm/ConfigurationContainer.java
index 8b4f7cc..30f3bc5 100644
--- a/services/core/java/com/android/server/wm/ConfigurationContainer.java
+++ b/services/core/java/com/android/server/wm/ConfigurationContainer.java
@@ -134,9 +134,9 @@
onConfigurationChanged(newParentConfig, true /*forwardToChildren*/);
}
- // TODO: Consolidate with onConfigurationChanged() method above once unification is done. This
- // is only currently need during the process of unification where we don't want configuration
- // forwarded to a child from both parents.
+ // TODO(root-unify): Consolidate with onConfigurationChanged() method above once unification is
+ // done. This is only currently need during the process of unification where we don't want
+ // configuration forwarded to a child from both parents.
public void onConfigurationChanged(Configuration newParentConfig, boolean forwardToChildren) {
mResolvedTmpConfig.setTo(mResolvedOverrideConfiguration);
resolveOverrideConfiguration(newParentConfig);
diff --git a/services/core/java/com/android/server/wm/RecentsAnimation.java b/services/core/java/com/android/server/wm/RecentsAnimation.java
index 2dae126..01cbc5d 100644
--- a/services/core/java/com/android/server/wm/RecentsAnimation.java
+++ b/services/core/java/com/android/server/wm/RecentsAnimation.java
@@ -211,9 +211,9 @@
// If there are multiple tasks in the target stack (ie. the home stack, with 3p
// and default launchers coexisting), then move the task to the top as a part of
// moving the stack to the front
- if (targetStack.topTask() != targetActivity.getTaskRecord()) {
- targetStack.addTask(targetActivity.getTaskRecord(), true /* toTop */,
- "startRecentsActivity");
+ final TaskRecord task = targetActivity.getTaskRecord();
+ if (targetStack.topTask() != task) {
+ targetStack.insertTaskAtTop(task, targetActivity);
}
} else {
// No recents activity, create the new recents activity bottom most
diff --git a/services/core/java/com/android/server/wm/RootActivityContainer.java b/services/core/java/com/android/server/wm/RootActivityContainer.java
index 51a3e720..dc78922 100644
--- a/services/core/java/com/android/server/wm/RootActivityContainer.java
+++ b/services/core/java/com/android/server/wm/RootActivityContainer.java
@@ -1265,8 +1265,7 @@
: task.realActivity != null ? task.realActivity.flattenToString()
: task.getTopActivity() != null ? task.getTopActivity().packageName
: "unknown";
- taskBounds[i] = new Rect();
- task.getWindowContainerBounds(taskBounds[i]);
+ taskBounds[i] = mService.getTaskBounds(task.mTaskId);
taskUserIds[i] = task.mUserId;
}
info.taskIds = taskIds;
@@ -1876,7 +1875,12 @@
ActivityStack getNextFocusableStack(@NonNull ActivityStack currentFocus,
boolean ignoreCurrent) {
// First look for next focusable stack on the same display
- final ActivityDisplay preferredDisplay = currentFocus.getDisplay();
+ ActivityDisplay preferredDisplay = currentFocus.getDisplay();
+ if (preferredDisplay == null) {
+ // Stack is currently detached because it is being removed. Use the previous display it
+ // was on.
+ preferredDisplay = getActivityDisplay(currentFocus.mPrevDisplayId);
+ }
final ActivityStack preferredFocusableStack = preferredDisplay.getNextFocusableStack(
currentFocus, ignoreCurrent);
if (preferredFocusableStack != null) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index f5d3aff..149bcfb 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -206,7 +206,7 @@
}
@Override
- void onChildPositionChanged() {
+ void onChildPositionChanged(WindowContainer child) {
mWmService.updateFocusedWindowLocked(UPDATE_FOCUS_NORMAL,
!mWmService.mPerDisplayFocusEnabled /* updateInputWindows */);
}
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 634990b..dce15bc 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static android.app.ActivityTaskManager.INVALID_STACK_ID;
import static android.app.ActivityTaskManager.RESIZE_MODE_SYSTEM_SCREEN_ROTATION;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
@@ -24,6 +25,7 @@
import static android.content.res.Configuration.EMPTY;
import static android.view.SurfaceControl.METADATA_TASK_ID;
+import static com.android.server.EventLogTags.WM_TASK_CREATED;
import static com.android.server.EventLogTags.WM_TASK_REMOVED;
import static com.android.server.wm.DragResizeMode.DRAG_RESIZE_MODE_DOCKED_DIVIDER;
import static com.android.server.wm.TaskProto.APP_WINDOW_TOKENS;
@@ -63,17 +65,21 @@
class Task extends WindowContainer<ActivityRecord> implements ConfigurationContainerListener{
static final String TAG = TAG_WITH_CLASS_NAME ? "Task" : TAG_WM;
+ final ActivityTaskManagerService mAtmService;
+
// TODO: Track parent marks like this in WindowContainer.
TaskStack mStack;
/* Unique identifier for this task. */
final int mTaskId;
/* User for which this task was created. */
- final int mUserId;
+ // TODO: Make final
+ int mUserId;
final Rect mPreparedFrozenBounds = new Rect();
final Configuration mPreparedFrozenMergedConfig = new Configuration();
// If non-empty, bounds used to display the task during animations/interactions.
+ // TODO(b/119687367): This member is temporary.
private final Rect mOverrideDisplayedBounds = new Rect();
/** ID of the display which rotation {@link #mRotation} has. */
@@ -90,11 +96,12 @@
private Rect mTmpRect2 = new Rect();
// Resize mode of the task. See {@link ActivityInfo#resizeMode}
- private int mResizeMode;
+ // Based on the {@link ActivityInfo#resizeMode} of the root activity.
+ int mResizeMode;
- // Whether the task supports picture-in-picture.
- // See {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE}
- private boolean mSupportsPictureInPicture;
+ // Whether or not this task and its activities support PiP. Based on the
+ // {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag of the root activity.
+ boolean mSupportsPictureInPicture;
// Whether the task is currently being drag-resized
private boolean mDragResizing;
@@ -116,40 +123,23 @@
/** @see #setCanAffectSystemUiFlags */
private boolean mCanAffectSystemUiFlags = true;
- // TODO: remove after unification
- TaskRecord mTaskRecord;
-
- // TODO: Remove after unification.
- @Override
- public void onConfigurationChanged(Configuration newParentConfig, boolean forwardToChildren) {
- // Forward configuration changes in cases
- // - children won't get it from TaskRecord
- // - it's a pinned task
- forwardToChildren &= (mTaskRecord == null) || inPinnedWindowingMode();
- super.onConfigurationChanged(newParentConfig, forwardToChildren);
- }
-
- Task(int taskId, TaskStack stack, int userId, WindowManagerService service, int resizeMode,
- boolean supportsPictureInPicture, TaskDescription taskDescription,
- TaskRecord taskRecord) {
- super(service);
+ Task(int taskId, TaskStack stack, int userId, int resizeMode, boolean supportsPictureInPicture,
+ TaskDescription taskDescription, ActivityTaskManagerService atm) {
+ super(atm.mWindowManager);
+ mAtmService = atm;
mTaskId = taskId;
mStack = stack;
mUserId = userId;
mResizeMode = resizeMode;
mSupportsPictureInPicture = supportsPictureInPicture;
- mTaskRecord = taskRecord;
mTaskDescription = taskDescription;
+ EventLog.writeEvent(WM_TASK_CREATED, mTaskId,
+ stack != null ? stack.mStackId : INVALID_STACK_ID);
// Tasks have no set orientation value (including SCREEN_ORIENTATION_UNSPECIFIED).
setOrientation(SCREEN_ORIENTATION_UNSET);
- if (mTaskRecord != null) {
- // This can be null when we call createTaskInStack in WindowTestUtils. Remove this after
- // unification.
- mTaskRecord.registerConfigurationChangeListener(this);
- } else {
- setBounds(getResolvedOverrideBounds());
- }
+ // TODO(task-merge): Is this really needed?
+ setBounds(getResolvedOverrideBounds());
}
@Override
@@ -157,37 +147,40 @@
return mStack != null ? mStack.getDisplayContent() : null;
}
- private int getAdjustedAddPosition(int suggestedPosition) {
- final int size = mChildren.size();
- if (suggestedPosition >= size) {
- return Math.min(size, suggestedPosition);
+ int getAdjustedAddPosition(ActivityRecord r, int suggestedPosition) {
+ int maxPosition = mChildren.size();
+ if (!r.mTaskOverlay) {
+ // We want to place all non-overlay activities below overlays.
+ while (maxPosition > 0) {
+ final ActivityRecord current = mChildren.get(maxPosition - 1);
+ if (current.mTaskOverlay && !current.removed) {
+ --maxPosition;
+ continue;
+ }
+ break;
+ }
+ if (maxPosition < 0) {
+ maxPosition = 0;
+ }
}
- for (int pos = 0; pos < size && pos < suggestedPosition; ++pos) {
+ if (suggestedPosition >= maxPosition) {
+ return Math.min(maxPosition, suggestedPosition);
+ }
+
+ for (int pos = 0; pos < maxPosition && pos < suggestedPosition; ++pos) {
// TODO: Confirm that this is the behavior we want long term.
if (mChildren.get(pos).removed) {
// suggestedPosition assumes removed tokens are actually gone.
++suggestedPosition;
}
}
- return Math.min(size, suggestedPosition);
- }
-
- @Override
- void addChild(ActivityRecord child, int position) {
- position = getAdjustedAddPosition(position);
- super.addChild(child, position);
-
- // Inform the TaskRecord side of the child addition
- // TODO(task-unify): Will be removed after task unification.
- if (mTaskRecord != null) {
- mTaskRecord.onChildAdded(child, position);
- }
+ return Math.min(maxPosition, suggestedPosition);
}
@Override
void positionChildAt(int position, ActivityRecord child, boolean includingParents) {
- position = getAdjustedAddPosition(position);
+ position = getAdjustedAddPosition(child, position);
super.positionChildAt(position, child, includingParents);
}
@@ -222,47 +215,34 @@
void removeImmediately() {
if (DEBUG_STACK) Slog.i(TAG, "removeTask: removing taskId=" + mTaskId);
EventLog.writeEvent(WM_TASK_REMOVED, mTaskId, "removeTask");
- if (mTaskRecord != null) {
- mTaskRecord.unregisterConfigurationChangeListener(this);
- }
-
super.removeImmediately();
}
- void reparent(TaskStack stack, int position, boolean moveParents) {
- if (stack == mStack) {
- throw new IllegalArgumentException(
- "task=" + this + " already child of stack=" + mStack);
- }
- if (stack == null) {
- throw new IllegalArgumentException("reparent: could not find stack.");
- }
+ // TODO: Consolidate this with TaskRecord.reparent()
+ void reparent(TaskStack stack, int position, boolean moveParents, String reason) {
if (DEBUG_STACK) Slog.i(TAG, "reParentTask: removing taskId=" + mTaskId
+ " from stack=" + mStack);
EventLog.writeEvent(WM_TASK_REMOVED, mTaskId, "reParentTask");
- final DisplayContent prevDisplayContent = getDisplayContent();
- // If we are moving from the fullscreen stack to the pinned stack
- // then we want to preserve our insets so that there will not
- // be a jump in the area covered by system decorations. We rely
- // on the pinned animation to later unset this value.
- if (stack.inPinnedWindowingMode()) {
- mPreserveNonFloatingState = true;
- } else {
- mPreserveNonFloatingState = false;
+ final ActivityStack prevStack = mStack.mActivityStack;
+ final boolean wasTopFocusedStack =
+ mAtmService.mRootActivityContainer.isTopDisplayFocusedStack(prevStack);
+ final ActivityDisplay prevStackDisplay = prevStack.getDisplay();
+
+ reparent(stack, position);
+
+ if (!moveParents) {
+ // Only move home stack forward if we are not going to move the new parent forward.
+ prevStack.moveHomeStackToFrontIfNeeded(wasTopFocusedStack, prevStackDisplay, reason);
}
- getParent().removeChild(this);
- stack.addTask(this, position, showForAllUsers(), moveParents);
+ mStack = stack;
+ stack.positionChildAt(position, this, moveParents);
- // Relayout display(s).
- final DisplayContent displayContent = stack.getDisplayContent();
- displayContent.setLayoutNeeded();
- if (prevDisplayContent != displayContent) {
- onDisplayChanged(displayContent);
- prevDisplayContent.setLayoutNeeded();
- }
- getDisplayContent().layoutAndAssignWindowLayersIfNeeded();
+ // If we are moving from the fullscreen stack to the pinned stack then we want to preserve
+ // our insets so that there will not be a jump in the area covered by system decorations.
+ // We rely on the pinned animation to later unset this value.
+ mPreserveNonFloatingState = stack.inPinnedWindowingMode();
}
/** @see ActivityTaskManagerService#positionTaskInStack(int, int, int). */
@@ -270,46 +250,6 @@
mStack.positionChildAt(position, this, false /* includingParents */);
}
- @Override
- void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
- super.onParentChanged(newParent, oldParent);
-
- // Update task bounds if needed.
- adjustBoundsForDisplayChangeIfNeeded(getDisplayContent());
-
- if (getWindowConfiguration().windowsAreScaleable()) {
- // We force windows out of SCALING_MODE_FREEZE so that we can continue to animate them
- // while a resize is pending.
- forceWindowsScaleable(true /* force */);
- } else {
- forceWindowsScaleable(false /* force */);
- }
- }
-
- @Override
- void removeChild(ActivityRecord child) {
- if (!mChildren.contains(child)) {
- Slog.e(TAG, "removeChild: token=" + this + " not found.");
- return;
- }
-
- super.removeChild(child);
-
- // Inform the TaskRecord side of the child removal
- // TODO(task-unify): Will be removed after task unification.
- if (mTaskRecord != null) {
- mTaskRecord.onChildRemoved(child);
- }
-
- // TODO(task-unify): Need to make this account for what we are doing in
- // ActivityRecord.removeFromHistory so that the task isn't removed in some situations when
- // we unify task level.
- if (mChildren.isEmpty()) {
- EventLog.writeEvent(WM_TASK_REMOVED, mTaskId, "removeActivity: last activity");
- removeIfPossible();
- }
- }
-
void setSendingToBottom(boolean toBottom) {
for (int appTokenNdx = 0; appTokenNdx < mChildren.size(); appTokenNdx++) {
mChildren.get(appTokenNdx).sendingToBottom = toBottom;
@@ -331,7 +271,7 @@
@Override
public int setBounds(Rect bounds) {
int rotation = Surface.ROTATION_0;
- final DisplayContent displayContent = mStack.getDisplayContent();
+ final DisplayContent displayContent = mStack != null ? mStack.getDisplayContent() : null;
if (displayContent != null) {
rotation = displayContent.getDisplayInfo().rotation;
} else if (bounds == null) {
@@ -355,9 +295,8 @@
// No one in higher hierarchy handles this request, let's adjust our bounds to fulfill
// it if possible.
- // TODO: Move to TaskRecord after unification is done.
- if (mTaskRecord != null && mTaskRecord.getParent() != null) {
- mTaskRecord.onConfigurationChanged(mTaskRecord.getParent().getConfiguration());
+ if (getParent() != null) {
+ onConfigurationChanged(getParent().getConfiguration());
return true;
}
return false;
@@ -379,8 +318,9 @@
}
/**
- * Sets bounds that override where the task is displayed. Used during transient operations
- * like animation / interaction.
+ * Displayed bounds are used to set where the task is drawn at any given time. This is
+ * separate from its actual bounds so that the app doesn't see any meaningful configuration
+ * changes during transitionary periods.
*/
void setOverrideDisplayedBounds(Rect overrideDisplayedBounds) {
if (overrideDisplayedBounds != null) {
@@ -399,13 +339,13 @@
return mOverrideDisplayedBounds;
}
- void setResizeable(int resizeMode) {
- mResizeMode = resizeMode;
+ boolean isResizeable(boolean checkSupportsPip) {
+ return (mAtmService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
+ || (checkSupportsPip && mSupportsPictureInPicture));
}
boolean isResizeable() {
- return ActivityInfo.isResizeableMode(mResizeMode) || mSupportsPictureInPicture
- || mWmService.mAtmService.mForceResizableActivities;
+ return isResizeable(true /* checkSupportsPip */);
}
/**
@@ -462,6 +402,10 @@
}
}
+ /**
+ * Gets the current overridden displayed bounds. These will be empty if the task is not
+ * currently overriding where it is displayed.
+ */
@Override
public Rect getDisplayedBounds() {
if (mOverrideDisplayedBounds.isEmpty()) {
@@ -577,7 +521,7 @@
setDragResizing(resizing, DRAG_RESIZE_MODE_DOCKED_DIVIDER);
}
- private void adjustBoundsForDisplayChangeIfNeeded(final DisplayContent displayContent) {
+ void adjustBoundsForDisplayChangeIfNeeded(final DisplayContent displayContent) {
if (displayContent == null) {
return;
}
@@ -618,9 +562,7 @@
displayContent.rotateBounds(mRotation, newRotation, mTmpRect2);
if (setBounds(mTmpRect2) != BOUNDS_CHANGE_NONE) {
- if (mTaskRecord != null) {
- mTaskRecord.requestResize(getBounds(), RESIZE_MODE_SYSTEM_SCREEN_ROTATION);
- }
+ mAtmService.resizeTask(mTaskId, getBounds(), RESIZE_MODE_SYSTEM_SCREEN_ROTATION);
}
}
@@ -758,7 +700,8 @@
}
void onSnapshotChanged(ActivityManager.TaskSnapshot snapshot) {
- mTaskRecord.onSnapshotChanged(snapshot);
+ mAtmService.getTaskChangeNotificationController().notifyTaskSnapshotChanged(
+ mTaskId, snapshot);
}
TaskDescription getTaskDescription() {
@@ -794,11 +737,6 @@
mDimmer.dontAnimateExit();
}
- @Override
- public String toString() {
- return "{taskId=" + mTaskId + " appTokens=" + mChildren + "}";
- }
-
String getName() {
return toShortString();
}
@@ -825,9 +763,8 @@
}
}
- @CallSuper
- @Override
- public void writeToProto(ProtoOutputStream proto, long fieldId,
+ // TODO(proto-merge): Remove once protos for TaskRecord and Task are merged.
+ void writeToProtoInnerTaskOnly(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
return;
@@ -843,8 +780,10 @@
proto.write(FILLS_PARENT, matchParentBounds());
getBounds().writeToProto(proto, BOUNDS);
mOverrideDisplayedBounds.writeToProto(proto, DISPLAYED_BOUNDS);
- proto.write(SURFACE_WIDTH, mSurfaceControl.getWidth());
- proto.write(SURFACE_HEIGHT, mSurfaceControl.getHeight());
+ if (mSurfaceControl != null) {
+ proto.write(SURFACE_WIDTH, mSurfaceControl.getWidth());
+ proto.write(SURFACE_HEIGHT, mSurfaceControl.getHeight());
+ }
proto.end(token);
}
diff --git a/services/core/java/com/android/server/wm/TaskRecord.java b/services/core/java/com/android/server/wm/TaskRecord.java
index 6920d9d..672827f 100644
--- a/services/core/java/com/android/server/wm/TaskRecord.java
+++ b/services/core/java/com/android/server/wm/TaskRecord.java
@@ -52,11 +52,10 @@
import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
import static android.view.Display.DEFAULT_DISPLAY;
-import static com.android.server.EventLogTags.WM_TASK_CREATED;
+import static com.android.server.EventLogTags.WM_TASK_REMOVED;
import static com.android.server.am.TaskRecordProto.ACTIVITIES;
import static com.android.server.am.TaskRecordProto.ACTIVITY_TYPE;
import static com.android.server.am.TaskRecordProto.BOUNDS;
-import static com.android.server.am.TaskRecordProto.CONFIGURATION_CONTAINER;
import static com.android.server.am.TaskRecordProto.FULLSCREEN;
import static com.android.server.am.TaskRecordProto.ID;
import static com.android.server.am.TaskRecordProto.LAST_NON_FULLSCREEN_BOUNDS;
@@ -66,11 +65,9 @@
import static com.android.server.am.TaskRecordProto.REAL_ACTIVITY;
import static com.android.server.am.TaskRecordProto.RESIZE_MODE;
import static com.android.server.am.TaskRecordProto.STACK_ID;
+import static com.android.server.am.TaskRecordProto.TASK;
import static com.android.server.wm.ActivityRecord.FINISH_RESULT_REMOVED;
import static com.android.server.wm.ActivityRecord.STARTING_WINDOW_SHOWN;
-import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_DESTROYING;
-import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING;
-import static com.android.server.wm.ActivityStack.REMOVE_TASK_MODE_MOVING_TO_TOP;
import static com.android.server.wm.ActivityStackSupervisor.ON_TOP;
import static com.android.server.wm.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.ActivityStackSupervisor.REMOVE_FROM_RECENTS;
@@ -85,10 +82,6 @@
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_ATM;
import static com.android.server.wm.ActivityTaskManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.wm.ProtoLogGroup.WM_DEBUG_ADD_REMOVE;
-import static com.android.server.wm.WindowContainer.POSITION_BOTTOM;
-import static com.android.server.wm.WindowContainer.POSITION_TOP;
-import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_STACK;
-import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
import static java.lang.Integer.MAX_VALUE;
@@ -143,7 +136,7 @@
import java.util.ArrayList;
import java.util.Objects;
-class TaskRecord extends ConfigurationContainer {
+class TaskRecord extends Task {
private static final String TAG = TAG_WITH_CLASS_NAME ? "TaskRecord" : TAG_ATM;
private static final String TAG_ADD_REMOVE = TAG + POSTFIX_ADD_REMOVE;
private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
@@ -212,7 +205,6 @@
*/
private static TaskRecordFactory sTaskRecordFactory;
- final int mTaskId; // Unique identifier for this task.
String affinity; // The affinity name for this task, or null; may change identity.
String rootAffinity; // Initial base affinity, or null; does not change from initial root.
final IVoiceInteractionSession voiceSession; // Voice interaction session driving task
@@ -238,17 +230,11 @@
boolean hasBeenVisible; // Set if any activities in the task have been visible to the user.
String stringName; // caching of toString() result.
- int mUserId; // user for which this task was created
boolean mUserSetupComplete; // The user set-up is complete as of the last time the task activity
// was changed.
int numFullscreen; // Number of fullscreen activities.
- int mResizeMode; // The resize mode of this task and its activities.
- // Based on the {@link ActivityInfo#resizeMode} of the root activity.
- private boolean mSupportsPictureInPicture; // Whether or not this task and its activities
- // support PiP. Based on the {@link ActivityInfo#FLAG_SUPPORTS_PICTURE_IN_PICTURE} flag
- // of the root activity.
/** Can't be put in lockTask mode. */
final static int LOCK_TASK_AUTH_DONT_LOCK = 0;
/** Can enter app pinning with user approval. Can never start over existing lockTask task. */
@@ -264,13 +250,6 @@
int mLockTaskUid = -1; // The uid of the application that called startLockTask().
- // This represents the last resolved activity values for this task
- // NOTE: This value needs to be persisted with each task
- TaskDescription mTaskDescription;
-
- /** List of all activities in the task arranged in history order */
- final ArrayList<ActivityRecord> mActivities;
-
/** Current stack. Setter must always be used to update the value. */
private ActivityStack mStack;
@@ -308,8 +287,6 @@
int mCallingUid;
String mCallingPackage;
- final ActivityTaskManagerService mAtmService;
-
private final Rect mTmpStableBounds = new Rect();
private final Rect mTmpNonDecorBounds = new Rect();
private final Rect mTmpBounds = new Rect();
@@ -328,17 +305,9 @@
// This number will be assigned when we evaluate OOM scores for all visible tasks.
int mLayerRank = -1;
- // When non-empty, this represents the bounds this task will be drawn at. This gets set during
- // transient operations such as split-divider dragging and animations.
- // TODO(b/119687367): This member is temporary.
- final Rect mDisplayedBounds = new Rect();
-
/** Helper object used for updating override configuration. */
private Configuration mTmpConfig = new Configuration();
- // TODO: remove after unification
- Task mTask;
-
/** Used by fillTaskInfo */
final TaskActivitiesReport mReuseActivitiesReport = new TaskActivitiesReport();
@@ -346,21 +315,21 @@
* Don't use constructor directly. Use {@link #create(ActivityTaskManagerService, int,
* ActivityInfo, Intent, TaskDescription)} instead.
*/
- TaskRecord(ActivityTaskManagerService atmService, int _taskId, ActivityInfo info,
- Intent _intent, IVoiceInteractionSession _voiceSession,
- IVoiceInteractor _voiceInteractor, TaskDescription _taskDescription) {
+ TaskRecord(ActivityTaskManagerService atmService, int _taskId, ActivityInfo info, Intent _intent,
+ IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor,
+ TaskDescription _taskDescription, ActivityStack stack) {
this(atmService, _taskId, _intent, null /*_affinityIntent*/, null /*_affinity*/,
null /*_rootAffinity*/, null /*_realActivity*/, null /*_origActivity*/,
false /*_rootWasReset*/, false /*_autoRemoveRecents*/, false /*_askedCompatMode*/,
UserHandle.getUserId(info.applicationInfo.uid), 0 /*_effectiveUid*/,
- null /*_lastDescription*/, new ArrayList<>(), System.currentTimeMillis(),
+ null /*_lastDescription*/, System.currentTimeMillis(),
true /*neverRelinquishIdentity*/,
_taskDescription != null ? _taskDescription : new TaskDescription(),
_taskId, INVALID_TASK_ID, INVALID_TASK_ID, 0 /*taskAffiliationColor*/,
info.applicationInfo.uid, info.packageName, info.resizeMode,
info.supportsPictureInPicture(), false /*_realActivitySuspended*/,
false /*userSetupComplete*/, INVALID_MIN_SIZE, INVALID_MIN_SIZE, info,
- _voiceSession, _voiceInteractor);
+ _voiceSession, _voiceInteractor, stack);
}
/** Don't use constructor directly. This is only used by XML parser. */
@@ -368,15 +337,16 @@
Intent _affinityIntent, String _affinity, String _rootAffinity,
ComponentName _realActivity, ComponentName _origActivity, boolean _rootWasReset,
boolean _autoRemoveRecents, boolean _askedCompatMode, int _userId,
- int _effectiveUid, String _lastDescription, ArrayList<ActivityRecord> activities,
+ int _effectiveUid, String _lastDescription,
long lastTimeMoved, boolean neverRelinquishIdentity,
TaskDescription _lastTaskDescription, int taskAffiliation, int prevTaskId,
int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
int resizeMode, boolean supportsPictureInPicture, boolean _realActivitySuspended,
boolean userSetupComplete, int minWidth, int minHeight, ActivityInfo info,
- IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor) {
- mAtmService = atmService;
- mTaskId = _taskId;
+ IVoiceInteractionSession _voiceSession, IVoiceInteractor _voiceInteractor,
+ ActivityStack stack) {
+ super(_taskId, stack != null ? stack.mTaskStack : null, _userId, resizeMode,
+ supportsPictureInPicture, _lastTaskDescription, atmService);
mRemoteToken = new RemoteToken(this);
affinityIntent = _affinityIntent;
affinity = _affinity;
@@ -390,15 +360,12 @@
isAvailable = true;
autoRemoveRecents = _autoRemoveRecents;
askedCompatMode = _askedCompatMode;
- mUserId = _userId;
mUserSetupComplete = userSetupComplete;
effectiveUid = _effectiveUid;
touchActiveTime();
lastDescription = _lastDescription;
- mActivities = activities;
mLastTimeMoved = lastTimeMoved;
mNeverRelinquishIdentity = neverRelinquishIdentity;
- mTaskDescription = _lastTaskDescription;
mAffiliatedTaskId = taskAffiliation;
mAffiliatedTaskColor = taskAffiliationColor;
mPrevAffiliateTaskId = prevTaskId;
@@ -406,7 +373,6 @@
mCallingUid = callingUid;
mCallingPackage = callingPackage;
mResizeMode = resizeMode;
- mSupportsPictureInPicture = supportsPictureInPicture;
if (info != null) {
setIntent(_intent, info);
setMinDimensions(info);
@@ -418,39 +384,6 @@
mAtmService.getTaskChangeNotificationController().notifyTaskCreated(_taskId, realActivity);
}
- Task getTask() {
- return mTask;
- }
-
- void createTask(boolean onTop, boolean showForAllUsers) {
- if (mTask != null) {
- throw new IllegalArgumentException("mTask=" + mTask
- + " already created for task=" + this);
- }
-
- final Rect bounds = updateOverrideConfigurationFromLaunchBounds();
- final TaskStack stack = getStack().getTaskStack();
-
- if (stack == null) {
- throw new IllegalArgumentException("TaskRecord: invalid stack=" + mStack);
- }
- EventLog.writeEvent(WM_TASK_CREATED, mTaskId, stack.mStackId);
- mTask = new Task(mTaskId, stack, mUserId, mAtmService.mWindowManager, mResizeMode,
- mSupportsPictureInPicture, mTaskDescription, this);
- final int position = onTop ? POSITION_TOP : POSITION_BOTTOM;
-
- if (!mDisplayedBounds.isEmpty()) {
- mTask.setOverrideDisplayedBounds(mDisplayedBounds);
- }
- // We only want to move the parents to the parents if we are creating this task at the
- // top of its stack.
- stack.addTask(mTask, position, showForAllUsers, onTop /* moveParents */);
- }
-
- void setTask(Task task) {
- mTask = task;
- }
-
void cleanUpResourcesForDestroy() {
if (hasChild()) {
return;
@@ -473,60 +406,33 @@
mAtmService.mStackSupervisor.mRecentTasks.remove(this);
}
- removeWindowContainer();
+ removeIfPossible();
}
@VisibleForTesting
- void removeWindowContainer() {
+ @Override
+ void removeIfPossible() {
mAtmService.getLockTaskController().clearLockedTask(this);
- if (mTask == null) {
- if (DEBUG_STACK) Slog.i(TAG_WM, "removeTask: could not find taskId=" + mTaskId);
- return;
- }
- mTask.removeIfPossible();
- mTask = null;
- if (!getWindowConfiguration().persistTaskBounds()) {
- // Reset current bounds for task whose bounds shouldn't be persisted so it uses
- // default configuration the next time it launches.
- setBounds(null);
- }
+ super.removeIfPossible();
mAtmService.getTaskChangeNotificationController().notifyTaskRemoved(mTaskId);
}
- void onSnapshotChanged(TaskSnapshot snapshot) {
- mAtmService.getTaskChangeNotificationController().notifyTaskSnapshotChanged(mTaskId, snapshot);
- }
-
void setResizeMode(int resizeMode) {
if (mResizeMode == resizeMode) {
return;
}
mResizeMode = resizeMode;
- mTask.setResizeable(resizeMode);
mAtmService.mRootActivityContainer.ensureActivitiesVisible(null, 0, !PRESERVE_WINDOWS);
mAtmService.mRootActivityContainer.resumeFocusedStacksTopActivities();
}
- void setTaskDockedResizing(boolean resizing) {
- if (mTask == null) {
- Slog.w(TAG_WM, "setTaskDockedResizing: taskId " + mTaskId + " not found.");
- return;
- }
- mTask.setTaskDockedResizing(resizing);
- }
-
- // TODO: Consolidate this with the resize() method below.
- public void requestResize(Rect bounds, int resizeMode) {
- mAtmService.resizeTask(mTaskId, bounds, resizeMode);
- }
-
boolean resize(Rect bounds, int resizeMode, boolean preserveWindow, boolean deferResume) {
mAtmService.deferWindowLayout();
try {
final boolean forced = (resizeMode & RESIZE_MODE_FORCED) != 0;
- if (mTask == null) {
+ if (getParent() == null) {
// Task doesn't exist in window manager yet (e.g. was restored from recents).
// All we can do for now is update the bounds so it can be used when the task is
// added to window manager.
@@ -577,7 +483,7 @@
}
}
}
- mTask.resize(kept, forced);
+ resize(kept, forced);
saveLaunchingStateIfNeeded();
@@ -588,19 +494,6 @@
}
}
- // TODO: Investigate combining with the resize() method above.
- void resizeWindowContainer() {
- mTask.resize(false /* relayout */, false /* forced */);
- }
-
- void getWindowContainerBounds(Rect bounds) {
- if (mTask != null) {
- mTask.getBounds(bounds);
- } else {
- bounds.setEmpty();
- }
- }
-
/**
* Convenience method to reparent a task to the top or bottom position of the stack.
*/
@@ -708,32 +601,16 @@
// Adjust the position for the new parent stack as needed.
position = toStack.getAdjustedPositionForTask(this, position, null /* starting */);
- // Must reparent first in window manager to avoid a situation where AM can delete the
- // we are coming from in WM before we reparent because it became empty.
- mTask.reparent(toStack.getTaskStack(), position,
- moveStackMode == REPARENT_MOVE_STACK_TO_FRONT);
-
final boolean moveStackToFront = moveStackMode == REPARENT_MOVE_STACK_TO_FRONT
|| (moveStackMode == REPARENT_KEEP_STACK_AT_FRONT && (wasFocused || wasFront));
- // Move the task
- sourceStack.removeTask(this, reason, moveStackToFront
- ? REMOVE_TASK_MODE_MOVING_TO_TOP : REMOVE_TASK_MODE_MOVING);
- toStack.addTask(this, position, false /* schedulePictureInPictureModeChange */, reason);
+
+ reparent(toStack.getTaskStack(), position, moveStackToFront, reason);
if (schedulePictureInPictureModeChange) {
// Notify of picture-in-picture mode changes
supervisor.scheduleUpdatePictureInPictureModeIfNeeded(this, sourceStack);
}
- // TODO: Ensure that this is actually necessary here
- // Notify the voice session if required
- if (voiceSession != null) {
- try {
- voiceSession.taskStarted(intent, mTaskId);
- } catch (RemoteException e) {
- }
- }
-
// If the task had focus before (or we're requested to move focus), move focus to the
// new stack by moving the stack to the front.
if (r != null) {
@@ -809,14 +686,6 @@
|| targetWindowingMode == WINDOWING_MODE_FREEFORM;
}
- void cancelWindowTransition() {
- if (mTask == null) {
- Slog.w(TAG_WM, "cancelWindowTransition: taskId " + mTaskId + " not found.");
- return;
- }
- mTask.cancelTaskWindowTransition();
- }
-
/**
* DO NOT HOLD THE ACTIVITY MANAGER LOCK WHEN CALLING THIS METHOD!
*/
@@ -970,67 +839,105 @@
return (T) mStack;
}
- /**
- * Must be used for setting parent stack because it performs configuration updates.
- * Must be called after adding task as a child to the stack.
- */
- // TODO(task-unify): Remove or rework after task level unification.
- void setStack(ActivityStack stack) {
- if (stack != null && !stack.isInStackLocked(this)) {
- throw new IllegalStateException("Task must be added as a Stack child first.");
- }
- final ActivityStack oldStack = mStack;
- mStack = stack;
+ // TODO(stack-unify): Can be removed on stack unified.
+ void onParentChanged(ActivityStack newParent, ActivityStack oldParent) {
+ onParentChanged(
+ newParent != null ? newParent.mTaskStack : null,
+ oldParent != null ? oldParent.mTaskStack : null);
+ }
- // If the new {@link TaskRecord} is from a different {@link ActivityStack}, remove this
- // {@link ActivityRecord} from its current {@link ActivityStack}.
+ @Override
+ void onParentChanged(ConfigurationContainer newParent, ConfigurationContainer oldParent) {
+ final ActivityStack oldStack = (oldParent != null)
+ ? ((TaskStack) oldParent).mActivityStack : null;
+ final ActivityStack newStack = (newParent != null)
+ ? ((TaskStack) newParent).mActivityStack : null;
- if (oldStack != mStack) {
+ mStack = newStack;
+
+ super.onParentChanged(newParent, oldParent);
+
+ if (oldStack != null) {
for (int i = getChildCount() - 1; i >= 0; --i) {
final ActivityRecord activity = getChildAt(i);
+ oldStack.onActivityRemovedFromStack(activity);
+ }
- if (oldStack != null) {
- oldStack.onActivityRemovedFromStack(activity);
- }
+ updateTaskMovement(true /*toFront*/);
- if (mStack != null) {
- stack.onActivityAddedToStack(activity);
+ if (oldStack.inPinnedWindowingMode()
+ && (newStack == null || !newStack.inPinnedWindowingMode())) {
+ // Notify if a task from the pinned stack is being removed
+ // (or moved depending on the mode).
+ mAtmService.getTaskChangeNotificationController().notifyActivityUnpinned();
+ }
+ }
+
+ if (newStack != null) {
+ for (int i = getChildCount() - 1; i >= 0; --i) {
+ final ActivityRecord activity = getChildAt(i);
+ newStack.onActivityAddedToStack(activity);
+ }
+
+ // TODO: Ensure that this is actually necessary here
+ // Notify the voice session if required
+ if (voiceSession != null) {
+ try {
+ voiceSession.taskStarted(intent, mTaskId);
+ } catch (RemoteException e) {
}
}
}
- onParentChanged(mStack, oldStack);
+ // First time we are adding the task to the system.
+ if (oldParent == null && newParent != null) {
+
+ // TODO: Super random place to be doing this, but aligns with what used to be done
+ // before we unified Task level. Look into if this can be done in a better place.
+ updateOverrideConfigurationFromLaunchBounds();
+ }
+
+ // Task is being removed.
+ if (oldParent != null && newParent == null) {
+ cleanUpResourcesForDestroy();
+ }
+
+
+ // Update task bounds if needed.
+ adjustBoundsForDisplayChangeIfNeeded(getDisplayContent());
+
+ if (getWindowConfiguration().windowsAreScaleable()) {
+ // We force windows out of SCALING_MODE_FREEZE so that we can continue to animate them
+ // while a resize is pending.
+ forceWindowsScaleable(true /* force */);
+ } else {
+ forceWindowsScaleable(false /* force */);
+ }
+
+ mAtmService.mRootActivityContainer.updateUIDsPresentOnDisplay();
+ }
+
+ /** TODO(task-merge): Consolidate into {@link TaskStack#onChildPositionChanged}. */
+ void updateTaskMovement(boolean toFront) {
+ if (isPersistable) {
+ mLastTimeMoved = System.currentTimeMillis();
+ // Sign is used to keep tasks sorted when persisted. Tasks sent to the bottom most
+ // recently will be most negative, tasks sent to the bottom before that will be less
+ // negative. Similarly for recent tasks moved to the top which will be most positive.
+ if (!toFront) {
+ mLastTimeMoved *= -1;
+ }
+ }
+ mAtmService.mRootActivityContainer.invalidateTaskLayers();
}
/**
- * @return Id of current stack, {@link INVALID_STACK_ID} if no stack is set.
+ * @return Id of current stack, {@link ActivityTaskManager#INVALID_STACK_ID} if no stack is set.
*/
int getStackId() {
return mStack != null ? mStack.mStackId : INVALID_STACK_ID;
}
- @Override
- protected int getChildCount() {
- return mActivities.size();
- }
-
- @Override
- protected ActivityRecord getChildAt(int index) {
- return mActivities.get(index);
- }
-
- @Override
- protected ConfigurationContainer getParent() {
- return mStack;
- }
-
- @Override
- protected void onParentChanged(
- ConfigurationContainer newParent, ConfigurationContainer oldParent) {
- super.onParentChanged(newParent, oldParent);
- mAtmService.mRootActivityContainer.updateUIDsPresentOnDisplay();
- }
-
// Close up recents linked list.
private void closeRecentsChain() {
if (mPrevAffiliate != null) {
@@ -1121,16 +1028,6 @@
return null;
}
- boolean isVisible() {
- for (int i = getChildCount() - 1; i >= 0; --i) {
- final ActivityRecord r = getChildAt(i);
- if (r.visible) {
- return true;
- }
- }
- return false;
- }
-
/**
* Return true if any activities in this task belongs to input uid.
*/
@@ -1210,15 +1107,10 @@
* Reorder the history stack so that the passed activity is brought to the front.
*/
final void moveActivityToFrontLocked(ActivityRecord newTop) {
- if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE,
- "Removing and adding activity " + newTop
- + " to stack at top callers=" + Debug.getCallers(4));
+ if (DEBUG_ADD_REMOVE) Slog.i(TAG_ADD_REMOVE, "Removing and adding activity "
+ + newTop + " to stack at top callers=" + Debug.getCallers(4));
- mActivities.remove(newTop);
- mActivities.add(newTop);
-
- // Make sure window manager is aware of the position change.
- mTask.positionChildAtTop(newTop);
+ positionChildAtTop(newTop);
updateEffectiveIntent();
}
@@ -1232,19 +1124,29 @@
return getChildAt(0).getActivityType();
}
- /** Called when a Task child is added from the Task.java side. */
- // TODO(task-unify): Just override addChild to do what is needed when someone calls to add a
- // child.
- void onChildAdded(ActivityRecord r, int index) {
+ @Override
+ void addChild(ActivityRecord r, int index) {
+ if (r.getParent() != null) {
+ // Shouldn't already have a parent since we are just adding to the task...Maybe you
+ // meant to use reparent?
+ throw new IllegalStateException(
+ "r=" + r + " parent=" + r.getParent() + " task=" + this);
+ }
+
+ // If this task had any child before we added this one.
+ boolean hadChild = hasChild();
+
+ index = getAdjustedAddPosition(r, index);
+ super.addChild(r, index);
+
+ ProtoLog.v(WM_DEBUG_ADD_REMOVE, "addChild: %s at top.", this);
r.inHistory = true;
- // Remove r first, and if it wasn't already in the list and it's fullscreen, count it.
- if (!mActivities.remove(r) && r.occludesParent()) {
- // Was not previously in list.
+ if (r.occludesParent()) {
numFullscreen++;
}
// Only set this based on the first activity
- if (!hasChild()) {
+ if (!hadChild) {
if (r.getActivityType() == ACTIVITY_TYPE_UNDEFINED) {
// Normally non-standard activity type for the activity record will be set when the
// object is created, however we delay setting the standard application type until
@@ -1264,20 +1166,6 @@
r.setActivityType(getActivityType());
}
- final int size = getChildCount();
-
- if (index == size && size > 0) {
- final ActivityRecord top = getChildAt(size - 1);
- if (top.mTaskOverlay) {
- // Place below the task overlay activity since the overlay activity should always
- // be on top.
- index--;
- }
- }
-
- index = Math.min(size, index);
- mActivities.add(index, r);
-
updateEffectiveIntent();
if (r.isPersistable()) {
mAtmService.notifyTaskPersisterLocked(this, false);
@@ -1288,31 +1176,23 @@
mAtmService.mRootActivityContainer.updateUIDsPresentOnDisplay();
}
- // TODO(task-unify): Merge onChildAdded method below into this since task will be a single
- // object.
void addChild(ActivityRecord r) {
- if (r.getParent() != null) {
- // Shouldn't already have a parent since we are just adding to the task...
- throw new IllegalStateException(
- "r=" + r + " parent=" + r.getParent() + " task=" + this);
- }
-
- ProtoLog.v(WM_DEBUG_ADD_REMOVE, "addChild: %s at top.", this);
- // This means the activity isn't attached to Task.java yet. Go ahead and do that.
- // TODO(task-unify): Remove/call super once we unify task level.
- if (mTask != null) {
- mTask.addChild(r, Integer.MAX_VALUE /* add on top */);
- } else {
- onChildAdded(r, Integer.MAX_VALUE);
- }
+ addChild(r, Integer.MAX_VALUE /* add on top */);
}
- /** Called when a Task child is removed from the Task.java side. */
- // TODO(task-unify): Just override removeChild to do what is needed when someone calls to remove
- // a child.
- void onChildRemoved(ActivityRecord r) {
- if (mActivities.remove(r) && r.occludesParent()) {
- // Was previously in list.
+ @Override
+ void removeChild(ActivityRecord r) {
+ removeChild(r, "removeChild");
+ }
+
+ void removeChild(ActivityRecord r, String reason) {
+ if (!mChildren.contains(r)) {
+ Slog.e(TAG, "removeChild: r=" + r + " not found in t=" + this);
+ return;
+ }
+
+ super.removeChild(r);
+ if (r.occludesParent()) {
numFullscreen--;
}
if (r.isPersistable()) {
@@ -1336,16 +1216,19 @@
// When destroying a task, tell the supervisor to remove it so that any activity it
// has can be cleaned up correctly. This is currently the only place where we remove
// a task with the DESTROYING mode, so instead of passing the onlyHasTaskOverlays
- // state into removeTask(), we just clear the task here before the other residual
+ // state into removeChild(), we just clear the task here before the other residual
// work.
- // TODO: If the callers to removeTask() changes such that we have multiple places
- // where we are destroying the task, move this back into removeTask()
+ // 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 */,
- !REMOVE_FROM_RECENTS, "onChildRemoved");
+ !REMOVE_FROM_RECENTS, reason);
}
} else if (!mReuseTask) {
// Remove entire task if it doesn't have any activity left and it isn't marked for reuse
- mStack.removeTask(this, "onChildRemoved", REMOVE_TASK_MODE_DESTROYING);
+ mStack.removeChild(this, reason);
+ EventLog.writeEvent(WM_TASK_REMOVED, mTaskId,
+ "removeChild: last r=" + r + " in t=" + this);
+ removeIfPossible();
}
}
@@ -1380,7 +1263,7 @@
* Completely remove all activities associated with an existing
* task starting at a specified index.
*/
- final void performClearTaskAtIndexLocked(int activityNdx, String reason) {
+ private void performClearTaskAtIndexLocked(int activityNdx, String reason) {
int numActivities = getChildCount();
for ( ; activityNdx < numActivities; ++activityNdx) {
final ActivityRecord r = getChildAt(activityNdx);
@@ -1390,7 +1273,7 @@
if (mStack == null) {
// Task was restored from persistent storage.
r.takeFromHistory();
- mActivities.remove(activityNdx);
+ removeChild(r);
--activityNdx;
--numActivities;
} else if (r.finishIfPossible(Activity.RESULT_CANCELED, null /* resultData */, reason,
@@ -1526,20 +1409,13 @@
" mLockTaskAuth=" + lockTaskAuthToString());
}
- private boolean isResizeable(boolean checkSupportsPip) {
- return (mAtmService.mForceResizableActivities || ActivityInfo.isResizeableMode(mResizeMode)
- || (checkSupportsPip && mSupportsPictureInPicture));
- }
-
- boolean isResizeable() {
- return isResizeable(true /* checkSupportsPip */);
- }
-
@Override
public boolean supportsSplitScreenWindowingMode() {
// A task can not be docked even if it is considered resizeable because it only supports
// picture-in-picture mode but has a non-resizeable resizeMode
return super.supportsSplitScreenWindowingMode()
+ // TODO(task-group): Probably makes sense to move this and associated code into
+ // WindowContainer so it affects every node.
&& mAtmService.mSupportsSplitScreenMultiWindow
&& (mAtmService.mForceResizableActivities
|| (isResizeable(false /* checkSupportsPip */)
@@ -1672,15 +1548,13 @@
}
topActivity = false;
}
- mTaskDescription = new TaskDescription(label, null, iconResource, iconFilename,
- colorPrimary, colorBackground, statusBarColor, navigationBarColor,
+ final TaskDescription taskDescription = new TaskDescription(label, null, iconResource,
+ iconFilename, colorPrimary, colorBackground, statusBarColor, navigationBarColor,
statusBarContrastWhenTransparent, navigationBarContrastWhenTransparent);
- if (mTask != null) {
- mTask.setTaskDescription(mTaskDescription);
- }
+ setTaskDescription(taskDescription);
// Update the task affiliation color if we are the parent of the group
if (mTaskId == mAffiliatedTaskId) {
- mAffiliatedTaskColor = mTaskDescription.getPrimaryColor();
+ mAffiliatedTaskColor = taskDescription.getPrimaryColor();
}
}
}
@@ -1903,38 +1777,6 @@
}
/**
- * Displayed bounds are used to set where the task is drawn at any given time. This is
- * separate from its actual bounds so that the app doesn't see any meaningful configuration
- * changes during transitionary periods.
- */
- void setDisplayedBounds(Rect bounds) {
- if (bounds == null) {
- mDisplayedBounds.setEmpty();
- } else {
- mDisplayedBounds.set(bounds);
- }
- if (mTask != null) {
- mTask.setOverrideDisplayedBounds(
- mDisplayedBounds.isEmpty() ? null : mDisplayedBounds);
- }
- }
-
- /**
- * Gets the current overridden displayed bounds. These will be empty if the task is not
- * currently overriding where it is displayed.
- */
- Rect getDisplayedBounds() {
- return mDisplayedBounds;
- }
-
- /**
- * @return {@code true} if this has overridden displayed bounds.
- */
- boolean hasDisplayedBounds() {
- return !mDisplayedBounds.isEmpty();
- }
-
- /**
* Intersects inOutBounds with intersectBounds-intersectInsets. If inOutBounds is larger than
* intersectBounds on a side, then the respective side will not be intersected.
*
@@ -2190,16 +2032,10 @@
computeConfigResourceOverrides(getResolvedOverrideConfiguration(), newParentConfig);
}
- /** @see WindowContainer#handlesOrientationChangeFromDescendant */
- boolean handlesOrientationChangeFromDescendant() {
- return mTask != null && mTask.getParent() != null
- && mTask.getParent().handlesOrientationChangeFromDescendant();
- }
-
/**
- * Compute bounds (letterbox or pillarbox) for {@link #WINDOWING_MODE_FULLSCREEN} when the
- * parent doesn't handle the orientation change and the requested orientation is different from
- * the parent.
+ * Compute bounds (letterbox or pillarbox) for
+ * {@link WindowConfiguration#WINDOWING_MODE_FULLSCREEN} when the parent doesn't handle the
+ * orientation change and the requested orientation is different from the parent.
*/
void computeFullscreenBounds(@NonNull Rect outBounds, @Nullable ActivityRecord refActivity,
@NonNull Rect parentBounds, int parentOrientation) {
@@ -2345,7 +2181,7 @@
info.realActivity = realActivity;
info.numActivities = mReuseActivitiesReport.numActivities;
info.lastActiveTime = lastActiveTime;
- info.taskDescription = new ActivityManager.TaskDescription(mTaskDescription);
+ info.taskDescription = new ActivityManager.TaskDescription(getTaskDescription());
info.supportsSplitScreenMultiWindow = supportsSplitScreenWindowingMode();
info.resizeMode = mResizeMode;
info.configuration.setTo(getConfiguration());
@@ -2435,7 +2271,7 @@
}
pw.println(")");
}
- pw.print(prefix); pw.print("Activities="); pw.println(mActivities);
+ pw.print(prefix); pw.print("Activities="); pw.println(mChildren);
if (!askedCompatMode || !inRecents || !isAvailable) {
pw.print(prefix); pw.print("askedCompatMode="); pw.print(askedCompatMode);
pw.print(" inRecents="); pw.print(inRecents);
@@ -2490,6 +2326,7 @@
return toString();
}
+ @Override
public void writeToProto(ProtoOutputStream proto, long fieldId,
@WindowTraceLogLevel int logLevel) {
if (logLevel == WindowTraceLogLevel.CRITICAL && !isVisible()) {
@@ -2497,13 +2334,13 @@
}
final long token = proto.start(fieldId);
- super.writeToProto(proto, CONFIGURATION_CONTAINER, logLevel);
+ writeToProtoInnerTaskOnly(proto, TASK, logLevel);
proto.write(ID, mTaskId);
for (int i = getChildCount() - 1; i >= 0; i--) {
- ActivityRecord activity = getChildAt(i);
+ final ActivityRecord activity = getChildAt(i);
activity.writeToProto(proto, ACTIVITIES);
}
- proto.write(STACK_ID, mStack.mStackId);
+ proto.write(STACK_ID, getStackId());
if (mLastNonFullscreenBounds != null) {
mLastNonFullscreenBounds.writeToProto(proto, LAST_NON_FULLSCREEN_BOUNDS);
}
@@ -2579,8 +2416,8 @@
if (lastDescription != null) {
out.attribute(null, ATTR_LASTDESCRIPTION, lastDescription.toString());
}
- if (mTaskDescription != null) {
- mTaskDescription.saveToXml(out);
+ if (getTaskDescription() != null) {
+ getTaskDescription().saveToXml(out);
}
out.attribute(null, ATTR_TASK_AFFILIATION_COLOR, String.valueOf(mAffiliatedTaskColor));
out.attribute(null, ATTR_TASK_AFFILIATION, String.valueOf(mAffiliatedTaskId));
@@ -2641,14 +2478,14 @@
static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Intent intent, IVoiceInteractionSession voiceSession,
- IVoiceInteractor voiceInteractor) {
+ IVoiceInteractor voiceInteractor, ActivityStack stack) {
return getTaskRecordFactory().create(
- service, taskId, info, intent, voiceSession, voiceInteractor);
+ service, taskId, info, intent, voiceSession, voiceInteractor, stack);
}
static TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
- Intent intent, TaskDescription taskDescription) {
- return getTaskRecordFactory().create(service, taskId, info, intent, taskDescription);
+ Intent intent, TaskDescription taskDescription, ActivityStack stack) {
+ return getTaskRecordFactory().create(service, taskId, info, intent, taskDescription, stack);
}
static TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
@@ -2665,15 +2502,15 @@
TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
Intent intent, IVoiceInteractionSession voiceSession,
- IVoiceInteractor voiceInteractor) {
+ IVoiceInteractor voiceInteractor, ActivityStack stack) {
return new TaskRecord(service, taskId, info, intent, voiceSession, voiceInteractor,
- null /*taskDescription*/);
+ null /*taskDescription*/, stack);
}
TaskRecord create(ActivityTaskManagerService service, int taskId, ActivityInfo info,
- Intent intent, TaskDescription taskDescription) {
+ Intent intent, TaskDescription taskDescription, ActivityStack stack) {
return new TaskRecord(service, taskId, info, intent, null /*voiceSession*/,
- null /*voiceInteractor*/, taskDescription);
+ null /*voiceInteractor*/, taskDescription, stack);
}
/**
@@ -2683,20 +2520,20 @@
Intent affinityIntent, String affinity, String rootAffinity,
ComponentName realActivity, ComponentName origActivity, boolean rootWasReset,
boolean autoRemoveRecents, boolean askedCompatMode, int userId,
- int effectiveUid, String lastDescription, ArrayList<ActivityRecord> activities,
+ int effectiveUid, String lastDescription,
long lastTimeMoved, boolean neverRelinquishIdentity,
TaskDescription lastTaskDescription, int taskAffiliation, int prevTaskId,
int nextTaskId, int taskAffiliationColor, int callingUid, String callingPackage,
int resizeMode, boolean supportsPictureInPicture, boolean realActivitySuspended,
- boolean userSetupComplete, int minWidth, int minHeight) {
+ boolean userSetupComplete, int minWidth, int minHeight, ActivityStack stack) {
return new TaskRecord(service, taskId, intent, affinityIntent, affinity,
rootAffinity, realActivity, origActivity, rootWasReset, autoRemoveRecents,
- askedCompatMode, userId, effectiveUid, lastDescription, activities,
+ askedCompatMode, userId, effectiveUid, lastDescription,
lastTimeMoved, neverRelinquishIdentity, lastTaskDescription, taskAffiliation,
prevTaskId, nextTaskId, taskAffiliationColor, callingUid, callingPackage,
resizeMode, supportsPictureInPicture, realActivitySuspended, userSetupComplete,
minWidth, minHeight, null /*ActivityInfo*/, null /*_voiceSession*/,
- null /*_voiceInteractor*/);
+ null /*_voiceInteractor*/, stack);
}
TaskRecord restoreFromXml(XmlPullParser in, ActivityStackSupervisor stackSupervisor)
@@ -2908,15 +2745,15 @@
taskId, intent, affinityIntent,
affinity, rootAffinity, realActivity, origActivity, rootHasReset,
autoRemoveRecents, askedCompatMode, userId, effectiveUid, lastDescription,
- activities, lastTimeOnTop, neverRelinquishIdentity, taskDescription,
+ lastTimeOnTop, neverRelinquishIdentity, taskDescription,
taskAffiliation, prevTaskId, nextTaskId, taskAffiliationColor, callingUid,
callingPackage, resizeMode, supportsPictureInPicture, realActivitySuspended,
- userSetupComplete, minWidth, minHeight);
+ userSetupComplete, minWidth, minHeight, null /*stack*/);
task.mLastNonFullscreenBounds = lastNonFullscreenBounds;
task.setBounds(lastNonFullscreenBounds);
for (int activityNdx = activities.size() - 1; activityNdx >=0; --activityNdx) {
- activities.get(activityNdx).setTask(task);
+ task.addChild(activities.get(activityNdx));
}
if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Restored task=" + task);
diff --git a/services/core/java/com/android/server/wm/TaskStack.java b/services/core/java/com/android/server/wm/TaskStack.java
index 56211e2..68b76fb 100644
--- a/services/core/java/com/android/server/wm/TaskStack.java
+++ b/services/core/java/com/android/server/wm/TaskStack.java
@@ -116,7 +116,6 @@
/** ActivityRecords that are exiting, but still on screen for animations. */
final ArrayList<ActivityRecord> mExitingActivities = new ArrayList<>();
- final ArrayList<ActivityRecord> mTmpActivities = new ArrayList<>();
/** Detach this stack from its display when animation completes. */
// TODO: maybe tie this to WindowContainer#removeChild some how...
@@ -330,7 +329,7 @@
}
/** Bounds of the stack with other system factors taken into consideration. */
- public void getDimBounds(Rect out) {
+ void getDimBounds(Rect out) {
getBounds(out);
}
@@ -482,11 +481,6 @@
dividerSize);
}
- // TODO: Checkout the call points of this method and the ones below to see how they can fit in WC.
- void addTask(Task task, int position) {
- addTask(task, position, task.showForAllUsers(), true /* moveParents */);
- }
-
/**
* Put a Task in this stack. Used for adding only.
* When task is added to top of the stack, the entire branch of the hierarchy (including stack
@@ -495,22 +489,21 @@
* @param position Target position to add the task to.
* @param showForAllUsers Whether to show the task regardless of the current user.
*/
- void addTask(Task task, int position, boolean showForAllUsers, boolean moveParents) {
- final TaskStack currentStack = task.mStack;
- // TODO: We pass stack to task's constructor, but we still need to call this method.
- // This doesn't make sense, mStack will already be set equal to "this" at this point.
- if (currentStack != null && currentStack.mStackId != mStackId) {
- throw new IllegalStateException("Trying to add taskId=" + task.mTaskId
- + " to stackId=" + mStackId
- + ", but it is already attached to stackId=" + task.mStack.mStackId);
- }
-
+ void addChild(Task task, int position, boolean showForAllUsers, boolean moveParents) {
// Add child task.
task.mStack = this;
addChild(task, null);
// Move child to a proper position, as some restriction for position might apply.
- positionChildAt(position, task, moveParents /* includingParents */, showForAllUsers);
+ position = positionChildAt(
+ position, task, moveParents /* includingParents */, showForAllUsers);
+ // TODO(task-merge): Remove cast.
+ mActivityStack.onChildAdded((TaskRecord) task, position);
+ }
+
+ @Override
+ void addChild(Task task, int position) {
+ addChild(task, position, task.showForAllUsers(), false /* includingParents */);
}
void positionChildAt(Task child, int position) {
@@ -563,13 +556,12 @@
/**
* Overridden version of {@link TaskStack#positionChildAt(int, Task, boolean)}. Used in
- * {@link TaskStack#addTask(Task, int, boolean showForAllUsers, boolean)}, as it can receive
- * showForAllUsers param from {@link AppWindowToken} instead of {@link Task#showForAllUsers()}.
+ * {@link TaskStack#addChild(Task, int, boolean showForAllUsers, boolean)}, as it can receive
+ * showForAllUsers param from {@link ActivityRecord} instead of {@link Task#showForAllUsers()}.
*/
- private void positionChildAt(int position, Task child, boolean includingParents,
+ int positionChildAt(int position, Task child, boolean includingParents,
boolean showForAllUsers) {
- final int targetPosition = findPositionForTask(child, position, showForAllUsers,
- false /* addingNew */);
+ final int targetPosition = findPositionForTask(child, position, showForAllUsers);
super.positionChildAt(targetPosition, child, includingParents);
// Log positioning.
@@ -578,6 +570,14 @@
final int toTop = targetPosition == mChildren.size() - 1 ? 1 : 0;
EventLog.writeEvent(EventLogTags.WM_TASK_MOVED, child.mTaskId, toTop, targetPosition);
+
+ return targetPosition;
+ }
+
+ @Override
+ void onChildPositionChanged(WindowContainer child) {
+ // TODO(task-merge): Read comment on updateTaskMovement method.
+ //((TaskRecord) child).updateTaskMovement(true);
}
void reparent(int displayId, Rect outStackBounds, boolean onTop) {
@@ -597,14 +597,13 @@
// TODO: We should really have users as a window container in the hierarchy so that we don't
// have to do complicated things like we are doing in this method.
- private int findPositionForTask(Task task, int targetPosition, boolean showForAllUsers,
- boolean addingNew) {
+ private int findPositionForTask(Task task, int targetPosition, boolean showForAllUsers) {
final boolean canShowTask =
showForAllUsers || mWmService.isCurrentProfileLocked(task.mUserId);
final int stackSize = mChildren.size();
int minPosition = 0;
- int maxPosition = addingNew ? stackSize : stackSize - 1;
+ int maxPosition = stackSize - 1;
if (canShowTask) {
minPosition = computeMinPosition(minPosition, stackSize);
@@ -615,8 +614,7 @@
// preserve POSITION_BOTTOM/POSITION_TOP positions if they are still valid.
if (targetPosition == POSITION_BOTTOM && minPosition == 0) {
return POSITION_BOTTOM;
- } else if (targetPosition == POSITION_TOP
- && maxPosition == (addingNew ? stackSize : stackSize - 1)) {
+ } else if (targetPosition == POSITION_TOP && maxPosition == (stackSize - 1)) {
return POSITION_TOP;
}
// Reset position based on minimum/maximum possible positions.
@@ -669,24 +667,17 @@
*/
@Override
void removeChild(Task task) {
+ if (!mChildren.contains(task)) {
+ // Not really in this stack anymore...
+ return;
+ }
if (DEBUG_TASK_MOVEMENT) Slog.d(TAG_WM, "removeChild: task=" + task);
super.removeChild(task);
task.mStack = null;
- if (mDisplayContent != null) {
- if (mChildren.isEmpty()) {
- getParent().positionChildAt(POSITION_BOTTOM, this, false /* includingParents */);
- }
- mDisplayContent.setLayoutNeeded();
- }
- for (int appNdx = mExitingActivities.size() - 1; appNdx >= 0; --appNdx) {
- final ActivityRecord activity = mExitingActivities.get(appNdx);
- if (activity.getTask() == task) {
- activity.mIsExiting = false;
- mExitingActivities.remove(appNdx);
- }
- }
+ // TODO(task-merge): Remove cast.
+ mActivityStack.onChildRemoved((TaskRecord) task, mDisplayContent);
}
@Override
@@ -1298,7 +1289,7 @@
super.writeToProto(proto, WINDOW_CONTAINER, logLevel);
proto.write(ID, mStackId);
for (int taskNdx = mChildren.size() - 1; taskNdx >= 0; taskNdx--) {
- mChildren.get(taskNdx).writeToProto(proto, TASKS, logLevel);
+ mChildren.get(taskNdx).writeToProtoInnerTaskOnly(proto, TASKS, logLevel);
}
proto.write(FILLS_PARENT, matchParentBounds());
getRawBounds().writeToProto(proto, BOUNDS);
diff --git a/services/core/java/com/android/server/wm/WindowContainer.java b/services/core/java/com/android/server/wm/WindowContainer.java
index 7ce2b5e..a393ba6 100644
--- a/services/core/java/com/android/server/wm/WindowContainer.java
+++ b/services/core/java/com/android/server/wm/WindowContainer.java
@@ -428,7 +428,7 @@
parent.mTreeWeight += child.mTreeWeight;
parent = parent.getParent();
}
- onChildPositionChanged();
+ onChildPositionChanged(child);
}
/**
@@ -454,7 +454,7 @@
parent.mTreeWeight -= child.mTreeWeight;
parent = parent.getParent();
}
- onChildPositionChanged();
+ onChildPositionChanged(child);
}
/**
@@ -583,7 +583,7 @@
if (mChildren.peekLast() != child) {
mChildren.remove(child);
mChildren.add(child);
- onChildPositionChanged();
+ onChildPositionChanged(child);
}
if (includingParents && getParent() != null) {
getParent().positionChildAt(POSITION_TOP, this /* child */,
@@ -594,7 +594,7 @@
if (mChildren.peekFirst() != child) {
mChildren.remove(child);
mChildren.addFirst(child);
- onChildPositionChanged();
+ onChildPositionChanged(child);
}
if (includingParents && getParent() != null) {
getParent().positionChildAt(POSITION_BOTTOM, this /* child */,
@@ -608,14 +608,14 @@
// doing this adjustment here and remove any adjustments in the callers.
mChildren.remove(child);
mChildren.add(position, child);
- onChildPositionChanged();
+ onChildPositionChanged(child);
}
}
/**
* Notify that a child's position has changed. Possible changes are adding or removing a child.
*/
- void onChildPositionChanged() { }
+ void onChildPositionChanged(WindowContainer child) { }
/**
* Update override configuration and recalculate full config.