From 0796187e95420b263c8e35a4a43a8749479bc559 Mon Sep 17 00:00:00 2001 From: Jorim Jaggi Date: Wed, 23 Nov 2016 11:28:57 +0100 Subject: [PATCH] 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 --- api/current.txt | 2 +- api/system-current.txt | 2 +- api/test-current.txt | 2 +- core/java/android/view/WindowManager.java | 5 ++- .../com/android/server/am/ActivityStack.java | 7 ++-- .../android/server/am/KeyguardController.java | 38 +++++++++++++++---- 6 files changed, 41 insertions(+), 15 deletions(-) diff --git a/api/current.txt b/api/current.txt index 40b57a34ddea6..5cce3be8201ce 100644 --- a/api/current.txt +++ b/api/current.txt @@ -44180,7 +44180,7 @@ package android.view { field public static final int FLAG_ALT_FOCUSABLE_IM = 131072; // 0x20000 field public static final deprecated int FLAG_BLUR_BEHIND = 4; // 0x4 field public static final int FLAG_DIM_BEHIND = 2; // 0x2 - field public static final int FLAG_DISMISS_KEYGUARD = 4194304; // 0x400000 + field public static final deprecated int FLAG_DISMISS_KEYGUARD = 4194304; // 0x400000 field public static final deprecated int FLAG_DITHER = 4096; // 0x1000 field public static final int FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS = -2147483648; // 0x80000000 field public static final int FLAG_FORCE_NOT_FULLSCREEN = 2048; // 0x800 diff --git a/api/system-current.txt b/api/system-current.txt index 60d98a7265ebc..1a8ddfa7619ad 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -47351,7 +47351,7 @@ package android.view { field public static final int FLAG_ALT_FOCUSABLE_IM = 131072; // 0x20000 field public static final deprecated int FLAG_BLUR_BEHIND = 4; // 0x4 field public static final int FLAG_DIM_BEHIND = 2; // 0x2 - field public static final int FLAG_DISMISS_KEYGUARD = 4194304; // 0x400000 + field public static final deprecated int FLAG_DISMISS_KEYGUARD = 4194304; // 0x400000 field public static final deprecated int FLAG_DITHER = 4096; // 0x1000 field public static final int FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS = -2147483648; // 0x80000000 field public static final int FLAG_FORCE_NOT_FULLSCREEN = 2048; // 0x800 diff --git a/api/test-current.txt b/api/test-current.txt index be55a949a5b77..a11dfb12f756d 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -44425,7 +44425,7 @@ package android.view { field public static final int FLAG_ALT_FOCUSABLE_IM = 131072; // 0x20000 field public static final deprecated int FLAG_BLUR_BEHIND = 4; // 0x4 field public static final int FLAG_DIM_BEHIND = 2; // 0x2 - field public static final int FLAG_DISMISS_KEYGUARD = 4194304; // 0x400000 + field public static final deprecated int FLAG_DISMISS_KEYGUARD = 4194304; // 0x400000 field public static final deprecated int FLAG_DITHER = 4096; // 0x1000 field public static final int FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS = -2147483648; // 0x80000000 field public static final int FLAG_FORCE_NOT_FULLSCREEN = 2048; // 0x800 diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java index b8408dd7434bd..aa7631de55a76 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -922,8 +922,11 @@ public interface WindowManager extends ViewManager { * unlock credential) than the user will still need to confirm it before * seeing this window, unless {@link #FLAG_SHOW_WHEN_LOCKED} has * also been set. - * @see KeyguardManager#dismissKeyguard + * @deprecated Use {@link #FLAG_SHOW_WHEN_LOCKED} or {@link KeyguardManager#dismissKeyguard} + * instead. The Keyguard should never be dismissed automatically repeatedly as it also + * guards against unintentional touches. */ + @Deprecated public static final int FLAG_DISMISS_KEYGUARD = 0x00400000; /** Window flag: when set the window will accept for touch events diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java index 005b8aa16bd1c..6a0ba61bb9ee4 100644 --- a/services/core/java/com/android/server/am/ActivityStack.java +++ b/services/core/java/com/android/server/am/ActivityStack.java @@ -1825,11 +1825,10 @@ final class ActivityStack extends ConfigurationContainer { // If keyguard is showing, nothing is visible, except if we are able to dismiss Keyguard // right away. return shouldBeVisible && mStackSupervisor.mKeyguardController - .canShowActivityWhileKeyguardShowing(dismissKeyguard); + .canShowActivityWhileKeyguardShowing(r, dismissKeyguard); } else if (keyguardLocked) { - - // Show when locked windows above keyguard. - return shouldBeVisible && showWhenLocked; + return shouldBeVisible && mStackSupervisor.mKeyguardController.canShowWhileOccluded( + dismissKeyguard, showWhenLocked); } else { return shouldBeVisible; } diff --git a/services/core/java/com/android/server/am/KeyguardController.java b/services/core/java/com/android/server/am/KeyguardController.java index 5e02597f1991b..19bf5369a57ba 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 @@ class KeyguardController { 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 @@ class KeyguardController { 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 @@ class KeyguardController { * @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 @@ class KeyguardController { // 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 @@ class KeyguardController { * 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 @@ class KeyguardController { 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); } }