diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java index 2ed125dc08f74..fec7550af66dc 100644 --- a/core/java/android/view/WindowManagerPolicy.java +++ b/core/java/android/view/WindowManagerPolicy.java @@ -637,6 +637,11 @@ public interface WindowManagerPolicy { */ public boolean canBeForceHidden(WindowState win, WindowManager.LayoutParams attrs); + /** + * Return the window that is hiding the keyguard, if such a thing exists. + */ + public WindowState getWinShowWhenLockedLw(); + /** * Called when the system would like to show a UI to indicate that an * application is starting. You can use this to add a diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java index 9daa190ba6431..5874f63169ecc 100644 --- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java +++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java @@ -439,6 +439,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { WindowState mTopFullscreenOpaqueWindowState; HashSet mAppsToBeHidden = new HashSet(); + HashSet mAppsThatDismissKeyguard = new HashSet(); boolean mTopIsFullscreen; boolean mForceStatusBar; boolean mForceStatusBarFromKeyguard; @@ -1758,6 +1759,11 @@ public class PhoneWindowManager implements WindowManagerPolicy { } } + @Override + public WindowState getWinShowWhenLockedLw() { + return mWinShowWhenLocked; + } + /** {@inheritDoc} */ @Override public View addStartingWindow(IBinder appToken, String packageName, int theme, @@ -3751,6 +3757,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { public void beginPostLayoutPolicyLw(int displayWidth, int displayHeight) { mTopFullscreenOpaqueWindowState = null; mAppsToBeHidden.clear(); + mAppsThatDismissKeyguard.clear(); mForceStatusBar = false; mForceStatusBarFromKeyguard = false; mForcingShowNavBar = false; @@ -3791,7 +3798,7 @@ public class PhoneWindowManager implements WindowManagerPolicy { mShowingLockscreen = true; } boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW - && attrs.type <= LAST_APPLICATION_WINDOW; + && attrs.type < FIRST_SYSTEM_WINDOW; if (attrs.type == TYPE_DREAM) { // If the lockscreen was showing when the dream started then wait // for the dream to draw before hiding the lockscreen. @@ -3806,38 +3813,44 @@ public class PhoneWindowManager implements WindowManagerPolicy { final boolean dismissKeyguard = (fl & FLAG_DISMISS_KEYGUARD) != 0; final boolean secureKeyguard = isKeyguardSecure(); if (appWindow) { - if (showWhenLocked || (dismissKeyguard && !secureKeyguard)) { + final IApplicationToken appToken = win.getAppToken(); + if (showWhenLocked) { // Remove any previous windows with the same appToken. - mAppsToBeHidden.remove(win.getAppToken()); - if (mAppsToBeHidden.isEmpty() && showWhenLocked && - isKeyguardSecureIncludingHidden()) { + mAppsToBeHidden.remove(appToken); + mAppsThatDismissKeyguard.remove(appToken); + if (mAppsToBeHidden.isEmpty() && isKeyguardSecureIncludingHidden()) { mWinShowWhenLocked = win; mHideLockScreen = true; mForceStatusBarFromKeyguard = false; } + } else if (dismissKeyguard) { + if (secureKeyguard) { + mAppsToBeHidden.add(appToken); + } else { + mAppsToBeHidden.remove(appToken); + } + mAppsThatDismissKeyguard.add(appToken); } else { - mAppsToBeHidden.add(win.getAppToken()); + mAppsToBeHidden.add(appToken); } if (attrs.x == 0 && attrs.y == 0 && attrs.width == WindowManager.LayoutParams.MATCH_PARENT && attrs.height == WindowManager.LayoutParams.MATCH_PARENT) { if (DEBUG_LAYOUT) Slog.v(TAG, "Fullscreen window: " + win); mTopFullscreenOpaqueWindowState = win; - if (mAppsToBeHidden.isEmpty()) { - if (showWhenLocked) { - if (DEBUG_LAYOUT) Slog.v(TAG, - "Setting mHideLockScreen to true by win " + win); - mHideLockScreen = true; - mForceStatusBarFromKeyguard = false; - } - if (dismissKeyguard && mDismissKeyguard == DISMISS_KEYGUARD_NONE) { - if (DEBUG_LAYOUT) Slog.v(TAG, - "Setting mDismissKeyguard true by win " + win); - mDismissKeyguard = mWinDismissingKeyguard == win ? - DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START; - mWinDismissingKeyguard = win; - mForceStatusBarFromKeyguard = mShowingLockscreen && secureKeyguard; - } + if (!mAppsThatDismissKeyguard.isEmpty() && + mDismissKeyguard == DISMISS_KEYGUARD_NONE) { + if (DEBUG_LAYOUT) Slog.v(TAG, + "Setting mDismissKeyguard true by win " + win); + mDismissKeyguard = mWinDismissingKeyguard == win ? + DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START; + mWinDismissingKeyguard = win; + mForceStatusBarFromKeyguard = mShowingLockscreen && secureKeyguard; + } else if (mAppsToBeHidden.isEmpty() && showWhenLocked) { + if (DEBUG_LAYOUT) Slog.v(TAG, + "Setting mHideLockScreen to true by win " + win); + mHideLockScreen = true; + mForceStatusBarFromKeyguard = false; } if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) { mAllowLockscreenWhenOn = true; diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 50e417b533268..05fc4249d47aa 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -252,6 +252,10 @@ public class WindowAnimator { final boolean showImeOverKeyguard = imeTarget != null && imeTarget.isVisibleNow() && (imeTarget.getAttrs().flags & FLAG_SHOW_WHEN_LOCKED) != 0; + final WindowState winShowWhenLocked = (WindowState) mPolicy.getWinShowWhenLockedLw(); + final AppWindowToken appShowWhenLocked = winShowWhenLocked == null ? + null : winShowWhenLocked.mAppToken; + for (int i = windows.size() - 1; i >= 0; i--) { WindowState win = windows.get(i); WindowStateAnimator winAnimator = win.mWinAnimator; @@ -316,8 +320,8 @@ public class WindowAnimator { + " hidden=" + win.mRootToken.hidden + " anim=" + win.mWinAnimator.mAnimation); } else if (mPolicy.canBeForceHidden(win, win.mAttrs)) { - final boolean hideWhenLocked = (flags & FLAG_SHOW_WHEN_LOCKED) == 0 && - !(win.mIsImWindow && showImeOverKeyguard); + final boolean hideWhenLocked = !((win.mIsImWindow && showImeOverKeyguard) || + (appShowWhenLocked != null && appShowWhenLocked == win.mAppToken)); final boolean changed; if (((mForceHiding == KEYGUARD_ANIMATING_IN) && (!winAnimator.isAnimating() || hideWhenLocked))