From f19d2726f08a5a011532b43d5dda03dc14c2877a Mon Sep 17 00:00:00 2001 From: Aaron Heuckroth Date: Mon, 11 Mar 2019 17:06:02 -0400 Subject: [PATCH] Move grid-based Global Actions to power button when not using panel. Use a pixel-value instead of a dp-value for defining location of the power button to ensure the menu appears in the correct place at different display sizes. Improve separated list logic to avoid showing an empty separated list. Switch ListGridLayout priority to minimize rows instead of columns. Test: Automated tests pass. GA menu appears next to button when the panel is disabled (feature flag), and snaps to the bottom of the screen when the panel is enabled. Change-Id: Ic0246dc4a2af7679e65c71ae8d9db758aeb9a3a8 Fixes: 127740041 --- .../res/layout-land/global_actions_grid.xml | 3 +- .../global_actions_grid_seascape.xml | 3 +- .../res/layout/global_actions_grid.xml | 3 +- packages/SystemUI/res/values/dimens.xml | 4 +- .../android/systemui/HardwareUiLayout.java | 20 ++++---- .../com/android/systemui/MultiListLayout.java | 26 ++++++---- .../globalactions/GlobalActionsDialog.java | 48 +++++++++++-------- .../GlobalActionsGridLayout.java | 23 +++++++-- .../globalactions/ListGridLayout.java | 4 +- 9 files changed, 85 insertions(+), 49 deletions(-) diff --git a/packages/SystemUI/res/layout-land/global_actions_grid.xml b/packages/SystemUI/res/layout-land/global_actions_grid.xml index 235d0fc62e2d5..c51e71b5c61f1 100644 --- a/packages/SystemUI/res/layout-land/global_actions_grid.xml +++ b/packages/SystemUI/res/layout-land/global_actions_grid.xml @@ -7,7 +7,8 @@ android:orientation="horizontal" android:clipToPadding="false" android:theme="@style/qs_theme" - android:gravity="top|right" + android:paddingLeft="@dimen/global_actions_top_padding" + android:gravity="top|left" android:clipChildren="false" > 120dp - 120dp 12dp 9dp + + 330px + 4dp diff --git a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java index 5086c997613ad..72ab02c211928 100644 --- a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java +++ b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java @@ -215,7 +215,7 @@ public class HardwareUiLayout extends MultiListLayout implements Tunable { } else { rotateLeft(); } - if (mSeparated) { + if (mAdapter.hasSeparatedItems()) { if (from == ROTATION_SEASCAPE || to == ROTATION_SEASCAPE) { // Separated view has top margin, so seascape separated view need special rotation, // not a full left or right rotation. @@ -257,10 +257,10 @@ public class HardwareUiLayout extends MultiListLayout implements Tunable { @Override public void onUpdateList() { - removeAllItems(); + super.onUpdateList(); ArrayList separatedActions = - mAdapter.getSeparatedItems(mSeparated); - ArrayList listActions = mAdapter.getListItems(mSeparated); + mAdapter.getSeparatedItems(); + ArrayList listActions = mAdapter.getListItems(); for (int i = 0; i < mAdapter.getCount(); i++) { Object action = mAdapter.getItem(i); @@ -461,8 +461,9 @@ public class HardwareUiLayout extends MultiListLayout implements Tunable { if (mList == null) return; // If got separated button, setRotatedBackground to false, // all items won't get white background. - mListBackground.setRotatedBackground(mSeparated); - mSeparatedViewBackground.setRotatedBackground(mSeparated); + boolean separated = mAdapter.hasSeparatedItems(); + mListBackground.setRotatedBackground(separated); + mSeparatedViewBackground.setRotatedBackground(separated); if (mDivision != null && mDivision.getVisibility() == VISIBLE) { int index = mRotatedBackground ? 0 : 1; mDivision.getLocationOnScreen(mTmp2); @@ -508,26 +509,27 @@ public class HardwareUiLayout extends MultiListLayout implements Tunable { int screenHeight; int totalHeight; int targetGravity; + boolean separated = mAdapter.hasSeparatedItems(); MarginLayoutParams params = (MarginLayoutParams) mSeparatedView.getLayoutParams(); switch (RotationUtils.getRotation(getContext())) { case RotationUtils.ROTATION_LANDSCAPE: defaultTopPadding = getPaddingLeft(); viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth(); - separatedViewTopMargin = mSeparated ? params.leftMargin : 0; + separatedViewTopMargin = separated ? params.leftMargin : 0; screenHeight = getMeasuredWidth(); targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.TOP; break; case RotationUtils.ROTATION_SEASCAPE: defaultTopPadding = getPaddingRight(); viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth(); - separatedViewTopMargin = mSeparated ? params.leftMargin : 0; + separatedViewTopMargin = separated ? params.leftMargin : 0; screenHeight = getMeasuredWidth(); targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM; break; default: // Portrait defaultTopPadding = getPaddingTop(); viewsTotalHeight = mList.getMeasuredHeight() + mSeparatedView.getMeasuredHeight(); - separatedViewTopMargin = mSeparated ? params.topMargin : 0; + separatedViewTopMargin = separated ? params.topMargin : 0; screenHeight = getMeasuredHeight(); targetGravity = Gravity.CENTER_VERTICAL|Gravity.RIGHT; break; diff --git a/packages/SystemUI/src/com/android/systemui/MultiListLayout.java b/packages/SystemUI/src/com/android/systemui/MultiListLayout.java index 2bc4720656768..d063a0f4086eb 100644 --- a/packages/SystemUI/src/com/android/systemui/MultiListLayout.java +++ b/packages/SystemUI/src/com/android/systemui/MultiListLayout.java @@ -33,8 +33,8 @@ import java.util.ArrayList; */ public abstract class MultiListLayout extends LinearLayout { protected boolean mHasOutsideTouch; - protected boolean mSeparated; protected MultiListAdapter mAdapter; + protected boolean mSnapToEdge; protected int mRotation; protected RotationListener mRotationListener; @@ -70,12 +70,10 @@ public abstract class MultiListLayout extends LinearLayout { } /** - * Sets whether the separated view should be shown, and handles updating visibility on - * that view. + * Sets whether the GlobalActions view should snap to the edge of the screen. */ - public void setSeparated(boolean separated) { - mSeparated = separated; - setSeparatedViewVisibility(separated); + public void setSnapToEdge(boolean snap) { + mSnapToEdge = snap; } /** @@ -123,7 +121,9 @@ public abstract class MultiListLayout extends LinearLayout { onUpdateList(); } - protected abstract void onUpdateList(); + protected void onUpdateList() { + setSeparatedViewVisibility(mAdapter.hasSeparatedItems()); + } public void setRotationListener(RotationListener listener) { mRotationListener = listener; @@ -156,13 +156,13 @@ public abstract class MultiListLayout extends LinearLayout { * Creates an ArrayList of items which should be rendered in the separated view. * @param useSeparatedView is true if the separated view will be used, false otherwise. */ - public abstract ArrayList getSeparatedItems(boolean useSeparatedView); + public abstract ArrayList getSeparatedItems(); /** * Creates an ArrayList of items which should be rendered in the list view. * @param useSeparatedView True if the separated view will be used, false otherwise. */ - public abstract ArrayList getListItems(boolean useSeparatedView); + public abstract ArrayList getListItems(); /** * Callback to run when an individual item is clicked or pressed. @@ -176,5 +176,13 @@ public abstract class MultiListLayout extends LinearLayout { * @return True if the long-click was handled, false otherwise. */ public abstract boolean onLongClickItem(int position); + + /** + * Determines whether the mAdapter contains any separated items, used to determine whether + * or not to hide the separated list from view. + */ + public boolean hasSeparatedItems() { + return getSeparatedItems().size() > 0; + } } } diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index 5666eca92f0e3..48cd62f07040b 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -154,7 +154,6 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private boolean mHasVibrator; private boolean mHasLogoutButton; private boolean mHasLockdownButton; - private boolean mUseSeparatedList; private final boolean mShowSilentToggle; private final EmergencyAffordanceManager mEmergencyAffordanceManager; private final ScreenshotHelper mScreenshotHelper; @@ -332,7 +331,6 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, ArraySet addedKeys = new ArraySet(); mHasLogoutButton = false; mHasLockdownButton = false; - mUseSeparatedList = true; for (int i = 0; i < defaultActions.length; i++) { String actionKey = defaultActions[i]; if (addedKeys.contains(actionKey)) { @@ -380,7 +378,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, mHasLogoutButton = true; } } else if (GLOBAL_ACTION_KEY_EMERGENCY.equals(actionKey)) { - if (mUseSeparatedList + if (shouldUseSeparatedView() && !mEmergencyAffordanceManager.needsEmergencyAffordance()) { mItems.add(new EmergencyDialerAction()); } @@ -405,8 +403,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } }) : null; - ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, mUseSeparatedList, - panelViewController); + ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, panelViewController); dialog.setCanceledOnTouchOutside(false); // Handled by the custom class. dialog.setKeyguardShowing(mKeyguardShowing); @@ -692,7 +689,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private Action getEmergencyAction() { Drawable emergencyIcon = mContext.getDrawable(R.drawable.emergency_icon); - if (!mUseSeparatedList) { + if (!shouldUseSeparatedView()) { // use un-colored legacy treatment emergencyIcon.setTintList(null); } @@ -921,9 +918,9 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } @Override - public ArrayList getSeparatedItems(boolean shouldUseSeparatedView) { + public ArrayList getSeparatedItems() { ArrayList separatedActions = new ArrayList(); - if (!shouldUseSeparatedView) { + if (!shouldUseSeparatedView()) { return separatedActions; } for (int i = 0; i < mItems.size(); i++) { @@ -936,8 +933,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } @Override - public ArrayList getListItems(boolean shouldUseSeparatedView) { - if (!shouldUseSeparatedView) { + public ArrayList getListItems() { + if (!shouldUseSeparatedView()) { return new ArrayList(mItems); } ArrayList listActions = new ArrayList(); @@ -1485,17 +1482,15 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private final ColorExtractor mColorExtractor; private final GlobalActionsPanelPlugin.PanelViewController mPanelController; private boolean mKeyguardShowing; - private boolean mUseSeparatedList; private boolean mShowing; private final float mScrimAlpha; - ActionsDialog(Context context, MyAdapter adapter, boolean separated, + ActionsDialog(Context context, MyAdapter adapter, GlobalActionsPanelPlugin.PanelViewController plugin) { super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions); mContext = context; mAdapter = adapter; mColorExtractor = Dependency.get(SysuiColorExtractor.class); - mUseSeparatedList = separated; // Window initialization Window window = getWindow(); @@ -1561,7 +1556,6 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, mGlobalActionsLayout = (MultiListLayout) findViewById(com.android.systemui.R.id.global_actions_view); mGlobalActionsLayout.setOutsideTouchListener(view -> dismiss()); - mGlobalActionsLayout.setSeparated(mUseSeparatedList); mGlobalActionsLayout.setListViewAccessibilityDelegate(new View.AccessibilityDelegate() { @Override public boolean dispatchPopulateAccessibilityEvent( @@ -1573,11 +1567,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, }); mGlobalActionsLayout.setRotationListener(this::onRotate); mGlobalActionsLayout.setAdapter(mAdapter); - } - - private boolean isPanelEnabled(Context context) { - return FeatureFlagUtils.isEnabled( - context, FeatureFlagUtils.GLOBAL_ACTIONS_PANEL_ENABLED); + mGlobalActionsLayout.setSnapToEdge(isPanelEnabled(mContext) + && mPanelController != null); } private int getGlobalActionsLayoutId(Context context) { @@ -1718,9 +1709,24 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } /** - * Determines whether or not the Global Actions Dialog should use the newer grid-style layout. + * Determines whether or not the Global Actions menu should use the newer grid-style layout. */ - public static boolean isGridEnabled(Context context) { + private static boolean isGridEnabled(Context context) { return FeatureFlagUtils.isEnabled(context, FeatureFlagUtils.GLOBAL_ACTIONS_GRID_ENABLED); } + + /** + * Determines whether or not the Global Actions Panel should appear when the power button + * is held. + */ + private static boolean isPanelEnabled(Context context) { + return FeatureFlagUtils.isEnabled( + context, FeatureFlagUtils.GLOBAL_ACTIONS_PANEL_ENABLED); } + + /** + * Determines whether the Global Actions menu should use a separated view for emergency actions. + */ + private static boolean shouldUseSeparatedView() { + return true; + } } diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java index cda7669a90b68..058ea605bc879 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java @@ -19,6 +19,7 @@ package com.android.systemui.globalactions; import android.content.Context; import android.text.TextUtils; import android.util.AttributeSet; +import android.view.Gravity; import android.view.View; import android.view.ViewGroup; @@ -71,10 +72,10 @@ public class GlobalActionsGridLayout extends MultiListLayout { @Override public void onUpdateList() { - removeAllItems(); + super.onUpdateList(); ArrayList separatedActions = - mAdapter.getSeparatedItems(mSeparated); - ArrayList listActions = mAdapter.getListItems(mSeparated); + mAdapter.getSeparatedItems(); + ArrayList listActions = mAdapter.getListItems(); setExpectedListItemCount(listActions.size()); int rotation = RotationUtils.getRotation(mContext); @@ -108,6 +109,7 @@ public class GlobalActionsGridLayout extends MultiListLayout { parent.addView(v); } } + updateSnapPosition(); } @Override @@ -115,6 +117,19 @@ public class GlobalActionsGridLayout extends MultiListLayout { return findViewById(com.android.systemui.R.id.separated_button); } + private void updateSnapPosition() { + if (mSnapToEdge) { + setPadding(0, 0, 0, 0); + if (mRotation == RotationUtils.ROTATION_LANDSCAPE) { + setGravity(Gravity.RIGHT); + } else if (mRotation == RotationUtils.ROTATION_SEASCAPE) { + setGravity(Gravity.LEFT); + } else { + setGravity(Gravity.BOTTOM); + } + } + } + @Override protected ListGridLayout getListView() { return findViewById(android.R.id.list); @@ -148,7 +163,7 @@ public class GlobalActionsGridLayout extends MultiListLayout { } /** - * Not used in this implementation of the Global Actions Menu, but necessary for some others. + * Not ued in this implementation of the Global Actions Menu, but necessary for some others. */ @Override public void setDivisionView(View v) { diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java index 6c106dfe9db61..048f801967814 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java @@ -114,7 +114,7 @@ public class ListGridLayout extends LinearLayout { if (mExpectedCount == 3) { return 1; } - return (int) Math.ceil(Math.sqrt(mExpectedCount)); + return (int) Math.round(Math.sqrt(mExpectedCount)); } private int getColumnCount() { @@ -122,6 +122,6 @@ public class ListGridLayout extends LinearLayout { if (mExpectedCount == 3) { return 3; } - return (int) Math.round(Math.sqrt(mExpectedCount)); + return (int) Math.ceil(Math.sqrt(mExpectedCount)); } }