Implement correct dimens for new footer

Bug: 215686414
Test: manual in different devices and configs
Test: atest SystemUITests
Change-Id: If9cc89dff3225e57d92a930aab0cad0f3985c962
This commit is contained in:
Fabian Kozynski
2022-02-03 11:10:45 -05:00
parent 24c3cf7519
commit 7394063883
14 changed files with 109 additions and 48 deletions

View File

@@ -20,7 +20,11 @@
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:layout_width="match_parent"
android:layout_height="@dimen/qs_footer_height"
android:layout_height="@dimen/new_footer_height"
android:elevation="@dimen/qs_panel_elevation"
android:paddingTop="8dp"
android:paddingBottom="4dp"
android:background="@drawable/qs_footer_actions_background"
android:gravity="center_vertical"
android:layout_gravity="bottom"
>
@@ -31,23 +35,24 @@
android:layout_weight="1"
/>
<!-- Negative margin equal to -->
<LinearLayout
android:layout_height="match_parent"
android:layout_width="wrap_content"
android:layout_marginEnd="@dimen/new_qs_footer_action_inset_negative"
>
<com.android.systemui.statusbar.phone.MultiUserSwitch
android:id="@+id/multi_user_switch"
android:layout_width="@dimen/qs_footer_action_button_size"
android:layout_height="@dimen/qs_footer_action_button_size"
android:layout_marginEnd="@dimen/qs_tile_margin_horizontal"
android:background="@drawable/qs_footer_action_circle"
android:focusable="true">
<ImageView
android:id="@+id/multi_user_avatar"
android:layout_width="@dimen/multi_user_avatar_expanded_size"
android:layout_height="@dimen/multi_user_avatar_expanded_size"
android:layout_width="@dimen/qs_footer_icon_size"
android:layout_height="@dimen/qs_footer_icon_size"
android:layout_gravity="center"
android:scaleType="centerInside" />
</com.android.systemui.statusbar.phone.MultiUserSwitch>
@@ -56,19 +61,17 @@
android:id="@+id/settings_button_container"
android:layout_width="@dimen/qs_footer_action_button_size"
android:layout_height="@dimen/qs_footer_action_button_size"
android:layout_marginEnd="@dimen/qs_tile_margin_horizontal"
android:background="@drawable/qs_footer_action_circle"
android:clipChildren="false"
android:clipToPadding="false">
<com.android.systemui.statusbar.phone.SettingsButton
android:id="@+id/settings_button"
android:layout_width="match_parent"
android:layout_height="@dimen/qs_footer_action_button_size"
android:layout_width="@dimen/qs_footer_icon_size"
android:layout_height="@dimen/qs_footer_icon_size"
android:layout_gravity="center"
android:background="@android:color/transparent"
android:contentDescription="@string/accessibility_quick_settings_settings"
android:padding="@dimen/qs_footer_icon_padding"
android:scaleType="centerInside"
android:src="@drawable/ic_settings"
android:tint="?android:attr/textColorPrimary" />

View File

@@ -15,10 +15,7 @@
~ limitations under the License.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetTop="@dimen/qs_footer_action_inset"
android:insetBottom="@dimen/qs_footer_action_inset"
android:insetLeft="@dimen/qs_footer_action_inset"
android:insetRight="@dimen/qs_footer_action_inset">
android:inset="@dimen/new_qs_footer_action_inset">
<ripple
android:color="?android:attr/colorControlHighlight">
<item android:id="@android:id/mask">

View File

@@ -15,10 +15,7 @@
~ limitations under the License.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android"
android:insetTop="@dimen/qs_footer_action_inset"
android:insetBottom="@dimen/qs_footer_action_inset"
android:insetLeft="@dimen/qs_footer_action_inset"
android:insetRight="@dimen/qs_footer_action_inset">
android:inset="@dimen/new_qs_footer_action_inset">
<ripple
android:color="?android:attr/colorControlHighlight">
<item android:id="@android:id/mask">

View File

@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014 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.
-->
<inset xmlns:android="http://schemas.android.com/apk/res/android">
<shape>
<solid android:color="?attr/underSurfaceColor"/>
<corners android:topLeftRadius="@dimen/qs_corner_radius"
android:topRightRadius="@dimen/qs_corner_radius"/>
</shape>
</inset>

View File

@@ -25,7 +25,7 @@
android:id="@+id/expanded_qs_scroll_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:elevation="4dp"
android:elevation="@dimen/qs_panel_elevation"
android:importantForAccessibility="no"
android:scrollbars="none"
android:clipChildren="false"
@@ -55,7 +55,7 @@
android:id="@+id/container_stub"
android:inflatedId="@+id/qs_footer_actions"
android:layout="@layout/new_footer_actions"
android:layout_height="@dimen/qs_footer_height"
android:layout_height="@dimen/new_footer_height"
android:layout_width="match_parent"
android:layout_gravity="bottom"
/>

