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

Commit 360e2987 authored by Tiger Huang's avatar Tiger Huang Committed by Android (Google) Code Review
Browse files

Merge "Re-land: Make action mode view extend into system insets area" into main

parents 1cce78ff be6a9a57
Loading
Loading
Loading
Loading
+97 −51
Original line number Diff line number Diff line
@@ -120,6 +120,7 @@ import com.android.internal.view.menu.MenuHelper;
import com.android.internal.widget.ActionBarContextView;
import com.android.internal.widget.BackgroundFallback;
import com.android.internal.widget.floatingtoolbar.FloatingToolbar;
import com.android.window.flags.Flags;

import java.util.List;
import java.util.concurrent.Executor;
@@ -201,6 +202,13 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
    ActionMode mPrimaryActionMode;
    private ActionMode mFloatingActionMode;
    private ActionBarContextView mPrimaryActionModeView;

    // Paddings loaded from R.attr.actionModeStyle.
    private int mActionModeViewInternalPaddingLeft;
    private int mActionModeViewInternalPaddingTop;
    private int mActionModeViewInternalPaddingRight;
    private int mActionModeViewInternalPaddingBottom;

    private PopupWindow mPrimaryActionModePopup;
    private Runnable mShowPrimaryActionModePopup;
    private ViewTreeObserver.OnPreDrawListener mFloatingToolbarPreDrawListener;
@@ -1003,7 +1011,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
    public void onWindowSystemUiVisibilityChanged(int visible) {
        updateColorViews(null /* insets */, true /* animate */);

        if (mStatusGuard != null && mStatusGuard.getVisibility() == VISIBLE) {
        if (!Flags.actionModeEdgeToEdge()
                && mStatusGuard != null && mStatusGuard.getVisibility() == VISIBLE) {
            updateStatusGuardColor();
        }
    }
@@ -1040,7 +1049,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
        }
        mFrameOffsets.set(insets.getSystemWindowInsetsAsRect());
        insets = updateColorViews(insets, true /* animate */);
        insets = updateStatusGuard(insets);
        insets = updateActionModeInsets(insets);
        if (getForeground() != null) {
            drawableChanged();
        }
