diff options
author | Craig Mautner <cmautner@google.com> | 2014-07-16 14:56:05 -0700 |
---|---|---|
committer | Craig Mautner <cmautner@google.com> | 2014-07-16 15:03:11 -0700 |
commit | ee36c77acd3b92c64e53e19c570e2482382db870 (patch) | |
tree | d350d8ebe7258f0f30892496f0fe40150a087fc2 /services | |
parent | 575537759222e0277c3979e33342407aa7ca1a78 (diff) | |
download | frameworks_base-ee36c77acd3b92c64e53e19c570e2482382db870.zip frameworks_base-ee36c77acd3b92c64e53e19c570e2482382db870.tar.gz frameworks_base-ee36c77acd3b92c64e53e19c570e2482382db870.tar.bz2 |
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
Diffstat (limited to 'services')
3 files changed, 57 insertions, 45 deletions
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index b68089c..a6deed5 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -340,28 +340,6 @@ public final class ActivityManagerService extends ActivityManagerNative // devices. private boolean mShowDialogs = true; - /** - * 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; - } - } - - final ArrayList<PendingActivityLaunch> mPendingActivityLaunches - = new ArrayList<PendingActivityLaunch>(); - BroadcastQueue mFgBroadcastQueue; BroadcastQueue mBgBroadcastQueue; // Convenient for easy iteration over the queues. Foreground is first @@ -1323,7 +1301,7 @@ public final class ActivityManagerService extends ActivityManagerNative } break; case DO_PENDING_ACTIVITY_LAUNCHES_MSG: { synchronized (ActivityManagerService.this) { - doPendingActivityLaunchesLocked(true); + mStackSupervisor.doPendingActivityLaunchesLocked(true); } } break; case KILL_APPLICATION_MSG: { @@ -3034,19 +3012,6 @@ public final class ActivityManagerService extends ActivityManagerNative mProcessObservers.finishBroadcast(); } - final void doPendingActivityLaunchesLocked(boolean doResume) { - final int N = mPendingActivityLaunches.size(); - if (N <= 0) { - return; - } - for (int i=0; i<N; i++) { - PendingActivityLaunch pal = mPendingActivityLaunches.get(i); - mStackSupervisor.startActivityUncheckedLocked(pal.r, pal.sourceRecord, pal.startFlags, - doResume && i == (N-1), null); - } - mPendingActivityLaunches.clear(); - } - @Override public final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, @@ -8280,6 +8245,7 @@ public final class ActivityManagerService extends ActivityManagerNative } } + @Override public void stopAppSwitches() { if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES) != PackageManager.PERMISSION_GRANTED) { diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 1038ac0..224946c 100755 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -2558,18 +2558,23 @@ final class ActivityStack { return r; } - void finishAllActivitiesLocked() { + void finishAllActivitiesLocked(boolean immediately) { + boolean noActivitiesInStack = true; for (int taskNdx = mTaskHistory.size() - 1; taskNdx >= 0; --taskNdx) { final ArrayList<ActivityRecord> activities = mTaskHistory.get(taskNdx).mActivities; for (int activityNdx = activities.size() - 1; activityNdx >= 0; --activityNdx) { final ActivityRecord r = activities.get(activityNdx); - if (r.finishing) { + noActivitiesInStack = false; + if (r.finishing && !immediately) { continue; } - Slog.d(TAG, "finishAllActivitiesLocked: finishing " + r); + Slog.d(TAG, "finishAllActivitiesLocked: finishing " + r + " immediately"); finishCurrentActivityLocked(r, FINISH_IMMEDIATELY, false); } } + if (noActivitiesInStack) { + mActivityContainer.onTaskListEmptyLocked(); + } } final boolean navigateUpToLocked(IBinder token, Intent destIntent, int resultCode, @@ -2683,6 +2688,7 @@ final class ActivityStack { // down to the max limit while they are still waiting to finish. mStackSupervisor.mFinishingActivities.remove(r); mStackSupervisor.mWaitingVisibleActivities.remove(r); + mStackSupervisor.removePendingActivityLaunchesLocked(r); // Remove any pending results. if (r.finishing && r.pendingResults != null) { 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 android.view.Surface; 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 @@ public final class ActivityStackSupervisor implements DisplayListener { 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 @@ public final class ActivityStackSupervisor implements DisplayListener { 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 @@ public final class ActivityStackSupervisor implements DisplayListener { mService.mDidAppSwitch = true; } - mService.doPendingActivityLaunchesLocked(false); + doPendingActivityLaunchesLocked(false); err = startActivityUncheckedLocked(r, sourceRecord, startFlags, true, options); @@ -1830,6 +1851,23 @@ public final class ActivityStackSupervisor implements DisplayListener { 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 @@ public final class ActivityStackSupervisor implements DisplayListener { 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 @@ public final class ActivityStackSupervisor implements DisplayListener { 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); } |