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

Commit 23cc9aa5 authored by Jorim Jaggi's avatar Jorim Jaggi
Browse files

Fix window affecting SysUi visibility for once and all

This unforunately introduces another quasi-visibiltiy method but
I think this is the best solution, as the code is pretty clean.

Test: Navigate through, settings, make sure no flickering
Test: Launch music from notification
Test: Launch United app
Test: Go settings -> app -> settings repeadetly 100 times, make
sure light bar transition is always clean
Fixes: 38216281

Change-Id: I0b97334dea3bfef2966ad0c7dd8bbd9907f2574c
parent ff389264
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -400,6 +400,13 @@ public interface WindowManagerPolicy {
         */
        boolean isAnimatingLw();

        /**
         * @return Whether the window can affect SystemUI flags, meaning that SystemUI (system bars,
         *         for example) will be  affected by the flags specified in this window. This is the
         *         case when the surface is on screen but not exiting.
         */
        boolean canAffectSystemUiFlags();

        /**
         * Is this window considered to be gone for purposes of layout?
         */
+9 −8
Original line number Diff line number Diff line
@@ -5333,11 +5333,12 @@ public class PhoneWindowManager implements WindowManagerPolicy {
    @Override
    public void applyPostLayoutPolicyLw(WindowState win, WindowManager.LayoutParams attrs,
            WindowState attached, WindowState imeTarget) {
        final boolean visible = win.isVisibleLw() && win.getAttrs().alpha > 0f;
        if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": isVisible=" + visible);
        final boolean affectsSystemUi = win.canAffectSystemUiFlags();
        if (DEBUG_LAYOUT) Slog.i(TAG, "Win " + win + ": affectsSystemUi=" + affectsSystemUi);
        applyKeyguardPolicyLw(win, imeTarget);
        final int fl = PolicyControl.getWindowFlags(win, attrs);
        if (mTopFullscreenOpaqueWindowState == null && visible && attrs.type == TYPE_INPUT_METHOD) {
        if (mTopFullscreenOpaqueWindowState == null && affectsSystemUi
                && attrs.type == TYPE_INPUT_METHOD) {
            mForcingShowNavBar = true;
            mForcingShowNavBarLayer = win.getSurfaceLayer();
        }
@@ -5353,7 +5354,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        boolean appWindow = attrs.type >= FIRST_APPLICATION_WINDOW
                && attrs.type < FIRST_SYSTEM_WINDOW;
        final int stackId = win.getStackId();
        if (mTopFullscreenOpaqueWindowState == null && visible) {
        if (mTopFullscreenOpaqueWindowState == null && affectsSystemUi) {
            if ((fl & FLAG_FORCE_NOT_FULLSCREEN) != 0) {
                mForceStatusBar = true;
            }
@@ -5385,7 +5386,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }

        // Voice interaction overrides both top fullscreen and top docked.
        if (visible && win.getAttrs().type == TYPE_VOICE_INTERACTION) {
        if (affectsSystemUi && win.getAttrs().type == TYPE_VOICE_INTERACTION) {
            if (mTopFullscreenOpaqueWindowState == null) {
                mTopFullscreenOpaqueWindowState = win;
                if (mTopFullscreenOpaqueOrDimmingWindowState == null) {
@@ -5401,7 +5402,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        }

        // Keep track of the window if it's dimming but not necessarily fullscreen.
        if (mTopFullscreenOpaqueOrDimmingWindowState == null && visible
        if (mTopFullscreenOpaqueOrDimmingWindowState == null && affectsSystemUi
                && win.isDimming() && StackId.normallyFullscreenWindows(stackId)) {
            mTopFullscreenOpaqueOrDimmingWindowState = win;
        }
@@ -5409,7 +5410,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {
        // We need to keep track of the top "fullscreen" opaque window for the docked stack
        // separately, because both the "real fullscreen" opaque window and the one for the docked
        // stack can control View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR.
        if (mTopDockedOpaqueWindowState == null && visible && appWindow && attached == null
        if (mTopDockedOpaqueWindowState == null && affectsSystemUi && appWindow && attached == null
                && isFullscreen(attrs) && stackId == DOCKED_STACK_ID) {
            mTopDockedOpaqueWindowState = win;
            if (mTopDockedOpaqueOrDimmingWindowState == null) {
@@ -5419,7 +5420,7 @@ public class PhoneWindowManager implements WindowManagerPolicy {

        // Also keep track of any windows that are dimming but not necessarily fullscreen in the
        // docked stack.
        if (mTopDockedOpaqueOrDimmingWindowState == null && visible && win.isDimming()
        if (mTopDockedOpaqueOrDimmingWindowState == null && affectsSystemUi && win.isDimming()
                && stackId == DOCKED_STACK_ID) {
            mTopDockedOpaqueOrDimmingWindowState = win;
        }
+10 −0
Original line number Diff line number Diff line
@@ -1403,6 +1403,16 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
                        || ((mAppToken != null) && (mAppToken.mAppAnimator.animation != null)));
    }

    // TODO: Another visibility method that was added late in the release to minimize risk.
    @Override
    public boolean canAffectSystemUiFlags() {
        final boolean shown = mWinAnimator.getShown();
        final boolean exiting = mAnimatingExit || mDestroying
                || mAppToken != null && mAppToken.hidden;
        final boolean translucent = mAttrs.alpha == 0.0f;
        return shown && !exiting && !translucent;
    }

    /**
     * Like isOnScreen, but returns false if the surface hasn't yet
     * been drawn.