diff options
5 files changed, 406 insertions, 3 deletions
diff --git a/packages/SystemUI/res/layout/global_actions_grid_item_v2.xml b/packages/SystemUI/res/layout/global_actions_grid_item_v2.xml new file mode 100644 index 000000000000..50aa212c94a6 --- /dev/null +++ b/packages/SystemUI/res/layout/global_actions_grid_item_v2.xml @@ -0,0 +1,68 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2008 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. +--> + +<!-- RelativeLayouts have an issue enforcing minimum heights, so just + work around this for now with LinearLayouts. --> +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="center" + android:paddingTop="@dimen/global_actions_grid_item_vertical_margin" + android:paddingBottom="@dimen/global_actions_grid_item_vertical_margin" + android:paddingLeft="@dimen/global_actions_grid_item_side_margin" + android:paddingRight="@dimen/global_actions_grid_item_side_margin" + android:layout_marginRight="3dp" + android:layout_marginLeft="3dp" + android:background="@drawable/rounded_bg_full"> + <LinearLayout + android:layout_width="@dimen/global_actions_grid_item_width" + android:layout_height="@dimen/global_actions_grid_item_height" + android:gravity="top|center_horizontal" + android:orientation="vertical"> + <ImageView + android:id="@*android:id/icon" + android:layout_width="@dimen/global_actions_grid_item_icon_width" + android:layout_height="@dimen/global_actions_grid_item_icon_height" + android:layout_marginTop="@dimen/global_actions_grid_item_icon_top_margin" + android:layout_marginBottom="@dimen/global_actions_grid_item_icon_bottom_margin" + android:layout_marginLeft="@dimen/global_actions_grid_item_icon_side_margin" + android:layout_marginRight="@dimen/global_actions_grid_item_icon_side_margin" + android:scaleType="centerInside" + android:tint="@color/global_actions_text" /> + + <TextView + android:id="@*android:id/message" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:ellipsize="marquee" + android:marqueeRepeatLimit="marquee_forever" + android:singleLine="true" + android:gravity="center" + android:textSize="12dp" + android:textColor="@color/global_actions_text" + android:textAppearance="?android:attr/textAppearanceSmall" /> + + <TextView + android:visibility="gone" + android:id="@*android:id/status" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:textColor="@color/global_actions_text" + android:textAppearance="?android:attr/textAppearanceSmall" /> + </LinearLayout> +</LinearLayout> diff --git a/packages/SystemUI/res/layout/global_actions_grid_v2.xml b/packages/SystemUI/res/layout/global_actions_grid_v2.xml new file mode 100644 index 000000000000..4cfb47e3c642 --- /dev/null +++ b/packages/SystemUI/res/layout/global_actions_grid_v2.xml @@ -0,0 +1,130 @@ +<?xml version="1.0" encoding="utf-8"?> +<ScrollView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent"> + + <androidx.constraintlayout.widget.ConstraintLayout + android:id="@+id/global_actions_grid_root" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:clipChildren="false" + android:clipToPadding="false" + android:layout_marginBottom="@dimen/global_actions_grid_container_negative_shadow_offset"> + + <com.android.systemui.globalactions.GlobalActionsFlatLayout + android:id="@id/global_actions_view" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="horizontal" + android:theme="@style/qs_theme" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toRightOf="parent" + android:gravity="top | center_horizontal" + android:clipChildren="false" + android:clipToPadding="false" + android:paddingBottom="@dimen/global_actions_grid_container_shadow_offset" + android:layout_marginTop="@dimen/global_actions_top_margin" + android:layout_marginBottom="@dimen/global_actions_grid_container_negative_shadow_offset"> + <LinearLayout + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:layoutDirection="ltr" + android:clipChildren="false" + android:clipToPadding="false" + android:layout_marginBottom="@dimen/global_actions_grid_container_bottom_margin"> + <!-- For separated items--> + <LinearLayout + android:id="@+id/separated_button" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_marginLeft="@dimen/global_actions_grid_side_margin" + android:layout_marginRight="@dimen/global_actions_grid_side_margin" + android:paddingLeft="@dimen/global_actions_grid_horizontal_padding" + android:paddingRight="@dimen/global_actions_grid_horizontal_padding" + android:paddingTop="@dimen/global_actions_grid_vertical_padding" + android:paddingBottom="@dimen/global_actions_grid_vertical_padding" + android:orientation="vertical" + android:gravity="center" + android:translationZ="@dimen/global_actions_translate" + /> + <!-- Grid of action items --> + <com.android.systemui.globalactions.ListGridLayout + android:id="@android:id/list" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:orientation="vertical" + android:gravity="right" + android:layout_marginRight="@dimen/global_actions_grid_side_margin" + android:translationZ="@dimen/global_actions_translate" + android:paddingLeft="@dimen/global_actions_grid_horizontal_padding" + android:paddingRight="@dimen/global_actions_grid_horizontal_padding" + android:paddingTop="@dimen/global_actions_grid_vertical_padding" + android:paddingBottom="@dimen/global_actions_grid_vertical_padding" + > + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="gone" + android:layoutDirection="locale" + /> + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="gone" + android:layoutDirection="locale" + /> + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:visibility="gone" + android:layoutDirection="locale" + /> + </com.android.systemui.globalactions.ListGridLayout> + </LinearLayout> + </com.android.systemui.globalactions.GlobalActionsFlatLayout> + + <LinearLayout + android:id="@+id/global_actions_panel" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toRightOf="parent" + app:layout_constraintTop_toBottomOf="@id/global_actions_view"> + + <FrameLayout + android:translationY="@dimen/global_actions_plugin_offset" + android:id="@+id/global_actions_panel_container" + android:layout_width="match_parent" + android:layout_height="wrap_content" /> + </LinearLayout> + + <LinearLayout + android:translationY="@dimen/global_actions_plugin_offset" + android:id="@+id/global_actions_controls" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toRightOf="parent" + app:layout_constraintTop_toBottomOf="@id/global_actions_panel"> + <TextView + android:text="Home" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:singleLine="true" + android:gravity="center" + android:textSize="25dp" + android:textColor="?android:attr/textColorPrimary" + android:fontFamily="@*android:string/config_headlineFontFamily" /> + <LinearLayout + android:id="@+id/global_actions_controls_list" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:orientation="vertical" /> + </LinearLayout> + </androidx.constraintlayout.widget.ConstraintLayout> +</ScrollView> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index da0323ac7357..3ce39f9c434b 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -950,6 +950,9 @@ <dimen name="cell_overlay_padding">18dp</dimen> <!-- Global actions power menu --> + <dimen name="global_actions_top_margin">12dp</dimen> + <dimen name="global_actions_plugin_offset">-145dp</dimen> + <dimen name="global_actions_panel_width">120dp</dimen> <dimen name="global_actions_padding">12dp</dimen> <dimen name="global_actions_translate">9dp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java index 3ccad64d76dc..e7ce134db834 100644 --- a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsDialog.java @@ -431,7 +431,8 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, mKeyguardManager.isDeviceLocked()) : null; - ActionsDialog dialog = new ActionsDialog(mContext, mAdapter, panelViewController); + ActionsDialog dialog = new ActionsDialog( + mContext, mAdapter, panelViewController, isControlsEnabled(mContext)); dialog.setCanceledOnTouchOutside(false); // Handled by the custom class. dialog.setKeyguardShowing(mKeyguardShowing); @@ -506,7 +507,7 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, @Override public boolean shouldBeSeparated() { - return shouldUseSeparatedView(); + return !isControlsEnabled(mContext); } @Override @@ -1148,6 +1149,9 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } protected int getActionLayoutId(Context context) { + if (isControlsEnabled(context)) { + return com.android.systemui.R.layout.global_actions_grid_item_v2; + } return com.android.systemui.R.layout.global_actions_grid_item; } @@ -1533,15 +1537,18 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private ResetOrientationData mResetOrientationData; private boolean mHadTopUi; private final StatusBarWindowController mStatusBarWindowController; + private boolean mControlsEnabled; ActionsDialog(Context context, MyAdapter adapter, - GlobalActionsPanelPlugin.PanelViewController plugin) { + GlobalActionsPanelPlugin.PanelViewController plugin, + boolean controlsEnabled) { super(context, com.android.systemui.R.style.Theme_SystemUI_Dialog_GlobalActions); mContext = context; mAdapter = adapter; mColorExtractor = Dependency.get(SysuiColorExtractor.class); mStatusBarService = Dependency.get(IStatusBarService.class); mStatusBarWindowController = Dependency.get(StatusBarWindowController.class); + mControlsEnabled = controlsEnabled; // Window initialization Window window = getWindow(); @@ -1658,6 +1665,10 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, } private int getGlobalActionsLayoutId(Context context) { + if (mControlsEnabled) { + return com.android.systemui.R.layout.global_actions_grid_v2; + } + int rotation = RotationUtils.getRotation(context); boolean useGridLayout = isForceGridEnabled(context) || (shouldUsePanel() && rotation == RotationUtils.ROTATION_NONE); @@ -1861,4 +1872,9 @@ public class GlobalActionsDialog implements DialogInterface.OnDismissListener, private static boolean shouldUseSeparatedView() { return true; } + + private static boolean isControlsEnabled(Context context) { + return Settings.Secure.getInt( + context.getContentResolver(), "systemui.controls_available", 0) == 1; + } } diff --git a/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java new file mode 100644 index 000000000000..6749f1d663eb --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/globalactions/GlobalActionsFlatLayout.java @@ -0,0 +1,186 @@ +/* + * 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.globalactions; + +import static com.android.systemui.util.leak.RotationUtils.ROTATION_LANDSCAPE; +import static com.android.systemui.util.leak.RotationUtils.ROTATION_NONE; +import static com.android.systemui.util.leak.RotationUtils.ROTATION_SEASCAPE; + +import android.content.Context; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; + +import com.android.internal.annotations.VisibleForTesting; + +/** + * Single row implementation of the button layout created by the global actions dialog. + */ +public class GlobalActionsFlatLayout extends GlobalActionsLayout { + public GlobalActionsFlatLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + mBackgroundsSet = true; + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + // backgrounds set only once, the first time onMeasure is called after inflation + // if (getListView() != null && !mBackgroundsSet) { + // setBackgrounds(); + // mBackgroundsSet = true; + // } + } + + @VisibleForTesting + protected void setupListView() { + ListGridLayout listView = getListView(); + listView.setExpectedCount(Math.min(2, mAdapter.countListItems())); + listView.setReverseSublists(shouldReverseSublists()); + listView.setReverseItems(shouldReverseListItems()); + listView.setSwapRowsAndColumns(shouldSwapRowsAndColumns()); + } + + @Override + public void onUpdateList() { + setupListView(); + super.onUpdateList(); + updateSeparatedItemSize(); + } + + /** + * If the separated view contains only one item, expand the bounds of that item to take up the + * entire view, so that the whole thing is touch-able. + */ + @VisibleForTesting + protected void updateSeparatedItemSize() { + ViewGroup separated = getSeparatedView(); + if (separated.getChildCount() == 0) { + return; + } + View firstChild = separated.getChildAt(0); + ViewGroup.LayoutParams childParams = firstChild.getLayoutParams(); + + if (separated.getChildCount() == 1) { + childParams.width = ViewGroup.LayoutParams.MATCH_PARENT; + childParams.height = ViewGroup.LayoutParams.MATCH_PARENT; + } else { + childParams.width = ViewGroup.LayoutParams.WRAP_CONTENT; + childParams.height = ViewGroup.LayoutParams.WRAP_CONTENT; + } + } + + @Override + protected ListGridLayout getListView() { + return (ListGridLayout) super.getListView(); + } + + @Override + protected void removeAllListViews() { + ListGridLayout list = getListView(); + if (list != null) { + list.removeAllItems(); + } + } + + @Override + protected void addToListView(View v, boolean reverse) { + ListGridLayout list = getListView(); + if (list != null) { + list.addItem(v); + } + } + + @Override + public void removeAllItems() { + ViewGroup separatedList = getSeparatedView(); + ListGridLayout list = getListView(); + if (separatedList != null) { + separatedList.removeAllViews(); + } + if (list != null) { + list.removeAllItems(); + } + } + + /** + * Determines whether the ListGridLayout should fill sublists in the reverse order. + * Used to account for sublist ordering changing between landscape and seascape views. + */ + @VisibleForTesting + protected boolean shouldReverseSublists() { + if (getCurrentRotation() == ROTATION_SEASCAPE) { + return true; + } + return false; + } + + /** + * Determines whether the ListGridLayout should fill rows first instead of columns. + * Used to account for vertical/horizontal changes due to landscape or seascape rotations. + */ + @VisibleForTesting + protected boolean shouldSwapRowsAndColumns() { + if (getCurrentRotation() == ROTATION_NONE) { + return false; + } + return true; + } + + @Override + protected boolean shouldReverseListItems() { + int rotation = getCurrentRotation(); + boolean reverse = false; // should we add items to parents in the reverse order? + if (rotation == ROTATION_NONE + || rotation == ROTATION_SEASCAPE) { + reverse = !reverse; // if we're in portrait or seascape, reverse items + } + if (getCurrentLayoutDirection() == View.LAYOUT_DIRECTION_RTL) { + reverse = !reverse; // if we're in an RTL language, reverse items (again) + } + return reverse; + } + + @VisibleForTesting + protected float getAnimationDistance() { + int rows = getListView().getRowCount(); + float gridItemSize = getContext().getResources().getDimension( + com.android.systemui.R.dimen.global_actions_grid_item_height); + return rows * gridItemSize / 2; + } + + @Override + public float getAnimationOffsetX() { + switch (getCurrentRotation()) { + case ROTATION_LANDSCAPE: + return getAnimationDistance(); + case ROTATION_SEASCAPE: + return -getAnimationDistance(); + default: // Portrait + return 0; + } + } + + @Override + public float getAnimationOffsetY() { + if (getCurrentRotation() == ROTATION_NONE) { + return getAnimationDistance(); + } + return 0; + } +} |