View File

@@ -329,6 +329,9 @@
etc. -->
<dimen name="qs_footer_height">48dp</dimen>
<!-- 40dp (circles) + 8dp (circle padding) + 8dp (top) + 4dp (bottom) -->
<dimen name="new_footer_height">60dp</dimen>
<!-- The size of each of the icon buttons in the QS footer -->
<dimen name="qs_footer_action_button_size">48dp</dimen>
@@ -336,6 +339,9 @@
<!-- (48dp - 44dp) / 2 -->
<dimen name="qs_footer_action_inset">2dp</dimen>
<!-- (48dp - 40dp) / 2 -->
<dimen name="new_qs_footer_action_inset">4dp</dimen>
<dimen name="new_qs_footer_action_inset_negative">-4dp</dimen>
<!-- Margins on each side of QS Footer -->
<dimen name="qs_footer_margin">2dp</dimen>
@@ -491,7 +497,8 @@
<dimen name="qs_tile_text_size">14sp</dimen>
<dimen name="qs_panel_padding">16dp</dimen>
<dimen name="qs_dual_tile_padding_horizontal">6dp</dimen>
<dimen name="qs_panel_padding_bottom">@dimen/qs_footer_height</dimen>
<dimen name="qs_panel_elevation">4dp</dimen>
<dimen name="qs_panel_padding_bottom">@dimen/new_footer_height</dimen>
<dimen name="qs_panel_padding_top">48dp</dimen>
<dimen name="qs_detail_header_padding">0dp</dimen>
<dimen name="qs_detail_image_width">56dp</dimen>

View File

@@ -29,7 +29,6 @@ import com.android.internal.logging.MetricsLogger
import com.android.internal.logging.UiEventLogger
import com.android.internal.logging.nano.MetricsProto
import com.android.keyguard.KeyguardUpdateMonitor
import com.android.settingslib.Utils
import com.android.systemui.R
import com.android.systemui.animation.ActivityLaunchAnimator
import com.android.systemui.flags.FeatureFlags
@@ -90,11 +89,6 @@ class FooterActionsController @Inject constructor(
updateVisibility()
}
init {
view.elevation = resources.displayMetrics.density * 4f
view.setBackgroundColor(Utils.getColorAttrDefaultColor(context, R.attr.underSurfaceColor))
}
private val settingsButton: SettingsButton = view.findViewById(R.id.settings_button)
private val settingsButtonContainer: View? = view.findViewById(R.id.settings_button_container)
private val powerMenuLite: View = view.findViewById(R.id.pm_lite)

View File

