diff options
| author | 2013-09-23 10:28:14 -0700 | |
|---|---|---|
| committer | 2013-09-24 10:36:05 -0700 | |
| commit | 2acc389d6197f8b099e7d72ea944ccbf14065761 (patch) | |
| tree | d33d079f2b33ca80f57f5642c452a344c171d750 | |
| parent | 10385a17cb31de6fdf495b50d17a0afbec83e98e (diff) | |
Pause activities behind keyguard after boot.
Following boot the initial activity was automatically resumed even if
a lockscreen is obscuring it. Refer to CL 363859 for why this breaks
things.
This fix pauses all activities the first time a lockscreen appears.
Completes the fix for bug 10732489.
Change-Id: I6fcac14b574c495aa0e16d798cddc1263c6b4c25
3 files changed, 55 insertions, 12 deletions
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index 47297c0583b8..5453daef2f52 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -336,7 +336,7 @@ public final class ActivityManagerService extends ActivityManagerNative final int startFlags; final ActivityStack stack; - public PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, + PendingActivityLaunch(ActivityRecord _r, ActivityRecord _sourceRecord, int _startFlags, ActivityStack _stack) { r = _r; sourceRecord = _sourceRecord; @@ -815,7 +815,11 @@ public final class ActivityManagerService extends ActivityManagerNative /** * State of external call telling us if the lock screen is shown. */ - boolean mLockScreenShown = false; + static final int LOCK_SCREEN_NEVER_SHOWN = 0; + static final int LOCK_SCREEN_FIRST_SHOWN = 1; + static final int LOCK_SCREEN_HIDDEN = 2; + static final int LOCK_SCREEN_SHOWING = 3; + int mLockScreenState = LOCK_SCREEN_NEVER_SHOWN; /** * Set if we are shutting down the system, similar to sleeping. @@ -4895,8 +4899,8 @@ public final class ActivityManagerService extends ActivityManagerNative final long token = Binder.clearCallingIdentity(); try { synchronized (this) { - if (mLockScreenShown) { - mLockScreenShown = false; + if (lockScreenShowing()) { + mLockScreenState = LOCK_SCREEN_HIDDEN; comeOutOfSleepIfNeededLocked(); } mStackSupervisor.setDismissKeyguard(true); @@ -7937,8 +7941,22 @@ public final class ActivityManagerService extends ActivityManagerNative Binder.restoreCallingIdentity(origId); } + boolean lockScreenShowing() { + switch (mLockScreenState) { + case LOCK_SCREEN_NEVER_SHOWN: + case LOCK_SCREEN_HIDDEN: + return false; + case LOCK_SCREEN_FIRST_SHOWN: + case LOCK_SCREEN_SHOWING: + return true; + default: + Slog.e(TAG, "lockScreenShowing: illegal state"); + throw new IllegalStateException("mLockScreenState=" + mLockScreenState); + } + } + private void comeOutOfSleepIfNeededLocked() { - if (!mWentToSleep && !mLockScreenShown) { + if (!mWentToSleep && !lockScreenShowing()) { if (mSleeping) { mSleeping = false; mStackSupervisor.comeOutOfSleepIfNeededLocked(); @@ -7974,7 +7992,12 @@ public final class ActivityManagerService extends ActivityManagerNative synchronized(this) { long ident = Binder.clearCallingIdentity(); try { - mLockScreenShown = shown; + if (shown && mLockScreenState == LOCK_SCREEN_NEVER_SHOWN) { + mStackSupervisor.pauseStacks(false, true); + mLockScreenState = LOCK_SCREEN_FIRST_SHOWN; + } else { + mLockScreenState = shown ? LOCK_SCREEN_SHOWING : LOCK_SCREEN_HIDDEN; + } comeOutOfSleepIfNeededLocked(); } finally { Binder.restoreCallingIdentity(ident); @@ -10505,9 +10528,9 @@ public final class ActivityManagerService extends ActivityManagerNative } } if (dumpPackage == null) { - if (mSleeping || mWentToSleep || mLockScreenShown) { + if (mSleeping || mWentToSleep || lockScreenShowing()) { pw.println(" mSleeping=" + mSleeping + " mWentToSleep=" + mWentToSleep - + " mLockScreenShown " + mLockScreenShown); + + " mLockScreenState=" + lockScreenStateToString()); } if (mShuttingDown) { pw.println(" mShuttingDown=" + mShuttingDown); @@ -16079,4 +16102,14 @@ public final class ActivityManagerService extends ActivityManagerNative info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId); return info; } + + private String lockScreenStateToString() { + switch (mLockScreenState) { + case LOCK_SCREEN_NEVER_SHOWN: return "LOCK_SCREEN_NEVER_SHOWN"; + case LOCK_SCREEN_FIRST_SHOWN: return "LOCK_SCREEN_FIRST_SHOWN"; + case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN"; + case LOCK_SCREEN_SHOWING: return "LOCK_SCREEN_SHOWING"; + default: return "unknown (" + mLockScreenState + ")"; + } + } } diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index f5607a29a08f..c760a3b4f7cc 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -1190,6 +1190,10 @@ final class ActivityStack { } final boolean resumeTopActivityLocked(ActivityRecord prev, Bundle options) { + if (mService.mLockScreenState == ActivityManagerService.LOCK_SCREEN_FIRST_SHOWN) { + return false; + } + // Find the first activity that is not finishing. ActivityRecord next = topRunningActivityLocked(null); @@ -1325,7 +1329,7 @@ final class ActivityStack { // We need to start pausing the current activity so the top one // can be resumed... - boolean pausing = mStackSupervisor.pauseBackStacks(userLeaving); + boolean pausing = mStackSupervisor.pauseStacks(userLeaving, false); if (mResumedActivity != null) { pausing = true; startPausingLocked(userLeaving, false); diff --git a/services/java/com/android/server/am/ActivityStackSupervisor.java b/services/java/com/android/server/am/ActivityStackSupervisor.java index 4c65a8ab1272..f11dca9f13f5 100644 --- a/services/java/com/android/server/am/ActivityStackSupervisor.java +++ b/services/java/com/android/server/am/ActivityStackSupervisor.java @@ -465,12 +465,18 @@ public final class ActivityStackSupervisor { return true; } - boolean pauseBackStacks(boolean userLeaving) { + /** + * Pause all activities in either all of the stacks or just the back stacks. + * @param userLeaving Passed to pauseActivity() to indicate whether to call onUserLeaving(). + * @param allStacks Whether to pause all the stacks (true), or just the back stacks (false). + * @return true if any activity was paused as a result of this call. + */ + boolean pauseStacks(boolean userLeaving, boolean allStacks) { boolean someActivityPaused = false; for (int stackNdx = mStacks.size() - 1; stackNdx >= 0; --stackNdx) { final ActivityStack stack = mStacks.get(stackNdx); - if (!isFrontStack(stack) && stack.mResumedActivity != null) { - if (DEBUG_STATES) Slog.d(TAG, "pauseBackStacks: stack=" + stack + + if ((allStacks || !isFrontStack(stack)) && stack.mResumedActivity != null) { + if (DEBUG_STATES) Slog.d(TAG, "pauseStacks: stack=" + stack + " mResumedActivity=" + stack.mResumedActivity); stack.startPausingLocked(userLeaving, false); someActivityPaused = true; |