diff options
4 files changed, 56 insertions, 32 deletions
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java index 962056f25fd1..3573b8b3e2d6 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_MULTIPROCESS; 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 @@ final class ActivityRecord implements AppWindowContainerListener { // 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 @@ final class ActivityRecord implements AppWindowContainerListener { } } - 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 54082ea55b7d..10d108b6a677 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 @@ final class ActivityStack extends ConfigurationContainer implements StackWindowL // 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 @@ final class ActivityStack extends ConfigurationContainer implements StackWindowL + 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 73ef88b5c9a8..c2fc9dc24864 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 @@ class ActivityStarter { 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 @@ class ActivityStarter { 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 @@ class ActivityStarter { // 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 @@ class ActivityStarter { // 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 @@ class ActivityStarter { // 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 @@ class ActivityStarter { 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 @@ class ActivityStarter { 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 fef4073922c6..9e09cbbfb0c7 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 android.util.Slog; 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 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta * 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 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta } } + index = Math.min(size, index); mActivities.add(index, r); updateEffectiveIntent(); if (r.isPersistable()) { @@ -1071,7 +1079,12 @@ final class TaskRecord extends ConfigurationContainer implements TaskWindowConta // 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(); } |