@@ -1592,7 +1601,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
        }
    }

    private WindowInsets updateStatusGuard(WindowInsets insets) {
    private WindowInsets updateActionModeInsets(WindowInsets insets) {
        boolean showStatusGuard = false;
        // Show the status guard when the non-overlay contextual action bar is showing
        if (mPrimaryActionModeView != null) {
@@ -1608,15 +1617,39 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
                    final Rect rect = mTempRect;

                    // Apply the insets that have not been applied by the contentParent yet.
                    WindowInsets innerInsets =
                    final WindowInsets innerInsets =
                            mWindow.mContentParent.computeSystemWindowInsets(insets, rect);
                    final boolean consumesSystemWindowInsetsTop;
                    if (Flags.actionModeEdgeToEdge()) {
                        final Insets systemWindowInsets = innerInsets.getSystemWindowInsets();
                        final Insets newMargin = innerInsets.getInsets(
                                WindowInsets.Type.navigationBars());

                        // Don't extend into navigation bar area so the width can align with status
                        // bar color view.
                        if (mlp.leftMargin != newMargin.left
                                || mlp.rightMargin != newMargin.right) {
                            mlpChanged = true;
                            mlp.leftMargin = newMargin.left;
                            mlp.rightMargin = newMargin.right;
                        }

                        mPrimaryActionModeView.setPadding(
                                mActionModeViewInternalPaddingLeft + systemWindowInsets.left
                                        - newMargin.left,
                                mActionModeViewInternalPaddingTop + systemWindowInsets.top,
                                mActionModeViewInternalPaddingRight + systemWindowInsets.right
                                        - newMargin.right,
                                mActionModeViewInternalPaddingBottom);
                        consumesSystemWindowInsetsTop = systemWindowInsets.top > 0;
                    } else {
                        int newTopMargin = innerInsets.getSystemWindowInsetTop();
                        int newLeftMargin = innerInsets.getSystemWindowInsetLeft();
                        int newRightMargin = innerInsets.getSystemWindowInsetRight();

                    // Must use root window insets for the guard, because the color views consume
                    // the navigation bar inset if the window does not request LAYOUT_HIDE_NAV - but
                    // the status guard is attached at the root.
                        // Must use root window insets for the guard, because the color views
                        // consume the navigation bar inset if the window does not request
                        // LAYOUT_HIDE_NAV - but the status guard is attached at the root.
                        WindowInsets rootInsets = getRootWindowInsets();
                        int newGuardLeftMargin = rootInsets.getSystemWindowInsetLeft();
                        int newGuardRightMargin = rootInsets.getSystemWindowInsetRight();
@@ -1657,6 +1690,8 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
                            // If it wasn't previously shown, the color may be stale
                            updateStatusGuardColor();
                        }
                        consumesSystemWindowInsetsTop = showStatusGuard;
                    }

                    // We only need to consume the insets if the action
                    // mode is overlaid on the app content (e.g. it's
@@ -1664,22 +1699,24 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
                    // screen_simple_overlay_action_mode.xml).
                    final boolean nonOverlay = (mWindow.getLocalFeaturesPrivate()
                            & (1 << Window.FEATURE_ACTION_MODE_OVERLAY)) == 0;
                    if (nonOverlay && showStatusGuard) {
                    if (nonOverlay && consumesSystemWindowInsetsTop) {
                        insets = insets.inset(0, insets.getSystemWindowInsetTop(), 0, 0);
                    }
                } else {
                    if (!Flags.actionModeEdgeToEdge()) {
                        // reset top margin
                        if (mlp.topMargin != 0 || mlp.leftMargin != 0 || mlp.rightMargin != 0) {
                            mlpChanged = true;
                            mlp.topMargin = 0;
                        }
                    }
                }
                if (mlpChanged) {
                    mPrimaryActionModeView.setLayoutParams(mlp);
                }
            }
        }
        if (mStatusGuard != null) {
        if (!Flags.actionModeEdgeToEdge() && mStatusGuard != null) {
            mStatusGuard.setVisibility(showStatusGuard ? VISIBLE : GONE);
        }
        return insets;
@@ -1987,6 +2024,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
                }

                mPrimaryActionModeView = new ActionBarContextView(actionBarContext);
                initializeActionModeViewInternalPadding();
                mPrimaryActionModePopup = new PopupWindow(actionBarContext, null,
                        R.attr.actionModePopupWindowStyle);
                mPrimaryActionModePopup.setWindowLayoutType(
@@ -2033,6 +2071,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
                ViewStub stub = findViewById(R.id.action_mode_bar_stub);
                if (stub != null) {
                    mPrimaryActionModeView = (ActionBarContextView) stub.inflate();
                    initializeActionModeViewInternalPadding();
                    mPrimaryActionModePopup = null;
                }
            }
