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

Commit 85d202b1 authored by Adrian Roos's avatar Adrian Roos
Browse files

Seascape Navigation Bar View

Allow placing navigation bar on the left side aka seascape. Also
deal with fallout from this change in frame calculations, decor view,
and all over SystemUI - notably no changes to the navigation bar view.

Bug: 28823676
Change-Id: I91187a974a10a940787a858e2609f2e9c5bade78
parent 912e2b2c
Loading
Loading
Loading
Loading
+5 −1
Original line number Diff line number Diff line
@@ -370,6 +370,8 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
                systemInsets.bottom);
        final int rightInset = DecorView.getColorViewRightInset(stableInsets.right,
                systemInsets.right);
        final int leftInset = DecorView.getColorViewLeftInset(stableInsets.left,
                systemInsets.left);
        if (mStatusBarColor != null) {
            mStatusBarColor.setBounds(0, 0, left + width, topInset);
            mStatusBarColor.draw(canvas);
@@ -379,9 +381,11 @@ public class BackdropFrameRenderer extends Thread implements Choreographer.Frame
        // don't want the navigation bar background be moving around when resizing in docked mode.
        // However, we need it for the transitions into/out of docked mode.
        if (mNavigationBarColor != null && fullscreen) {
            final int size = DecorView.getNavBarSize(bottomInset, rightInset);
            final int size = DecorView.getNavBarSize(bottomInset, rightInset, leftInset);
            if (DecorView.isNavBarToRightEdge(bottomInset, rightInset)) {
                mNavigationBarColor.setBounds(width - size, 0, width, height);
            } else if (DecorView.isNavBarToLeftEdge(bottomInset, rightInset)) {
                mNavigationBarColor.setBounds(0, 0, size, height);
            } else {
                mNavigationBarColor.setBounds(0, height - size, width, height);
            }
+56 −18
Original line number Diff line number Diff line
@@ -97,7 +97,6 @@ import static android.view.WindowManager.LayoutParams.FLAG_DRAWS_SYSTEM_BAR_BACK
import static android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_INSET_DECOR;
import static android.view.WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN;
import static android.view.WindowManager.LayoutParams.FLAG_SHOW_WALLPAPER;
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION;
import static android.view.WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
@@ -162,13 +161,13 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind

    private final ColorViewState mStatusColorViewState = new ColorViewState(
            SYSTEM_UI_FLAG_FULLSCREEN, FLAG_TRANSLUCENT_STATUS,
            Gravity.TOP, Gravity.LEFT,
            Gravity.TOP, Gravity.LEFT, Gravity.RIGHT,
            Window.STATUS_BAR_BACKGROUND_TRANSITION_NAME,
            com.android.internal.R.id.statusBarBackground,
            FLAG_FULLSCREEN);
    private final ColorViewState mNavigationColorViewState = new ColorViewState(
            SYSTEM_UI_FLAG_HIDE_NAVIGATION, FLAG_TRANSLUCENT_NAVIGATION,
            Gravity.BOTTOM, Gravity.RIGHT,
            Gravity.BOTTOM, Gravity.RIGHT, Gravity.LEFT,
            Window.NAVIGATION_BAR_BACKGROUND_TRANSITION_NAME,
            com.android.internal.R.id.navigationBarBackground,
            0 /* hideWindowFlag */);
@@ -184,9 +183,11 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
    private int mLastTopInset = 0;
    private int mLastBottomInset = 0;
    private int mLastRightInset = 0;
    private int mLastLeftInset = 0;
    private boolean mLastHasTopStableInset = false;
    private boolean mLastHasBottomStableInset = false;
    private boolean mLastHasRightStableInset = false;
    private boolean mLastHasLeftStableInset = false;
    private int mLastWindowFlags = 0;
    private boolean mLastShouldAlwaysConsumeNavBar = false;

@@ -991,12 +992,21 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
        return Math.min(stableRight, systemRight);
    }

    static int getColorViewLeftInset(int stableLeft, int systemLeft) {
        return Math.min(stableLeft, systemLeft);
    }

    static boolean isNavBarToRightEdge(int bottomInset, int rightInset) {
        return bottomInset == 0 && rightInset > 0;
    }

    static int getNavBarSize(int bottomInset, int rightInset) {
        return isNavBarToRightEdge(bottomInset, rightInset) ? rightInset : bottomInset;
    static boolean isNavBarToLeftEdge(int bottomInset, int leftInset) {
        return bottomInset == 0 && leftInset > 0;
    }

    static int getNavBarSize(int bottomInset, int rightInset, int leftInset) {
        return isNavBarToRightEdge(bottomInset, rightInset) ? rightInset
                : isNavBarToLeftEdge(bottomInset, leftInset) ? leftInset : bottomInset;
    }

    WindowInsets updateColorViews(WindowInsets insets, boolean animate) {
@@ -1016,6 +1026,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
                        insets.getSystemWindowInsetBottom());
                mLastRightInset = getColorViewRightInset(insets.getStableInsetRight(),
                        insets.getSystemWindowInsetRight());
                mLastLeftInset = getColorViewRightInset(insets.getStableInsetLeft(),
                        insets.getSystemWindowInsetLeft());

                // Don't animate if the presence of stable insets has changed, because that
                // indicates that the window was either just added and received them for the
@@ -1031,21 +1043,32 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
                boolean hasRightStableInset = insets.getStableInsetRight() != 0;
                disallowAnimate |= (hasRightStableInset != mLastHasRightStableInset);
                mLastHasRightStableInset = hasRightStableInset;

                boolean hasLeftStableInset = insets.getStableInsetLeft() != 0;
                disallowAnimate |= (hasLeftStableInset != mLastHasLeftStableInset);
                mLastHasLeftStableInset = hasLeftStableInset;

                mLastShouldAlwaysConsumeNavBar = insets.shouldAlwaysConsumeNavBar();
            }

            boolean navBarToRightEdge = isNavBarToRightEdge(mLastBottomInset, mLastRightInset);
            int navBarSize = getNavBarSize(mLastBottomInset, mLastRightInset);
            boolean navBarToLeftEdge = isNavBarToLeftEdge(mLastBottomInset, mLastLeftInset);
            int navBarSize = getNavBarSize(mLastBottomInset, mLastRightInset, mLastLeftInset);
            updateColorViewInt(mNavigationColorViewState, sysUiVisibility,
                    mWindow.mNavigationBarColor, navBarSize, navBarToRightEdge,
                    0 /* rightInset */, animate && !disallowAnimate, false /* force */);
                    mWindow.mNavigationBarColor, navBarSize, navBarToRightEdge || navBarToLeftEdge,
                    navBarToLeftEdge,
                    0 /* sideInset */, animate && !disallowAnimate, false /* force */);

            boolean statusBarNeedsRightInset = navBarToRightEdge
                    && mNavigationColorViewState.present;
            int statusBarRightInset = statusBarNeedsRightInset ? mLastRightInset : 0;
            boolean statusBarNeedsLeftInset = navBarToLeftEdge
                    && mNavigationColorViewState.present;
            int statusBarSideInset = statusBarNeedsRightInset ? mLastRightInset
                    : statusBarNeedsLeftInset ? mLastLeftInset : 0;
            updateColorViewInt(mStatusColorViewState, sysUiVisibility,
                    calculateStatusBarColor(), mLastTopInset,
                    false /* matchVertical */, statusBarRightInset, animate && !disallowAnimate,
                    false /* matchVertical */, statusBarNeedsLeftInset, statusBarSideInset,
                    animate && !disallowAnimate,
                    mForceWindowDrawsStatusBarBackground);
        }

