Additional cleanup after stack deletion.
- Remove activity from PendingActivityLaunch list when it is removed
from stack. This prevents the delayed launch causing
IllegalArgumentException in b/16045752.
- Move PendingActivityLaunch from ActivityManagerService to
ActivityStackSupervisor.
- Immediately call onTaskListEmptyLocked() in cases where no
activities are found in stack.
Fixes bug 16045752.
Change-Id: Ia69a449e7f5e08ab6e36157d0fd793c4d2fdaca4
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index bca215d..cdccccc 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -88,7 +88,6 @@
import com.android.internal.app.HeavyWeightSwitcherActivity;
import com.android.internal.os.TransferPipe;
import com.android.server.LocalServices;
-import com.android.server.am.ActivityManagerService.PendingActivityLaunch;
import com.android.server.am.ActivityStack.ActivityState;
import com.android.server.wm.WindowManagerService;
@@ -234,6 +233,28 @@
InputManagerInternal mInputManagerInternal;
+ final ArrayList<PendingActivityLaunch> mPendingActivityLaunches
+ = new ArrayList<PendingActivityLaunch>();
+
+ /**
+ * Description of a request to start a new activity, which has been held
+ * due to app switches being disabled.
+ */
+ static class PendingActivityLaunch {
+ final ActivityRecord r;
+ final ActivityRecord sourceRecord;
+ final int startFlags;
+ final ActivityStack stack;
+
+ PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord,
+ int _startFlags, ActivityStack _stack) {
+ r = _r;
+ sourceRecord = _sourceRecord;
+ startFlags = _startFlags;
+ stack = _stack;
+ }
+ }
+
public ActivityStackSupervisor(ActivityManagerService service) {
mService = service;
PowerManager pm = (PowerManager)mService.mContext.getSystemService(Context.POWER_SERVICE);
@@ -1304,7 +1325,7 @@
if (!mService.checkAppSwitchAllowedLocked(callingPid, callingUid, "Activity start")) {
PendingActivityLaunch pal =
new PendingActivityLaunch(r, sourceRecord, startFlags, stack);
- mService.mPendingActivityLaunches.add(pal);
+ mPendingActivityLaunches.add(pal);
setDismissKeyguard(false);
ActivityOptions.abort(options);
return ActivityManager.START_SWITCHES_CANCELED;
@@ -1322,7 +1343,7 @@
mService.mDidAppSwitch = true;
}
- mService.doPendingActivityLaunchesLocked(false);
+ doPendingActivityLaunchesLocked(false);
err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options);
@@ -1830,6 +1851,23 @@
return ActivityManager.START_SUCCESS;
}
+ final void doPendingActivityLaunchesLocked(boolean doResume) {
+ while (!mPendingActivityLaunches.isEmpty()) {
+ PendingActivityLaunch pal = mPendingActivityLaunches.remove(0);
+ startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags,
+ doResume && mPendingActivityLaunches.isEmpty(), null);
+ }
+ }
+
+ void removePendingActivityLaunchesLocked(ActivityRecord r) {
+ for (int palNdx = mPendingActivityLaunches.size() - 1; palNdx >= 0; --palNdx) {
+ PendingActivityLaunch pal = mPendingActivityLaunches.get(palNdx);
+ if (pal.r == r) {
+ mPendingActivityLaunches.remove(palNdx);
+ }
+ }
+ }
+
void acquireLaunchWakelock() {
if (VALIDATE_WAKE_LOCK_CALLER && Binder.getCallingUid() != Process.myUid()) {
throw new IllegalStateException("Calling must be system uid");
@@ -2960,7 +2998,9 @@
synchronized (mService) {
Slog.w(TAG, "Timeout waiting for all activities in task to finish. " +
msg.obj);
- ((ActivityContainer) msg.obj).onTaskListEmptyLocked();
+ final ActivityContainer container = (ActivityContainer) msg.obj;
+ container.mStack.finishAllActivitiesLocked(true);
+ container.onTaskListEmptyLocked();
}
} break;
}
@@ -3054,11 +3094,11 @@
final Message msg =
mHandler.obtainMessage(CONTAINER_TASK_LIST_EMPTY_TIMEOUT, this);
- mHandler.sendMessageDelayed(msg, 1000);
+ mHandler.sendMessageDelayed(msg, 2000);
long origId = Binder.clearCallingIdentity();
try {
- mStack.finishAllActivitiesLocked();
+ mStack.finishAllActivitiesLocked(false);
} finally {
Binder.restoreCallingIdentity(origId);
}