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

Commit 5b9145bf authored by John Spurlock's avatar John Spurlock
Browse files

Improve transient bar transitions.

1. If app clears transient flag w/ a gesture, the touch-outside
listener would always win, causing an unsightly hide + immediate
reshow.  Instead, give the app some time to clear the flag, then
perform a smooth transition in place.

2. When the transient bars are hidden, we do not know ahead of time
which background will be used on reshow (if transient bars are
revealed, the background is semi-transparent, if transient bars
are cleared, the background is opaque).  Window manager is responsible
for showing windows, but sysui is responsible for setting the view
background.  Therefore, we need some level of coordination between
the two in this case.  Introduce two new non-public sysui flags
that represent the window manager's request to reshow the hidden
bars, but do not reshow until sysui acknowledges (by clearing the flag).
This gives sysui whatever time is necessary to prepare itself for
reshow, avoiding unsightly blip from opaque -> transparent during
the enter animation.

3. When both system bars are hidden, any low-profile changes are
moot.  Avoid unsightly low-profile animations during bar reshow
by suppressing the flag in this case.

4. Improve transient bar home -> launcher transition by cancelling
the -> opaque animation.  This also fixes a bug where hitting
home from the transient bar would leave you with a semi-transparent
bar in a non-transient state.

Bug:10284800
Change-Id: I238210561d8d5f70c1a517283b986c9105a1ec75
parent f01f1e9b
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -66,8 +66,9 @@ public class StatusBarManager {
    public static final int WINDOW_STATUS_BAR = 1;
    public static final int WINDOW_NAVIGATION_BAR = 2;

    public static final int WINDOW_STATE_SHOWING = 0;
    public static final int WINDOW_STATE_HIDING = 1;
    public static final int WINDOW_STATE_SHOWING = 2;
    public static final int WINDOW_STATE_HIDDEN = 2;

    private Context mContext;
    private IStatusBarService mService;
@@ -185,4 +186,12 @@ public class StatusBarManager {
            throw new RuntimeException(ex);
        }
    }

    /** @hide */
    public static String windowStateToString(int state) {
        if (state == WINDOW_STATE_HIDING) return "WINDOW_STATE_HIDING";
        if (state == WINDOW_STATE_HIDDEN) return "WINDOW_STATE_HIDDEN";
        if (state == WINDOW_STATE_SHOWING) return "WINDOW_STATE_SHOWING";
        return "WINDOW_STATE_UNKNOWN";
    }
}
+20 −0
Original line number Diff line number Diff line
@@ -2540,6 +2540,26 @@ public class View implements Drawable.Callback, KeyEvent.Callback,
     */
    public static final int NAVIGATION_BAR_TRANSIENT = 0x08000000;
    /**
     * @hide
     *
     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
     * out of the public fields to keep the undefined bits out of the developer's way.
     *
     * Flag to specify that the hidden status bar would like to be shown.
     */
    public static final int STATUS_BAR_UNHIDE = 0x10000000;
    /**
     * @hide
     *
     * NOTE: This flag may only be used in subtreeSystemUiVisibility. It is masked
     * out of the public fields to keep the undefined bits out of the developer's way.
     *
     * Flag to specify that the hidden navigation bar would like to be shown.
     */
    public static final int NAVIGATION_BAR_UNHIDE = 0x20000000;
    /**
     * @hide
     */