@@ -1070,15 +1093,17 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
        int consumedTop = consumingStatusBar ? mLastTopInset : 0;
        int consumedRight = consumingNavBar ? mLastRightInset : 0;
        int consumedBottom = consumingNavBar ? mLastBottomInset : 0;
        int consumedLeft = consumingNavBar ? mLastLeftInset : 0;

        if (mContentRoot != null
                && mContentRoot.getLayoutParams() instanceof MarginLayoutParams) {
            MarginLayoutParams lp = (MarginLayoutParams) mContentRoot.getLayoutParams();
            if (lp.topMargin != consumedTop || lp.rightMargin != consumedRight
                    || lp.bottomMargin != consumedBottom) {
                    || lp.bottomMargin != consumedBottom || lp.leftMargin != consumedLeft) {
                lp.topMargin = consumedTop;
                lp.rightMargin = consumedRight;
                lp.bottomMargin = consumedBottom;
                lp.leftMargin = consumedLeft;
                mContentRoot.setLayoutParams(lp);

                if (insets == null) {
@@ -1089,7 +1114,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
            }
            if (insets != null) {
                insets = insets.replaceSystemWindowInsets(
                        insets.getSystemWindowInsetLeft(),
                        insets.getSystemWindowInsetLeft() - consumedLeft,
                        insets.getSystemWindowInsetTop() - consumedTop,
                        insets.getSystemWindowInsetRight() - consumedRight,
                        insets.getSystemWindowInsetBottom() - consumedBottom);
@@ -1126,11 +1151,12 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
     * @param size the current size in the non-parent-matching dimension.
     * @param verticalBar if true the view is attached to a vertical edge, otherwise to a
     *                    horizontal edge,
     * @param rightMargin rightMargin for the color view.
     * @param sideMargin sideMargin for the color view.
     * @param animate if true, the change will be animated.
     */
    private void updateColorViewInt(final ColorViewState state, int sysUiVis, int color,
            int size, boolean verticalBar, int rightMargin, boolean animate, boolean force) {
            int size, boolean verticalBar, boolean seascape, int sideMargin,
            boolean animate, boolean force) {
        state.present = (sysUiVis & state.systemUiHideFlag) == 0
                && (mWindow.getAttributes().flags & state.hideWindowFlag) == 0
                && ((mWindow.getAttributes().flags & FLAG_DRAWS_SYSTEM_BAR_BACKGROUNDS) != 0
@@ -1145,7 +1171,9 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind

        int resolvedHeight = verticalBar ? LayoutParams.MATCH_PARENT : size;
        int resolvedWidth = verticalBar ? size : LayoutParams.MATCH_PARENT;
        int resolvedGravity = verticalBar ? state.horizontalGravity : state.verticalGravity;
        int resolvedGravity = verticalBar
                ? (seascape ? state.seascapeGravity : state.horizontalGravity)
                : state.verticalGravity;

        if (view == null) {
            if (showView) {
@@ -1159,7 +1187,11 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind

                LayoutParams lp = new LayoutParams(resolvedWidth, resolvedHeight,
                        resolvedGravity);
                lp.rightMargin = rightMargin;
                if (seascape) {
                    lp.leftMargin = sideMargin;
                } else {
                    lp.rightMargin = sideMargin;
                }
                addView(view, lp);
                updateColorViewTranslations();
            }
@@ -1168,12 +1200,16 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
            visibilityChanged = state.targetVisibility != vis;
            state.targetVisibility = vis;
            LayoutParams lp = (LayoutParams) view.getLayoutParams();
            int rightMargin = seascape ? 0 : sideMargin;
            int leftMargin = seascape ? sideMargin : 0;
            if (lp.height != resolvedHeight || lp.width != resolvedWidth
                    || lp.gravity != resolvedGravity || lp.rightMargin != rightMargin) {
                    || lp.gravity != resolvedGravity || lp.rightMargin != rightMargin
                    || lp.leftMargin != leftMargin) {
                lp.height = resolvedHeight;
                lp.width = resolvedWidth;
                lp.gravity = resolvedGravity;
                lp.rightMargin = rightMargin;
                lp.leftMargin = leftMargin;
                view.setLayoutParams(lp);
            }
            if (showView) {
@@ -2210,17 +2246,19 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
        final int translucentFlag;
        final int verticalGravity;
        final int horizontalGravity;
        final int seascapeGravity;
        final String transitionName;
        final int hideWindowFlag;

        ColorViewState(int systemUiHideFlag,
                int translucentFlag, int verticalGravity, int horizontalGravity,
                String transitionName, int id, int hideWindowFlag) {
                int seascapeGravity, String transitionName, int id, int hideWindowFlag) {
            this.id = id;
            this.systemUiHideFlag = systemUiHideFlag;
            this.translucentFlag = translucentFlag;
            this.verticalGravity = verticalGravity;
            this.horizontalGravity = horizontalGravity;
            this.seascapeGravity = seascapeGravity;
            this.transitionName = transitionName;
            this.hideWindowFlag = hideWindowFlag;
        }
+16 −5
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ public class ScrimView extends View
    private float mViewAlpha = 1.0f;
    private ValueAnimator mAlphaAnimator;
    private Rect mExcludedRect = new Rect();
    private int mLeftInset = 0;
    private boolean mHasExcludedArea;
    private ValueAnimator.AnimatorUpdateListener mAlphaUpdateListener
            = new ValueAnimator.AnimatorUpdateListener() {
@@ -87,12 +88,12 @@ public class ScrimView extends View
                if (mExcludedRect.top > 0) {
                    canvas.drawRect(0, 0, getWidth(), mExcludedRect.top, mPaint);
                }
                if (mExcludedRect.left > 0) {
                    canvas.drawRect(0,  mExcludedRect.top, mExcludedRect.left, mExcludedRect.bottom,
                            mPaint);
                if (mExcludedRect.left + mLeftInset > 0) {
                    canvas.drawRect(0,  mExcludedRect.top, mExcludedRect.left + mLeftInset,
                            mExcludedRect.bottom, mPaint);
                }
                if (mExcludedRect.right < getWidth()) {
                    canvas.drawRect(mExcludedRect.right,
                if (mExcludedRect.right + mLeftInset < getWidth()) {
                    canvas.drawRect(mExcludedRect.right + mLeftInset,
                            mExcludedRect.top,
                            getWidth(),
                            mExcludedRect.bottom,
@@ -183,4 +184,14 @@ public class ScrimView extends View
    public void setChangeRunnable(Runnable changeRunnable) {
        mChangeRunnable = changeRunnable;
    }

    public void setLeftInset(int leftInset) {
        if (mLeftInset != leftInset) {
            mLeftInset = leftInset;

            if (mHasExcludedArea) {
                invalidate();
            }
        }
    }
}
+4 −0
Original line number Diff line number Diff line
@@ -524,6 +524,10 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener,
        mScrimBehind.setExcludedArea(area);
    }

    public void setLeftInset(int inset) {
        mScrimBehind.setLeftInset(inset);
    }

    public int getScrimBehindColor() {
        return mScrimBehind.getScrimColorWithAlpha();
    }
+12 −7
Original line number Diff line number Diff line
@@ -70,6 +70,7 @@ public class StatusBarWindowView extends FrameLayout {
    private View mBrightnessMirror;

    private int mRightInset = 0;
    private int mLeftInset = 0;

    private PhoneStatusBar mService;
    private final Paint mTransparentSrcPaint = new Paint();
@@ -93,25 +94,26 @@ public class StatusBarWindowView extends FrameLayout {
    @Override
    protected boolean fitSystemWindows(Rect insets) {
        if (getFitsSystemWindows()) {
            boolean paddingChanged = insets.left != getPaddingLeft()
                    || insets.top != getPaddingTop()
            boolean paddingChanged = insets.top != getPaddingTop()
                    || insets.bottom != getPaddingBottom();

            // Super-special right inset handling, because scrims and backdrop need to ignore it.
            if (insets.right != mRightInset) {
            if (insets.right != mRightInset || insets.left != mLeftInset) {
                mRightInset = insets.right;
                mLeftInset = insets.left;
                applyMargins();
            }
            // Drop top inset, apply left inset and pass through bottom inset.
            // Drop top inset, and pass through bottom inset.
            if (paddingChanged) {
                setPadding(insets.left, 0, 0, 0);
                setPadding(0, 0, 0, 0);
            }
            insets.left = 0;
            insets.top = 0;
            insets.right = 0;
        } else {
            if (mRightInset != 0) {
            if (mRightInset != 0 || mLeftInset != 0) {
                mRightInset = 0;
                mLeftInset = 0;
                applyMargins();
            }
            boolean changed = getPaddingLeft() != 0
@@ -127,13 +129,16 @@ public class StatusBarWindowView extends FrameLayout {
    }

    private void applyMargins() {
        mService.mScrimController.setLeftInset(mLeftInset);
        final int N = getChildCount();
        for (int i = 0; i < N; i++) {
            View child = getChildAt(i);
            if (child.getLayoutParams() instanceof LayoutParams) {
                LayoutParams lp = (LayoutParams) child.getLayoutParams();
                if (!lp.ignoreRightInset && lp.rightMargin != mRightInset) {
                if (!lp.ignoreRightInset
                        && (lp.rightMargin != mRightInset || lp.leftMargin != mLeftInset)) {
                    lp.rightMargin = mRightInset;
                    lp.leftMargin = mLeftInset;
                    child.requestLayout();
                }
            }
Loading