Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c9457fae authored by Craig Mautner's avatar Craig Mautner
Browse files

Do not display unsecure windows behind dialogs

If a dialog activity has FLAG_SHOW_WHEN_LOCKED set it will dismiss
the keyguard. Previously this would expose any full screen unsecure
windows behind the dialog. With this fix the dialog is displayed
over the wallpaper.

Fixes bug 15006623.

Change-Id: I85a6713c7647db52211bd0f7280010e859723710
parent 02a9c359
Loading
Loading
Loading
Loading
+6 −8
Original line number Diff line number Diff line
@@ -605,21 +605,21 @@ public interface WindowManagerPolicy {
    public int getConfigDisplayHeight(int fullWidth, int fullHeight, int rotation);

    /**
     * Return whether the given window should forcibly hide everything
     * behind it.  Typically returns true for the keyguard.
     * Return whether the given window is forcibly hiding all windows except windows with
     * FLAG_SHOW_WHEN_LOCKED set.  Typically returns true for the keyguard.
     */
    public boolean doesForceHide(WindowManager.LayoutParams attrs);
    public boolean isForceHiding(WindowManager.LayoutParams attrs);


    /**
     * Return whether the given window can become one that passes doesForceHide() test.
     * Return whether the given window can become one that passes isForceHiding() test.
     * Typically returns true for the StatusBar.
     */
    public boolean isKeyguardHostWindow(WindowManager.LayoutParams attrs);

    /**
     * Determine if a window that is behind one that is force hiding
     * (as determined by {@link #doesForceHide}) should actually be hidden.
     * (as determined by {@link #isForceHiding}) should actually be hidden.
     * For example, typically returns false for the status bar.  Be careful
     * to return false for any window that you may hide yourself, since this
     * will conflict with what you set.
@@ -830,13 +830,11 @@ public interface WindowManagerPolicy {
     * setting the window's frame, either here or in finishLayout().
     * 
     * @param win The window being positioned.
     * @param attrs The LayoutParams of the window.
     * @param attached For sub-windows, the window it is attached to; this
     *                 window will already have had layoutWindow() called on it
     *                 so you can use its Rect.  Otherwise null.
     */
    public void layoutWindowLw(WindowState win,
            WindowManager.LayoutParams attrs, WindowState attached);
    public void layoutWindowLw(WindowState win, WindowState attached);

    
    /**
+45 −9
Original line number Diff line number Diff line
@@ -434,6 +434,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
     * be done once per window. */
    private WindowState mWinDismissingKeyguard;

    /** The window that is currently showing "over" the keyguard. If there is an app window
     * belonging to another app on top of this the keyguard shows. If there is a fullscreen
     * app window under this, still dismiss the keyguard but don't show the app underneath. Show
     * the wallpaper. */
    private WindowState mWinShowWhenLocked;

    boolean mShowingLockscreen;
    boolean mShowingDream;
    boolean mDreamingLockscreen;
@@ -1668,8 +1674,9 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    }

    @Override
    public boolean doesForceHide(WindowManager.LayoutParams attrs) {
        return (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0;
    public boolean isForceHiding(WindowManager.LayoutParams attrs) {
        return (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0 ||
                (isKeyguardHostWindow(attrs) && isKeyguardSecureIncludingHidden());
    }

    @Override
@@ -3112,10 +3119,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {

    /** {@inheritDoc} */
    @Override
    public void layoutWindowLw(WindowState win, WindowManager.LayoutParams attrs,
            WindowState attached) {
    public void layoutWindowLw(WindowState win, WindowState attached) {
        // we've already done the status bar
        if ((win == mStatusBar && !doesForceHide(attrs)) || win == mNavigationBar) {
        final WindowManager.LayoutParams attrs = win.getAttrs();
        if ((win == mStatusBar && (attrs.privateFlags & PRIVATE_FLAG_KEYGUARD) == 0) ||
                win == mNavigationBar) {
            return;
        }
        final boolean isDefaultDisplay = win.isDefaultDisplay();
@@ -3596,12 +3604,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        mDismissKeyguard = DISMISS_KEYGUARD_NONE;
        mShowingLockscreen = false;
        mShowingDream = false;
        mWinShowWhenLocked = null;
    }

    /** {@inheritDoc} */
    @Override
    public void applyPostLayoutPolicyLw(WindowState win,
                                WindowManager.LayoutParams attrs) {
    public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs) {
        if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisibleOrBehindKeyguardLw="
                + win.isVisibleOrBehindKeyguardLw());
        final int fl = PolicyControl.getWindowFlags(win, attrs);
@@ -3639,9 +3647,17 @@ public class PhoneWindowManager implements WindowManagerPolicy {

            final boolean showWhenLocked = (fl & FLAG_SHOW_WHEN_LOCKED) != 0;
            final boolean dismissKeyguard = (fl & FLAG_DISMISS_KEYGUARD) != 0;
            final boolean secureKeyguard = isKeyguardSecure();
            if (appWindow) {
                if (showWhenLocked || (dismissKeyguard && !isKeyguardSecure())) {
                if (showWhenLocked || (dismissKeyguard && !secureKeyguard)) {
                    // Remove any previous windows with the same appToken.
                    mAppsToBeHidden.remove(win.getAppToken());
                    if (mAppsToBeHidden.isEmpty() && showWhenLocked &&
                            isKeyguardSecureIncludingHidden()) {
                        mWinShowWhenLocked = win;
                        mHideLockScreen = true;
                        mForceStatusBarFromKeyguard = false;
                    }
                } else {
                    mAppsToBeHidden.add(win.getAppToken());
                }
@@ -3663,13 +3679,18 @@ public class PhoneWindowManager implements WindowManagerPolicy {
                            mDismissKeyguard = mWinDismissingKeyguard == win ?
                                    DISMISS_KEYGUARD_CONTINUE : DISMISS_KEYGUARD_START;
                            mWinDismissingKeyguard = win;
                            mForceStatusBarFromKeyguard = mShowingLockscreen && isKeyguardSecure();
                            mForceStatusBarFromKeyguard = mShowingLockscreen && secureKeyguard;
                        }
                    }
                    if ((fl & FLAG_ALLOW_LOCK_WHILE_SCREEN_ON) != 0) {
                        mAllowLockscreenWhenOn = true;
                    }
                }

                if (mWinShowWhenLocked != null &&
                        mWinShowWhenLocked.getAppToken() != win.getAppToken()) {
                    win.hideLw(false);
                }
            }
        }
    }
@@ -3677,6 +3698,16 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    /** {@inheritDoc} */
    @Override
    public int finishPostLayoutPolicyLw() {
        if (mWinShowWhenLocked != null &&
                mWinShowWhenLocked != mTopFullscreenOpaqueWindowState) {
            // A dialog is dismissing the keyguard. Put the wallpaper behind it and hide the
            // fullscreen window.
            // TODO: Make sure FLAG_SHOW_WALLPAPER is restored when dialog is dismissed. Or not.
            mWinShowWhenLocked.getAttrs().flags |= FLAG_SHOW_WALLPAPER;
            mTopFullscreenOpaqueWindowState.hideLw(false);
            mTopFullscreenOpaqueWindowState = mWinShowWhenLocked;
        }

        int changes = 0;
        boolean topIsFullscreen = false;

@@ -4632,6 +4663,11 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        return mKeyguardDelegate.isSecure();
    }

    // Returns true if keyguard is currently locked whether or not it is currently hidden.
    private boolean isKeyguardSecureIncludingHidden() {
        return mKeyguardDelegate.isSecure() && mKeyguardDelegate.isShowing();
    }

    /** {@inheritDoc} */
    public boolean inKeyguardRestrictedKeyInputMode() {
        if (mKeyguardDelegate == null) return false;
+3 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.wm;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED;

import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_KEYGUARD;
import static com.android.server.wm.WindowManagerService.LayoutFields.SET_UPDATE_ROTATION;
import static com.android.server.wm.WindowManagerService.LayoutFields.SET_WALLPAPER_MAY_CHANGE;
import static com.android.server.wm.WindowManagerService.LayoutFields.SET_FORCE_HIDING_CHANGED;
@@ -227,7 +228,7 @@ public class WindowAnimator {
                    continue;
                }
                final WindowStateAnimator winAnimator = win.mWinAnimator;
                if (mPolicy.doesForceHide(win.mAttrs)) {
                if ((win.mAttrs.privateFlags & PRIVATE_FLAG_KEYGUARD) != 0) {
                    if (!winAnimator.mAnimating) {
                        // Create a new animation to delay until keyguard is gone on its own.
                        winAnimator.mAnimation = new AlphaAnimation(1.0f, 1.0f);
@@ -268,7 +269,7 @@ public class WindowAnimator {
                    }
                }

                if (mPolicy.doesForceHide(win.mAttrs)) {
                if (mPolicy.isForceHiding(win.mAttrs)) {
                    if (!wasAnimating && nowAnimating) {
                        if (WindowManagerService.DEBUG_ANIM ||
                                WindowManagerService.DEBUG_VISIBILITY) Slog.v(TAG,
+2 −2
Original line number Diff line number Diff line
@@ -8443,7 +8443,7 @@ public class WindowManagerService extends IWindowManager.Stub
                    }
                    win.mLayoutNeeded = false;
                    win.prelayout();
                    mPolicy.layoutWindowLw(win, win.mAttrs, null);
                    mPolicy.layoutWindowLw(win, null);
                    win.mLayoutSeq = seq;
                    if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame="
                            + win.mFrame + " mContainingFrame="
@@ -8495,7 +8495,7 @@ public class WindowManagerService extends IWindowManager.Stub
                    }
                    win.mLayoutNeeded = false;
                    win.prelayout();
                    mPolicy.layoutWindowLw(win, win.mAttrs, win.mAttachedWindow);
                    mPolicy.layoutWindowLw(win, win.mAttachedWindow);
                    win.mLayoutSeq = seq;
                    if (DEBUG_LAYOUT) Slog.v(TAG, "  LAYOUT: mFrame="
                            + win.mFrame + " mContainingFrame="