Deprecate FLAG_DISMISS_KEYGUARD
Since we now have an explicit dismiss method the flag is only
dangerous for falsing. The behavior will be migrated in the
following way:
- Insecure: Treat as FLAG_SHOW_WHEN_LOCKED
- Trusted: Actually dismiss Keyguard.
- Secure: Show bouncer.
We also restore the behavior to not allow dismissing the Keyguard
while it is occluded, which was the case in Nougat.
Test: cts/hostsidetests/services/activityandwindowmanager/util/run-test
android.server.cts.KeyguardTests
Test: cts/hostsidetests/services/activityandwindowmanager/util/run-test
android.server.cts.KeyguardLockedTests
Test: Insecure: Launch FLAG_DISMISS_KEYGUARD activity, make sure
Keyguard is occluded.
Test: Secure: Launch FLAG_DISMISS_KEYGUARD from SHOW_WHEN_LOCKED, make
sure bouncer is shown.
Test: Trusted: Launch FLAG_DISMISS_KEYGUARD from SHOW_WHEN_LOCKED, make
sure Keyguard gets unlocked.
Test: Trusted: Launch FLAG_DISMISS_KEYGUARD, lock screen, make sure
Keyguard is not dismissed/occluded.
Change-Id: I0d1ec9397a83975adb065c6cb81bf23b08c55395
diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java
index 5e02597..19bf536 100644
--- a/services/core/java/com/android/server/am/KeyguardController.java
+++ b/services/core/java/com/android/server/am/KeyguardController.java
@@ -57,6 +57,7 @@
private boolean mKeyguardShowing;
private boolean mKeyguardGoingAway;
private boolean mOccluded;
+ private boolean mDismissalRequested;
private ActivityRecord mDismissingKeyguardActivity;
private int mBeforeUnoccludeTransit;
private int mVisibilityTransactionDepth;
@@ -95,9 +96,7 @@
mKeyguardShowing = showing;
if (showing) {
mKeyguardGoingAway = false;
-
- // Allow an activity to redismiss Keyguard.
- mDismissingKeyguardActivity = null;
+ mDismissalRequested = false;
}
mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
mService.updateSleepIfNeededLocked();
@@ -183,8 +182,20 @@
* @return True if we may show an activity while Keyguard is showing because we are in the
* process of dismissing it anyways, false otherwise.
*/
- boolean canShowActivityWhileKeyguardShowing(boolean dismissKeyguard) {
- return dismissKeyguard && canDismissKeyguard();
+ boolean canShowActivityWhileKeyguardShowing(ActivityRecord r, boolean dismissKeyguard) {
+
+ // Allow to show it when we are about to dismiss Keyguard. This isn't allowed if r is
+ // already the dismissing activity, in which case we don't allow it to repeatedly dismiss
+ // Keyguard.
+ return dismissKeyguard && canDismissKeyguard() &&
+ (mDismissalRequested || r != mDismissingKeyguardActivity);
+ }
+
+ /**
+ * @return True if we may show an activity while Keyguard is occluded, false otherwise.
+ */
+ boolean canShowWhileOccluded(boolean dismissKeyguard, boolean showWhenLocked) {
+ return showWhenLocked || dismissKeyguard && !mWindowManager.isKeyguardSecure();
}
private void visibilitiesUpdated() {
@@ -199,7 +210,14 @@
// Only the very top activity may control occluded state
if (stackNdx == topStackNdx) {
- mOccluded = stack.topActivityOccludesKeyguard();
+
+ // A dismissing activity occludes Keyguard in the insecure case for legacy reasons.
+ final ActivityRecord topDismissing = stack.getTopDismissingKeyguardActivity();
+ mOccluded = stack.topActivityOccludesKeyguard()
+ || (topDismissing != null
+ && stack.topRunningActivityLocked() == topDismissing
+ && canShowWhileOccluded(true /* dismissKeyguard */,
+ false /* showWhenLocked */));
}
if (mDismissingKeyguardActivity == null
&& stack.getTopDismissingKeyguardActivity() != null) {
@@ -239,8 +257,13 @@
* Called when somebody might want to dismiss the Keyguard.
*/
private void handleDismissKeyguard() {
- if (mDismissingKeyguardActivity != null) {
+ // We only allow dismissing Keyguard via the flag when Keyguard is secure for legacy
+ // reasons, because that's how apps used to dismiss Keyguard in the secure case. In the
+ // insecure case, we actually show it on top of the lockscreen. See #canShowWhileOccluded.
+ if (!mOccluded && mDismissingKeyguardActivity != null
+ && mWindowManager.isKeyguardSecure()) {
mWindowManager.dismissKeyguard(null /* callback */);
+ mDismissalRequested = true;
// If we are about to unocclude the Keyguard, but we can dismiss it without security,
// we immediately dismiss the Keyguard so the activity gets shown without a flicker.
@@ -296,6 +319,7 @@
pw.println(prefix + " mKeyguardGoingAway=" + mKeyguardGoingAway);
pw.println(prefix + " mOccluded=" + mOccluded);
pw.println(prefix + " mDismissingKeyguardActivity=" + mDismissingKeyguardActivity);
+ pw.println(prefix + " mDismissalRequested=" + mDismissalRequested);
pw.println(prefix + " mVisibilityTransactionDepth=" + mVisibilityTransactionDepth);
}
}