@@ -211,9 +211,13 @@ public class QSContainerImpl extends FrameLayout implements Dumpable {
// Some views are always full width or have dependent padding
continue;
}
LayoutParams lp = (LayoutParams) view.getLayoutParams();
lp.rightMargin = mSideMargins;
lp.leftMargin = mSideMargins;
if (!(view instanceof FooterActionsView)) {
// Only padding for FooterActionsView, no margin. That way, the background goes
// all the way to the edge.
LayoutParams lp = (LayoutParams) view.getLayoutParams();
lp.rightMargin = mSideMargins;
lp.leftMargin = mSideMargins;
}
if (view == mQSPanelContainer) {
// QS panel lays out some of its content full width
qsPanelController.setContentMargins(mContentPadding, mContentPadding);

View File

@@ -110,6 +110,7 @@ public class QSPanel extends LinearLayout implements Tunable {
private float mSquishinessFraction = 1f;
private final ArrayMap<View, Integer> mChildrenLayoutTop = new ArrayMap<>();
private final Rect mClippingRect = new Rect();
private boolean mUseNewFooter = false;
public QSPanel(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -151,6 +152,10 @@ public class QSPanel extends LinearLayout implements Tunable {
}
}
void setUseNewFooter(boolean useNewFooter) {
mUseNewFooter = useNewFooter;
}
protected void setHorizontalContentContainerClipping() {
mHorizontalContentContainer.setClipChildren(true);
mHorizontalContentContainer.setClipToPadding(false);
@@ -368,11 +373,12 @@ public class QSPanel extends LinearLayout implements Tunable {
protected void updatePadding() {
final Resources res = mContext.getResources();
int padding = res.getDimensionPixelSize(R.dimen.qs_panel_padding_top);
int paddingTop = res.getDimensionPixelSize(R.dimen.qs_panel_padding_top);
// Bottom padding only when there's a new footer with its height.
setPaddingRelative(getPaddingStart(),
padding,
paddingTop,
getPaddingEnd(),
res.getDimensionPixelSize(R.dimen.qs_panel_padding_bottom));
mUseNewFooter ? res.getDimensionPixelSize(R.dimen.qs_panel_padding_bottom) : 0);
}
void addOnConfigurationChangedListener(OnConfigurationChangedListener listener) {

View File

@@ -31,6 +31,8 @@ import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.media.MediaHierarchyManager;
import com.android.systemui.media.MediaHost;
import com.android.systemui.plugins.FalsingManager;
@@ -104,7 +106,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
DumpManager dumpManager, MetricsLogger metricsLogger, UiEventLogger uiEventLogger,
QSLogger qsLogger, BrightnessController.Factory brightnessControllerFactory,
BrightnessSliderController.Factory brightnessSliderFactory,
FalsingManager falsingManager, CommandQueue commandQueue) {
FalsingManager falsingManager, CommandQueue commandQueue, FeatureFlags featureFlags) {
super(view, qstileHost, qsCustomizerController, usingMediaPlayer, mediaHost,
metricsLogger, uiEventLogger, qsLogger, dumpManager);
mQSFgsManagerFooter = qsFgsManagerFooter;
@@ -121,6 +123,7 @@ public class QSPanelController extends QSPanelControllerBase<QSPanel> {
mBrightnessController = brightnessControllerFactory.create(mBrightnessSliderController);
mBrightnessMirrorHandler = new BrightnessMirrorHandler(mBrightnessController);
view.setUseNewFooter(featureFlags.isEnabled(Flags.NEW_FOOTER));
}
@Override

View File

@@ -102,17 +102,21 @@ class NotificationsQSContainerController @Inject constructor(
private fun updateBottomSpacing() {
val (containerPadding, notificationsMargin) = calculateBottomSpacing()
var qsScrollPaddingBottom = 0
if (!(splitShadeEnabled || isQSCustomizing || isQSDetailShowing || isGestureNavigation ||
taskbarVisible)) {
val newFooter = featureFlags.isEnabled(Flags.NEW_FOOTER)
if (!newFooter && !(splitShadeEnabled || isQSCustomizing || isQSDetailShowing ||
isGestureNavigation || taskbarVisible)) {
// no taskbar, portrait, navigation buttons enabled:
// padding is needed so QS can scroll up over bottom insets - to reach the point when
// the whole QS is above bottom insets
qsScrollPaddingBottom = bottomStableInsets
} else if (newFooter && !(isQSCustomizing || isQSDetailShowing)) {
// With the new footer, we also want this padding in the bottom in these cases
qsScrollPaddingBottom = bottomStableInsets
}
mView.setPadding(0, 0, 0, containerPadding)
mView.setNotificationsMarginBottom(notificationsMargin)
if (featureFlags.isEnabled(Flags.NEW_FOOTER)) {
mView.setQSContainerPaddingBottom(notificationsMargin)
if (newFooter) {
mView.setQSContainerPaddingBottom(qsScrollPaddingBottom)
} else {
mView.setQSScrollPaddingBottom(qsScrollPaddingBottom)
}

View File

@@ -36,6 +36,7 @@ import com.android.internal.logging.testing.UiEventLoggerFake;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.classifier.FalsingManagerFake;
import com.android.systemui.dump.DumpManager;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.media.MediaHost;
import com.android.systemui.plugins.qs.QSTileView;
import com.android.systemui.qs.customize.QSCustomizerController;
@@ -106,6 +107,8 @@ public class QSPanelControllerTest extends SysuiTestCase {
Resources mResources;
@Mock
Configuration mConfiguration;
@Mock
FeatureFlags mFeatureFlags;
private QSPanelController mController;
@@ -133,7 +136,7 @@ public class QSPanelControllerTest extends SysuiTestCase {
mTunerService, mQSTileHost, mQSCustomizerController, true, mMediaHost,
mQSTileRevealControllerFactory, mDumpManager, mMetricsLogger, mUiEventLogger,
mQSLogger, mBrightnessControllerFactory, mToggleSliderViewControllerFactory,
mFalsingManager, mCommandQueue
mFalsingManager, mCommandQueue, mFeatureFlags
);
mController.init();

View File

@@ -162,6 +162,20 @@ class QSPanelTest : SysuiTestCase() {
assertThat(mQsPanel.indexOfChild(mQsPanel.mSecurityFooter)).isEqualTo(-1)
}
@Test
fun testBottomPadding() {
mQsPanel.setUseNewFooter(false)
mQsPanel.updatePadding()
assertThat(mQsPanel.paddingBottom).isEqualTo(0)
mQsPanel.setUseNewFooter(true)
mQsPanel.updatePadding()
assertThat(mQsPanel.paddingBottom)
.isEqualTo(mContext.resources.getDimensionPixelSize(R.dimen.new_footer_height))
}
private fun getNewOrientationConfig(@Configuration.Orientation newOrientation: Int) =
context.resources.configuration.apply { orientation = newOrientation }
}

View File

@@ -114,13 +114,15 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
navigationMode = GESTURES_NAVIGATION,
insets = windowInsets().withStableBottom())
then(expectedContainerPadding = 0, // taskbar should disappear when shade is expanded
expectedNotificationsMargin = NOTIFICATIONS_MARGIN)
expectedNotificationsMargin = NOTIFICATIONS_MARGIN,
expectedQsPadding = STABLE_INSET_BOTTOM)
given(taskbarVisible = true,
navigationMode = BUTTONS_NAVIGATION,
insets = windowInsets().withStableBottom())
then(expectedContainerPadding = STABLE_INSET_BOTTOM,
expectedNotificationsMargin = NOTIFICATIONS_MARGIN)
expectedNotificationsMargin = NOTIFICATIONS_MARGIN,
expectedQsPadding = STABLE_INSET_BOTTOM)
}
@Test
@@ -150,13 +152,15 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
given(taskbarVisible = false,
navigationMode = GESTURES_NAVIGATION,
insets = windowInsets().withStableBottom())
then(expectedContainerPadding = 0)
then(expectedContainerPadding = 0,
expectedQsPadding = STABLE_INSET_BOTTOM)
given(taskbarVisible = false,
navigationMode = BUTTONS_NAVIGATION,
insets = windowInsets().withStableBottom())
then(expectedContainerPadding = 0, // qs goes full height as it's not obscuring nav buttons
expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN)
expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN,
expectedQsPadding = STABLE_INSET_BOTTOM)
}
@Test
@@ -190,7 +194,8 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
navigationMode = BUTTONS_NAVIGATION,
insets = windowInsets().withCutout().withStableBottom())
then(expectedContainerPadding = 0,
expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN)
expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN,
expectedQsPadding = STABLE_INSET_BOTTOM)
}
@Test
@@ -217,12 +222,14 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
given(taskbarVisible = true,
navigationMode = GESTURES_NAVIGATION,
insets = windowInsets().withStableBottom())
then(expectedContainerPadding = 0)
then(expectedContainerPadding = 0,
expectedQsPadding = STABLE_INSET_BOTTOM)
given(taskbarVisible = true,
navigationMode = BUTTONS_NAVIGATION,
insets = windowInsets().withStableBottom())
then(expectedContainerPadding = STABLE_INSET_BOTTOM)
then(expectedContainerPadding = STABLE_INSET_BOTTOM,
expectedQsPadding = STABLE_INSET_BOTTOM)
}
@Test
@@ -259,7 +266,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
given(taskbarVisible = false,
navigationMode = GESTURES_NAVIGATION,
insets = windowInsets().withCutout().withStableBottom())
then(expectedContainerPadding = CUTOUT_HEIGHT)
then(expectedContainerPadding = CUTOUT_HEIGHT, expectedQsPadding = STABLE_INSET_BOTTOM)
given(taskbarVisible = false,
navigationMode = BUTTONS_NAVIGATION,
@@ -350,6 +357,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testDetailShowingInSplitShade() {
notificationsQSContainerController.splitShadeEnabled = true
notificationsQSContainerController.setDetailShowing(true)
useNewFooter(false)
given(taskbarVisible = false,
@@ -357,7 +365,6 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
insets = windowInsets().withStableBottom())
then(expectedContainerPadding = 0)
notificationsQSContainerController.setDetailShowing(true)
// should not influence spacing
given(taskbarVisible = false,
navigationMode = BUTTONS_NAVIGATION,
@@ -368,6 +375,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
@Test
fun testDetailShowingInSplitShade_newFooter() {
notificationsQSContainerController.splitShadeEnabled = true
notificationsQSContainerController.setDetailShowing(true)
useNewFooter(true)
given(taskbarVisible = false,
@@ -375,7 +383,6 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
insets = windowInsets().withStableBottom())
then(expectedContainerPadding = 0)
notificationsQSContainerController.setDetailShowing(true)
// should not influence spacing
given(taskbarVisible = false,
navigationMode = BUTTONS_NAVIGATION,
@@ -417,7 +424,7 @@ class NotificationQSContainerControllerTest : SysuiTestCase() {
val newFooter = featureFlags.isEnabled(Flags.NEW_FOOTER)
if (newFooter) {
verify(notificationsQSContainer)
.setQSContainerPaddingBottom(expectedNotificationsMargin)
.setQSContainerPaddingBottom(expectedQsPadding)
} else {
verify(notificationsQSContainer).setQSScrollPaddingBottom(expectedQsPadding)
}