Merge "Addition separation of adding vs. reparenting activity"
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 962056f..3573b8b 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -37,6 +37,8 @@
import static android.content.pm.ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
import static android.content.pm.ActivityInfo.FLAG_STATE_NOT_NEEDED;
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;
import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
@@ -773,7 +775,10 @@
// Remove the activity from the old task and add it to the new task
prevTask.removeActivity(this);
- setTask(newTask, null);
+ // TODO(b/34179495): This should really be set to null in removeActivity() call above,
+ // but really bad things that I can't track down right now happen when I do that.
+ // So, setting it here now and will change later when there is time for investigation.
+ task = null;
newTask.addActivityAtIndex(position, this);
}
@@ -821,19 +826,8 @@
}
}
- void setTask(TaskRecord newTask, TaskRecord taskToAffiliateWith) {
- if (task != null && task.removeActivity(this) && task != newTask
- && task.getStack() != null) {
- task.getStack().removeTask(task, "setTask");
- }
- task = newTask;
- setTaskToAffiliateWith(taskToAffiliateWith);
- }
-
void setTaskToAffiliateWith(TaskRecord taskToAffiliateWith) {
- if (taskToAffiliateWith != null &&
- launchMode != ActivityInfo.LAUNCH_SINGLE_INSTANCE &&
- launchMode != ActivityInfo.LAUNCH_SINGLE_TASK) {
+ if (launchMode != LAUNCH_SINGLE_INSTANCE && launchMode != LAUNCH_SINGLE_TASK) {
task.setTaskToAffiliateWith(taskToAffiliateWith);
}
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index 54082ea..10d108b 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -2775,7 +2775,12 @@
// 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.createWindowContainer();
+ // TODO: Need to investigate if it is okay for the controller to already be created by the
+ // time we get to this point. I think it is, but need to double check.
+ // Use test in b/34179495 to trace the call path.
+ if (r.getWindowContainerController() == null) {
+ r.createWindowContainer();
+ }
task.setFrontOfTask();
if (!isHomeOrRecentsStack() || numActivities() > 0) {
@@ -2952,8 +2957,7 @@
+ targetTask + " Callers=" + Debug.getCallers(4));
if (DEBUG_TASKS) Slog.v(TAG_TASKS,
"Pushing next activity " + p + " out to target's task " + target.task);
- p.setTask(targetTask, null);
- targetTask.addActivityAtBottom(p);
+ p.reparent(targetTask, 0 /* position - bottom */, "resetTargetTaskIfNeeded");
}
mWindowContainerController.positionChildAtBottom(
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 73ef88b..c2fc9dc 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -1615,7 +1615,7 @@
mNewTaskInfo != null ? mNewTaskInfo : mStartActivity.info,
mNewTaskIntent != null ? mNewTaskIntent : mIntent, mVoiceSession,
mVoiceInteractor, !mLaunchTaskBehind /* toTop */, mStartActivity.mActivityType);
- mStartActivity.setTask(task, taskToAffiliate);
+ addOrReparentStartingActivity(task, "setTaskFromReuseOrCreateNewTask - mReuseTask");
if (mLaunchBounds != null) {
final int stackId = mTargetStack.mStackId;
if (StackId.resizeStackWithLaunchBounds(stackId)) {
@@ -1625,11 +1625,14 @@
mStartActivity.task.updateOverrideConfiguration(mLaunchBounds);
}
}
- if (DEBUG_TASKS) Slog.v(TAG_TASKS,
- "Starting new activity " +
- mStartActivity + " in new task " + mStartActivity.task);
+ if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+ + " in new task " + mStartActivity.task);
} else {
- mStartActivity.setTask(mReuseTask, taskToAffiliate);
+ addOrReparentStartingActivity(mReuseTask, "setTaskFromReuseOrCreateNewTask");
+ }
+
+ if (taskToAffiliate != null) {
+ mStartActivity.setTaskToAffiliateWith(taskToAffiliate);
}
if (mSupervisor.isLockTaskModeViolation(mStartActivity.task)) {
@@ -1719,7 +1722,7 @@
// An existing activity is starting this new activity, so we want to keep the new one in
// the same task as the one that is starting it.
- mStartActivity.setTask(sourceTask, null);
+ addOrReparentStartingActivity(sourceTask, "setTaskFromSourceRecord");
if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+ " in existing task " + mStartActivity.task + " from source " + mSourceRecord);
return START_SUCCESS;
@@ -1752,7 +1755,8 @@
// Check whether we should actually launch the new activity in to the task,
// or just reuse the current activity on top.
ActivityRecord top = mInTask.getTopActivity();
- if (top != null && top.realActivity.equals(mStartActivity.realActivity) && top.userId == mStartActivity.userId) {
+ if (top != null && top.realActivity.equals(mStartActivity.realActivity)
+ && top.userId == mStartActivity.userId) {
if ((mLaunchFlags & FLAG_ACTIVITY_SINGLE_TOP) != 0
|| mLaunchSingleTop || mLaunchSingleTask) {
ActivityStack.logStartActivity(AM_NEW_INTENT, top, top.task);
@@ -1761,7 +1765,8 @@
// anything if that is the case, so this is it!
return START_RETURN_INTENT_TO_CALLER;
}
- top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent, mStartActivity.launchedFromPackage);
+ top.deliverNewIntentLocked(mCallingUid, mStartActivity.intent,
+ mStartActivity.launchedFromPackage);
return START_DELIVERED_TO_TOP;
}
}
@@ -1773,9 +1778,9 @@
return START_TASK_TO_FRONT;
}
- mStartActivity.setTask(mInTask, null);
- if (DEBUG_TASKS) Slog.v(TAG_TASKS,
- "Starting new activity " + mStartActivity + " in explicit task " + mStartActivity.task);
+ addOrReparentStartingActivity(mInTask, "setTaskFromInTask");
+ if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+ + " in explicit task " + mStartActivity.task);
return START_SUCCESS;
}
@@ -1790,10 +1795,18 @@
final TaskRecord task = (prev != null) ? prev.task : mTargetStack.createTaskRecord(
mSupervisor.getNextTaskIdForUserLocked(mStartActivity.userId), mStartActivity.info,
mIntent, null, null, true, mStartActivity.mActivityType);
- mStartActivity.setTask(task, null);
- mStartActivity.task.getStack().positionChildWindowContainerAtTop(mStartActivity.task);
- if (DEBUG_TASKS) Slog.v(TAG_TASKS,
- "Starting new activity " + mStartActivity + " in new guessed " + mStartActivity.task);
+ addOrReparentStartingActivity(task, "setTaskToCurrentTopOrCreateNewTask");
+ mTargetStack.positionChildWindowContainerAtTop(task);
+ if (DEBUG_TASKS) Slog.v(TAG_TASKS, "Starting new activity " + mStartActivity
+ + " in new guessed " + mStartActivity.task);
+ }
+
+ private void addOrReparentStartingActivity(TaskRecord parent, String reason) {
+ if (mStartActivity.task == null) {
+ parent.addActivityToTop(mStartActivity);
+ } else {
+ mStartActivity.reparent(parent, parent.mActivities.size() /* top */, reason);
+ }
}
private int adjustLaunchFlagsToDocumentMode(ActivityRecord r, boolean launchSingleInstance,
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index fef4073..9e09cbb 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -51,6 +51,7 @@
import com.android.internal.app.IVoiceInteractor;
import com.android.internal.util.XmlUtils;
+import com.android.server.wm.AppWindowContainerController;
import com.android.server.wm.TaskWindowContainerController;
import com.android.server.wm.TaskWindowContainerListener;
@@ -1033,6 +1034,12 @@
* be in the current task or unparented to any task.
*/
void addActivityAtIndex(int index, ActivityRecord r) {
+ if (r.task != null && r.task != this) {
+ throw new IllegalArgumentException("Can not add r=" + " to task=" + this
+ + " current parent=" + r.task);
+ }
+ r.task = this;
+
// Remove r first, and if it wasn't already in the list and it's fullscreen, count it.
if (!mActivities.remove(r) && r.fullscreen) {
// Was not previously in list.
@@ -1063,6 +1070,7 @@
}
}
+ index = Math.min(size, index);
mActivities.add(index, r);
updateEffectiveIntent();
if (r.isPersistable()) {
@@ -1071,7 +1079,12 @@
// Sync. with window manager
updateOverrideConfigurationFromLaunchBounds();
- mWindowContainerController.positionChildAt(r.getWindowContainerController(), index);
+ final AppWindowContainerController appController = r.getWindowContainerController();
+ if (appController != null) {
+ // Only attempt to move in WM if the child has a controller. It is possible we haven't
+ // created controller for the activity we are starting yet.
+ mWindowContainerController.positionChildAt(appController, index);
+ }
r.onOverrideConfigurationSent();
}