+1 −1
Original line number Diff line number Diff line
@@ -236,7 +236,7 @@ public class CommandQueue extends IStatusBar.Stub {

    public void setWindowState(int window, int state) {
        synchronized (mList) {
            mHandler.removeMessages(MSG_SET_WINDOW_STATE);
            // don't coalesce these
            mHandler.obtainMessage(MSG_SET_WINDOW_STATE, window, state, null).sendToTarget();
        }
    }
+18 −9
Original line number Diff line number Diff line
@@ -37,12 +37,13 @@ public class BarTransitions {
    public static final int MODE_TRANSPARENT = 2;

    private final String mTag;
    private final View mTarget;
    private final int mOpaque;
    private final int mSemiTransparent;
    protected final View mTarget;
    protected final int mOpaque;
    protected final int mSemiTransparent;

    protected Drawable mTransparent;
    private int mMode;
    private ValueAnimator mBackgroundColorAnimator;

    private final AnimatorUpdateListener mBackgroundColorListener = new AnimatorUpdateListener() {
        @Override
@@ -80,10 +81,11 @@ public class BarTransitions {
    }

    protected void onTransition(int oldMode, int newMode, boolean animate) {
        cancelBackgroundColorAnimation();
        if (animate && oldMode == MODE_SEMI_TRANSPARENT && newMode == MODE_OPAQUE) {
            startColorAnimation(mSemiTransparent, mOpaque);
            startBackgroundColorAnimation(mSemiTransparent, mOpaque);
        } else if (animate && oldMode == MODE_OPAQUE && newMode == MODE_SEMI_TRANSPARENT) {
            startColorAnimation(mOpaque, mSemiTransparent);
            startBackgroundColorAnimation(mOpaque, mSemiTransparent);
        } else if (newMode == MODE_OPAQUE || newMode == MODE_SEMI_TRANSPARENT) {
            mTarget.setBackgroundColor(newMode == MODE_OPAQUE ? mOpaque : mSemiTransparent);
        } else {
@@ -93,10 +95,17 @@ public class BarTransitions {
        }
    }

    private void startColorAnimation(int from, int to) {
        ValueAnimator anim = ValueAnimator.ofObject(new ArgbEvaluator(), from, to);
        anim.addUpdateListener(mBackgroundColorListener);
        anim.start();
    private void startBackgroundColorAnimation(int from, int to) {
        mBackgroundColorAnimator = ValueAnimator.ofObject(new ArgbEvaluator(), from, to);
        mBackgroundColorAnimator.addUpdateListener(mBackgroundColorListener);
        mBackgroundColorAnimator.start();
    }

    private void cancelBackgroundColorAnimation() {
        if (mBackgroundColorAnimator != null && mBackgroundColorAnimator.isStarted()) {
            mBackgroundColorAnimator.cancel();
            mBackgroundColorAnimator = null;
        }
    }

    public static String modeToString(int mode) {
+34 −24
Original line number Diff line number Diff line
@@ -1841,36 +1841,25 @@ public class PhoneStatusBar extends BaseStatusBar {

    @Override // CommandQueue
    public void setWindowState(int window, int state) {
        boolean showing = state == StatusBarManager.WINDOW_STATE_SHOWING;
        if (mStatusBarWindow != null
                && window == StatusBarManager.WINDOW_STATUS_BAR
                && mStatusBarWindowState != state) {
            mStatusBarWindowState = state;
            if (DEBUG) Log.d(TAG, "Status bar window " + stateString(state));
            if (state == StatusBarManager.WINDOW_STATE_HIDING) {
                mStatusBarWindow.setEnabled(false);
            if (DEBUG) Log.d(TAG, "Status bar " + StatusBarManager.windowStateToString(state));
            mStatusBarWindow.setEnabled(showing);
            if (!showing) {
                mStatusBarView.collapseAllPanels(false);
            } else if (state == StatusBarManager.WINDOW_STATE_SHOWING) {
                mStatusBarWindow.setEnabled(true);
            }
        }
        if (mNavigationBarView != null
                && window == StatusBarManager.WINDOW_NAVIGATION_BAR
                && mNavigationBarWindowState != state) {
            mNavigationBarWindowState = state;
            if (DEBUG) Log.d(TAG, "Navigation bar window " + stateString(state));
            if (state == StatusBarManager.WINDOW_STATE_HIDING) {
                mNavigationBarView.setEnabled(false);
            } else if (state == StatusBarManager.WINDOW_STATE_SHOWING) {
                mNavigationBarView.setEnabled(true);
            if (DEBUG) Log.d(TAG, "Navigation bar " + StatusBarManager.windowStateToString(state));
            mNavigationBarView.setEnabled(showing);
        }
    }
    }

    private static String stateString(int state) {
        if (state == StatusBarManager.WINDOW_STATE_HIDING) return "hiding";
        if (state == StatusBarManager.WINDOW_STATE_SHOWING) return "showing";
        return "unknown";
    }

    @Override // CommandQueue
    public void setSystemUiVisibility(int vis, int mask) {
@@ -1904,11 +1893,13 @@ public class PhoneStatusBar extends BaseStatusBar {

            // update status bar mode
            int sbMode = updateBarMode(oldVal, newVal, mStatusBarView.getBarTransitions(),
                    View.STATUS_BAR_TRANSIENT, View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS);
                    View.STATUS_BAR_TRANSIENT, View.SYSTEM_UI_FLAG_TRANSPARENT_STATUS,
                    mStatusBarWindowState);

            // update navigation bar mode
            int nbMode = updateBarMode(oldVal, newVal, mNavigationBarView.getBarTransitions(),
                    View.NAVIGATION_BAR_TRANSIENT, View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION);
                    View.NAVIGATION_BAR_TRANSIENT, View.SYSTEM_UI_FLAG_TRANSPARENT_NAVIGATION,
                    mNavigationBarWindowState);

            if (sbMode != -1 || nbMode != -1) {
                // update transient bar autohide
@@ -1919,19 +1910,29 @@ public class PhoneStatusBar extends BaseStatusBar {
                }
            }

            // ready to unhide
            if ((vis & View.STATUS_BAR_UNHIDE) != 0) {
                mSystemUiVisibility &= ~View.STATUS_BAR_UNHIDE;
            }
            if ((vis & View.NAVIGATION_BAR_UNHIDE) != 0) {
                mSystemUiVisibility &= ~View.NAVIGATION_BAR_UNHIDE;
            }

            // send updated sysui visibility to window manager
            notifyUiVisibilityChanged(mSystemUiVisibility);
        }
    }

    private int updateBarMode(int oldVis, int newVis, BarTransitions transitions,
            int transientFlag, int transparentFlag) {
            int transientFlag, int transparentFlag, int windowState) {
        final int oldMode = barMode(oldVis, transientFlag, transparentFlag);
        final int newMode = barMode(newVis, transientFlag, transparentFlag);
        if (oldMode == newMode) {
            return -1; // no mode change
        }
        transitions.transitionTo(newMode);
        boolean animate = windowState == StatusBarManager.WINDOW_STATE_SHOWING
                && oldMode == MODE_SEMI_TRANSPARENT && newMode == MODE_OPAQUE;
        transitions.transitionTo(newMode, animate);
        return newMode;
    }

@@ -1941,11 +1942,19 @@ public class PhoneStatusBar extends BaseStatusBar {
                : MODE_OPAQUE;
    }

    private final Runnable mResumeSemiTransparent = new Runnable() {
        @Override
        public void run() {
            if ((mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0) {
                animateTransitionTo(BarTransitions.MODE_SEMI_TRANSPARENT);
            }
        }};

    @Override
    public void resumeAutohide() {
        if (mAutohideSuspended) {
            scheduleAutohide();
            animateTransitionTo(BarTransitions.MODE_SEMI_TRANSPARENT);
            mHandler.postDelayed(mResumeSemiTransparent, 500); // longer than home -> launcher
        }
    }

@@ -1959,7 +1968,8 @@ public class PhoneStatusBar extends BaseStatusBar {
    @Override
    public void suspendAutohide() {
        mHandler.removeCallbacks(mAutohide);
        mAutohideSuspended = 0 != (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT);
        mHandler.removeCallbacks(mResumeSemiTransparent);
        mAutohideSuspended = (mSystemUiVisibility & STATUS_OR_NAV_TRANSIENT) != 0;
        animateTransitionTo(BarTransitions.MODE_OPAQUE);
    }

@@ -1984,7 +1994,7 @@ public class PhoneStatusBar extends BaseStatusBar {

    private void userAutohide() {
        cancelAutohide();
        mHandler.postDelayed(mAutohide, 25);
        mHandler.postDelayed(mAutohide, 350); // longer than app gesture -> flag clear
    }

    private void setStatusBarLowProfile(boolean lightsOut) {
Loading