OSDN Git Service

Use isKeyguardLocked to determine whether to resume.
authorBryce Lee <brycelee@google.com>
Mon, 12 Mar 2018 16:04:44 +0000 (09:04 -0700)
committerBryce Lee <brycelee@google.com>
Tue, 13 Mar 2018 01:42:13 +0000 (18:42 -0700)
Previously, we used isKeyguardActive to determine whether we should
resume an activity. This does not account for the keyguard going
away, which can leads to a timing issue where we do not resume an
activity when coming out of sleep from fingerprint unlock.

This change also prevents us from pausing a stopped activity that is
is considered to be the resumed activity as it will be brought to
the resumed state.

Fixes: 73991496
Test: Open display settings, lock screen, fingerprint unlock, press
      back, verify main settings page is shown immediately.

Change-Id: I3a7a33f5359a41fc958e3d8e799c39f5193ecb56

services/core/java/com/android/server/am/ActivityRecord.java
services/core/java/com/android/server/am/ActivityStackSupervisor.java
services/core/java/com/android/server/am/KeyguardController.java
services/tests/servicestests/src/com/android/server/am/ActivityRecordTests.java

index 59f027a..e38be67 100644 (file)
@@ -1750,8 +1750,11 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
             // this when there is an activity waiting to become translucent as the extra binder
             // calls will lead to noticeable jank. A later call to
             // ActivityStack#ensureActivitiesVisibleLocked will bring the activity to the proper
-            // paused state.
-            if (isState(STOPPED, STOPPING) && stack.mTranslucentActivityWaiting == null) {
+            // paused state. We also avoid doing this for the activity the stack supervisor
+            // considers the resumed activity, as normal means will bring the activity from STOPPED
+            // to RESUMED. Adding PAUSING in this scenario will lead to double lifecycles.
+            if (isState(STOPPED, STOPPING) && stack.mTranslucentActivityWaiting == null
+                    && mStackSupervisor.getResumedActivityLocked() != this) {
                 // Capture reason before state change
                 final String reason = getLifecycleDescription("makeVisibleIfNeeded");
 
index 869c635..185897a 100644 (file)
@@ -3375,11 +3375,11 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
                     stack.goToSleepIfPossible(false /* shuttingDown */);
                 } else {
                     stack.awakeFromSleepingLocked();
-                    if (isFocusedStack(stack)
-                            && !mKeyguardController.isKeyguardActive(display.mDisplayId)) {
-                        // If there is no keyguard on this display - resume immediately. Otherwise
-                        // we'll wait for keyguard visibility callback and resume while ensuring
-                        // activities visibility
+                    if (isFocusedStack(stack) && !mKeyguardController.isKeyguardLocked()) {
+                        // If the keyguard is unlocked - resume immediately.
+                        // It is possible that the display will not be awake at the time we
+                        // process the keyguard going away, which can happen before the sleep token
+                        // is released. As a result, it is important we resume the activity here.
                         resumeFocusedStackTopActivityLocked();
                     }
                 }
index 6b8b380..72882de 100644 (file)
@@ -86,16 +86,8 @@ class KeyguardController {
      *         display, false otherwise
      */
     boolean isKeyguardShowing(int displayId) {
-        return isKeyguardActive(displayId) && !mKeyguardGoingAway;
-    }
-
-    /**
-     * @return true if Keyguard is showing and not occluded. We ignore whether it is going away or
-     *         not here.
-     */
-    boolean isKeyguardActive(int displayId) {
-        return mKeyguardShowing && (displayId == DEFAULT_DISPLAY ? !mOccluded
-                : displayId == mSecondaryDisplayShowing);
+        return mKeyguardShowing && !mKeyguardGoingAway &&
+                (displayId == DEFAULT_DISPLAY ? !mOccluded : displayId == mSecondaryDisplayShowing);
     }
 
     /**
index 5b1f5c1..ac212dd 100644 (file)
@@ -123,12 +123,20 @@ public class ActivityRecordTests extends ActivityTestsBase {
             }
             return null;
         }).when(mActivity.app.thread).scheduleTransaction(any());
+
         mActivity.setState(STOPPED, "testPausingWhenVisibleFromStopped");
 
+        // The activity is in the focused stack so it should not move to paused.
         mActivity.makeVisibleIfNeeded(null /* starting */);
+        assertTrue(mActivity.isState(STOPPED));
+        assertFalse(pauseFound.value);
 
-        assertTrue(mActivity.isState(PAUSING));
+        // Clear focused stack
+        mActivity.mStackSupervisor.mFocusedStack = null;
 
+        // In the unfocused stack, the activity should move to paused.
+        mActivity.makeVisibleIfNeeded(null /* starting */);
+        assertTrue(mActivity.isState(PAUSING));
         assertTrue(pauseFound.value);
 
         // Make sure that the state does not change for current non-stopping states.