Addition separation of adding vs. reparenting activity
- Removed method ActivityRecord.setTask which did only half of what is needed when adding a task and also only did half of what is needed for reparenting. Previous callers now need to call either ActivityRecord.reparent() to reparent and activity or TaskRecord.addActivityAtIndex() to add an activity to a task. - Fixed some NPE that resulted from the above change. Test: adb shell am instrument -w -e class com.google.android.setupwizard.tests.activity.SetupWizardExitActivityTest com.google.android.setupwizard.tests.activity Bug: 34179495 Change-Id: Ic69487f51d1bd139825e6a8054a49ce143065a57
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user