Loading packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java +34 −15 Original line number Diff line number Diff line Loading @@ -32,10 +32,13 @@ import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; import android.widget.LinearLayout; import com.android.systemui.globalactions.GlobalActionsDialog; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; import com.android.systemui.util.leak.RotationUtils; import java.util.ArrayList; /** * Layout for placing two containers at a specific physical position on the device, relative to the * device's hardware, regardless of screen rotation. Loading Loading @@ -89,15 +92,6 @@ public class HardwareUiLayout extends MultiListLayout implements Tunable { } } @Override public ViewGroup getParentView(boolean separated, int index, int rotation) { if (separated) { return getSeparatedView(); } else { return getListView(); } } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); Loading Loading @@ -221,7 +215,7 @@ public class HardwareUiLayout extends MultiListLayout implements Tunable { } else { rotateLeft(); } if (mHasSeparatedView) { if (mSeparated) { 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. Loading Loading @@ -261,6 +255,31 @@ public class HardwareUiLayout extends MultiListLayout implements Tunable { } } @Override public void onUpdateList() { removeAllItems(); ArrayList<GlobalActionsDialog.Action> separatedActions = mAdapter.getSeparatedItems(mSeparated); ArrayList<GlobalActionsDialog.Action> listActions = mAdapter.getListItems(mSeparated); for (int i = 0; i < mAdapter.getCount(); i++) { Object action = mAdapter.getItem(i); int separatedIndex = separatedActions.indexOf(action); ViewGroup parent; if (separatedIndex != -1) { parent = getSeparatedView(); } else { int listIndex = listActions.indexOf(action); parent = getListView(); } View v = mAdapter.getView(i, null, parent); final int pos = i; v.setOnClickListener(view -> mAdapter.onClickItem(pos)); v.setOnLongClickListener(view -> mAdapter.onLongClickItem(pos)); parent.addView(v); } } private void rotateRight() { rotateRight(this); rotateRight(mList); Loading Loading @@ -442,8 +461,8 @@ 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(mHasSeparatedView); mSeparatedViewBackground.setRotatedBackground(mHasSeparatedView); mListBackground.setRotatedBackground(mSeparated); mSeparatedViewBackground.setRotatedBackground(mSeparated); if (mDivision != null && mDivision.getVisibility() == VISIBLE) { int index = mRotatedBackground ? 0 : 1; mDivision.getLocationOnScreen(mTmp2); Loading Loading @@ -494,21 +513,21 @@ public class HardwareUiLayout extends MultiListLayout implements Tunable { case RotationUtils.ROTATION_LANDSCAPE: defaultTopPadding = getPaddingLeft(); viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth(); separatedViewTopMargin = mHasSeparatedView ? params.leftMargin : 0; separatedViewTopMargin = mSeparated ? params.leftMargin : 0; screenHeight = getMeasuredWidth(); targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.TOP; break; case RotationUtils.ROTATION_SEASCAPE: defaultTopPadding = getPaddingRight(); viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth(); separatedViewTopMargin = mHasSeparatedView ? params.leftMargin : 0; separatedViewTopMargin = mSeparated ? params.leftMargin : 0; screenHeight = getMeasuredWidth(); targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM; break; default: // Portrait defaultTopPadding = getPaddingTop(); viewsTotalHeight = mList.getMeasuredHeight() + mSeparatedView.getMeasuredHeight(); separatedViewTopMargin = mHasSeparatedView ? params.topMargin : 0; separatedViewTopMargin = mSeparated ? params.topMargin : 0; screenHeight = getMeasuredHeight(); targetGravity = Gravity.CENTER_VERTICAL|Gravity.RIGHT; break; Loading packages/SystemUI/src/com/android/systemui/MultiListLayout.java +57 −37 Original line number Diff line number Diff line Loading @@ -21,19 +21,20 @@ import android.content.res.Configuration; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.LinearLayout; import com.android.systemui.util.leak.RotationUtils; import java.util.ArrayList; /** * Layout class representing the Global Actions menu which appears when the power button is held. */ public abstract class MultiListLayout extends LinearLayout { protected boolean mHasOutsideTouch; protected boolean mHasSeparatedView; protected int mExpectedSeparatedItemCount; protected int mExpectedListItemCount; protected boolean mSeparated; protected MultiListAdapter mAdapter; protected int mRotation; protected RotationListener mRotationListener; Loading @@ -52,18 +53,6 @@ public abstract class MultiListLayout extends LinearLayout { */ public abstract void removeAllItems(); /** * Get the parent view which will be used to contain the item at the specified index. * @param separated Whether or not this index refers to a position in the separated or list * container. * @param index The index of the item within the container. * @param rotation Specifies the rotation of the device, which is used in some cases to * determine child ordering. * @return The parent ViewGroup which will be used to contain the specified item * after it has been added to the layout. */ public abstract ViewGroup getParentView(boolean separated, int index, int rotation); /** * Sets the divided view, which may have a differently-colored background. */ Loading @@ -81,32 +70,19 @@ public abstract class MultiListLayout extends LinearLayout { } /** * Sets the number of items expected to be rendered in the separated container. This allows the * layout to correctly determine which parent containers will be used for items before they have * beenadded to the layout. * @param count The number of items expected. */ public void setExpectedSeparatedItemCount(int count) { mExpectedSeparatedItemCount = count; } /** * Sets the number of items expected to be rendered in the list container. This allows the * layout to correctly determine which parent containers will be used for items before they have * beenadded to the layout. * @param count The number of items expected. * Sets whether the separated view should be shown, and handles updating visibility on * that view. */ public void setExpectedListItemCount(int count) { mExpectedListItemCount = count; public void setSeparated(boolean separated) { mSeparated = separated; setSeparatedViewVisibility(separated); } /** * Sets whether the separated view should be shown, and handles updating visibility on * that view. * Sets the adapter used to inflate items. */ public void setHasSeparatedView(boolean hasSeparatedView) { mHasSeparatedView = hasSeparatedView; setSeparatedViewVisibility(hasSeparatedView); public void setAdapter(MultiListAdapter adapter) { mAdapter = adapter; } /** Loading Loading @@ -136,6 +112,19 @@ public abstract class MultiListLayout extends LinearLayout { } } /** * Update the list of items in both the separated and list views. * For this to work, mAdapter must already have been set. */ public void updateList() { if (mAdapter == null) { throw new IllegalStateException("mAdapter must be set before calling updateList"); } onUpdateList(); } protected abstract void onUpdateList(); public void setRotationListener(RotationListener listener) { mRotationListener = listener; } Loading @@ -157,4 +146,35 @@ public abstract class MultiListLayout extends LinearLayout { public interface RotationListener { void onRotate(int from, int to); } /** * Adapter class for converting items into child views for MultiListLayout and handling * callbacks for input events. */ public abstract static class MultiListAdapter extends BaseAdapter { /** * 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); /** * 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); /** * Callback to run when an individual item is clicked or pressed. * @param position The index of the item which was clicked. */ public abstract void onClickItem(int position); /** * Callback to run when an individual item is long-clicked or long-pressed. * @param position The index of the item which was long-clicked. * @return True if the long-click was handled, false otherwise. */ public abstract boolean onLongClickItem(int position); } } packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +46 −92 Original line number Diff line number Diff line Loading @@ -65,8 +65,6 @@ import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityEvent; import android.widget.AdapterView.OnItemLongClickListener; import android.widget.BaseAdapter; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ImageView.ScaleType; Loading @@ -87,6 +85,7 @@ import com.android.internal.widget.LockPatternUtils; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.MultiListLayout; import com.android.systemui.MultiListLayout.MultiListAdapter; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.GlobalActions.GlobalActionsManager; import com.android.systemui.plugins.GlobalActionsPanelPlugin; Loading @@ -99,16 +98,14 @@ import com.android.systemui.volume.SystemUIInterpolators.LogAccelerateInterpolat import java.util.ArrayList; import java.util.List; import java.util.Locale; /** * Helper to show the global actions dialog. Each item is an {@link Action} that * may show depending on whether the keyguard is showing, and whether the device * is provisioned. */ class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener, DialogInterface.OnShowListener, ConfigurationController.ConfigurationListener { public class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogInterface.OnShowListener, ConfigurationController.ConfigurationListener { static public final String SYSTEM_DIALOG_REASON_KEY = "reason"; static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions"; Loading Loading @@ -158,7 +155,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, private boolean mHasVibrator; private boolean mHasLogoutButton; private boolean mHasLockdownButton; private boolean mSeparatedEmergencyButtonEnabled; private boolean mUseSeparatedList; private final boolean mShowSilentToggle; private final EmergencyAffordanceManager mEmergencyAffordanceManager; private final ScreenshotHelper mScreenshotHelper; Loading Loading @@ -336,7 +333,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, ArraySet<String> addedKeys = new ArraySet<String>(); mHasLogoutButton = false; mHasLockdownButton = false; mSeparatedEmergencyButtonEnabled = true; mUseSeparatedList = true; for (int i = 0; i < defaultActions.length; i++) { String actionKey = defaultActions[i]; if (addedKeys.contains(actionKey)) { Loading Loading @@ -384,7 +381,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, mHasLogoutButton = true; } } else if (GLOBAL_ACTION_KEY_EMERGENCY.equals(actionKey)) { if (mSeparatedEmergencyButtonEnabled if (mUseSeparatedList && !mEmergencyAffordanceManager.needsEmergencyAffordance()) { mItems.add(new EmergencyDialerAction()); } Loading @@ -401,14 +398,6 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, mAdapter = new MyAdapter(); OnItemLongClickListener onItemLongClickListener = (parent, view, position, id) -> { final Action action = mAdapter.getItem(position); if (action instanceof LongPressAction) { mDialog.dismiss(); return ((LongPressAction) action).onLongPress(); } return false; }; GlobalActionsPanelPlugin.PanelViewController panelViewController = mPanelExtension.get() != null ? mPanelExtension.get().onPanelShown(() -> { Loading @@ -417,8 +406,8 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, } }) : null; ActionsDialog dialog = new ActionsDialog(mContext, this, mAdapter, onItemLongClickListener, mSeparatedEmergencyButtonEnabled, panelViewController); ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, mUseSeparatedList, panelViewController); dialog.setCanceledOnTouchOutside(false); // Handled by the custom class. dialog.setKeyguardShowing(mKeyguardShowing); Loading Loading @@ -548,7 +537,6 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, } } private class ScreenshotAction extends SinglePressAction implements LongPressAction { public ScreenshotAction() { super(R.drawable.ic_screenshot, R.string.global_action_screenshot); Loading Loading @@ -713,7 +701,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, private Action getEmergencyAction() { Drawable emergencyIcon = mContext.getDrawable(R.drawable.emergency_icon); if(!mSeparatedEmergencyButtonEnabled) { if (!mUseSeparatedList) { // use un-colored legacy treatment emergencyIcon.setTintList(null); } Loading Loading @@ -906,15 +894,6 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, } } /** {@inheritDoc} */ public void onClick(DialogInterface dialog, int which) { Action item = mAdapter.getItem(which); if (!(item instanceof SilentModeTriStateAction)) { dialog.dismiss(); } item.onPress(); } /** {@inheritDoc} */ public void onShow(DialogInterface dialog) { MetricsLogger.visible(mContext, MetricsEvent.POWER_MENU); Loading @@ -927,11 +906,10 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, * the device is provisioned * via {@link com.android.systemui.globalactions.GlobalActionsDialog#mDeviceProvisioned}. */ private class MyAdapter extends BaseAdapter { public class MyAdapter extends MultiListAdapter { @Override public int getCount() { int count = 0; for (int i = 0; i < mItems.size(); i++) { final Action action = mItems.get(i); Loading @@ -951,7 +929,8 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, return getItem(position).isEnabled(); } public ArrayList<Action> getSeparatedActions(boolean shouldUseSeparatedView) { @Override public ArrayList<Action> getSeparatedItems(boolean shouldUseSeparatedView) { ArrayList<Action> separatedActions = new ArrayList<Action>(); if (!shouldUseSeparatedView) { return separatedActions; Loading @@ -965,7 +944,8 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, return separatedActions; } public ArrayList<Action> getListActions(boolean shouldUseSeparatedView) { @Override public ArrayList<Action> getListItems(boolean shouldUseSeparatedView) { if (!shouldUseSeparatedView) { return new ArrayList<Action>(mItems); } Loading @@ -984,6 +964,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, return false; } @Override public Action getItem(int position) { int filteredPos = 0; Loading Loading @@ -1013,6 +994,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Action action = getItem(position); View view = action.create(mContext, convertView, parent, LayoutInflater.from(mContext)); Loading @@ -1022,6 +1004,25 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, } return view; } @Override public boolean onLongClickItem(int position) { final Action action = mAdapter.getItem(position); if (action instanceof LongPressAction) { mDialog.dismiss(); return ((LongPressAction) action).onLongPress(); } return false; } @Override public void onClickItem(int position) { Action item = mAdapter.getItem(position); if (!(item instanceof SilentModeTriStateAction)) { mDialog.dismiss(); } item.onPress(); } } // note: the scheme below made more sense when we were planning on having Loading @@ -1033,7 +1034,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, /** * What each item in the global actions dialog must be able to support. */ private interface Action { public interface Action { /** * @return Text that will be announced when dialog is created. null * for none. Loading @@ -1052,7 +1053,8 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, /** * @return whether this action should appear in the dialog before the * device is provisioned. * device is provisioned.onlongpress * */ boolean showBeforeProvisioning(); Loading Loading @@ -1488,26 +1490,21 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, private final Context mContext; private final MyAdapter mAdapter; private MultiListLayout mGlobalActionsLayout; private final OnClickListener mClickListener; private final OnItemLongClickListener mLongClickListener; private final Drawable mBackgroundDrawable; private final ColorExtractor mColorExtractor; private final GlobalActionsPanelPlugin.PanelViewController mPanelController; private boolean mKeyguardShowing; private boolean mShouldDisplaySeparatedButton; private boolean mUseSeparatedList; private boolean mShowing; private final float mScrimAlpha; public ActionsDialog(Context context, OnClickListener clickListener, MyAdapter adapter, OnItemLongClickListener longClickListener, boolean shouldDisplaySeparatedButton, ActionsDialog(Context context, MyAdapter adapter, boolean separated, GlobalActionsPanelPlugin.PanelViewController plugin) { super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions); mContext = context; mAdapter = adapter; mClickListener = clickListener; mLongClickListener = longClickListener; mColorExtractor = Dependency.get(SysuiColorExtractor.class); mShouldDisplaySeparatedButton = shouldDisplaySeparatedButton; mUseSeparatedList = separated; // Window initialization Window window = getWindow(); Loading Loading @@ -1573,7 +1570,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, mGlobalActionsLayout = (MultiListLayout) findViewById(com.android.systemui.R.id.global_actions_view); mGlobalActionsLayout.setOutsideTouchListener(view -> dismiss()); mGlobalActionsLayout.setHasSeparatedView(mShouldDisplaySeparatedButton); mGlobalActionsLayout.setSeparated(mUseSeparatedList); mGlobalActionsLayout.setListViewAccessibilityDelegate(new View.AccessibilityDelegate() { @Override public boolean dispatchPopulateAccessibilityEvent( Loading @@ -1584,6 +1581,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, } }); mGlobalActionsLayout.setRotationListener(this::onRotate); mGlobalActionsLayout.setAdapter(mAdapter); } private boolean isPanelEnabled(Context context) { Loading @@ -1601,55 +1599,11 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, return com.android.systemui.R.layout.global_actions_wrapped; } private void updateList() { mGlobalActionsLayout.removeAllItems(); ArrayList<Action> separatedActions = mAdapter.getSeparatedActions(mShouldDisplaySeparatedButton); ArrayList<Action> listActions = mAdapter.getListActions(mShouldDisplaySeparatedButton); mGlobalActionsLayout.setExpectedListItemCount(listActions.size()); mGlobalActionsLayout.setExpectedSeparatedItemCount(separatedActions.size()); int rotation = RotationUtils.getRotation(mContext); boolean reverse = false; // should we add items to parents in the reverse order? if (isGridEnabled(mContext)) { if (rotation == RotationUtils.ROTATION_NONE || rotation == RotationUtils.ROTATION_SEASCAPE) { reverse = !reverse; // if we're in portrait or seascape, reverse items } if (TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) == View.LAYOUT_DIRECTION_RTL) { reverse = !reverse; // if we're in an RTL language, reverse items (again) } } for (int i = 0; i < mAdapter.getCount(); i++) { Action action = mAdapter.getItem(i); int separatedIndex = separatedActions.indexOf(action); ViewGroup parent; if (separatedIndex != -1) { parent = mGlobalActionsLayout.getParentView(true, separatedIndex, rotation); } else { int listIndex = listActions.indexOf(action); parent = mGlobalActionsLayout.getParentView(false, listIndex, rotation); } View v = mAdapter.getView(i, null, parent); final int pos = i; v.setOnClickListener(view -> mClickListener.onClick(this, pos)); v.setOnLongClickListener(view -> mLongClickListener.onItemLongClick(null, v, pos, 0)); if (reverse) { parent.addView(v, 0); // reverse order of items } else { parent.addView(v); } } } @Override protected void onStart() { super.setCanceledOnTouchOutside(true); super.onStart(); updateList(); mGlobalActionsLayout.updateList(); if (mBackgroundDrawable instanceof GradientDrawable) { Point displaySize = new Point(); Loading Loading @@ -1767,7 +1721,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, public void onRotate(int from, int to) { if (mShowing && isGridEnabled(mContext)) { initializeLayout(); updateList(); mGlobalActionsLayout.updateList(); } } } Loading packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java +51 −3 File changed.Preview size limit exceeded, changes collapsed. Show changes packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java +1 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.systemui.globalactions; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; Loading @@ -39,6 +38,7 @@ import android.widget.LinearLayout; */ public class ListGridLayout extends LinearLayout { private static final String TAG = "ListGridLayout"; private int mExpectedCount; private int mRows; private int mColumns; Loading Loading @@ -103,12 +103,10 @@ public class ListGridLayout extends LinearLayout { setSublistVisibility(i, false); } } } private void setSublistVisibility(int index, boolean visible) { View subList = getChildAt(index); Log.d("ListGrid", "index: " + index + ", visibility: " + visible); if (subList != null) { subList.setVisibility(visible ? View.VISIBLE : View.GONE); } Loading Loading
packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java +34 −15 Original line number Diff line number Diff line Loading @@ -32,10 +32,13 @@ import android.view.ViewOutlineProvider; import android.view.ViewTreeObserver; import android.widget.LinearLayout; import com.android.systemui.globalactions.GlobalActionsDialog; import com.android.systemui.tuner.TunerService; import com.android.systemui.tuner.TunerService.Tunable; import com.android.systemui.util.leak.RotationUtils; import java.util.ArrayList; /** * Layout for placing two containers at a specific physical position on the device, relative to the * device's hardware, regardless of screen rotation. Loading Loading @@ -89,15 +92,6 @@ public class HardwareUiLayout extends MultiListLayout implements Tunable { } } @Override public ViewGroup getParentView(boolean separated, int index, int rotation) { if (separated) { return getSeparatedView(); } else { return getListView(); } } @Override protected void onAttachedToWindow() { super.onAttachedToWindow(); Loading Loading @@ -221,7 +215,7 @@ public class HardwareUiLayout extends MultiListLayout implements Tunable { } else { rotateLeft(); } if (mHasSeparatedView) { if (mSeparated) { 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. Loading Loading @@ -261,6 +255,31 @@ public class HardwareUiLayout extends MultiListLayout implements Tunable { } } @Override public void onUpdateList() { removeAllItems(); ArrayList<GlobalActionsDialog.Action> separatedActions = mAdapter.getSeparatedItems(mSeparated); ArrayList<GlobalActionsDialog.Action> listActions = mAdapter.getListItems(mSeparated); for (int i = 0; i < mAdapter.getCount(); i++) { Object action = mAdapter.getItem(i); int separatedIndex = separatedActions.indexOf(action); ViewGroup parent; if (separatedIndex != -1) { parent = getSeparatedView(); } else { int listIndex = listActions.indexOf(action); parent = getListView(); } View v = mAdapter.getView(i, null, parent); final int pos = i; v.setOnClickListener(view -> mAdapter.onClickItem(pos)); v.setOnLongClickListener(view -> mAdapter.onLongClickItem(pos)); parent.addView(v); } } private void rotateRight() { rotateRight(this); rotateRight(mList); Loading Loading @@ -442,8 +461,8 @@ 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(mHasSeparatedView); mSeparatedViewBackground.setRotatedBackground(mHasSeparatedView); mListBackground.setRotatedBackground(mSeparated); mSeparatedViewBackground.setRotatedBackground(mSeparated); if (mDivision != null && mDivision.getVisibility() == VISIBLE) { int index = mRotatedBackground ? 0 : 1; mDivision.getLocationOnScreen(mTmp2); Loading Loading @@ -494,21 +513,21 @@ public class HardwareUiLayout extends MultiListLayout implements Tunable { case RotationUtils.ROTATION_LANDSCAPE: defaultTopPadding = getPaddingLeft(); viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth(); separatedViewTopMargin = mHasSeparatedView ? params.leftMargin : 0; separatedViewTopMargin = mSeparated ? params.leftMargin : 0; screenHeight = getMeasuredWidth(); targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.TOP; break; case RotationUtils.ROTATION_SEASCAPE: defaultTopPadding = getPaddingRight(); viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth(); separatedViewTopMargin = mHasSeparatedView ? params.leftMargin : 0; separatedViewTopMargin = mSeparated ? params.leftMargin : 0; screenHeight = getMeasuredWidth(); targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM; break; default: // Portrait defaultTopPadding = getPaddingTop(); viewsTotalHeight = mList.getMeasuredHeight() + mSeparatedView.getMeasuredHeight(); separatedViewTopMargin = mHasSeparatedView ? params.topMargin : 0; separatedViewTopMargin = mSeparated ? params.topMargin : 0; screenHeight = getMeasuredHeight(); targetGravity = Gravity.CENTER_VERTICAL|Gravity.RIGHT; break; Loading
packages/SystemUI/src/com/android/systemui/MultiListLayout.java +57 −37 Original line number Diff line number Diff line Loading @@ -21,19 +21,20 @@ import android.content.res.Configuration; import android.util.AttributeSet; import android.view.View; import android.view.ViewGroup; import android.widget.BaseAdapter; import android.widget.LinearLayout; import com.android.systemui.util.leak.RotationUtils; import java.util.ArrayList; /** * Layout class representing the Global Actions menu which appears when the power button is held. */ public abstract class MultiListLayout extends LinearLayout { protected boolean mHasOutsideTouch; protected boolean mHasSeparatedView; protected int mExpectedSeparatedItemCount; protected int mExpectedListItemCount; protected boolean mSeparated; protected MultiListAdapter mAdapter; protected int mRotation; protected RotationListener mRotationListener; Loading @@ -52,18 +53,6 @@ public abstract class MultiListLayout extends LinearLayout { */ public abstract void removeAllItems(); /** * Get the parent view which will be used to contain the item at the specified index. * @param separated Whether or not this index refers to a position in the separated or list * container. * @param index The index of the item within the container. * @param rotation Specifies the rotation of the device, which is used in some cases to * determine child ordering. * @return The parent ViewGroup which will be used to contain the specified item * after it has been added to the layout. */ public abstract ViewGroup getParentView(boolean separated, int index, int rotation); /** * Sets the divided view, which may have a differently-colored background. */ Loading @@ -81,32 +70,19 @@ public abstract class MultiListLayout extends LinearLayout { } /** * Sets the number of items expected to be rendered in the separated container. This allows the * layout to correctly determine which parent containers will be used for items before they have * beenadded to the layout. * @param count The number of items expected. */ public void setExpectedSeparatedItemCount(int count) { mExpectedSeparatedItemCount = count; } /** * Sets the number of items expected to be rendered in the list container. This allows the * layout to correctly determine which parent containers will be used for items before they have * beenadded to the layout. * @param count The number of items expected. * Sets whether the separated view should be shown, and handles updating visibility on * that view. */ public void setExpectedListItemCount(int count) { mExpectedListItemCount = count; public void setSeparated(boolean separated) { mSeparated = separated; setSeparatedViewVisibility(separated); } /** * Sets whether the separated view should be shown, and handles updating visibility on * that view. * Sets the adapter used to inflate items. */ public void setHasSeparatedView(boolean hasSeparatedView) { mHasSeparatedView = hasSeparatedView; setSeparatedViewVisibility(hasSeparatedView); public void setAdapter(MultiListAdapter adapter) { mAdapter = adapter; } /** Loading Loading @@ -136,6 +112,19 @@ public abstract class MultiListLayout extends LinearLayout { } } /** * Update the list of items in both the separated and list views. * For this to work, mAdapter must already have been set. */ public void updateList() { if (mAdapter == null) { throw new IllegalStateException("mAdapter must be set before calling updateList"); } onUpdateList(); } protected abstract void onUpdateList(); public void setRotationListener(RotationListener listener) { mRotationListener = listener; } Loading @@ -157,4 +146,35 @@ public abstract class MultiListLayout extends LinearLayout { public interface RotationListener { void onRotate(int from, int to); } /** * Adapter class for converting items into child views for MultiListLayout and handling * callbacks for input events. */ public abstract static class MultiListAdapter extends BaseAdapter { /** * 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); /** * 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); /** * Callback to run when an individual item is clicked or pressed. * @param position The index of the item which was clicked. */ public abstract void onClickItem(int position); /** * Callback to run when an individual item is long-clicked or long-pressed. * @param position The index of the item which was long-clicked. * @return True if the long-click was handled, false otherwise. */ public abstract boolean onLongClickItem(int position); } }
packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +46 −92 Original line number Diff line number Diff line Loading @@ -65,8 +65,6 @@ import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerGlobal; import android.view.accessibility.AccessibilityEvent; import android.widget.AdapterView.OnItemLongClickListener; import android.widget.BaseAdapter; import android.widget.FrameLayout; import android.widget.ImageView; import android.widget.ImageView.ScaleType; Loading @@ -87,6 +85,7 @@ import com.android.internal.widget.LockPatternUtils; import com.android.systemui.Dependency; import com.android.systemui.Interpolators; import com.android.systemui.MultiListLayout; import com.android.systemui.MultiListLayout.MultiListAdapter; import com.android.systemui.colorextraction.SysuiColorExtractor; import com.android.systemui.plugins.GlobalActions.GlobalActionsManager; import com.android.systemui.plugins.GlobalActionsPanelPlugin; Loading @@ -99,16 +98,14 @@ import com.android.systemui.volume.SystemUIInterpolators.LogAccelerateInterpolat import java.util.ArrayList; import java.util.List; import java.util.Locale; /** * Helper to show the global actions dialog. Each item is an {@link Action} that * may show depending on whether the keyguard is showing, and whether the device * is provisioned. */ class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogInterface.OnClickListener, DialogInterface.OnShowListener, ConfigurationController.ConfigurationListener { public class GlobalActionsDialog implements DialogInterface.OnDismissListener, DialogInterface.OnShowListener, ConfigurationController.ConfigurationListener { static public final String SYSTEM_DIALOG_REASON_KEY = "reason"; static public final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions"; Loading Loading @@ -158,7 +155,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, private boolean mHasVibrator; private boolean mHasLogoutButton; private boolean mHasLockdownButton; private boolean mSeparatedEmergencyButtonEnabled; private boolean mUseSeparatedList; private final boolean mShowSilentToggle; private final EmergencyAffordanceManager mEmergencyAffordanceManager; private final ScreenshotHelper mScreenshotHelper; Loading Loading @@ -336,7 +333,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, ArraySet<String> addedKeys = new ArraySet<String>(); mHasLogoutButton = false; mHasLockdownButton = false; mSeparatedEmergencyButtonEnabled = true; mUseSeparatedList = true; for (int i = 0; i < defaultActions.length; i++) { String actionKey = defaultActions[i]; if (addedKeys.contains(actionKey)) { Loading Loading @@ -384,7 +381,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, mHasLogoutButton = true; } } else if (GLOBAL_ACTION_KEY_EMERGENCY.equals(actionKey)) { if (mSeparatedEmergencyButtonEnabled if (mUseSeparatedList && !mEmergencyAffordanceManager.needsEmergencyAffordance()) { mItems.add(new EmergencyDialerAction()); } Loading @@ -401,14 +398,6 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, mAdapter = new MyAdapter(); OnItemLongClickListener onItemLongClickListener = (parent, view, position, id) -> { final Action action = mAdapter.getItem(position); if (action instanceof LongPressAction) { mDialog.dismiss(); return ((LongPressAction) action).onLongPress(); } return false; }; GlobalActionsPanelPlugin.PanelViewController panelViewController = mPanelExtension.get() != null ? mPanelExtension.get().onPanelShown(() -> { Loading @@ -417,8 +406,8 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, } }) : null; ActionsDialog dialog = new ActionsDialog(mContext, this, mAdapter, onItemLongClickListener, mSeparatedEmergencyButtonEnabled, panelViewController); ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, mUseSeparatedList, panelViewController); dialog.setCanceledOnTouchOutside(false); // Handled by the custom class. dialog.setKeyguardShowing(mKeyguardShowing); Loading Loading @@ -548,7 +537,6 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, } } private class ScreenshotAction extends SinglePressAction implements LongPressAction { public ScreenshotAction() { super(R.drawable.ic_screenshot, R.string.global_action_screenshot); Loading Loading @@ -713,7 +701,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, private Action getEmergencyAction() { Drawable emergencyIcon = mContext.getDrawable(R.drawable.emergency_icon); if(!mSeparatedEmergencyButtonEnabled) { if (!mUseSeparatedList) { // use un-colored legacy treatment emergencyIcon.setTintList(null); } Loading Loading @@ -906,15 +894,6 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, } } /** {@inheritDoc} */ public void onClick(DialogInterface dialog, int which) { Action item = mAdapter.getItem(which); if (!(item instanceof SilentModeTriStateAction)) { dialog.dismiss(); } item.onPress(); } /** {@inheritDoc} */ public void onShow(DialogInterface dialog) { MetricsLogger.visible(mContext, MetricsEvent.POWER_MENU); Loading @@ -927,11 +906,10 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, * the device is provisioned * via {@link com.android.systemui.globalactions.GlobalActionsDialog#mDeviceProvisioned}. */ private class MyAdapter extends BaseAdapter { public class MyAdapter extends MultiListAdapter { @Override public int getCount() { int count = 0; for (int i = 0; i < mItems.size(); i++) { final Action action = mItems.get(i); Loading @@ -951,7 +929,8 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, return getItem(position).isEnabled(); } public ArrayList<Action> getSeparatedActions(boolean shouldUseSeparatedView) { @Override public ArrayList<Action> getSeparatedItems(boolean shouldUseSeparatedView) { ArrayList<Action> separatedActions = new ArrayList<Action>(); if (!shouldUseSeparatedView) { return separatedActions; Loading @@ -965,7 +944,8 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, return separatedActions; } public ArrayList<Action> getListActions(boolean shouldUseSeparatedView) { @Override public ArrayList<Action> getListItems(boolean shouldUseSeparatedView) { if (!shouldUseSeparatedView) { return new ArrayList<Action>(mItems); } Loading @@ -984,6 +964,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, return false; } @Override public Action getItem(int position) { int filteredPos = 0; Loading Loading @@ -1013,6 +994,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { Action action = getItem(position); View view = action.create(mContext, convertView, parent, LayoutInflater.from(mContext)); Loading @@ -1022,6 +1004,25 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, } return view; } @Override public boolean onLongClickItem(int position) { final Action action = mAdapter.getItem(position); if (action instanceof LongPressAction) { mDialog.dismiss(); return ((LongPressAction) action).onLongPress(); } return false; } @Override public void onClickItem(int position) { Action item = mAdapter.getItem(position); if (!(item instanceof SilentModeTriStateAction)) { mDialog.dismiss(); } item.onPress(); } } // note: the scheme below made more sense when we were planning on having Loading @@ -1033,7 +1034,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, /** * What each item in the global actions dialog must be able to support. */ private interface Action { public interface Action { /** * @return Text that will be announced when dialog is created. null * for none. Loading @@ -1052,7 +1053,8 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, /** * @return whether this action should appear in the dialog before the * device is provisioned. * device is provisioned.onlongpress * */ boolean showBeforeProvisioning(); Loading Loading @@ -1488,26 +1490,21 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, private final Context mContext; private final MyAdapter mAdapter; private MultiListLayout mGlobalActionsLayout; private final OnClickListener mClickListener; private final OnItemLongClickListener mLongClickListener; private final Drawable mBackgroundDrawable; private final ColorExtractor mColorExtractor; private final GlobalActionsPanelPlugin.PanelViewController mPanelController; private boolean mKeyguardShowing; private boolean mShouldDisplaySeparatedButton; private boolean mUseSeparatedList; private boolean mShowing; private final float mScrimAlpha; public ActionsDialog(Context context, OnClickListener clickListener, MyAdapter adapter, OnItemLongClickListener longClickListener, boolean shouldDisplaySeparatedButton, ActionsDialog(Context context, MyAdapter adapter, boolean separated, GlobalActionsPanelPlugin.PanelViewController plugin) { super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions); mContext = context; mAdapter = adapter; mClickListener = clickListener; mLongClickListener = longClickListener; mColorExtractor = Dependency.get(SysuiColorExtractor.class); mShouldDisplaySeparatedButton = shouldDisplaySeparatedButton; mUseSeparatedList = separated; // Window initialization Window window = getWindow(); Loading Loading @@ -1573,7 +1570,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, mGlobalActionsLayout = (MultiListLayout) findViewById(com.android.systemui.R.id.global_actions_view); mGlobalActionsLayout.setOutsideTouchListener(view -> dismiss()); mGlobalActionsLayout.setHasSeparatedView(mShouldDisplaySeparatedButton); mGlobalActionsLayout.setSeparated(mUseSeparatedList); mGlobalActionsLayout.setListViewAccessibilityDelegate(new View.AccessibilityDelegate() { @Override public boolean dispatchPopulateAccessibilityEvent( Loading @@ -1584,6 +1581,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, } }); mGlobalActionsLayout.setRotationListener(this::onRotate); mGlobalActionsLayout.setAdapter(mAdapter); } private boolean isPanelEnabled(Context context) { Loading @@ -1601,55 +1599,11 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, return com.android.systemui.R.layout.global_actions_wrapped; } private void updateList() { mGlobalActionsLayout.removeAllItems(); ArrayList<Action> separatedActions = mAdapter.getSeparatedActions(mShouldDisplaySeparatedButton); ArrayList<Action> listActions = mAdapter.getListActions(mShouldDisplaySeparatedButton); mGlobalActionsLayout.setExpectedListItemCount(listActions.size()); mGlobalActionsLayout.setExpectedSeparatedItemCount(separatedActions.size()); int rotation = RotationUtils.getRotation(mContext); boolean reverse = false; // should we add items to parents in the reverse order? if (isGridEnabled(mContext)) { if (rotation == RotationUtils.ROTATION_NONE || rotation == RotationUtils.ROTATION_SEASCAPE) { reverse = !reverse; // if we're in portrait or seascape, reverse items } if (TextUtils.getLayoutDirectionFromLocale(Locale.getDefault()) == View.LAYOUT_DIRECTION_RTL) { reverse = !reverse; // if we're in an RTL language, reverse items (again) } } for (int i = 0; i < mAdapter.getCount(); i++) { Action action = mAdapter.getItem(i); int separatedIndex = separatedActions.indexOf(action); ViewGroup parent; if (separatedIndex != -1) { parent = mGlobalActionsLayout.getParentView(true, separatedIndex, rotation); } else { int listIndex = listActions.indexOf(action); parent = mGlobalActionsLayout.getParentView(false, listIndex, rotation); } View v = mAdapter.getView(i, null, parent); final int pos = i; v.setOnClickListener(view -> mClickListener.onClick(this, pos)); v.setOnLongClickListener(view -> mLongClickListener.onItemLongClick(null, v, pos, 0)); if (reverse) { parent.addView(v, 0); // reverse order of items } else { parent.addView(v); } } } @Override protected void onStart() { super.setCanceledOnTouchOutside(true); super.onStart(); updateList(); mGlobalActionsLayout.updateList(); if (mBackgroundDrawable instanceof GradientDrawable) { Point displaySize = new Point(); Loading Loading @@ -1767,7 +1721,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener, public void onRotate(int from, int to) { if (mShowing && isGridEnabled(mContext)) { initializeLayout(); updateList(); mGlobalActionsLayout.updateList(); } } } Loading
packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsGridLayout.java +51 −3 File changed.Preview size limit exceeded, changes collapsed. Show changes
packages/SystemUI/src/com/android/systemui/globalactions/ListGridLayout.java +1 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package com.android.systemui.globalactions; import android.content.Context; import android.util.AttributeSet; import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; Loading @@ -39,6 +38,7 @@ import android.widget.LinearLayout; */ public class ListGridLayout extends LinearLayout { private static final String TAG = "ListGridLayout"; private int mExpectedCount; private int mRows; private int mColumns; Loading Loading @@ -103,12 +103,10 @@ public class ListGridLayout extends LinearLayout { setSublistVisibility(i, false); } } } private void setSublistVisibility(int index, boolean visible) { View subList = getChildAt(index); Log.d("ListGrid", "index: " + index + ", visibility: " + visible); if (subList != null) { subList.setVisibility(visible ? View.VISIBLE : View.GONE); } Loading