Prevent windows below the keyguard from showing Fixes a bug where windows below the lock screen could become visible if a SHOW_WHEN_LOCKED activity hides the status bar. Bug: 21450145 Change-Id: Ie660394cb96d7e6839bd4fb7c2729133bac2dfc5
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index f7b6405..ca5f5ad 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java
@@ -1058,6 +1058,13 @@ public boolean isKeyguardSecure(); /** + * Return whether the keyguard is on. + * + * @return true if in keyguard is on. + */ + public boolean isKeyguardShowingOrOccluded(); + + /** * inKeyguardRestrictedKeyInputMode * * if keyguard screen is showing or in restricted key input mode (i.e. in
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java index b8d0692..2839f08 100644 --- a/services/core/java/com/android/server/policy/PhoneWindowManager.java +++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -2116,7 +2116,9 @@ case TYPE_KEYGUARD_SCRIM: return false; default: - return true; + // Hide only windows below the keyguard host window. + return windowTypeToLayerLw(win.getBaseType()) + < windowTypeToLayerLw(TYPE_STATUS_BAR); } } @@ -5517,6 +5519,12 @@ /** {@inheritDoc} */ @Override + public boolean isKeyguardShowingOrOccluded() { + return mKeyguardDelegate == null ? false : mKeyguardDelegate.isShowing(); + } + + /** {@inheritDoc} */ + @Override public boolean inKeyguardRestrictedKeyInputMode() { if (mKeyguardDelegate == null) return false; return mKeyguardDelegate.isInputRestricted();
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 9169351..3305e1e 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -191,7 +191,8 @@ private boolean shouldForceHide(WindowState win) { final WindowState imeTarget = mService.mInputMethodTarget; final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleNow() && - (imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0; + ((imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0 + || !mPolicy.canBeForceHidden(imeTarget, imeTarget.mAttrs)); final WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw(); final AppWindowToken appShowWhenLocked = winShowWhenLocked == null ? @@ -203,7 +204,11 @@ || (win.mAttrs.flags & FLAG_SHOW_WHEN_LOCKED) != 0 && win.isAnimatingLw() // Show error dialogs over apps that dismiss keyguard. || (win.mAttrs.privateFlags & PRIVATE_FLAG_SYSTEM_ERROR) != 0))); - return (mForceHiding == KEYGUARD_SHOWN) && hideWhenLocked; + + // Only hide windows if the keyguard is active and not animating away. + boolean keyguardOn = mPolicy.isKeyguardShowingOrOccluded() + && mForceHiding != KEYGUARD_ANIMATING_OUT; + return keyguardOn && hideWhenLocked; } private void updateWindowsLocked(final int displayId) { @@ -228,6 +233,7 @@ winAnimator.mAnimation.setDuration(KEYGUARD_ANIM_TIMEOUT_MS); winAnimator.mAnimationIsEntrance = false; winAnimator.mAnimationStartTime = -1; + winAnimator.mKeyguardGoingAwayAnimation = true; } } else { if (DEBUG_KEYGUARD) Slog.d(TAG, @@ -310,7 +316,7 @@ mKeyguardGoingAway = false; } if (win.isReadyForDisplay()) { - if (nowAnimating) { + if (nowAnimating && win.mWinAnimator.mKeyguardGoingAwayAnimation) { mForceHiding = KEYGUARD_ANIMATING_OUT; } else { mForceHiding = win.isDrawnLw() ? KEYGUARD_SHOWN : KEYGUARD_NOT_SHOWN;