Prepare ActivityManagerService for multiple stacks.
- Replace mMainStack with mFocusedStack and mStacks.
- Remove stack from ActivityRecord.
- Add stack to TaskRecord.
Change-Id: I22e9ba34b12c2bd90806b14aafe063d5a2fe66ae
diff --git a/services/java/com/android/server/am/ActiveServices.java b/services/java/com/android/server/am/ActiveServices.java
index 5c24e67..10db70f 100644
--- a/services/java/com/android/server/am/ActiveServices.java
+++ b/services/java/com/android/server/am/ActiveServices.java
@@ -439,7 +439,7 @@
ActivityRecord activity = null;
if (token != null) {
- activity = mAm.mMainStack.isInStackLocked(token);
+ activity = ActivityRecord.isInStackLocked(token);
if (activity == null) {
Slog.w(TAG, "Binding with unknown activity: " + token);
return 0;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index d1b5071..21fbbda 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -272,7 +272,11 @@
static final String[] EMPTY_STRING_ARRAY = new String[0];
- public ActivityStack mMainStack;
+ /** All of the stacks in the system */
+ final public ArrayList<ActivityStack> mStacks = new ArrayList<ActivityStack>();
+
+ /** The current stack for manipulating */
+ public ActivityStack mFocusedStack;
private final boolean mHeadless;
@@ -749,7 +753,7 @@
* todo: Replace this with a TokenSpace class that generates non-repeating
* integers that won't wrap.
*/
- int mCurTask = 1;
+ private int mCurTask = 0;
/**
* Current sequence id for oom_adj computation traversal.
@@ -1461,8 +1465,9 @@
context.setTheme(android.R.style.Theme_Holo);
m.mContext = context;
m.mFactoryTest = factoryTest;
- m.mMainStack = new ActivityStack(m, context, true, thr.mLooper);
-
+ m.mFocusedStack = new ActivityStack(m, context, true, thr.mLooper);
+ m.mStacks.add(m.mFocusedStack);
+
m.mBatteryStatsService.publish(context);
m.mUsageStatsService.publish(context);
m.mAppOpsService.publish(context);
@@ -2292,7 +2297,7 @@
aInfo.applicationInfo.uid);
if (app == null || app.instrumentationClass == null) {
intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
- mMainStack.startActivityLocked(null, intent, null, aInfo,
+ mFocusedStack.startActivityLocked(null, intent, null, aInfo,
null, null, 0, 0, 0, null, 0, null, false, null);
}
}
@@ -2370,7 +2375,7 @@
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setComponent(new ComponentName(
ri.activityInfo.packageName, ri.activityInfo.name));
- mMainStack.startActivityLocked(null, intent, null, ri.activityInfo,
+ mFocusedStack.startActivityLocked(null, intent, null, ri.activityInfo,
null, null, 0, 0, 0, null, 0, null, false, null);
}
}
@@ -2500,7 +2505,7 @@
}
for (int i=0; i<N; i++) {
PendingActivityLaunch pal = mPendingActivityLaunches.get(i);
- mMainStack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
+ pal.r.task.stack.startActivityUncheckedLocked(pal.r, pal.sourceRecord,
pal.startFlags, doResume && i == (N-1), null);
}
mPendingActivityLaunches.clear();
@@ -2515,6 +2520,7 @@
startFlags, profileFile, profileFd, options, UserHandle.getCallingUserId());
}
+ @Override
public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags,
@@ -2522,11 +2528,12 @@
enforceNotIsolatedCaller("startActivity");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, true, "startActivity", null);
- return mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
+ return mFocusedStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
null, null, options, userId);
}
+ @Override
public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, String profileFile,
@@ -2535,12 +2542,13 @@
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, true, "startActivityAndWait", null);
WaitResult res = new WaitResult();
- mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
+ mFocusedStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, profileFile, profileFd,
res, null, options, UserHandle.getCallingUserId());
return res;
}
+ @Override
public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
Intent intent, String resolvedType, IBinder resultTo,
String resultWho, int requestCode, int startFlags, Configuration config,
@@ -2548,8 +2556,8 @@
enforceNotIsolatedCaller("startActivityWithConfig");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, true, "startActivityWithConfig", null);
- int ret = mMainStack.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
- resultTo, resultWho, requestCode, startFlags,
+ int ret = mFocusedStack.startActivityMayWait(caller, -1, callingPackage, intent,
+ resolvedType, resultTo, resultWho, requestCode, startFlags,
null, null, null, config, options, userId);
return ret;
}
@@ -2574,8 +2582,8 @@
synchronized (this) {
// If this is coming from the currently resumed activity, it is
// effectively saying that app switches are allowed at this point.
- if (mMainStack.mResumedActivity != null
- && mMainStack.mResumedActivity.info.applicationInfo.uid ==
+ if (mFocusedStack.mResumedActivity != null
+ && mFocusedStack.mResumedActivity.info.applicationInfo.uid ==
Binder.getCallingUid()) {
mAppSwitchesAllowedTime = 0;
}
@@ -2593,7 +2601,7 @@
}
synchronized (this) {
- ActivityRecord r = mMainStack.isInStackLocked(callingActivity);
+ final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
if (r == null) {
ActivityOptions.abort(options);
return false;
@@ -2667,7 +2675,7 @@
}
final long origId = Binder.clearCallingIdentity();
- int res = mMainStack.startActivityLocked(r.app.thread, intent,
+ int res = r.task.stack.startActivityLocked(r.app.thread, intent,
r.resolvedType, aInfo, resultTo != null ? resultTo.appToken : null,
resultWho, requestCode, -1, r.launchedFromUid, r.launchedFromPackage, 0,
options, false, null);
@@ -2688,7 +2696,7 @@
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, true, "startActivityInPackage", null);
- int ret = mMainStack.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
+ int ret = mFocusedStack.startActivityMayWait(null, uid, callingPackage, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags,
null, null, null, null, options, userId);
return ret;
@@ -2700,7 +2708,7 @@
enforceNotIsolatedCaller("startActivities");
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, true, "startActivity", null);
- int ret = mMainStack.startActivities(caller, -1, callingPackage, intents,
+ int ret = mFocusedStack.startActivities(caller, -1, callingPackage, intents,
resolvedTypes, resultTo, options, userId);
return ret;
}
@@ -2711,7 +2719,7 @@
userId = handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), userId,
false, true, "startActivityInPackage", null);
- int ret = mMainStack.startActivities(null, uid, callingPackage, intents, resolvedTypes,
+ int ret = mFocusedStack.startActivities(null, uid, callingPackage, intents, resolvedTypes,
resultTo, options, userId);
return ret;
}
@@ -2747,7 +2755,7 @@
public void setRequestedOrientation(IBinder token,
int requestedOrientation) {
synchronized (this) {
- ActivityRecord r = mMainStack.isInStackLocked(token);
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r == null) {
return;
}
@@ -2759,7 +2767,7 @@
if (config != null) {
r.frozenBeforeDestroy = true;
if (!updateConfigurationLocked(config, r, false, false)) {
- mMainStack.resumeTopActivityLocked(null);
+ r.task.stack.resumeTopActivityLocked(null);
}
}
Binder.restoreCallingIdentity(origId);
@@ -2768,7 +2776,7 @@
public int getRequestedOrientation(IBinder token) {
synchronized (this) {
- ActivityRecord r = mMainStack.isInStackLocked(token);
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r == null) {
return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
}
@@ -2785,6 +2793,7 @@
*
* @return Returns true if the activity successfully finished, or false if it is still running.
*/
+ @Override
public final boolean finishActivity(IBinder token, int resultCode, Intent resultData) {
// Refuse possible leaked file descriptors
if (resultData != null && resultData.hasFileDescriptors() == true) {
@@ -2792,9 +2801,13 @@
}
synchronized(this) {
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r == null) {
+ return true;
+ }
if (mController != null) {
// Find the first activity that is not finishing.
- ActivityRecord next = mMainStack.topRunningActivityLocked(token, 0);
+ ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
if (next != null) {
// ask watcher if this is allowed
boolean resumeOK = true;
@@ -2810,13 +2823,14 @@
}
}
final long origId = Binder.clearCallingIdentity();
- boolean res = mMainStack.requestFinishActivityLocked(token, resultCode,
+ boolean res = r.task.stack.requestFinishActivityLocked(token, resultCode,
resultData, "app-request", true);
Binder.restoreCallingIdentity(origId);
return res;
}
}
+ @Override
public final void finishHeavyWeightApp() {
if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
!= PackageManager.PERMISSION_GRANTED) {
@@ -2838,7 +2852,7 @@
for (int i=0; i<activities.size(); i++) {
ActivityRecord r = activities.get(i);
if (!r.finishing) {
- mMainStack.finishActivityLocked(r, Activity.RESULT_CANCELED,
+ r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
null, "finish-heavy", true);
}
}
@@ -2907,19 +2921,28 @@
}
}
+ @Override
public final void finishSubActivity(IBinder token, String resultWho,
int requestCode) {
synchronized(this) {
final long origId = Binder.clearCallingIdentity();
- mMainStack.finishSubActivityLocked(token, resultWho, requestCode);
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r != null) {
+ r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
+ }
Binder.restoreCallingIdentity(origId);
}
}
+ @Override
public boolean finishActivityAffinity(IBinder token) {
synchronized(this) {
final long origId = Binder.clearCallingIdentity();
- boolean res = mMainStack.finishActivityAffinityLocked(token);
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ boolean res = false;
+ if (r != null) {
+ res = r.task.stack.finishActivityAffinityLocked(r);
+ }
Binder.restoreCallingIdentity(origId);
return res;
}
@@ -2928,14 +2951,19 @@
@Override
public boolean willActivityBeVisible(IBinder token) {
synchronized(this) {
- return mMainStack.willActivityBeVisibleLocked(token);
+ ActivityStack stack = ActivityRecord.getStackLocked(token);
+ if (stack != null) {
+ return stack.willActivityBeVisibleLocked(token);
+ }
+ return false;
}
}
+ @Override
public void overridePendingTransition(IBinder token, String packageName,
int enterAnim, int exitAnim) {
synchronized(this) {
- ActivityRecord self = mMainStack.isInStackLocked(token);
+ ActivityRecord self = ActivityRecord.isInStackLocked(token);
if (self == null) {
return;
}
@@ -2969,20 +2997,37 @@
}
// Just in case...
- if (mMainStack.mPausingActivity != null && mMainStack.mPausingActivity.app == app) {
- if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
- "App died while pausing: " + mMainStack.mPausingActivity);
- mMainStack.mPausingActivity = null;
- }
- if (mMainStack.mLastPausedActivity != null && mMainStack.mLastPausedActivity.app == app) {
- mMainStack.mLastPausedActivity = null;
- }
+ final int numStacks = mStacks.size();
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ if (stack.mPausingActivity != null && stack.mPausingActivity.app == app) {
+ if (DEBUG_PAUSE || DEBUG_CLEANUP) Slog.v(TAG,
+ "App died while pausing: " + stack.mPausingActivity);
+ stack.mPausingActivity = null;
+ }
+ if (stack.mLastPausedActivity != null && stack.mLastPausedActivity.app == app) {
+ stack.mLastPausedActivity = null;
+ }
- // Remove this application's activities from active lists.
- boolean hasVisibleActivities = mMainStack.removeHistoryRecordsForAppLocked(app);
+ // Remove this application's activities from active lists.
+ boolean hasVisibleActivities = stack.removeHistoryRecordsForAppLocked(app);
+
+ if (!restarting) {
+ if (!stack.resumeTopActivityLocked(null)) {
+ // If there was nothing to resume, and we are not already
+ // restarting this process, but there is a visible activity that
+ // is hosted by the process... then make sure all visible
+ // activities are running, taking care of restarting this
+ // process.
+ if (hasVisibleActivities) {
+ stack.ensureActivitiesVisibleLocked(null, 0);
+ }
+ }
+ }
+ }
app.activities.clear();
-
+
if (app.instrumentationClass != null) {
Slog.w(TAG, "Crash of app " + app.processName
+ " running instrumentation " + app.instrumentationClass);
@@ -2990,19 +3035,6 @@
info.putString("shortMsg", "Process crashed.");
finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
}
-
- if (!restarting) {
- if (!mMainStack.resumeTopActivityLocked(null)) {
- // If there was nothing to resume, and we are not already
- // restarting this process, but there is a visible activity that
- // is hosted by the process... then make sure all visible
- // activities are running, taking care of restarting this
- // process.
- if (hasVisibleActivities) {
- mMainStack.ensureActivitiesVisibleLocked(null, 0);
- }
- }
- }
}
private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
@@ -3701,7 +3733,11 @@
}
mWindowManager.closeSystemDialogs(reason);
- mMainStack.closeSystemDialogsLocked();
+ final int numStacks = mStacks.size();
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ stack.closeSystemDialogsLocked();
+ }
broadcastIntentLocked(null, null, intent, null,
null, 0, null, null, null, AppOpsManager.OP_NONE, false, false, -1,
@@ -3909,11 +3945,15 @@
-100, callerWillRestart, true, doit, evenPersistent,
name == null ? ("force stop user " + userId) : ("force stop " + name));
- if (mMainStack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
- if (!doit) {
- return true;
+ final int numStacks = mStacks.size();
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ if (stack.forceStopPackageLocked(name, doit, evenPersistent, userId)) {
+ if (!doit) {
+ return true;
+ }
+ didSomething = true;
}
- didSomething = true;
}
if (mServices.forceStopLocked(name, userId, evenPersistent, doit)) {
@@ -4001,8 +4041,11 @@
}
}
if (mBooted) {
- mMainStack.resumeTopActivityLocked(null);
- mMainStack.scheduleIdleLocked();
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ stack.resumeTopActivityLocked(null);
+ stack.scheduleIdleLocked();
+ }
}
}
@@ -4255,14 +4298,14 @@
boolean didSomething = false;
// See if the top visible activity is waiting to run in this process...
- ActivityRecord hr = mMainStack.topRunningActivityLocked(null);
+ ActivityRecord hr = mFocusedStack.topRunningActivityLocked(null);
if (hr != null && normalMode) {
if (hr.app == null && app.uid == hr.info.applicationInfo.uid
&& processName.equals(hr.processName)) {
try {
if (mHeadless) {
Slog.e(TAG, "Starting activities not supported on headless device: " + hr);
- } else if (mMainStack.realStartActivityLocked(hr, app, true, true)) {
+ } else if (mFocusedStack.realStartActivityLocked(hr, app, true, true)) {
didSomething = true;
}
} catch (Exception e) {
@@ -4271,7 +4314,7 @@
badApp = true;
}
} else {
- mMainStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
+ mFocusedStack.ensureActivitiesVisibleLocked(hr, null, processName, 0);
}
}
@@ -4331,13 +4374,15 @@
}
}
+ @Override
public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
final long origId = Binder.clearCallingIdentity();
- ActivityRecord r = mMainStack.activityIdleInternal(token, false, config);
if (stopProfiling) {
synchronized (this) {
- if (mProfileProc == r.app) {
- if (mProfileFd != null) {
+ ActivityStack stack = ActivityRecord.getStackLocked(token);
+ if (stack != null) {
+ ActivityRecord r = stack.activityIdleInternal(token, false, config);
+ if ((mProfileProc == r.app) && (mProfileFd != null)) {
try {
mProfileFd.close();
} catch (IOException e) {
@@ -4374,7 +4419,7 @@
mLockScreenShown = false;
comeOutOfSleepIfNeededLocked();
}
- mMainStack.dismissKeyguardOnNextActivityLocked();
+ mFocusedStack.dismissKeyguardOnNextActivityLocked();
}
} finally {
Binder.restoreCallingIdentity(token);
@@ -4460,18 +4505,31 @@
}
}
+ @Override
public final void activityResumed(IBinder token) {
final long origId = Binder.clearCallingIdentity();
- mMainStack.activityResumed(token);
+ synchronized(this) {
+ ActivityStack stack = ActivityRecord.getStackLocked(token);
+ if (stack != null) {
+ stack.activityResumedLocked(token);
+ }
+ }
Binder.restoreCallingIdentity(origId);
}
+ @Override
public final void activityPaused(IBinder token) {
final long origId = Binder.clearCallingIdentity();
- mMainStack.activityPaused(token, false);
+ synchronized(this) {
+ ActivityStack stack = ActivityRecord.getStackLocked(token);
+ if (stack != null) {
+ stack.activityPausedLocked(token, false);
+ }
+ }
Binder.restoreCallingIdentity(origId);
}
+ @Override
public final void activityStopped(IBinder token, Bundle icicle, Bitmap thumbnail,
CharSequence description) {
if (localLOGV) Slog.v(
@@ -4487,9 +4545,9 @@
final long origId = Binder.clearCallingIdentity();
synchronized (this) {
- r = mMainStack.isInStackLocked(token);
+ r = ActivityRecord.isInStackLocked(token);
if (r != null) {
- r.stack.activityStoppedLocked(r, icicle, thumbnail, description);
+ r.task.stack.activityStoppedLocked(r, icicle, thumbnail, description);
}
}
@@ -4502,9 +4560,15 @@
Binder.restoreCallingIdentity(origId);
}
+ @Override
public final void activityDestroyed(IBinder token) {
if (DEBUG_SWITCH) Slog.v(TAG, "ACTIVITY DESTROYED: " + token);
- mMainStack.activityDestroyed(token);
+ synchronized (this) {
+ ActivityStack stack = ActivityRecord.getStackLocked(token);
+ if (stack != null) {
+ stack.activityDestroyedLocked(token);
+ }
+ }
}
public String getCallingPackage(IBinder token) {
@@ -4522,16 +4586,17 @@
}
private ActivityRecord getCallingRecordLocked(IBinder token) {
- ActivityRecord r = mMainStack.isInStackLocked(token);
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r == null) {
return null;
}
return r.resultTo;
}
+ @Override
public ComponentName getActivityClassForToken(IBinder token) {
synchronized(this) {
- ActivityRecord r = mMainStack.isInStackLocked(token);
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r == null) {
return null;
}
@@ -4541,7 +4606,7 @@
public String getPackageForToken(IBinder token) {
synchronized(this) {
- ActivityRecord r = mMainStack.isInStackLocked(token);
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r == null) {
return null;
}
@@ -4619,7 +4684,7 @@
}
}
}
-
+
IIntentSender getIntentSenderLocked(int type, String packageName,
int callingUid, int userId, IBinder token, String resultWho,
int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
@@ -4628,7 +4693,7 @@
Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
ActivityRecord activity = null;
if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
- activity = mMainStack.isInStackLocked(token);
+ activity = ActivityRecord.isInStackLocked(token);
if (activity == null) {
return null;
}
@@ -5654,7 +5719,8 @@
throw new SecurityException(msg);
}
- topRecord = mMainStack.getTasksLocked(maxNum, receiver, pending, list);
+ // TODO: Improve with MRU list from all ActivityStacks.
+ topRecord = mFocusedStack.getTasksLocked(maxNum, receiver, pending, list);
if (!pending.pendingRecords.isEmpty()) {
mPendingThumbnails.add(pending);
@@ -5760,49 +5826,77 @@
}
}
- private TaskRecord taskForIdLocked(int id) {
+ private TaskRecord recentTaskForIdLocked(int id) {
final int N = mRecentTasks.size();
- for (int i=0; i<N; i++) {
- TaskRecord tr = mRecentTasks.get(i);
- if (tr.taskId == id) {
- return tr;
+ for (int i=0; i<N; i++) {
+ TaskRecord tr = mRecentTasks.get(i);
+ if (tr.taskId == id) {
+ return tr;
+ }
+ }
+ return null;
+ }
+
+ TaskRecord anyTaskForIdLocked(int id) {
+ for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+ ActivityStack stack = mStacks.get(stackNdx);
+ TaskRecord task = stack.taskForIdLocked(id);
+ if (task != null) {
+ return task;
}
}
return null;
}
+ int getNextTaskId() {
+ do {
+ mCurTask++;
+ if (mCurTask <= 0) {
+ mCurTask = 1;
+ }
+ } while (anyTaskForIdLocked(mCurTask) != null);
+ return mCurTask;
+ }
+
+ @Override
public ActivityManager.TaskThumbnails getTaskThumbnails(int id) {
synchronized (this) {
enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
"getTaskThumbnails()");
- TaskRecord tr = taskForIdLocked(id);
+ TaskRecord tr = recentTaskForIdLocked(id);
if (tr != null) {
- return mMainStack.getTaskThumbnailsLocked(tr);
+ return tr.stack.getTaskThumbnailsLocked(tr);
}
}
return null;
}
+ @Override
public Bitmap getTaskTopThumbnail(int id) {
synchronized (this) {
enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
"getTaskTopThumbnail()");
- TaskRecord tr = taskForIdLocked(id);
+ TaskRecord tr = recentTaskForIdLocked(id);
if (tr != null) {
- return mMainStack.getTaskTopThumbnailLocked(tr);
+ return tr.stack.getTaskTopThumbnailLocked(tr);
}
}
return null;
}
+ @Override
public boolean removeSubTask(int taskId, int subTaskIndex) {
synchronized (this) {
enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
"removeSubTask()");
long ident = Binder.clearCallingIdentity();
try {
- return mMainStack.removeTaskActivitiesLocked(taskId, subTaskIndex,
- true) != null;
+ TaskRecord tr = recentTaskForIdLocked(taskId);
+ if (tr != null) {
+ return tr.stack.removeTaskActivitiesLocked(taskId, subTaskIndex,
+ true) != null;
+ }
+ return false;
} finally {
Binder.restoreCallingIdentity(ident);
}
@@ -5856,43 +5950,32 @@
}
}
+ @Override
public boolean removeTask(int taskId, int flags) {
synchronized (this) {
enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS,
"removeTask()");
long ident = Binder.clearCallingIdentity();
try {
- ActivityRecord r = mMainStack.removeTaskActivitiesLocked(taskId, -1,
- false);
- if (r != null) {
- mRecentTasks.remove(r.task);
- cleanUpRemovedTaskLocked(r.task, flags);
- return true;
- } else {
- TaskRecord tr = null;
- int i=0;
- while (i < mRecentTasks.size()) {
- TaskRecord t = mRecentTasks.get(i);
- if (t.taskId == taskId) {
- tr = t;
- break;
- }
- i++;
+ TaskRecord tr = recentTaskForIdLocked(taskId);
+ if (tr != null) {
+ ActivityRecord r = tr.stack.removeTaskActivitiesLocked(taskId, -1, false);
+ if (r != null) {
+ mRecentTasks.remove(tr);
+ cleanUpRemovedTaskLocked(tr, flags);
+ return true;
}
- if (tr != null) {
- if (tr.numActivities <= 0) {
- // Caller is just removing a recent task that is
- // not actively running. That is easy!
- mRecentTasks.remove(i);
- cleanUpRemovedTaskLocked(tr, flags);
- return true;
- } else {
- Slog.w(TAG, "removeTask: task " + taskId
- + " does not have activities to remove, "
- + " but numActivities=" + tr.numActivities
- + ": " + tr);
- }
+ if (tr.mActivities.size() == 0) {
+ // Caller is just removing a recent task that is
+ // not actively running. That is easy!
+ mRecentTasks.remove(tr);
+ cleanUpRemovedTaskLocked(tr, flags);
+ return true;
}
+ Slog.w(TAG, "removeTask: task " + taskId
+ + " does not have activities to remove, "
+ + " but numActivities=" + tr.numActivities
+ + ": " + tr);
}
} finally {
Binder.restoreCallingIdentity(ident);
@@ -5904,6 +5987,7 @@
/**
* TODO: Add mController hook
*/
+ @Override
public void moveTaskToFront(int task, int flags, Bundle options) {
enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
"moveTaskToFront()");
@@ -5916,21 +6000,25 @@
}
final long origId = Binder.clearCallingIdentity();
try {
- TaskRecord tr = taskForIdLocked(task);
+ TaskRecord tr = recentTaskForIdLocked(task);
if (tr != null) {
+ ActivityStack stack = tr.stack;
if ((flags&ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
- mMainStack.mUserLeaving = true;
+ stack.mUserLeaving = true;
}
if ((flags&ActivityManager.MOVE_TASK_WITH_HOME) != 0) {
// Caller wants the home activity moved with it. To accomplish this,
// we'll just move the home task to the top first.
- mMainStack.moveHomeToFrontLocked();
+ stack.moveHomeToFrontLocked();
}
- mMainStack.moveTaskToFrontLocked(tr, null, options);
+ stack.moveTaskToFrontLocked(tr, null, options);
return;
}
- if (mMainStack.findTaskToMoveToFrontLocked(task, flags, options)) {
- return;
+ // Failed to find the task in the recents list. Look in all stacks.
+ for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) {
+ if (mStacks.get(stackNdx).findTaskToMoveToFrontLocked(task, flags, options)) {
+ return;
+ }
}
} finally {
Binder.restoreCallingIdentity(origId);
@@ -5939,21 +6027,25 @@
}
}
+ @Override
public void moveTaskToBack(int task) {
enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
"moveTaskToBack()");
synchronized(this) {
- if (mMainStack.mResumedActivity != null
- && mMainStack.mResumedActivity.task.taskId == task) {
- if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
- Binder.getCallingUid(), "Task to back")) {
- return;
+ TaskRecord tr = recentTaskForIdLocked(task);
+ if (tr != null) {
+ ActivityStack stack = tr.stack;
+ if (stack.mResumedActivity != null && stack.mResumedActivity.task == tr) {
+ if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
+ Binder.getCallingUid(), "Task to back")) {
+ return;
+ }
}
+ final long origId = Binder.clearCallingIdentity();
+ stack.moveTaskToBackLocked(task, null);
+ Binder.restoreCallingIdentity(origId);
}
- final long origId = Binder.clearCallingIdentity();
- mMainStack.moveTaskToBackLocked(task, null);
- Binder.restoreCallingIdentity(origId);
}
}
@@ -5966,13 +6058,14 @@
* of a task; if true it will work for any activity in a task.
* @return Returns true if the move completed, false if not.
*/
+ @Override
public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
enforceNotIsolatedCaller("moveActivityTaskToBack");
synchronized(this) {
final long origId = Binder.clearCallingIdentity();
- int taskId = mMainStack.getTaskForActivityLocked(token, !nonRoot);
+ int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
if (taskId >= 0) {
- return mMainStack.moveTaskToBackLocked(taskId, null);
+ return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId, null);
}
Binder.restoreCallingIdentity(origId);
}
@@ -5998,9 +6091,10 @@
Slog.e(TAG, "moveTaskBackwards not yet implemented!");
}
+ @Override
public int getTaskForActivity(IBinder token, boolean onlyRoot) {
synchronized(this) {
- return mMainStack.getTaskForActivityLocked(token, onlyRoot);
+ return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
}
}
@@ -6025,7 +6119,7 @@
synchronized(this) {
if (r == null) {
- r = mMainStack.isInStackLocked(token);
+ r = ActivityRecord.isInStackLocked(token);
if (r == null) {
return;
}
@@ -6911,7 +7005,7 @@
synchronized(this) {
final long origId = Binder.clearCallingIdentity();
try {
- mMainStack.unhandledBackLocked();
+ mFocusedStack.unhandledBackLocked();
} finally {
Binder.restoreCallingIdentity(origId);
}
@@ -6970,7 +7064,11 @@
if (!mSleeping) {
mSleeping = true;
- mMainStack.stopIfSleepingLocked();
+ final int numStacks = mStacks.size();
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ stack.stopIfSleepingLocked();
+ }
// Initialize the wake times of all processes.
checkExcessivePowerUsageLocked(false);
@@ -6981,33 +7079,38 @@
}
}
+ @Override
public boolean shutdown(int timeout) {
if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
!= PackageManager.PERMISSION_GRANTED) {
throw new SecurityException("Requires permission "
+ android.Manifest.permission.SHUTDOWN);
}
-
+
boolean timedout = false;
-
+
synchronized(this) {
mShuttingDown = true;
updateEventDispatchingLocked();
- if (mMainStack.mResumedActivity != null) {
- mMainStack.stopIfSleepingLocked();
- final long endTime = System.currentTimeMillis() + timeout;
- while (mMainStack.mResumedActivity != null
- || mMainStack.mPausingActivity != null) {
- long delay = endTime - System.currentTimeMillis();
- if (delay <= 0) {
- Slog.w(TAG, "Activity manager shutdown timed out");
- timedout = true;
- break;
- }
- try {
- this.wait();
- } catch (InterruptedException e) {
+ final int numStacks = mStacks.size();
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ if (stack.mResumedActivity != null) {
+ stack.stopIfSleepingLocked();
+ final long endTime = System.currentTimeMillis() + timeout;
+ while (stack.mResumedActivity != null
+ || stack.mPausingActivity != null) {
+ long delay = endTime - System.currentTimeMillis();
+ if (delay <= 0) {
+ Slog.w(TAG, "Activity manager shutdown timed out");
+ timedout = true;
+ break;
+ }
+ try {
+ this.wait();
+ } catch (InterruptedException e) {
+ }
}
}
}
@@ -7016,7 +7119,7 @@
mAppOpsService.shutdown();
mUsageStatsService.shutdown();
mBatteryStatsService.shutdown();
-
+
return timedout;
}
@@ -7029,9 +7132,9 @@
final long origId = Binder.clearCallingIdentity();
synchronized (this) {
- r = mMainStack.isInStackLocked(token);
+ r = ActivityRecord.isInStackLocked(token);
if (r != null) {
- mMainStack.activitySleptLocked(r);
+ r.task.stack.activitySleptLocked(r);
}
}
@@ -7042,8 +7145,12 @@
if (!mWentToSleep && !mLockScreenShown) {
if (mSleeping) {
mSleeping = false;
- mMainStack.awakeFromSleepingLocked();
- mMainStack.resumeTopActivityLocked(null);
+ final int numStacks = mStacks.size();
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ stack.awakeFromSleepingLocked();
+ stack.resumeTopActivityLocked(null);
+ }
}
}
}
@@ -7318,7 +7425,7 @@
PendingActivityExtras pae;
Bundle extras = new Bundle();
synchronized (this) {
- ActivityRecord activity = mMainStack.mResumedActivity;
+ ActivityRecord activity = mFocusedStack.mResumedActivity;
if (activity == null) {
Slog.w(TAG, "getTopActivityExtras failed: no resumed activity");
return null;
@@ -7385,7 +7492,7 @@
public void setImmersive(IBinder token, boolean immersive) {
synchronized(this) {
- final ActivityRecord r = mMainStack.isInStackLocked(token);
+ final ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r == null) {
throw new IllegalArgumentException();
}
@@ -7403,7 +7510,7 @@
public boolean isImmersive(IBinder token) {
synchronized (this) {
- ActivityRecord r = mMainStack.isInStackLocked(token);
+ ActivityRecord r = ActivityRecord.isInStackLocked(token);
if (r == null) {
throw new IllegalArgumentException();
}
@@ -7414,7 +7521,7 @@
public boolean isTopActivityImmersive() {
enforceNotIsolatedCaller("startActivity");
synchronized (this) {
- ActivityRecord r = mMainStack.topRunningActivityLocked(null);
+ ActivityRecord r = mFocusedStack.topRunningActivityLocked(null);
return (r != null) ? r.immersive : false;
}
}
@@ -7912,7 +8019,7 @@
} finally {
Binder.restoreCallingIdentity(ident);
}
- mMainStack.resumeTopActivityLocked(null);
+ mFocusedStack.resumeTopActivityLocked(null);
sendUserSwitchBroadcastsLocked(-1, mCurrentUserId);
}
}
@@ -8001,13 +8108,17 @@
} else {
crashTime = null;
}
+ final int numStacks = mStacks.size();
if (crashTime != null && now < crashTime+ProcessList.MIN_CRASH_INTERVAL) {
// This process loses!
Slog.w(TAG, "Process " + app.info.processName
+ " has crashed too many times: killing!");
EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH,
app.userId, app.info.processName, app.uid);
- mMainStack.handleAppCrashLocked(app);
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ stack.handleAppCrashLocked(app);
+ }
if (!app.persistent) {
// We don't want to start this process again until the user
// explicitly does so... but for persistent process, we really
@@ -8027,12 +8138,21 @@
// annoy the user repeatedly. Unless it is persistent, since those
// processes run critical code.
removeProcessLocked(app, false, false, "crash");
- mMainStack.resumeTopActivityLocked(null);
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ stack.resumeTopActivityLocked(null);
+ }
return false;
}
- mMainStack.resumeTopActivityLocked(null);
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ stack.resumeTopActivityLocked(null);
+ }
} else {
- mMainStack.finishTopRunningActivityLocked(app);
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ stack.finishTopRunningActivityLocked(app);
+ }
}
// Bump up the crash count of any services currently running in the proc.
@@ -8052,9 +8172,9 @@
// from blocking the user to manually clear the list.
if (app == mHomeProcess && mHomeProcess.activities.size() > 0
&& (mHomeProcess.info.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
- Iterator it = mHomeProcess.activities.iterator();
+ Iterator<ActivityRecord> it = mHomeProcess.activities.iterator();
while (it.hasNext()) {
- ActivityRecord r = (ActivityRecord)it.next();
+ ActivityRecord r = it.next();
if (r.isHomeActivity) {
Log.i(TAG, "Clearing package preferred activities from " + r.packageName);
try {
@@ -9050,48 +9170,57 @@
boolean dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
- pw.println(" Main stack:");
- mMainStack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage);
- pw.println(" ");
- pw.println(" Running activities (most recent first):");
- dumpHistoryList(fd, pw, mMainStack.mLRUActivities, " ", "Run", false, !dumpAll, false,
- dumpPackage);
- if (mMainStack.mWaitingVisibleActivities.size() > 0) {
+ final int numStacks = mStacks.size();
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ pw.print(" Stack #"); pw.print(mStacks.indexOf(stack)); pw.println(":");
+ stack.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient, dumpPackage);
pw.println(" ");
- pw.println(" Activities waiting for another to become visible:");
- dumpHistoryList(fd, pw, mMainStack.mWaitingVisibleActivities, " ", "Wait", false,
- !dumpAll, false, dumpPackage);
- }
- if (mMainStack.mStoppingActivities.size() > 0) {
- pw.println(" ");
- pw.println(" Activities waiting to stop:");
- dumpHistoryList(fd, pw, mMainStack.mStoppingActivities, " ", "Stop", false,
- !dumpAll, false, dumpPackage);
- }
- if (mMainStack.mGoingToSleepActivities.size() > 0) {
- pw.println(" ");
- pw.println(" Activities waiting to sleep:");
- dumpHistoryList(fd, pw, mMainStack.mGoingToSleepActivities, " ", "Sleep", false,
- !dumpAll, false, dumpPackage);
- }
- if (mMainStack.mFinishingActivities.size() > 0) {
- pw.println(" ");
- pw.println(" Activities waiting to finish:");
- dumpHistoryList(fd, pw, mMainStack.mFinishingActivities, " ", "Fin", false,
- !dumpAll, false, dumpPackage);
+ pw.println(" Running activities (most recent first):");
+ dumpHistoryList(fd, pw, stack.mLRUActivities, " ", "Run", false, !dumpAll, false,
+ dumpPackage);
+ if (stack.mWaitingVisibleActivities.size() > 0) {
+ pw.println(" ");
+ pw.println(" Activities waiting for another to become visible:");
+ dumpHistoryList(fd, pw, stack.mWaitingVisibleActivities, " ", "Wait", false,
+ !dumpAll, false, dumpPackage);
+ }
+ if (stack.mStoppingActivities.size() > 0) {
+ pw.println(" ");
+ pw.println(" Activities waiting to stop:");
+ dumpHistoryList(fd, pw, stack.mStoppingActivities, " ", "Stop", false,
+ !dumpAll, false, dumpPackage);
+ }
+ if (stack.mGoingToSleepActivities.size() > 0) {
+ pw.println(" ");
+ pw.println(" Activities waiting to sleep:");
+ dumpHistoryList(fd, pw, stack.mGoingToSleepActivities, " ", "Sleep", false,
+ !dumpAll, false, dumpPackage);
+ }
+ if (stack.mFinishingActivities.size() > 0) {
+ pw.println(" ");
+ pw.println(" Activities waiting to finish:");
+ dumpHistoryList(fd, pw, stack.mFinishingActivities, " ", "Fin", false,
+ !dumpAll, false, dumpPackage);
+ }
}
pw.println(" ");
- if (mMainStack.mPausingActivity != null) {
- pw.println(" mPausingActivity: " + mMainStack.mPausingActivity);
- }
- pw.println(" mResumedActivity: " + mMainStack.mResumedActivity);
pw.println(" mFocusedActivity: " + mFocusedActivity);
- if (dumpAll) {
- pw.println(" mLastPausedActivity: " + mMainStack.mLastPausedActivity);
- pw.println(" mSleepTimeout: " + mMainStack.mSleepTimeout);
- pw.println(" mDismissKeyguardOnNextActivity: "
- + mMainStack.mDismissKeyguardOnNextActivity);
+ pw.println(" ");
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ pw.print(" Stack #"); pw.println(mStacks.indexOf(stack));
+ if (stack.mPausingActivity != null) {
+ pw.println(" mPausingActivity: " + stack.mPausingActivity);
+ }
+ pw.println(" mResumedActivity: " + stack.mResumedActivity);
+ if (dumpAll) {
+ pw.println(" mLastPausedActivity: " + stack.mLastPausedActivity);
+ pw.println(" mSleepTimeout: " + stack.mSleepTimeout);
+ pw.println(" mDismissKeyguardOnNextActivity: "
+ + stack.mDismissKeyguardOnNextActivity);
+ }
}
if (mRecentTasks.size() > 0) {
@@ -9336,7 +9465,7 @@
}
pw.println(" mConfiguration: " + mConfiguration);
if (dumpAll) {
- pw.println(" mConfigWillChange: " + mMainStack.mConfigWillChange);
+ pw.println(" mConfigWillChange: " + mFocusedStack.mConfigWillChange);
if (mCompatModePackages.getPackages().size() > 0) {
boolean printed = false;
for (Map.Entry<String, Integer> entry
@@ -9396,8 +9525,8 @@
pw.print(" mLastPowerCheckUptime=");
TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
pw.println("");
- pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
- pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
+ pw.println(" mGoingToSleep=" + mFocusedStack.mGoingToSleep);
+ pw.println(" mLaunchingActivity=" + mFocusedStack.mLaunchingActivity);
pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
pw.println(" mNumNonHiddenProcs=" + mNumNonHiddenProcs
+ " mNumHiddenProcs=" + mNumHiddenProcs
@@ -9584,7 +9713,7 @@
ArrayList<ActivityRecord> activities;
synchronized (this) {
- activities = mMainStack.getDumpActivitiesLocked(name);
+ activities = mFocusedStack.getDumpActivitiesLocked(name);
}
if (activities.size() <= 0) {
@@ -12314,21 +12443,25 @@
}
}
}
-
- if (changes != 0 && starting == null) {
- // If the configuration changed, and the caller is not already
- // in the process of starting an activity, then find the top
- // activity to check if its configuration needs to change.
- starting = mMainStack.topRunningActivityLocked(null);
+
+ final int numStacks = mStacks.size();
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ if (changes != 0 && starting == null) {
+ // If the configuration changed, and the caller is not already
+ // in the process of starting an activity, then find the top
+ // activity to check if its configuration needs to change.
+ starting = stack.topRunningActivityLocked(null);
+ }
+
+ if (starting != null) {
+ kept = stack.ensureActivityConfigurationLocked(starting, changes);
+ // And we need to make sure at this point that all other activities
+ // are made visible with the correct configuration.
+ stack.ensureActivitiesVisibleLocked(starting, changes);
+ }
}
-
- if (starting != null) {
- kept = mMainStack.ensureActivityConfigurationLocked(starting, changes);
- // And we need to make sure at this point that all other activities
- // are made visible with the correct configuration.
- mMainStack.ensureActivitiesVisibleLocked(starting, changes);
- }
-
+
if (values != null && mWindowManager != null) {
mWindowManager.setNewConfiguration(mConfiguration);
}
@@ -12376,12 +12509,11 @@
Intent resultData) {
synchronized (this) {
- ActivityRecord srec = ActivityRecord.forToken(token);
- if (srec == null) {
- return false;
+ final ActivityStack stack = ActivityRecord.getStackLocked(token);
+ if (stack != null) {
+ return stack.navigateUpToLocked(token, destIntent, resultCode, resultData);
}
- ActivityStack stack = srec.stack;
- return stack.navigateUpToLocked(srec, destIntent, resultCode, resultData);
+ return false;
}
}
@@ -13122,8 +13254,8 @@
}
}
return !processingBroadcasts
- && (mSleeping || (mMainStack.mResumedActivity != null &&
- mMainStack.mResumedActivity.idle));
+ && (mSleeping || (mFocusedStack.mResumedActivity != null &&
+ mFocusedStack.mResumedActivity.idle));
}
/**
@@ -13407,11 +13539,11 @@
}
private final ActivityRecord resumedAppLocked() {
- ActivityRecord resumedActivity = mMainStack.mResumedActivity;
+ ActivityRecord resumedActivity = mFocusedStack.mResumedActivity;
if (resumedActivity == null || resumedActivity.app == null) {
- resumedActivity = mMainStack.mPausingActivity;
+ resumedActivity = mFocusedStack.mPausingActivity;
if (resumedActivity == null || resumedActivity.app == null) {
- resumedActivity = mMainStack.topRunningActivityLocked(null);
+ resumedActivity = mFocusedStack.topRunningActivityLocked(null);
}
}
return resumedActivity;
@@ -13657,7 +13789,11 @@
// be in a consistent state at this point.
// For these apps we will also finish their activities
// to help them free memory.
- mMainStack.scheduleDestroyActivities(app, false, "trim");
+ final int numStacks = mStacks.size();
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ stack.scheduleDestroyActivities(app, false, "trim");
+ }
}
}
}
@@ -13731,7 +13867,11 @@
if (mAlwaysFinishActivities) {
// Need to do this on its own message because the stack may not
// be in a consistent state at this point.
- mMainStack.scheduleDestroyActivities(null, false, "always-finish");
+ final int numStacks = mStacks.size();
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ stack.scheduleDestroyActivities(null, false, "always-finish");
+ }
}
}
@@ -14097,7 +14237,12 @@
}
}
- boolean haveActivities = mMainStack.switchUserLocked(userId, uss);
+ boolean haveActivities = false;
+ final int numStacks = mStacks.size();
+ for (int stackNdx = 0; stackNdx < numStacks; ++stackNdx) {
+ final ActivityStack stack = mStacks.get(stackNdx);
+ haveActivities |= stack.switchUserLocked(userId, uss);
+ }
if (!haveActivities) {
startHomeActivityLocked(userId);
}
diff --git a/services/java/com/android/server/am/ActivityRecord.java b/services/java/com/android/server/am/ActivityRecord.java
index d134c13..2075af7 100644
--- a/services/java/com/android/server/am/ActivityRecord.java
+++ b/services/java/com/android/server/am/ActivityRecord.java
@@ -20,7 +20,6 @@
import com.android.server.AttributeCache;
import com.android.server.am.ActivityStack.ActivityState;
-import android.app.Activity;
import android.app.ActivityOptions;
import android.app.ResultInfo;
import android.content.ComponentName;
@@ -56,7 +55,6 @@
*/
final class ActivityRecord {
final ActivityManagerService service; // owner
- final ActivityStack stack; // owner
final IApplicationToken.Stub appToken; // window manager token
final ActivityInfo info; // all about me
final int launchedFromUid; // always the uid who started the activity.
@@ -183,7 +181,7 @@
if (newIntents != null && newIntents.size() > 0) {
pw.print(prefix); pw.println("Pending New Intents:");
for (int i=0; i<newIntents.size(); i++) {
- Intent intent = (Intent)newIntents.get(i);
+ Intent intent = newIntents.get(i);
pw.print(prefix); pw.print(" - ");
if (intent == null) {
pw.println("null");
@@ -327,13 +325,12 @@
}
}
- ActivityRecord(ActivityManagerService _service, ActivityStack _stack, ProcessRecord _caller,
+ ActivityRecord(ActivityManagerService _service, ProcessRecord _caller,
int _launchedFromUid, String _launchedFromPackage, Intent _intent, String _resolvedType,
ActivityInfo aInfo, Configuration _configuration,
ActivityRecord _resultTo, String _resultWho, int _reqCode,
boolean _componentSpecified) {
service = _service;
- stack = _stack;
appToken = new Token(this);
info = aInfo;
launchedFromUid = _launchedFromUid;
@@ -565,7 +562,7 @@
void addNewIntentLocked(Intent intent) {
if (newIntents == null) {
- newIntents = new ArrayList();
+ newIntents = new ArrayList<Intent>();
}
newIntents.add(intent);
}
@@ -585,7 +582,7 @@
// case we will deliver it if this is the current top activity on its
// stack.
if ((state == ActivityState.RESUMED || (service.mSleeping
- && stack.topRunningActivityLocked(null) == this))
+ && task.stack.topRunningActivityLocked(null) == this))
&& app != null && app.thread != null) {
try {
ArrayList<Intent> ar = new ArrayList<Intent>();
@@ -729,6 +726,7 @@
boolean continueLaunchTickingLocked() {
if (launchTickTime != 0) {
+ final ActivityStack stack = task.stack;
Message msg = stack.mHandler.obtainMessage(ActivityStack.LAUNCH_TICK_MSG);
msg.obj = this;
stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
@@ -740,7 +738,7 @@
void finishLaunchTickingLocked() {
launchTickTime = 0;
- stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
+ task.stack.mHandler.removeMessages(ActivityStack.LAUNCH_TICK_MSG);
}
// IApplicationToken
@@ -769,6 +767,7 @@
public void windowsDrawn() {
synchronized(service) {
if (launchTime != 0) {
+ final ActivityStack stack = task.stack;
final long curTime = SystemClock.uptimeMillis();
final long thisTime = curTime - launchTime;
final long totalTime = stack.mInitialStartTime != 0
@@ -804,6 +803,7 @@
public void windowsVisible() {
synchronized(service) {
+ final ActivityStack stack = task.stack;
stack.reportActivityVisibleLocked(this);
if (ActivityManagerService.DEBUG_SWITCH) Log.v(
ActivityManagerService.TAG, "windowsVisible(): " + this);
@@ -824,8 +824,7 @@
final int N = stack.mWaitingVisibleActivities.size();
if (N > 0) {
for (int i=0; i<N; i++) {
- ActivityRecord r = (ActivityRecord)
- stack.mWaitingVisibleActivities.get(i);
+ ActivityRecord r = stack.mWaitingVisibleActivities.get(i);
r.waitingVisible = false;
if (ActivityManagerService.DEBUG_SWITCH) Log.v(
ActivityManagerService.TAG,
@@ -853,6 +852,7 @@
// for another app to start, then we have paused dispatching
// for this activity.
ActivityRecord r = this;
+ final ActivityStack stack = task.stack;
if (r.waitingVisible) {
// Hmmm, who might we be waiting for?
r = stack.mResumedActivity;
@@ -902,6 +902,7 @@
if (app != null && app.thread != null) {
try {
app.thread.scheduleSleeping(appToken, _sleeping);
+ final ActivityStack stack = task.stack;
if (sleeping && !stack.mGoingToSleepActivities.contains(this)) {
stack.mGoingToSleepActivities.add(this);
}
@@ -913,6 +914,35 @@
}
}
+ static int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
+ final ActivityRecord r = ActivityRecord.forToken(token);
+ if (r == null) {
+ return -1;
+ }
+ final TaskRecord task = r.task;
+ switch (task.mActivities.indexOf(r)) {
+ case -1: return -1;
+ case 0: return task.taskId;
+ default: return onlyRoot ? -1 : task.taskId;
+ }
+ }
+
+ static ActivityRecord isInStackLocked(IBinder token) {
+ final ActivityRecord r = ActivityRecord.forToken(token);
+ if (r != null) {
+ return r.task.stack.isInStackLocked(token);
+ }
+ return null;
+ }
+
+ static final ActivityStack getStackLocked(IBinder token) {
+ final ActivityRecord r = ActivityRecord.isInStackLocked(token);
+ if (r != null) {
+ return r.task.stack;
+ }
+ return null;
+ }
+
@Override
public String toString() {
if (stringName != null) {
diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java
index 21fe0e8..fa7a024 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -164,11 +164,6 @@
private ArrayList<TaskRecord> mTaskHistory = new ArrayList<TaskRecord>();
/**
- * Mapping from taskId to TaskRecord
- */
- private SparseArray<TaskRecord> mTaskIdToTaskRecord = new SparseArray<TaskRecord>();
-
- /**
* Used for validating app tokens with window manager.
*/
final ArrayList<TaskGroup> mValidateAppTokens = new ArrayList<TaskGroup>();
@@ -368,9 +363,9 @@
mService.logAppTooSlow(r.app, r.pauseTime,
"pausing " + r);
}
- }
- activityPaused(r != null ? r.appToken : null, true);
+ activityPausedLocked(r != null ? r.appToken : null, true);
+ }
} break;
case IDLE_TIMEOUT_MSG: {
if (mService.mDidDexOpt) {
@@ -400,7 +395,9 @@
// We don't at this point know if the activity is fullscreen,
// so we need to be conservative and assume it isn't.
Slog.w(TAG, "Activity destroy timeout for " + r);
- activityDestroyed(r != null ? r.appToken : null);
+ synchronized (mService) {
+ activityDestroyedLocked(r != null ? r.appToken : null);
+ }
} break;
case IDLE_NOW_MSG: {
ActivityRecord r = (ActivityRecord)msg.obj;
@@ -526,28 +523,27 @@
return null;
}
- final ActivityRecord isInStackLocked(IBinder token) {
- final ActivityRecord r = ActivityRecord.forToken(token);
- if (r != null) {
- final TaskRecord task = r.task;
- if (mTaskHistory.contains(task) && task.mActivities.contains(r)) {
- return r;
+ TaskRecord taskForIdLocked(int id) {
+ for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
+ final TaskRecord task = mTaskHistory.get(taskNdx);
+ if (task.taskId == id) {
+ return task;
}
}
return null;
}
- int getTaskForActivityLocked(IBinder token, boolean onlyRoot) {
+ ActivityRecord isInStackLocked(IBinder token) {
final ActivityRecord r = ActivityRecord.forToken(token);
- if (r == null) {
- return -1;
+ if (r != null) {
+ final TaskRecord task = r.task;
+ if (task.mActivities.contains(r) && mTaskHistory.contains(task)) {
+ if (task.stack != this) Slog.w(TAG,
+ "Illegal state! task does not point to stack it is in.");
+ return r;
+ }
}
- final TaskRecord task = r.task;
- switch (task.mActivities.indexOf(r)) {
- case -1: return -1;
- case 0: return task.taskId;
- default: return onlyRoot ? -1 : task.taskId;
- }
+ return null;
}
private final boolean updateLRUListLocked(ActivityRecord r) {
@@ -819,9 +815,7 @@
r.stopped = false;
mResumedActivity = r;
r.task.touchActiveTime();
- if (mMainStack) {
- mService.addRecentTaskLocked(r.task);
- }
+ mService.addRecentTaskLocked(r.task);
completeResumeLocked(r);
checkReadyForSleepLocked();
if (DEBUG_SAVED_STATE) Slog.i(TAG, "Launch completed; removing icicle of " + r.icicle);
@@ -1092,36 +1086,30 @@
}
}
- final void activityResumed(IBinder token) {
- synchronized (mService) {
- final ActivityRecord r = isInStackLocked(token);
- if (r != null) {
- if (DEBUG_SAVED_STATE) Slog.i(TAG, "Resumed activity; dropping state of: " + r);
- r.icicle = null;
- r.haveState = false;
- }
- }
+ final void activityResumedLocked(IBinder token) {
+ final ActivityRecord r = ActivityRecord.forToken(token);
+ if (DEBUG_SAVED_STATE) Slog.i(TAG, "Resumed activity; dropping state of: " + r);
+ r.icicle = null;
+ r.haveState = false;
}
- final void activityPaused(IBinder token, boolean timeout) {
+ final void activityPausedLocked(IBinder token, boolean timeout) {
if (DEBUG_PAUSE) Slog.v(
TAG, "Activity paused: token=" + token + ", timeout=" + timeout);
- synchronized (mService) {
- final ActivityRecord r = isInStackLocked(token);
- if (r != null) {
- mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
- if (mPausingActivity == r) {
- if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
- + (timeout ? " (due to timeout)" : " (pause complete)"));
- r.state = ActivityState.PAUSED;
- completePauseLocked();
- } else {
- EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
- r.userId, System.identityHashCode(r), r.shortComponentName,
- mPausingActivity != null
- ? mPausingActivity.shortComponentName : "(none)");
- }
+ final ActivityRecord r = isInStackLocked(token);
+ if (r != null) {
+ mHandler.removeMessages(PAUSE_TIMEOUT_MSG, r);
+ if (mPausingActivity == r) {
+ if (DEBUG_STATES) Slog.v(TAG, "Moving to PAUSED: " + r
+ + (timeout ? " (due to timeout)" : " (pause complete)"));
+ r.state = ActivityState.PAUSED;
+ completePauseLocked();
+ } else {
+ EventLog.writeEvent(EventLogTags.AM_FAILED_TO_PAUSE,
+ r.userId, System.identityHashCode(r), r.shortComponentName,
+ mPausingActivity != null
+ ? mPausingActivity.shortComponentName : "(none)");
}
}
}
@@ -1706,9 +1694,7 @@
next.state = ActivityState.RESUMED;
mResumedActivity = next;
next.task.touchActiveTime();
- if (mMainStack) {
- mService.addRecentTaskLocked(next.task);
- }
+ mService.addRecentTaskLocked(next.task);
mService.updateLruProcessLocked(next.app, true);
updateLRUListLocked(next);
@@ -1843,16 +1829,16 @@
private final void startActivityLocked(ActivityRecord r, boolean newTask,
boolean doResume, boolean keepCurTransition, Bundle options) {
TaskRecord task = null;
- final int taskId = r.task.taskId;
- if (mTaskIdToTaskRecord.indexOfKey(taskId) < 0 || newTask) {
+ TaskRecord rTask = r.task;
+ final int taskId = rTask.taskId;
+ if (taskForIdLocked(taskId) == null || newTask) {
// Last activity in task had been removed or ActivityManagerService is reusing task.
// Insert or replace.
- mTaskIdToTaskRecord.put(taskId, r.task);
// Might not even be in.
- mTaskHistory.remove(r.task);
+ mTaskHistory.remove(rTask);
// Now put task at top.
- mTaskHistory.add(r.task);
- mService.mWindowManager.moveTaskToTop(r.task.taskId);
+ mTaskHistory.add(rTask);
+ mService.mWindowManager.moveTaskToTop(taskId);
}
if (!newTask) {
// If starting in an existing task, find where that is...
@@ -2073,14 +2059,8 @@
if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target
+ " out to bottom task " + p.task);
} else {
- do {
- mService.mCurTask++;
- if (mService.mCurTask <= 0) {
- mService.mCurTask = 1;
- }
- } while (mTaskIdToTaskRecord.get(mService.mCurTask) != null);
- setTask(target, createTaskRecord(mService.mCurTask, target.info, null, false),
- null, false);
+ setTask(target, createTaskRecord(mService.getNextTaskId(), target.info, null,
+ false), null, false);
target.task.affinityIntent = target.intent;
if (DEBUG_TASKS) Slog.v(TAG, "Start pushing activity " + target
+ " out to new task " + target.task);
@@ -2235,7 +2215,7 @@
} else {
if (taskInsertionPoint < 0) {
taskInsertionPoint = task.mActivities.size();
-
+
}
final int start = replyChainEnd >= 0 ? replyChainEnd : i;
@@ -2578,7 +2558,7 @@
} catch (RemoteException e) {
mService.mController = null;
}
-
+
if (abort) {
if (resultRecord != null) {
sendActivityResultLocked(-1,
@@ -2594,7 +2574,7 @@
}
}
- ActivityRecord r = new ActivityRecord(mService, this, callerApp, callingUid, callingPackage,
+ ActivityRecord r = new ActivityRecord(mService, callerApp, callingUid, callingPackage,
intent, resolvedType, aInfo, mService.mConfiguration,
resultRecord, resultWho, requestCode, componentSpecified);
if (outActivity != null) {
@@ -2615,7 +2595,7 @@
return ActivityManager.START_SWITCHES_CANCELED;
}
}
-
+
if (mService.mDidAppSwitch) {
// This is the second allowed switch since we stopped switches,
// so now just generally allow switches. Use case: user presses
@@ -2626,10 +2606,10 @@
} else {
mService.mDidAppSwitch = true;
}
-
+
mService.doPendingActivityLaunchesLocked(false);
}
-
+
err = startActivityUncheckedLocked(r, sourceRecord,
startFlags, true, options);
if (mDismissKeyguardOnNextActivity && mPausingActivity == null) {
@@ -2642,7 +2622,7 @@
}
return err;
}
-
+
final void moveHomeToFrontFromLaunchLocked(int launchFlags) {
if ((launchFlags &
(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_TASK_ON_HOME))
@@ -2660,20 +2640,20 @@
final int callingUid = r.launchedFromUid;
int launchFlags = intent.getFlags();
-
+
// We'll invoke onUserLeaving before onPause only if the launching
// activity did not explicitly state that this is an automated launch.
mUserLeaving = (launchFlags&Intent.FLAG_ACTIVITY_NO_USER_ACTION) == 0;
if (DEBUG_USER_LEAVING) Slog.v(TAG,
"startActivity() => mUserLeaving=" + mUserLeaving);
-
+
// If the caller has asked not to resume at this point, we make note
// of this in the record so that we can skip it when trying to find
// the top running activity.
if (!doResume) {
r.delayedResume = true;
}
-
+
ActivityRecord notTop = (launchFlags&Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP)
!= 0 ? r : null;
@@ -2935,12 +2915,8 @@
if (r.resultTo == null && !addingToTask
&& (launchFlags&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
if (reuseTask == null) {
- // todo: should do better management of integers.
- mService.mCurTask++;
- if (mService.mCurTask <= 0) {
- mService.mCurTask = 1;
- }
- setTask(r, createTaskRecord(mService.mCurTask, r.info, intent, true), null, true);
+ setTask(r, createTaskRecord(mService.getNextTaskId(), r.info, intent, true), null,
+ true);
if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
+ " in new task " + r.task);
} else {
@@ -2950,7 +2926,7 @@
if (!movedHome) {
moveHomeToFrontFromLaunchLocked(launchFlags);
}
-
+
} else if (sourceRecord != null) {
if (!addingToTask &&
(launchFlags&Intent.FLAG_ACTIVITY_CLEAR_TOP) != 0) {
@@ -3010,7 +2986,8 @@
}
setTask(r, prev != null
? prev.task
- : createTaskRecord(mService.mCurTask, r.info, intent, true), null, true);
+ : createTaskRecord(mService.getNextTaskId(), r.info, intent, true), null,
+ true);
if (DEBUG_TASKS) Slog.v(TAG, "Starting new activity " + r
+ " in new guessed " + r.task);
}
@@ -3654,12 +3631,7 @@
return true;
}
- final void finishSubActivityLocked(IBinder token, String resultWho, int requestCode) {
- ActivityRecord self = isInStackLocked(token);
- if (self == null) {
- return;
- }
-
+ final void finishSubActivityLocked(ActivityRecord self, String resultWho, int requestCode) {
for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) {
ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities;
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
@@ -3685,8 +3657,7 @@
+ r.intent.getComponent().flattenToShortString());
int taskNdx = mTaskHistory.indexOf(r.task);
int activityNdx = r.task.mActivities.indexOf(r);
- r.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
- null, "crashed", false);
+ finishActivityLocked(r, Activity.RESULT_CANCELED, null, "crashed", false);
// Also terminate any activities below it that aren't yet
// stopped, to avoid a situation where one will get
// re-start our crashing activity once it gets resumed again.
@@ -3708,22 +3679,14 @@
if (!r.isHomeActivity || mService.mHomeProcess != r.app) {
Slog.w(TAG, " Force finishing activity "
+ r.intent.getComponent().flattenToShortString());
- r.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
- null, "crashed", false);
+ finishActivityLocked(r, Activity.RESULT_CANCELED, null, "crashed", false);
}
}
}
}
}
- final boolean finishActivityAffinityLocked(IBinder token) {
- ActivityRecord r = isInStackLocked(token);
- if (DEBUG_RESULTS) Slog.v(
- TAG, "Finishing activity affinity token=" + token + " r=" + r);
- if (r == null) {
- return false;
- }
-
+ final boolean finishActivityAffinityLocked(ActivityRecord r) {
ArrayList<ActivityRecord> activities = r.task.mActivities;
for (int index = activities.indexOf(r); index >= 0; --index) {
ActivityRecord cur = activities.get(index);
@@ -3913,8 +3876,9 @@
return r;
}
- final boolean navigateUpToLocked(ActivityRecord srec, Intent destIntent, int resultCode,
+ final boolean navigateUpToLocked(IBinder token, Intent destIntent, int resultCode,
Intent resultData) {
+ final ActivityRecord srec = ActivityRecord.forToken(token);
final TaskRecord task = srec.task;
final ArrayList<ActivityRecord> activities = task.mActivities;
final int start = activities.indexOf(srec);
@@ -4165,10 +4129,7 @@
if (hadApp) {
if (removeFromApp) {
- int idx = r.app.activities.indexOf(r);
- if (idx >= 0) {
- r.app.activities.remove(idx);
- }
+ r.app.activities.remove(r);
if (mService.mHeavyWeightProcess == r.app && r.app.activities.size() <= 0) {
mService.mHeavyWeightProcess = null;
mService.mHandler.sendEmptyMessage(
@@ -4244,25 +4205,23 @@
return removedFromHistory;
}
- final void activityDestroyed(IBinder token) {
- synchronized (mService) {
- final long origId = Binder.clearCallingIdentity();
- try {
- ActivityRecord r = ActivityRecord.forToken(token);
- if (r != null) {
- mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
- }
-
- if (isInStackLocked(token) != null) {
- if (r.state == ActivityState.DESTROYING) {
- cleanUpActivityLocked(r, true, false);
- removeActivityFromHistoryLocked(r);
- }
- }
- resumeTopActivityLocked(null);
- } finally {
- Binder.restoreCallingIdentity(origId);
+ final void activityDestroyedLocked(IBinder token) {
+ final long origId = Binder.clearCallingIdentity();
+ try {
+ ActivityRecord r = ActivityRecord.forToken(token);
+ if (r != null) {
+ mHandler.removeMessages(DESTROY_TIMEOUT_MSG, r);
}
+
+ if (isInStackLocked(token) != null) {
+ if (r.state == ActivityState.DESTROYING) {
+ cleanUpActivityLocked(r, true, false);
+ removeActivityFromHistoryLocked(r);
+ }
+ }
+ resumeTopActivityLocked(null);
+ } finally {
+ Binder.restoreCallingIdentity(origId);
}
}
@@ -4358,7 +4317,7 @@
}
}
- r.stack.cleanUpActivityLocked(r, true, true);
+ cleanUpActivityLocked(r, true, true);
}
}
}
@@ -4397,8 +4356,8 @@
}
final boolean findTaskToMoveToFrontLocked(int taskId, int flags, Bundle options) {
- final TaskRecord task = mTaskIdToTaskRecord.get(taskId);
- if (mTaskHistory.contains(task)) {
+ final TaskRecord task = taskForIdLocked(taskId);
+ if (task != null) {
if ((flags & ActivityManager.MOVE_TASK_NO_USER_ACTION) == 0) {
mUserLeaving = true;
}
@@ -4496,7 +4455,10 @@
if (DEBUG_TRANSITION) Slog.v(TAG,
"Prepare to back transition: task=" + task);
- final TaskRecord tr = mTaskIdToTaskRecord.get(task);
+ final TaskRecord tr = taskForIdLocked(task);
+ if (tr == null) {
+ return false;
+ }
mTaskHistory.remove(tr);
mTaskHistory.add(0, tr);
@@ -4525,7 +4487,7 @@
TaskAccessInfo info = getTaskAccessInfoLocked(tr, true);
ActivityRecord resumed = mResumedActivity;
if (resumed != null && resumed.thumbHolder == tr) {
- info.mainThumbnail = resumed.stack.screenshotActivities(resumed);
+ info.mainThumbnail = screenshotActivities(resumed);
}
if (info.mainThumbnail == null) {
info.mainThumbnail = tr.lastThumbnail;
@@ -4538,7 +4500,7 @@
if (resumed != null && resumed.task == tr) {
// This task is the current resumed task, we just need to take
// a screenshot of it and return that.
- return resumed.stack.screenshotActivities(resumed);
+ return screenshotActivities(resumed);
}
// Return the information about the task, to figure out the top
// thumbnail to return.
@@ -4551,7 +4513,10 @@
public ActivityRecord removeTaskActivitiesLocked(int taskId, int subTaskIndex,
boolean taskRequired) {
- final TaskRecord task = mTaskIdToTaskRecord.get(taskId);
+ final TaskRecord task = taskForIdLocked(taskId);
+ if (task == null) {
+ return null;
+ }
TaskAccessInfo info = getTaskAccessInfoLocked(task, false);
if (info.root == null) {
if (taskRequired) {
@@ -4633,7 +4598,7 @@
TaskAccessInfo.SubTask sub = thumbs.subtasks.get(index);
ActivityRecord resumed = mResumedActivity;
if (resumed != null && resumed.thumbHolder == sub.holder) {
- return resumed.stack.screenshotActivities(resumed);
+ return screenshotActivities(resumed);
}
return sub.holder.lastThumbnail;
}
@@ -4847,8 +4812,7 @@
for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) {
final ActivityRecord r = activities.get(activityNdx);
if ((r.info.flags&ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS) != 0) {
- r.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
- null, "close-sys", true);
+ finishActivityLocked(r, Activity.RESULT_CANCELED, null, "close-sys", true);
}
}
}
@@ -4884,8 +4848,7 @@
r.app = null;
}
lastTask = r.task;
- r.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, null, "force-stop",
- true);
+ finishActivityLocked(r, Activity.RESULT_CANCELED, null, "force-stop", true);
}
}
}
@@ -4975,8 +4938,7 @@
if (r.app == app) {
Slog.w(TAG, " Force finishing activity "
+ r.intent.getComponent().flattenToShortString());
- r.stack.finishActivityLocked(r, Activity.RESULT_CANCELED, null, "crashed",
- false);
+ finishActivityLocked(r, Activity.RESULT_CANCELED, null, "crashed", false);
}
}
}
@@ -5048,11 +5010,11 @@
private void removeActivity(ActivityRecord r) {
final TaskRecord task = r.task;
+ // TODO: use ActivityManagerService.removeTask to do this.
if (task.removeActivity(r)) {
if (DEBUG_ADD_REMOVE) Slog.i(TAG, "removeActivity: Removing from history, task="
+ task);
mTaskHistory.remove(task);
- mTaskIdToTaskRecord.delete(task.taskId);
}
}
@@ -5066,13 +5028,7 @@
private TaskRecord createTaskRecord(int taskId, ActivityInfo info, Intent intent,
boolean toTop) {
- TaskRecord oldTask = mTaskIdToTaskRecord.get(taskId);
- if (oldTask != null) {
- Slog.w(TAG, "createTaskRecord: Reusing taskId=" + taskId + " without removing");
- mTaskHistory.remove(oldTask);
- }
- TaskRecord task = new TaskRecord(taskId, info, intent);
- mTaskIdToTaskRecord.put(taskId, task);
+ TaskRecord task = new TaskRecord(taskId, info, intent, this);
if (toTop) {
mTaskHistory.add(task);
} else {
diff --git a/services/java/com/android/server/am/CompatModePackages.java b/services/java/com/android/server/am/CompatModePackages.java
index 863bdad..c56fdff 100644
--- a/services/java/com/android/server/am/CompatModePackages.java
+++ b/services/java/com/android/server/am/CompatModePackages.java
@@ -166,7 +166,7 @@
}
public boolean getFrontActivityAskCompatModeLocked() {
- ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null);
+ ActivityRecord r = mService.mFocusedStack.topRunningActivityLocked(null);
if (r == null) {
return false;
}
@@ -178,7 +178,7 @@
}
public void setFrontActivityAskCompatModeLocked(boolean ask) {
- ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null);
+ ActivityRecord r = mService.mFocusedStack.topRunningActivityLocked(null);
if (r != null) {
setPackageAskCompatModeLocked(r.packageName, ask);
}
@@ -200,7 +200,7 @@
}
public int getFrontActivityScreenCompatModeLocked() {
- ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null);
+ ActivityRecord r = mService.mFocusedStack.topRunningActivityLocked(null);
if (r == null) {
return ActivityManager.COMPAT_MODE_UNKNOWN;
}
@@ -208,7 +208,7 @@
}
public void setFrontActivityScreenCompatModeLocked(int mode) {
- ActivityRecord r = mService.mMainStack.topRunningActivityLocked(null);
+ ActivityRecord r = mService.mFocusedStack.topRunningActivityLocked(null);
if (r == null) {
Slog.w(TAG, "setFrontActivityScreenCompatMode failed: no top activity");
return;
@@ -296,7 +296,7 @@
mHandler.sendMessageDelayed(msg, 10000);
- ActivityRecord starting = mService.mMainStack.restartPackage(packageName);
+ ActivityRecord starting = mService.mFocusedStack.restartPackage(packageName);
// Tell all processes that loaded this package about the change.
for (int i=mService.mLruProcesses.size()-1; i>=0; i--) {
@@ -315,10 +315,10 @@
}
if (starting != null) {
- mService.mMainStack.ensureActivityConfigurationLocked(starting, 0);
+ mService.mFocusedStack.ensureActivityConfigurationLocked(starting, 0);
// And we need to make sure at this point that all other activities
// are made visible with the correct configuration.
- mService.mMainStack.ensureActivitiesVisibleLocked(starting, 0);
+ mService.mFocusedStack.ensureActivitiesVisibleLocked(starting, 0);
}
}
}
diff --git a/services/java/com/android/server/am/PendingIntentRecord.java b/services/java/com/android/server/am/PendingIntentRecord.java
index 8ab71dd..28593fe 100644
--- a/services/java/com/android/server/am/PendingIntentRecord.java
+++ b/services/java/com/android/server/am/PendingIntentRecord.java
@@ -259,7 +259,7 @@
}
break;
case ActivityManager.INTENT_SENDER_ACTIVITY_RESULT:
- key.activity.stack.sendActivityResultLocked(-1, key.activity,
+ key.activity.task.stack.sendActivityResultLocked(-1, key.activity,
key.who, key.requestCode, code, finalIntent);
break;
case ActivityManager.INTENT_SENDER_BROADCAST:
diff --git a/services/java/com/android/server/am/TaskRecord.java b/services/java/com/android/server/am/TaskRecord.java
index 4c3b590..9833d31 100644
--- a/services/java/com/android/server/am/TaskRecord.java
+++ b/services/java/com/android/server/am/TaskRecord.java
@@ -43,12 +43,17 @@
int numFullscreen; // Number of fullscreen activities.
+ /** List of all activities in the task arranged in history order */
final ArrayList<ActivityRecord> mActivities = new ArrayList<ActivityRecord>();
- TaskRecord(int _taskId, ActivityInfo info, Intent _intent) {
+ /** Current stack */
+ ActivityStack stack;
+
+ TaskRecord(int _taskId, ActivityInfo info, Intent _intent, ActivityStack _stack) {
taskId = _taskId;
affinity = info.taskAffinity;
setIntent(_intent, info);
+ stack = _stack;
}
void touchActiveTime() {