summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Aaron Heuckroth <nesciosquid@google.com> 2019-01-17 15:31:38 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2019-01-17 15:31:38 +0000
commit184af56de9293c87960f88c6c2a92c47b6c4a8d5 (patch)
treec3c11f746be75ba0607b28e31b67332c9ecd96e2
parenta462966c8e56842ec18bc328bf1ded9522921dbe (diff)
parentf708d47e4b405388ebc4bdb0eed15828ede86dac (diff)
Merge "Extract GlobalActionsLayout to an abstract class."
-rw-r--r--packages/SystemUI/res/layout/global_actions_wrapped.xml1
-rw-r--r--packages/SystemUI/res/values/ids.xml3
-rw-r--r--packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java77
-rw-r--r--packages/SystemUI/src/com/android/systemui/MultiListLayout.java124
-rw-r--r--packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java99
5 files changed, 242 insertions, 62 deletions
diff --git a/packages/SystemUI/res/layout/global_actions_wrapped.xml b/packages/SystemUI/res/layout/global_actions_wrapped.xml
index 7f4e0d21078f..f932303473bd 100644
--- a/packages/SystemUI/res/layout/global_actions_wrapped.xml
+++ b/packages/SystemUI/res/layout/global_actions_wrapped.xml
@@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<com.android.systemui.HardwareUiLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@id/global_actions_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="top|right"
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index 633f8686b804..bd34beac7fd6 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -114,5 +114,8 @@
<item type="id" name="aod_mask_transition_progress_tag" />
<item type="id" name="aod_mask_transition_progress_end_tag" />
<item type="id" name="aod_mask_transition_progress_start_tag" />
+
+ <!-- Global Actions Menu -->
+ <item type="id" name="global_actions_view" />
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
index 16e869e9d317..e28aa9d369cb 100644
--- a/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/HardwareUiLayout.java
@@ -37,23 +37,25 @@ import com.android.systemui.tuner.TunerService;
import com.android.systemui.tuner.TunerService.Tunable;
import com.android.systemui.util.leak.RotationUtils;
-public class HardwareUiLayout extends LinearLayout implements Tunable {
+/**
+ * Layout for placing two containers at a specific physical position on the device, relative to the
+ * device's hardware, regardless of screen rotation.
+ */
+public class HardwareUiLayout extends MultiListLayout implements Tunable {
private static final String EDGE_BLEED = "sysui_hwui_edge_bleed";
private static final String ROUNDED_DIVIDER = "sysui_hwui_rounded_divider";
private final int[] mTmp2 = new int[2];
- private View mList;
- private View mSeparatedView;
+ private ViewGroup mList;
+ private ViewGroup mSeparatedView;
private int mOldHeight;
private boolean mAnimating;
private AnimatorSet mAnimation;
private View mDivision;
- private boolean mHasOutsideTouch;
private HardwareBgDrawable mListBackground;
private HardwareBgDrawable mSeparatedViewBackground;
private Animator mAnimator;
private boolean mCollapse;
- private boolean mHasSeparatedButton;
private int mEndPoint;
private boolean mEdgeBleed;
private boolean mRoundedDivider;
@@ -67,6 +69,35 @@ public class HardwareUiLayout extends LinearLayout implements Tunable {
}
@Override
+ protected ViewGroup getSeparatedView() {
+ return findViewById(com.android.systemui.R.id.separated_button);
+ }
+
+ @Override
+ protected ViewGroup getListView() {
+ return findViewById(android.R.id.list);
+ }
+
+ @Override
+ public void removeAllItems() {
+ if (mList != null) {
+ mList.removeAllViews();
+ }
+ if (mSeparatedView != null) {
+ mSeparatedView.removeAllViews();
+ }
+ }
+
+ @Override
+ public ViewGroup getParentView(boolean separated, int index) {
+ if (separated) {
+ return getSeparatedView();
+ } else {
+ return getListView();
+ }
+ }
+
+ @Override
protected void onAttachedToWindow() {
super.onAttachedToWindow();
updateSettings();
@@ -137,9 +168,9 @@ public class HardwareUiLayout extends LinearLayout implements Tunable {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
if (mList == null) {
if (getChildCount() != 0) {
- mList = getChildAt(0);
+ mList = getListView();
mList.setBackground(mListBackground);
- mSeparatedView = getChildAt(1);
+ mSeparatedView = getSeparatedView();
mSeparatedView.setBackground(mSeparatedViewBackground);
updateEdgeMargin(mEdgeBleed ? 0 : getEdgePadding());
mOldHeight = mList.getMeasuredHeight();
@@ -187,7 +218,7 @@ public class HardwareUiLayout extends LinearLayout implements Tunable {
} else {
rotateLeft();
}
- if (mHasSeparatedButton) {
+ if (mHasSeparatedView) {
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.
@@ -408,8 +439,8 @@ public class HardwareUiLayout extends LinearLayout implements Tunable {
if (mList == null) return;
// If got separated button, setRotatedBackground to false,
// all items won't get white background.
- mListBackground.setRotatedBackground(mHasSeparatedButton);
- mSeparatedViewBackground.setRotatedBackground(mHasSeparatedButton);
+ mListBackground.setRotatedBackground(mHasSeparatedView);
+ mSeparatedViewBackground.setRotatedBackground(mHasSeparatedView);
if (mDivision != null && mDivision.getVisibility() == VISIBLE) {
int index = mRotatedBackground ? 0 : 1;
mDivision.getLocationOnScreen(mTmp2);
@@ -460,21 +491,21 @@ public class HardwareUiLayout extends LinearLayout implements Tunable {
case RotationUtils.ROTATION_LANDSCAPE:
defaultTopPadding = getPaddingLeft();
viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth();
- separatedViewTopMargin = mHasSeparatedButton ? params.leftMargin : 0;
+ separatedViewTopMargin = mHasSeparatedView ? params.leftMargin : 0;
screenHeight = getMeasuredWidth();
targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.TOP;
break;
case RotationUtils.ROTATION_SEASCAPE:
defaultTopPadding = getPaddingRight();
viewsTotalHeight = mList.getMeasuredWidth() + mSeparatedView.getMeasuredWidth();
- separatedViewTopMargin = mHasSeparatedButton ? params.leftMargin : 0;
+ separatedViewTopMargin = mHasSeparatedView ? params.leftMargin : 0;
screenHeight = getMeasuredWidth();
targetGravity = Gravity.CENTER_HORIZONTAL|Gravity.BOTTOM;
break;
default: // Portrait
defaultTopPadding = getPaddingTop();
viewsTotalHeight = mList.getMeasuredHeight() + mSeparatedView.getMeasuredHeight();
- separatedViewTopMargin = mHasSeparatedButton ? params.topMargin : 0;
+ separatedViewTopMargin = mHasSeparatedView ? params.topMargin : 0;
screenHeight = getMeasuredHeight();
targetGravity = Gravity.CENTER_VERTICAL|Gravity.RIGHT;
break;
@@ -491,30 +522,10 @@ public class HardwareUiLayout extends LinearLayout implements Tunable {
return super.getOutlineProvider();
}
- public void setOutsideTouchListener(OnClickListener onClickListener) {
- mHasOutsideTouch = true;
- requestLayout();
- setOnClickListener(onClickListener);
- setClickable(true);
- setFocusable(true);
- }
-
public void setCollapse() {
mCollapse = true;
}
- public void setHasSeparatedButton(boolean hasSeparatedButton) {
- mHasSeparatedButton = hasSeparatedButton;
- }
-
- public static HardwareUiLayout get(View v) {
- if (v instanceof HardwareUiLayout) return (HardwareUiLayout) v;
- if (v.getParent() instanceof View) {
- return get((View) v.getParent());
- }
- return null;
- }
-
private final ViewTreeObserver.OnComputeInternalInsetsListener mInsetsListener = inoutInfo -> {
if (mHasOutsideTouch || (mList == null)) {
inoutInfo.setTouchableInsets(
diff --git a/packages/SystemUI/src/com/android/systemui/MultiListLayout.java b/packages/SystemUI/src/com/android/systemui/MultiListLayout.java
new file mode 100644
index 000000000000..0c7a9a9fffd2
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/MultiListLayout.java
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui;
+
+import android.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+
+/**
+ * Layout class representing the Global Actions menu which appears when the power button is held.
+ */
+public abstract class MultiListLayout extends LinearLayout {
+ boolean mHasOutsideTouch;
+ boolean mHasSeparatedView;
+
+ int mExpectedSeparatedItemCount;
+ int mExpectedListItemCount;
+
+ public MultiListLayout(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ protected abstract ViewGroup getSeparatedView();
+
+ protected abstract ViewGroup getListView();
+
+ /**
+ * Removes all child items from the separated and list views, if they exist.
+ */
+ 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.
+ * @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);
+
+ /**
+ * Sets the divided view, which may have a differently-colored background.
+ */
+ public abstract void setDivisionView(View v);
+
+ /**
+ * Set the view accessibility delegate for the list view container.
+ */
+ public void setListViewAccessibilityDelegate(View.AccessibilityDelegate delegate) {
+ getListView().setAccessibilityDelegate(delegate);
+ }
+
+ protected void setSeparatedViewVisibility(boolean visible) {
+ getSeparatedView().setVisibility(visible ? View.VISIBLE : View.GONE);
+ }
+
+ /**
+ * 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.
+ */
+ public void setExpectedListItemCount(int count) {
+ mExpectedListItemCount = count;
+ }
+
+ /**
+ * Sets whether the separated view should be shown, and handles updating visibility on
+ * that view.
+ */
+ public void setHasSeparatedView(boolean hasSeparatedView) {
+ mHasSeparatedView = hasSeparatedView;
+ setSeparatedViewVisibility(hasSeparatedView);
+ }
+
+ /**
+ * Sets this layout to respond to an outside touch listener.
+ */
+ public void setOutsideTouchListener(OnClickListener onClickListener) {
+ mHasOutsideTouch = true;
+ requestLayout();
+ setOnClickListener(onClickListener);
+ setClickable(true);
+ setFocusable(true);
+ }
+
+ /**
+ * Retrieve the MultiListLayout associated with the given view.
+ */
+ public static MultiListLayout get(View v) {
+ if (v instanceof MultiListLayout) return (MultiListLayout) v;
+ if (v.getParent() instanceof View) {
+ return get((View) v.getParent());
+ }
+ return null;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
index 268245bd4acd..7b18fad0e105 100644
--- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java
@@ -67,10 +67,8 @@ 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;
-import android.widget.LinearLayout;
import android.widget.TextView;
import com.android.internal.R;
@@ -86,8 +84,8 @@ import com.android.internal.util.ScreenRecordHelper;
import com.android.internal.util.ScreenshotHelper;
import com.android.internal.widget.LockPatternUtils;
import com.android.systemui.Dependency;
-import com.android.systemui.HardwareUiLayout;
import com.android.systemui.Interpolators;
+import com.android.systemui.MultiListLayout;
import com.android.systemui.colorextraction.SysuiColorExtractor;
import com.android.systemui.plugins.GlobalActions.GlobalActionsManager;
import com.android.systemui.statusbar.phone.ScrimController;
@@ -490,6 +488,11 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
public boolean showBeforeProvisioning() {
return true;
}
+
+ @Override
+ public boolean shouldBeSeparated() {
+ return true;
+ }
}
private final class RestartAction extends SinglePressAction implements LongPressAction {
@@ -926,6 +929,34 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
return getItem(position).isEnabled();
}
+ public ArrayList<Action> getSeparatedActions(boolean shouldUseSeparatedView) {
+ ArrayList<Action> separatedActions = new ArrayList<Action>();
+ if (!shouldUseSeparatedView) {
+ return separatedActions;
+ }
+ for (int i = 0; i < mItems.size(); i++) {
+ final Action action = mItems.get(i);
+ if (action.shouldBeSeparated()) {
+ separatedActions.add(action);
+ }
+ }
+ return separatedActions;
+ }
+
+ public ArrayList<Action> getListActions(boolean shouldUseSeparatedView) {
+ if (!shouldUseSeparatedView) {
+ return new ArrayList<Action>(mItems);
+ }
+ ArrayList<Action> listActions = new ArrayList<Action>();
+ for (int i = 0; i < mItems.size(); i++) {
+ final Action action = mItems.get(i);
+ if (!action.shouldBeSeparated()) {
+ listActions.add(action);
+ }
+ }
+ return listActions;
+ }
+
@Override
public boolean areAllItemsEnabled() {
return false;
@@ -965,7 +996,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
View view = action.create(mContext, convertView, parent, LayoutInflater.from(mContext));
// Everything but screenshot, the last item, gets white background.
if (position == getCount() - 1) {
- HardwareUiLayout.get(parent).setDivisionView(view);
+ MultiListLayout.get(parent).setDivisionView(view);
}
return view;
}
@@ -1004,6 +1035,10 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
boolean showBeforeProvisioning();
boolean isEnabled();
+
+ default boolean shouldBeSeparated() {
+ return false;
+ }
}
/**
@@ -1423,9 +1458,7 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
private final Context mContext;
private final MyAdapter mAdapter;
- private final LinearLayout mListView;
- private final FrameLayout mSeparatedView;
- private final HardwareUiLayout mHardwareLayout;
+ private final MultiListLayout mGlobalActionsLayout;
private final OnClickListener mClickListener;
private final OnItemLongClickListener mLongClickListener;
private final GradientDrawable mGradientDrawable;
@@ -1466,16 +1499,11 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
window.setType(WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY);
setContentView(com.android.systemui.R.layout.global_actions_wrapped);
- mListView = findViewById(android.R.id.list);
- mSeparatedView = findViewById(com.android.systemui.R.id.separated_button);
- if (!mShouldDisplaySeparatedButton) {
- mSeparatedView.setVisibility(View.GONE);
- }
- mHardwareLayout = HardwareUiLayout.get(mListView);
- mHardwareLayout.setOutsideTouchListener(view -> dismiss());
- mHardwareLayout.setHasSeparatedButton(mShouldDisplaySeparatedButton);
- setTitle(R.string.global_actions);
- mListView.setAccessibilityDelegate(new View.AccessibilityDelegate() {
+ mGlobalActionsLayout = (MultiListLayout)
+ findViewById(com.android.systemui.R.id.global_actions_view);
+ mGlobalActionsLayout.setOutsideTouchListener(view -> dismiss());
+ mGlobalActionsLayout.setHasSeparatedView(mShouldDisplaySeparatedButton);
+ mGlobalActionsLayout.setListViewAccessibilityDelegate(new View.AccessibilityDelegate() {
@Override
public boolean dispatchPopulateAccessibilityEvent(
View host, AccessibilityEvent event) {
@@ -1484,20 +1512,33 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
return true;
}
});
+ setTitle(R.string.global_actions);
}
private void updateList() {
- mListView.removeAllViews();
- mSeparatedView.removeAllViews();
+ mGlobalActionsLayout.removeAllItems();
+ ArrayList<Action> separatedActions =
+ mAdapter.getSeparatedActions(mShouldDisplaySeparatedButton);
+ ArrayList<Action> listActions = mAdapter.getListActions(mShouldDisplaySeparatedButton);
+ mGlobalActionsLayout.setExpectedListItemCount(listActions.size());
+ mGlobalActionsLayout.setExpectedSeparatedItemCount(separatedActions.size());
+
for (int i = 0; i < mAdapter.getCount(); i++) {
- ViewGroup parentView = mShouldDisplaySeparatedButton && i == mAdapter.getCount() - 1
- ? mSeparatedView : mListView;
- View v = mAdapter.getView(i, null, parentView);
+ Action action = mAdapter.getItem(i);
+ int separatedIndex = separatedActions.indexOf(action);
+ ViewGroup parent;
+ if (separatedIndex != -1) {
+ parent = mGlobalActionsLayout.getParentView(true, separatedIndex);
+ } else {
+ int listIndex = listActions.indexOf(action);
+ parent = mGlobalActionsLayout.getParentView(false, listIndex);
+ }
+ 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));
- parentView.addView(v);
+ parent.addView(v);
}
}
@@ -1543,9 +1584,9 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
super.show();
mShowing = true;
mGradientDrawable.setAlpha(0);
- mHardwareLayout.setTranslationX(getAnimTranslation());
- mHardwareLayout.setAlpha(0);
- mHardwareLayout.animate()
+ mGlobalActionsLayout.setTranslationX(getAnimTranslation());
+ mGlobalActionsLayout.setAlpha(0);
+ mGlobalActionsLayout.animate()
.alpha(1)
.translationX(0)
.setDuration(300)
@@ -1564,9 +1605,9 @@ class GlobalActionsDialog implements DialogInterface.OnDismissListener,
return;
}
mShowing = false;
- mHardwareLayout.setTranslationX(0);
- mHardwareLayout.setAlpha(1);
- mHardwareLayout.animate()
+ mGlobalActionsLayout.setTranslationX(0);
+ mGlobalActionsLayout.setAlpha(1);
+ mGlobalActionsLayout.animate()
.alpha(0)
.translationX(getAnimTranslation())
.setDuration(300)