@@ -2047,6 +2086,13 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
        return null;
    }

    private void initializeActionModeViewInternalPadding() {
        mActionModeViewInternalPaddingLeft = mPrimaryActionModeView.getPaddingLeft();
        mActionModeViewInternalPaddingTop = mPrimaryActionModeView.getPaddingTop();
        mActionModeViewInternalPaddingRight = mPrimaryActionModeView.getPaddingRight();
        mActionModeViewInternalPaddingBottom = mPrimaryActionModeView.getPaddingBottom();
    }

    private void endOnGoingFadeAnimation() {
        if (mFadeAnim != null) {
            mFadeAnim.end();
@@ -2183,7 +2229,7 @@ public class DecorView extends FrameLayout implements RootViewSurfaceTaker, Wind
        for (int i = getChildCount() - 1; i >= 0; i--) {
            View v = getChildAt(i);
            if (v != mStatusColorViewState.view && v != mNavigationColorViewState.view
                    && v != mStatusGuard) {
                    && (Flags.actionModeEdgeToEdge() || v != mStatusGuard)) {
                removeViewAt(i);
            }
        }
+28 −6
Original line number Diff line number Diff line
@@ -15,8 +15,10 @@
 */
package com.android.internal.widget;

import android.annotation.SuppressLint;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.TypedArray;
import android.graphics.drawable.Drawable;
import android.os.Build;
@@ -34,6 +36,7 @@ import android.widget.TextView;

import com.android.internal.R;
import com.android.internal.view.menu.MenuBuilder;
import com.android.window.flags.Flags;

/**
 * @hide
@@ -54,6 +57,7 @@ public class ActionBarContextView extends AbsActionBarView {
    private Drawable mSplitBackground;
    private boolean mTitleOptional;
    private int mCloseItemLayout;
    private final int mInternalVerticalPadding;

    public ActionBarContextView(Context context) {
        this(context, null);
@@ -92,6 +96,8 @@ public class ActionBarContextView extends AbsActionBarView {
                R.layout.action_mode_close_item);

        a.recycle();

        mInternalVerticalPadding = getPaddingTop() + getPaddingBottom();
    }

    @Override
@@ -103,6 +109,19 @@ public class ActionBarContextView extends AbsActionBarView {
        }
    }

    @SuppressLint("CustomViewStyleable")
    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);

        // Action mode can change size on configuration changes.
        // Reread the desired height from the theme-specified style.
        TypedArray a = getContext().obtainStyledAttributes(null, R.styleable.ActionMode,
                R.attr.actionModeStyle, 0);
        setContentHeight(a.getLayoutDimension(R.styleable.ActionMode_height, 0));
        a.recycle();
    }

    @Override
    public void setSplitToolbar(boolean split) {
        if (mSplitActionBar != split) {
@@ -314,12 +333,15 @@ public class ActionBarContextView extends AbsActionBarView {
        }

        final int contentWidth = MeasureSpec.getSize(widthMeasureSpec);

        int maxHeight = mContentHeight > 0 ?
                mContentHeight : MeasureSpec.getSize(heightMeasureSpec);
        int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight();

        final int verticalPadding = getPaddingTop() + getPaddingBottom();
        int availableWidth = contentWidth - getPaddingLeft() - getPaddingRight();
        final int externalVerticalPadding = Math.max(0, verticalPadding - mInternalVerticalPadding);
        final int maxHeight = mContentHeight > 0
                ? Flags.actionModeEdgeToEdge()
                        ? mContentHeight + externalVerticalPadding
                        : mContentHeight
                : MeasureSpec.getSize(heightMeasureSpec);
        final int height = maxHeight - verticalPadding;
        final int childSpecHeight = MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST);

+39 −46
Original line number Diff line number Diff line
@@ -294,54 +294,24 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
        }
    }

    private boolean applyInsets(View view, Rect insets, boolean toPadding,
            boolean left, boolean top, boolean right, boolean bottom) {
        boolean changed;
        if (toPadding) {
            changed = setMargin(view, EMPTY_RECT, left, top, right, bottom);
            changed |= setPadding(view, insets, left, top, right, bottom);
        } else {
            changed = setPadding(view, EMPTY_RECT, left, top, right, bottom);
            changed |= setMargin(view, insets, left, top, right, bottom);
        }
        return changed;
    }

    private boolean setPadding(View view, Rect insets,
            boolean left, boolean top, boolean right, boolean bottom) {
        if ((left && view.getPaddingLeft() != insets.left)
                || (top && view.getPaddingTop() != insets.top)
                || (right && view.getPaddingRight() != insets.right)
                || (bottom && view.getPaddingBottom() != insets.bottom)) {
            view.setPadding(
                    left ? insets.left : view.getPaddingLeft(),
                    top ? insets.top : view.getPaddingTop(),
                    right ? insets.right : view.getPaddingRight(),
                    bottom ? insets.bottom : view.getPaddingBottom());
            return true;
        }
        return false;
    }

    private boolean setMargin(View view,  Rect insets,
            boolean left, boolean top, boolean right, boolean bottom) {
    private boolean setMargin(View view, int left, int top, int right, int bottom) {
        final LayoutParams lp = (LayoutParams) view.getLayoutParams();
        boolean changed = false;
        if (left && lp.leftMargin != insets.left) {
        if (lp.leftMargin != left) {
            changed = true;
            lp.leftMargin = insets.left;
            lp.leftMargin = left;
        }
        if (top && lp.topMargin != insets.top) {
        if (lp.topMargin != top) {
            changed = true;
            lp.topMargin = insets.top;
            lp.topMargin = top;
        }
        if (right && lp.rightMargin != insets.right) {
        if (lp.rightMargin != right) {
            changed = true;
            lp.rightMargin = insets.right;
            lp.rightMargin = right;
        }
        if (bottom && lp.bottomMargin != insets.bottom) {
        if (lp.bottomMargin != bottom) {
            changed = true;
            lp.bottomMargin = insets.bottom;
            lp.bottomMargin = bottom;
        }
        return changed;
    }
@@ -367,12 +337,30 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
        final Insets sysInsets = insets.getSystemWindowInsets();
        mSystemInsets.set(sysInsets.left, sysInsets.top, sysInsets.right, sysInsets.bottom);

        // The top and bottom action bars are always within the content area.
        boolean changed = applyInsets(mActionBarTop, mSystemInsets,
                mActionBarExtendsIntoSystemInsets, true, true, true, false);
        boolean changed = false;
        if (mActionBarExtendsIntoSystemInsets) {
            // Don't extend into navigation bar area so the width can align with status bar
            // color view.
            final Insets navBarInsets = insets.getInsets(WindowInsets.Type.navigationBars());
            final int paddingLeft = sysInsets.left - navBarInsets.left;
            final int paddingRight = sysInsets.right - navBarInsets.right;
            mActionBarTop.setPadding(paddingLeft, sysInsets.top, paddingRight, 0);
            changed |= setMargin(
                    mActionBarTop, navBarInsets.left, 0, navBarInsets.right, 0);
            if (mActionBarBottom != null) {
            changed |= applyInsets(mActionBarBottom, mSystemInsets,
                    mActionBarExtendsIntoSystemInsets, true, false, true, true);
                mActionBarBottom.setPadding(paddingLeft, 0, paddingRight, sysInsets.bottom);
                changed |= setMargin(
                        mActionBarBottom, navBarInsets.left, 0, navBarInsets.right, 0);
            }
        } else {
            mActionBarTop.setPadding(0, 0, 0, 0);
            changed |= setMargin(
                    mActionBarTop, sysInsets.left, sysInsets.top, sysInsets.right, 0);
            if (mActionBarBottom != null) {
                mActionBarBottom.setPadding(0, 0, 0, 0);
                changed |= setMargin(
                        mActionBarBottom, sysInsets.left, 0, sysInsets.right, sysInsets.bottom);
            }
        }

        // Cannot use the result of computeSystemWindowInsets, because that consumes the
@@ -521,7 +509,12 @@ public class ActionBarOverlayLayout extends ViewGroup implements DecorContentPar
                );
            }
        }
        setMargin(mContent, mContentInsets, true, true, true, true);
        setMargin(
                mContent,
                mContentInsets.left,
                mContentInsets.top,
                mContentInsets.right,
                mContentInsets.bottom);

        if (!mLastInnerInsets.equals(mInnerInsets)) {
            // If the inner insets have changed, we need to dispatch this down to
+10 −0
Original line number Diff line number Diff line
@@ -1420,6 +1420,16 @@
                       android:resource="@xml/accessibility_shortcut_test_activity"/>
        </activity>

        <activity android:name="com.android.internal.widget.ActionBarContextViewActivity"
                  android:label="ActionBarContextViewActivity"
                  android:exported="true"
                  android:theme="@style/ActionBarContextViewTheme">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.FRAMEWORK_INSTRUMENTATION_TEST" />
            </intent-filter>
        </activity>

        <!-- Activity-level metadata -->
        <meta-data android:name="com.android.frameworks.coretests.isApp" android:value="true" />
        <meta-data android:name="com.android.frameworks.coretests.string" android:value="foo" />
+10 −0
Original line number Diff line number Diff line
@@ -84,5 +84,15 @@
        <item name="android:fontFeatureSettings">\"smcp\"</item>
        <item name="android:fontVariationSettings">\'wdth\' 150</item>
    </style>
    <style name="ActionBarContextViewTheme" parent="android:Theme.NoTitleBar">
        <item name="android:actionModeStyle">@style/ActionBarContextViewActionModeTheme</item>
    </style>
    <style name="ActionBarContextViewActionModeTheme">
        <item name="android:paddingLeft">10px</item>
        <item name="android:paddingTop">20px</item>
        <item name="android:paddingRight">30px</item>
        <item name="android:paddingBottom">40px</item>
        <item name="android:height">200px</item>
    </style>

</resources>
Loading