Loading core/java/com/android/internal/policy/DecorView.java +97 −51 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); } } Loading Loading @@ -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(); } Loading Loading @@ -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) { Loading @@ -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(); Loading Loading @@ -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 Loading @@ -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; Loading Loading @@ -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( Loading Loading @@ -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; } } Loading @@ -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(); Loading Loading @@ -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); } } Loading core/java/com/android/internal/widget/ActionBarContextView.java +28 −6 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading @@ -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); Loading Loading @@ -92,6 +96,8 @@ public class ActionBarContextView extends AbsActionBarView { R.layout.action_mode_close_item); a.recycle(); mInternalVerticalPadding = getPaddingTop() + getPaddingBottom(); } @Override Loading @@ -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) { Loading Loading @@ -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); Loading core/java/com/android/internal/widget/ActionBarOverlayLayout.java +39 −46 Original line number Diff line number Diff line Loading @@ -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; } Loading @@ -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 Loading Loading @@ -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 Loading core/tests/coretests/AndroidManifest.xml +10 −0 Original line number Diff line number Diff line Loading @@ -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" /> Loading core/tests/coretests/res/values/styles.xml +10 −0 Original line number Diff line number Diff line Loading @@ -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
core/java/com/android/internal/policy/DecorView.java +97 −51 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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(); } } Loading Loading @@ -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(); } Loading Loading @@ -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) { Loading @@ -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(); Loading Loading @@ -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 Loading @@ -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; Loading Loading @@ -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( Loading Loading @@ -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; } } Loading @@ -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(); Loading Loading @@ -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); } } Loading
core/java/com/android/internal/widget/ActionBarContextView.java +28 −6 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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 Loading @@ -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); Loading Loading @@ -92,6 +96,8 @@ public class ActionBarContextView extends AbsActionBarView { R.layout.action_mode_close_item); a.recycle(); mInternalVerticalPadding = getPaddingTop() + getPaddingBottom(); } @Override Loading @@ -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) { Loading Loading @@ -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); Loading
core/java/com/android/internal/widget/ActionBarOverlayLayout.java +39 −46 Original line number Diff line number Diff line Loading @@ -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; } Loading @@ -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 Loading Loading @@ -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 Loading
core/tests/coretests/AndroidManifest.xml +10 −0 Original line number Diff line number Diff line Loading @@ -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" /> Loading
core/tests/coretests/res/values/styles.xml +10 −0 Original line number Diff line number Diff line Loading @@ -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>