Merge "Pause activities behind keyguard after boot." into klp-dev
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 808bf88..327c854 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -336,7 +336,7 @@
         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 @@
     /**
      * 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.
@@ -4914,8 +4918,8 @@
         final long token = Binder.clearCallingIdentity();
         try {
             synchronized (this) {
-                if (mLockScreenShown) {
-                    mLockScreenShown = false;
+                if (lockScreenShowing()) {
+                    mLockScreenState = LOCK_SCREEN_HIDDEN;
                     comeOutOfSleepIfNeededLocked();
                 }
                 mStackSupervisor.setDismissKeyguard(true);
@@ -7956,8 +7960,22 @@
         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();
@@ -7993,7 +8011,12 @@
         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);
@@ -10524,9 +10547,9 @@
             }
         }
         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);
@@ -16098,4 +16121,14 @@
         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 f5607a2..c760a3b 100644
--- a/services/java/com/android/server/am/ActivityStack.java
+++ b/services/java/com/android/server/am/ActivityStack.java
@@ -1190,6 +1190,10 @@
     }
 
     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 @@
 
         // 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 4c65a8a..f11dca9 100644
--- a/services/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/java/com/android/server/am/ActivityStackSupervisor.java
@@ -465,12 +465,18 @@
         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;