Merge changes from topic "216302612"
* changes:
Change footer action buttons
Pin footer actions to bottom of QSContainerImpl
Remove QQS Footer Actions
diff --git a/packages/SystemUI/res-keyguard/layout/footer_actions.xml b/packages/SystemUI/res-keyguard/layout/footer_actions.xml
index ecb3cb3..339cab4 100644
--- a/packages/SystemUI/res-keyguard/layout/footer_actions.xml
+++ b/packages/SystemUI/res-keyguard/layout/footer_actions.xml
@@ -19,8 +19,10 @@
<com.android.systemui.qs.FooterActionsView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="48dp"
- android:gravity="center_vertical">
+ android:layout_height="@dimen/qs_footer_height"
+ android:gravity="center_vertical"
+ android:layout_gravity="bottom"
+>
<com.android.systemui.statusbar.phone.MultiUserSwitch
android:id="@+id/multi_user_switch"
diff --git a/packages/SystemUI/res-keyguard/layout/new_footer_actions.xml b/packages/SystemUI/res-keyguard/layout/new_footer_actions.xml
new file mode 100644
index 0000000..95bdd89
--- /dev/null
+++ b/packages/SystemUI/res-keyguard/layout/new_footer_actions.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+** Copyright 2022, 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.
+-->
+
+<!-- Action buttons for footer in QS/QQS, containing settings button, power off button etc -->
+<com.android.systemui.qs.FooterActionsView
+ 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:gravity="center_vertical"
+ android:layout_gravity="bottom"
+>
+
+ <View
+ android:layout_height="1dp"
+ android:layout_width="0dp"
+ android:layout_weight="1"
+ />
+
+ <LinearLayout
+ android:layout_height="match_parent"
+ android:layout_width="wrap_content"
+ >
+
+ <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_gravity="center"
+ android:scaleType="centerInside" />
+ </com.android.systemui.statusbar.phone.MultiUserSwitch>
+
+ <com.android.systemui.statusbar.AlphaOptimizedFrameLayout
+ 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_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" />
+
+ <com.android.systemui.statusbar.AlphaOptimizedImageView
+ android:id="@+id/tuner_icon"
+ android:layout_width="8dp"
+ android:layout_height="8dp"
+ android:layout_gravity="center_horizontal|bottom"
+ android:layout_marginBottom="@dimen/qs_footer_icon_padding"
+ android:src="@drawable/tuner"
+ android:tint="?android:attr/textColorTertiary"
+ android:visibility="invisible" />
+
+ </com.android.systemui.statusbar.AlphaOptimizedFrameLayout>
+
+ <com.android.systemui.statusbar.AlphaOptimizedImageView
+ android:id="@+id/pm_lite"
+ android:layout_width="@dimen/qs_footer_action_button_size"
+ android:layout_height="@dimen/qs_footer_action_button_size"
+ android:background="@drawable/qs_footer_action_circle_color"
+ android:clickable="true"
+ android:clipToPadding="false"
+ android:focusable="true"
+ android:padding="@dimen/qs_footer_icon_padding"
+ android:src="@*android:drawable/ic_lock_power_off"
+ android:contentDescription="@string/accessibility_quick_settings_power_menu"
+ android:tint="?androidprv:attr/textColorOnAccent" />
+
+ </LinearLayout>
+</com.android.systemui.qs.FooterActionsView>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_footer_action_circle.xml b/packages/SystemUI/res/drawable/qs_footer_action_circle.xml
new file mode 100644
index 0000000..f54c30f
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_footer_action_circle.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 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"
+ 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">
+ <ripple
+ android:color="?android:attr/colorControlHighlight">
+ <item android:id="@android:id/mask">
+ <shape android:shape="oval">
+ <solid android:color="@android:color/white"/>
+ </shape>
+ </item>
+ <item>
+ <shape android:shape="oval">
+ <solid android:color="?attr/offStateColor"/>
+ </shape>
+ </item>
+
+ </ripple>
+</inset>
\ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_footer_action_circle_color.xml b/packages/SystemUI/res/drawable/qs_footer_action_circle_color.xml
new file mode 100644
index 0000000..1a323bc
--- /dev/null
+++ b/packages/SystemUI/res/drawable/qs_footer_action_circle_color.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 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"
+ 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">
+ <ripple
+ android:color="?android:attr/colorControlHighlight">
+ <item android:id="@android:id/mask">
+ <shape android:shape="oval">
+ <solid android:color="@android:color/white"/>
+ </shape>
+ </item>
+ <item>
+ <shape android:shape="oval">
+ <solid android:color="?android:attr/colorAccent"/>
+ </shape>
+ </item>
+
+ </ripple>
+</inset>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_footer_impl.xml b/packages/SystemUI/res/layout/qs_footer_impl.xml
index 5cd9e94..b6e3499 100644
--- a/packages/SystemUI/res/layout/qs_footer_impl.xml
+++ b/packages/SystemUI/res/layout/qs_footer_impl.xml
@@ -19,7 +19,7 @@
<com.android.systemui.qs.QSFooterView xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/qs_footer"
android:layout_width="match_parent"
- android:layout_height="@dimen/qs_footer_height"
+ android:layout_height="wrap_content"
android:layout_marginStart="@dimen/qs_footer_margin"
android:layout_marginEnd="@dimen/qs_footer_margin"
android:layout_marginBottom="@dimen/qs_footers_margin_bottom"
@@ -36,7 +36,7 @@
<LinearLayout
android:layout_width="match_parent"
- android:layout_height="48dp"
+ android:layout_height="@dimen/qs_footer_height"
android:layout_gravity="center_vertical">
<TextView
@@ -80,8 +80,13 @@
</LinearLayout>
- <include layout="@layout/footer_actions"
- android:id="@+id/qs_footer_actions"/>
+ <ViewStub
+ android:id="@+id/footer_stub"
+ android:inflatedId="@+id/qs_footer_actions"
+ android:layout="@layout/footer_actions"
+ android:layout_height="@dimen/qs_footer_height"
+ android:layout_width="match_parent"
+ />
</LinearLayout>
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index f5c6036..22abd0c 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -51,6 +51,15 @@
android:id="@+id/qs_detail"
layout="@layout/qs_detail" />
+ <ViewStub
+ 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_width="match_parent"
+ android:layout_gravity="bottom"
+ />
+
<include
android:id="@+id/qs_customize"
layout="@layout/qs_customize_panel"
diff --git a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
index 10a2f4c..2c29f07 100644
--- a/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/quick_status_bar_expanded_header.xml
@@ -57,16 +57,6 @@
android:focusable="true"
android:paddingBottom="24dp"
android:importantForAccessibility="yes">
-
- <include
- layout="@layout/footer_actions"
- android:id="@+id/qqs_footer_actions"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="@dimen/qqs_layout_margin_top"
- android:layout_marginStart="@dimen/qs_footer_margin"
- android:layout_marginEnd="@dimen/qs_footer_margin"
- />
</com.android.systemui.qs.QuickQSPanel>
</RelativeLayout>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 74bb9e4..dba7290 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -327,7 +327,7 @@
<!-- The height of the quick settings footer that holds the user switcher, settings icon,
etc. -->
- <dimen name="qs_footer_height">96dp</dimen>
+ <dimen name="qs_footer_height">48dp</dimen>
<!-- The size of each of the icon buttons in the QS footer -->
<dimen name="qs_footer_action_button_size">48dp</dimen>
@@ -491,7 +491,7 @@
<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">0dp</dimen>
+ <dimen name="qs_panel_padding_bottom">@dimen/qs_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>
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
index c894b70..357a68f 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java
@@ -107,6 +107,8 @@
public static final ResourceBooleanFlag QS_USER_DETAIL_SHORTCUT =
new ResourceBooleanFlag(503, R.bool.flag_lockscreen_qs_user_detail_shortcut);
+ public static final BooleanFlag NEW_FOOTER = new BooleanFlag(504, false);
+
/***************************************/
// 600- status bar
public static final BooleanFlag COMBINED_STATUS_BAR_SIGNAL_ICONS =
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
index 7ac9205..4aedbc9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
@@ -29,14 +29,16 @@
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
+import com.android.systemui.flags.Flags
import com.android.systemui.globalactions.GlobalActionsDialogLite
import com.android.systemui.plugins.ActivityStarter
import com.android.systemui.plugins.FalsingManager
-import com.android.systemui.qs.FooterActionsController.ExpansionState.COLLAPSED
-import com.android.systemui.qs.FooterActionsController.ExpansionState.EXPANDED
import com.android.systemui.qs.dagger.QSFlagsModule.PM_LITE_ENABLED
+import com.android.systemui.qs.dagger.QSScope
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.phone.MultiUserSwitchController
import com.android.systemui.statusbar.phone.SettingsButton
@@ -54,13 +56,14 @@
* Main difference between QS and QQS behaviour is condition when buttons should be visible,
* determined by [buttonsVisibleState]
*/
+@QSScope
class FooterActionsController @Inject constructor(
view: FooterActionsView,
+ multiUserSwitchControllerFactory: MultiUserSwitchController.Factory,
private val activityStarter: ActivityStarter,
private val userManager: UserManager,
private val userTracker: UserTracker,
private val userInfoController: UserInfoController,
- private val multiUserSwitchController: MultiUserSwitchController,
private val deviceProvisionedController: DeviceProvisionedController,
private val falsingManager: FalsingManager,
private val metricsLogger: MetricsLogger,
@@ -68,20 +71,34 @@
private val globalActionsDialog: GlobalActionsDialogLite,
private val uiEventLogger: UiEventLogger,
@Named(PM_LITE_ENABLED) private val showPMLiteButton: Boolean,
- private val buttonsVisibleState: ExpansionState,
private val globalSetting: GlobalSettings,
- private val handler: Handler
+ private val handler: Handler,
+ private val featureFlags: FeatureFlags
) : ViewController<FooterActionsView>(view) {
- enum class ExpansionState { COLLAPSED, EXPANDED }
-
+ private var lastExpansion = -1f
private var listening: Boolean = false
- var expanded = false
+ private val alphaAnimator = TouchAnimator.Builder()
+ .addFloat(mView, "alpha", 0f, 1f)
+ .setStartDelay(0.9f)
+ .build()
+
+ var visible = true
+ set(value) {
+ field = value
+ 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)
+ private val multiUserSwitchController = multiUserSwitchControllerFactory.create(view)
private val onUserInfoChangedListener = OnUserInfoChangedListener { _, picture, _ ->
val isGuestUser: Boolean = userManager.isGuestUser(KeyguardUpdateMonitor.getCurrentUser())
@@ -99,9 +116,8 @@
}
private val onClickListener = View.OnClickListener { v ->
- // Don't do anything until views are unhidden. Don't do anything if the tap looks
- // suspicious.
- if (!buttonsVisible() || falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
+ // Don't do anything if the tap looks suspicious.
+ if (!visible || falsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
return@OnClickListener
}
if (v === settingsButton) {
@@ -110,9 +126,7 @@
activityStarter.postQSRunnableDismissingKeyguard {}
return@OnClickListener
}
- metricsLogger.action(
- if (expanded) MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH
- else MetricsProto.MetricsEvent.ACTION_QS_COLLAPSED_SETTINGS_LAUNCH)
+ metricsLogger.action(MetricsProto.MetricsEvent.ACTION_QS_EXPANDED_SETTINGS_LAUNCH)
if (settingsButton.isTunerClick) {
activityStarter.postQSRunnableDismissingKeyguard {
if (isTunerEnabled()) {
@@ -135,24 +149,14 @@
}
}
- private fun buttonsVisible(): Boolean {
- return when (buttonsVisibleState) {
- EXPANDED -> expanded
- COLLAPSED -> !expanded
- }
- }
-
override fun onInit() {
multiUserSwitchController.init()
}
- fun hideFooter() {
- mView.visibility = View.GONE
- }
-
- fun showFooter() {
- mView.visibility = View.VISIBLE
- updateView()
+ private fun updateVisibility() {
+ val previousVisibility = mView.visibility
+ mView.visibility = if (visible) View.VISIBLE else View.INVISIBLE
+ if (previousVisibility != mView.visibility) updateView()
}
private fun startSettingsActivity() {
@@ -204,24 +208,23 @@
}
fun setExpansion(headerExpansionFraction: Float) {
- mView.setExpansion(headerExpansionFraction)
- }
-
- fun updateAnimator(width: Int, numTiles: Int) {
- mView.updateAnimator(width, numTiles)
- }
-
- fun setKeyguardShowing() {
- mView.setKeyguardShowing()
- }
-
- fun refreshVisibility(shouldBeVisible: Boolean) {
- if (shouldBeVisible) {
- showFooter()
+ if (featureFlags.isEnabled(Flags.NEW_FOOTER)) {
+ if (headerExpansionFraction != lastExpansion) {
+ if (headerExpansionFraction >= 1f) {
+ mView.animate().alpha(1f).setDuration(500L).start()
+ } else if (lastExpansion >= 1f && headerExpansionFraction < 1f) {
+ mView.animate().alpha(0f).setDuration(250L).start()
+ }
+ lastExpansion = headerExpansionFraction
+ }
} else {
- hideFooter()
+ alphaAnimator.setPosition(headerExpansionFraction)
}
}
+ fun setKeyguardShowing(showing: Boolean) {
+ setExpansion(lastExpansion)
+ }
+
private fun isTunerEnabled() = tunerService.isTunerEnabled
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsControllerBuilder.kt b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsControllerBuilder.kt
deleted file mode 100644
index 7694be5..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsControllerBuilder.kt
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Copyright (C) 2021 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.qs
-
-import android.os.Handler
-import android.os.UserManager
-import com.android.internal.logging.MetricsLogger
-import com.android.internal.logging.UiEventLogger
-import com.android.systemui.dagger.qualifiers.Main
-import com.android.systemui.globalactions.GlobalActionsDialogLite
-import com.android.systemui.plugins.ActivityStarter
-import com.android.systemui.plugins.FalsingManager
-import com.android.systemui.qs.FooterActionsController.ExpansionState
-import com.android.systemui.qs.dagger.QSFlagsModule
-import com.android.systemui.settings.UserTracker
-import com.android.systemui.statusbar.phone.MultiUserSwitchController
-import com.android.systemui.statusbar.policy.DeviceProvisionedController
-import com.android.systemui.statusbar.policy.UserInfoController
-import com.android.systemui.tuner.TunerService
-import com.android.systemui.util.settings.GlobalSettings
-import javax.inject.Inject
-import javax.inject.Named
-
-class FooterActionsControllerBuilder @Inject constructor(
- private val activityStarter: ActivityStarter,
- private val userManager: UserManager,
- private val userTracker: UserTracker,
- private val userInfoController: UserInfoController,
- private val multiUserSwitchControllerFactory: MultiUserSwitchController.Factory,
- private val deviceProvisionedController: DeviceProvisionedController,
- private val falsingManager: FalsingManager,
- private val metricsLogger: MetricsLogger,
- private val tunerService: TunerService,
- private val globalActionsDialog: GlobalActionsDialogLite,
- private val uiEventLogger: UiEventLogger,
- @Named(QSFlagsModule.PM_LITE_ENABLED) private val showPMLiteButton: Boolean,
- private val globalSettings: GlobalSettings,
- @Main private val handler: Handler
-) {
- private lateinit var view: FooterActionsView
- private lateinit var buttonsVisibleState: ExpansionState
-
- fun withView(view: FooterActionsView): FooterActionsControllerBuilder {
- this.view = view
- return this
- }
-
- fun withButtonsVisibleWhen(state: ExpansionState): FooterActionsControllerBuilder {
- buttonsVisibleState = state
- return this
- }
-
- fun build(): FooterActionsController {
- return FooterActionsController(view, activityStarter, userManager,
- userTracker, userInfoController, multiUserSwitchControllerFactory.create(view),
- deviceProvisionedController, falsingManager, metricsLogger, tunerService,
- globalActionsDialog, uiEventLogger, showPMLiteButton, buttonsVisibleState,
- globalSettings, handler)
- }
-}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt
index e6fa2ae..18e0cfa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt
@@ -44,8 +44,6 @@
private lateinit var multiUserAvatar: ImageView
private lateinit var tunerIcon: View
- private var settingsCogAnimator: TouchAnimator? = null
-
private var qsDisabled = false
private var expansionAmount = 0f
@@ -66,19 +64,6 @@
importantForAccessibility = View.IMPORTANT_FOR_ACCESSIBILITY_YES
}
- fun updateAnimator(width: Int, numTiles: Int) {
- val size = (mContext.resources.getDimensionPixelSize(R.dimen.qs_quick_tile_size) -
- mContext.resources.getDimensionPixelSize(R.dimen.qs_tile_padding))
- val remaining = (width - numTiles * size) / (numTiles - 1)
- val defSpace = mContext.resources.getDimensionPixelOffset(R.dimen.default_gear_space)
- val translation = if (isLayoutRtl) (remaining - defSpace) else -(remaining - defSpace)
- settingsCogAnimator = TouchAnimator.Builder()
- .addFloat(settingsButton, "translationX", translation.toFloat(), 0f)
- .addFloat(settingsButton, "rotation", -120f, 0f)
- .build()
- setExpansion(expansionAmount)
- }
-
override fun onConfigurationChanged(newConfig: Configuration) {
super.onConfigurationChanged(newConfig)
updateResources()
@@ -95,15 +80,6 @@
tunerIcon.translationX = if (isLayoutRtl) (-tunerIconTranslation) else tunerIconTranslation
}
- fun setKeyguardShowing() {
- setExpansion(expansionAmount)
- }
-
- fun setExpansion(headerExpansionFraction: Float) {
- expansionAmount = headerExpansionFraction
- if (settingsCogAnimator != null) settingsCogAnimator!!.setPosition(headerExpansionFraction)
- }
-
fun disable(
state2: Int,
isTunerEnabled: Boolean,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
index ded6ae0..d1b569f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSAnimator.java
@@ -14,9 +14,6 @@
package com.android.systemui.qs;
-import static com.android.systemui.qs.dagger.QSFragmentModule.QQS_FOOTER;
-import static com.android.systemui.qs.dagger.QSFragmentModule.QS_FOOTER;
-
import android.animation.TimeInterpolator;
import android.animation.ValueAnimator;
import android.util.Log;
@@ -49,7 +46,6 @@
import java.util.concurrent.Executor;
import javax.inject.Inject;
-import javax.inject.Named;
/** */
@QSScope
@@ -88,8 +84,6 @@
private final QSFgsManagerFooter mFgsManagerFooter;
private final QSSecurityFooter mSecurityFooter;
private final QS mQs;
- private final View mQSFooterActions;
- private final View mQQSFooterActions;
@Nullable
private PagedTileLayout mPagedLayout;
@@ -154,16 +148,12 @@
QuickQSPanelController quickQSPanelController, QSTileHost qsTileHost,
QSFgsManagerFooter fgsManagerFooter, QSSecurityFooter securityFooter,
@Main Executor executor, TunerService tunerService,
- QSExpansionPathInterpolator qsExpansionPathInterpolator,
- @Named(QS_FOOTER) FooterActionsView qsFooterActionsView,
- @Named(QQS_FOOTER) FooterActionsView qqsFooterActionsView) {
+ QSExpansionPathInterpolator qsExpansionPathInterpolator) {
mQs = qs;
mQuickQsPanel = quickPanel;
mQsPanelController = qsPanelController;
mQuickQSPanelController = quickQSPanelController;
mQuickStatusBarHeader = quickStatusBarHeader;
- mQQSFooterActions = qqsFooterActionsView;
- mQSFooterActions = qsFooterActionsView;
mFgsManagerFooter = fgsManagerFooter;
mSecurityFooter = securityFooter;
mHost = qsTileHost;
@@ -476,12 +466,6 @@
.setListener(this)
.build();
- if (mQQSFooterActions.getVisibility() != View.GONE) {
- // only when qqs footer is present (which means split shade mode) it needs to
- // be animated
- updateQQSFooterAnimation();
- }
-
// Fade in the security footer and the divider as we reach the final position
Builder builder = new Builder().setStartDelay(EXPANDED_TILE_DELAY);
builder.addFloat(mFgsManagerFooter.getView(), "alpha", 0, 1);
@@ -627,14 +611,6 @@
}
}
- private void updateQQSFooterAnimation() {
- int translationY = getRelativeTranslationY(mQSFooterActions, mQQSFooterActions);
- mQQSFooterActionsAnimator = new TouchAnimator.Builder()
- .addFloat(mQQSFooterActions, "translationY", 0, translationY)
- .build();
- mAnimatedQsViews.add(mQSFooterActions);
- }
-
private int getRelativeTranslationY(View view1, View view2) {
int[] qsPosition = new int[2];
int[] qqsPosition = new int[2];
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
index e230e1b..7800027 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainerImpl.java
@@ -19,10 +19,8 @@
import static android.app.StatusBarManager.DISABLE2_QUICK_SETTINGS;
import android.content.Context;
-import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Path;
-import android.graphics.Point;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.View;
@@ -41,7 +39,6 @@
*/
public class QSContainerImpl extends FrameLayout implements Dumpable {
- private final Point mSizePoint = new Point();
private int mFancyClippingTop;
private int mFancyClippingBottom;
private final float[] mFancyClippingRadii = new float[] {0, 0, 0, 0, 0, 0, 0, 0};
@@ -78,12 +75,6 @@
}
@Override
- protected void onConfigurationChanged(Configuration newConfig) {
- super.onConfigurationChanged(newConfig);
- mSizePoint.set(0, 0); // Will be retrieved on next measure pass.
- }
-
- @Override
public boolean performClick() {
// Want to receive clicks so missing QQS tiles doesn't cause collapse, but
// don't want to do anything with them.
@@ -152,10 +143,10 @@
void updateResources(QSPanelController qsPanelController,
QuickStatusBarHeaderController quickStatusBarHeaderController) {
mQSPanelContainer.setPaddingRelative(
- getPaddingStart(),
+ mQSPanelContainer.getPaddingStart(),
Utils.getQsHeaderSystemIconsAreaHeight(mContext),
- getPaddingEnd(),
- getPaddingBottom()
+ mQSPanelContainer.getPaddingEnd(),
+ mQSPanelContainer.getPaddingBottom()
);
int sideMargins = getResources().getDimensionPixelSize(R.dimen.notification_side_paddings);
@@ -241,13 +232,6 @@
}
}
- private int getDisplayHeight() {
- if (mSizePoint.y == 0) {
- getDisplay().getRealSize(mSizePoint);
- }
- return mSizePoint.y;
- }
-
/**
* Clip QS bottom using a concave shape.
*/
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
index 0e0681b..aac5672 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooter.java
@@ -42,11 +42,6 @@
*/
void setExpansion(float expansion);
- /**
- * Sets whether or not this footer should set itself to listen for changes in any callbacks
- * that it has implemented.
- */
- void setListening(boolean listening);
/**
* Sets whether or not the keyguard is currently being shown.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
index 4622660..6c0ca49 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterView.java
@@ -46,7 +46,6 @@
public class QSFooterView extends FrameLayout {
private PageIndicator mPageIndicator;
private TextView mBuildText;
- private View mActionsContainer;
private View mEditButton;
@Nullable
@@ -78,7 +77,6 @@
protected void onFinishInflate() {
super.onFinishInflate();
mPageIndicator = findViewById(R.id.footer_page_indicator);
- mActionsContainer = requireViewById(R.id.qs_footer_actions);
mBuildText = findViewById(R.id.build);
mEditButton = findViewById(android.R.id.edit);
@@ -105,10 +103,6 @@
}
}
- void updateExpansion() {
- setExpansion(mExpansionAmount);
- }
-
@Override
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
@@ -129,7 +123,6 @@
@Nullable
private TouchAnimator createFooterAnimator() {
TouchAnimator.Builder builder = new TouchAnimator.Builder()
- .addFloat(mActionsContainer, "alpha", 0, 1)
.addFloat(mPageIndicator, "alpha", 0, 1)
.addFloat(mBuildText, "alpha", 0, 1)
.addFloat(mEditButton, "alpha", 0, 1)
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
index 5327b7e..bef4f43 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFooterViewController.java
@@ -16,8 +16,6 @@
package com.android.systemui.qs;
-import static com.android.systemui.qs.dagger.QSFragmentModule.QS_FOOTER;
-
import android.content.ClipData;
import android.content.ClipboardManager;
import android.text.TextUtils;
@@ -33,7 +31,6 @@
import com.android.systemui.util.ViewController;
import javax.inject.Inject;
-import javax.inject.Named;
/**
* Controller for {@link QSFooterView}.
@@ -43,8 +40,6 @@
private final UserTracker mUserTracker;
private final QSPanelController mQsPanelController;
- private final QuickQSPanelController mQuickQSPanelController;
- private final FooterActionsController mFooterActionsController;
private final TextView mBuildText;
private final PageIndicator mPageIndicator;
private final View mEditButton;
@@ -56,14 +51,10 @@
UserTracker userTracker,
FalsingManager falsingManager,
ActivityStarter activityStarter,
- QSPanelController qsPanelController,
- QuickQSPanelController quickQSPanelController,
- @Named(QS_FOOTER) FooterActionsController footerActionsController) {
+ QSPanelController qsPanelController) {
super(view);
mUserTracker = userTracker;
mQsPanelController = qsPanelController;
- mQuickQSPanelController = quickQSPanelController;
- mFooterActionsController = footerActionsController;
mFalsingManager = falsingManager;
mActivityStarter = activityStarter;
@@ -73,21 +64,7 @@
}
@Override
- protected void onInit() {
- super.onInit();
- mFooterActionsController.init();
- }
-
- @Override
protected void onViewAttached() {
- mView.addOnLayoutChangeListener(
- (v, left, top, right, bottom, oldLeft, oldTop, oldRight, oldBottom) -> {
- mView.updateExpansion();
- mFooterActionsController.updateAnimator(right - left,
- mQuickQSPanelController.getNumQuickTiles());
- }
- );
-
mBuildText.setOnLongClickListener(view -> {
CharSequence buildText = mBuildText.getText();
if (!TextUtils.isEmpty(buildText)) {
@@ -114,9 +91,7 @@
}
@Override
- protected void onViewDetached() {
- setListening(false);
- }
+ protected void onViewDetached() {}
@Override
public void setVisibility(int visibility) {
@@ -126,25 +101,17 @@
@Override
public void setExpanded(boolean expanded) {
- mFooterActionsController.setExpanded(expanded);
mView.setExpanded(expanded);
}
@Override
public void setExpansion(float expansion) {
mView.setExpansion(expansion);
- mFooterActionsController.setExpansion(expansion);
- }
-
- @Override
- public void setListening(boolean listening) {
- mFooterActionsController.setListening(listening);
}
@Override
public void setKeyguardShowing(boolean keyguardShowing) {
mView.setKeyguardShowing();
- mFooterActionsController.setKeyguardShowing();
}
/** */
@@ -156,6 +123,5 @@
@Override
public void disable(int state1, int state2, boolean animate) {
mView.disable(state2);
- mFooterActionsController.disable(state2);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index 259b786..50952bd 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -118,6 +118,7 @@
private QSPanelController mQSPanelController;
private QuickQSPanelController mQuickQSPanelController;
private QSCustomizerController mQSCustomizerController;
+ private FooterActionsController mQSFooterActionController;
@Nullable
private ScrollListener mScrollListener;
/**
@@ -188,9 +189,11 @@
QSFragmentComponent qsFragmentComponent = mQsComponentFactory.create(this);
mQSPanelController = qsFragmentComponent.getQSPanelController();
mQuickQSPanelController = qsFragmentComponent.getQuickQSPanelController();
+ mQSFooterActionController = qsFragmentComponent.getQSFooterActionController();
mQSPanelController.init();
mQuickQSPanelController.init();
+ mQSFooterActionController.init();
mQSPanelScrollView = view.findViewById(R.id.expanded_qs_scroll_view);
mQSPanelScrollView.addOnLayoutChangeListener(
@@ -380,6 +383,7 @@
mContainer.disable(state1, state2, animate);
mHeader.disable(state1, state2, animate);
mFooter.disable(state1, state2, animate);
+ mQSFooterActionController.disable(state2);
updateQsState();
}
@@ -396,10 +400,10 @@
: View.INVISIBLE);
mHeader.setExpanded((keyguardShowing && !mHeaderAnimating && !mShowCollapsedOnKeyguard)
|| (expanded && !mStackScrollerOverscrolling), mQuickQSPanelController);
- mFooter.setVisibility(!mQsDisabled && (expanded || !keyguardShowing || mHeaderAnimating
- || mShowCollapsedOnKeyguard)
- ? View.VISIBLE
- : View.INVISIBLE);
+ boolean footerVisible = !mQsDisabled && (expanded || !keyguardShowing || mHeaderAnimating
+ || mShowCollapsedOnKeyguard);
+ mFooter.setVisibility(footerVisible ? View.VISIBLE : View.INVISIBLE);
+ mQSFooterActionController.setVisible(footerVisible);
mFooter.setExpanded((keyguardShowing && !mHeaderAnimating && !mShowCollapsedOnKeyguard)
|| (expanded && !mStackScrollerOverscrolling));
mQSPanelController.setVisibility(
@@ -465,6 +469,7 @@
}
mFooter.setKeyguardShowing(keyguardShowing);
+ mQSFooterActionController.setKeyguardShowing(keyguardShowing);
updateQsState();
}
@@ -480,14 +485,13 @@
if (DEBUG) Log.d(TAG, "setListening " + listening);
mListening = listening;
mQSContainerImplController.setListening(listening);
- mFooter.setListening(listening);
+ mQSFooterActionController.setListening(listening);
mQSPanelController.setListening(mListening, mQsExpanded);
}
@Override
public void setHeaderListening(boolean listening) {
mQSContainerImplController.setListening(listening);
- mFooter.setListening(listening);
}
@Override
@@ -561,6 +565,7 @@
}
}
mFooter.setExpansion(onKeyguardAndExpanded ? 1 : expansion);
+ mQSFooterActionController.setExpansion(onKeyguardAndExpanded ? 1 : expansion);
mQSPanelController.setRevealExpansion(expansion);
mQSPanelController.getTileLayout().setExpansion(expansion, proposedTranslation);
mQuickQSPanelController.getTileLayout().setExpansion(expansion, proposedTranslation);
@@ -711,6 +716,7 @@
boolean customizing = isCustomizing();
mQSPanelScrollView.setVisibility(!customizing ? View.VISIBLE : View.INVISIBLE);
mFooter.setVisibility(!customizing ? View.VISIBLE : View.INVISIBLE);
+ mQSFooterActionController.setVisible(!customizing);
mHeader.setVisibility(!customizing ? View.VISIBLE : View.INVISIBLE);
// Let the panel know the position changed and it needs to update where notifications
// and whatnot are.
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
index 92690c7d..2d2fa1f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanelController.java
@@ -17,7 +17,6 @@
package com.android.systemui.qs;
import static com.android.systemui.media.dagger.MediaModule.QUICK_QS_PANEL;
-import static com.android.systemui.qs.dagger.QSFragmentModule.QQS_FOOTER;
import static com.android.systemui.qs.dagger.QSFragmentModule.QS_USING_MEDIA_PLAYER;
import com.android.internal.logging.MetricsLogger;
@@ -54,7 +53,6 @@
// brightness is visible only in split shade
private final QuickQSBrightnessController mBrightnessController;
private final BrightnessMirrorHandler mBrightnessMirrorHandler;
- private final FooterActionsController mFooterActionsController;
@Inject
QuickQSPanelController(QuickQSPanel view, QSTileHost qsTileHost,
@@ -63,14 +61,12 @@
@Named(QUICK_QS_PANEL) MediaHost mediaHost,
MetricsLogger metricsLogger, UiEventLogger uiEventLogger, QSLogger qsLogger,
DumpManager dumpManager,
- QuickQSBrightnessController quickQSBrightnessController,
- @Named(QQS_FOOTER) FooterActionsController footerActionsController
+ QuickQSBrightnessController quickQSBrightnessController
) {
super(view, qsTileHost, qsCustomizerController, usingMediaPlayer, mediaHost, metricsLogger,
uiEventLogger, qsLogger, dumpManager);
mBrightnessController = quickQSBrightnessController;
mBrightnessMirrorHandler = new BrightnessMirrorHandler(mBrightnessController);
- mFooterActionsController = footerActionsController;
}
@Override
@@ -80,8 +76,6 @@
mMediaHost.setShowsOnlyActiveMedia(true);
mMediaHost.init(MediaHierarchyManager.LOCATION_QQS);
mBrightnessController.init(mShouldUseSplitNotificationShade);
- mFooterActionsController.init();
- mFooterActionsController.refreshVisibility(mShouldUseSplitNotificationShade);
}
@Override
@@ -102,7 +96,6 @@
void setListening(boolean listening) {
super.setListening(listening);
mBrightnessController.setListening(listening);
- mFooterActionsController.setListening(listening);
}
public boolean isListening() {
@@ -123,7 +116,6 @@
@Override
protected void onConfigurationChanged() {
mBrightnessController.refreshVisibility(mShouldUseSplitNotificationShade);
- mFooterActionsController.refreshVisibility(mShouldUseSplitNotificationShade);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java
index 63cbc21..594f4f8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentComponent.java
@@ -16,6 +16,7 @@
package com.android.systemui.qs.dagger;
+import com.android.systemui.qs.FooterActionsController;
import com.android.systemui.qs.QSAnimator;
import com.android.systemui.qs.QSContainerImplController;
import com.android.systemui.qs.QSFooter;
@@ -61,4 +62,7 @@
/** Construct a {@link QSSquishinessController}. */
QSSquishinessController getQSSquishinessController();
+
+ /** Construct a {@link FooterActionsController}. */
+ FooterActionsController getQSFooterActionController();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
index 1958caf..776ee10 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSFragmentModule.java
@@ -21,15 +21,15 @@
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
+import android.view.ViewStub;
import com.android.systemui.R;
import com.android.systemui.battery.BatteryMeterView;
import com.android.systemui.dagger.qualifiers.RootView;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.plugins.qs.QS;
import com.android.systemui.privacy.OngoingPrivacyChip;
-import com.android.systemui.qs.FooterActionsController;
-import com.android.systemui.qs.FooterActionsController.ExpansionState;
-import com.android.systemui.qs.FooterActionsControllerBuilder;
import com.android.systemui.qs.FooterActionsView;
import com.android.systemui.qs.QSContainerImpl;
import com.android.systemui.qs.QSFooter;
@@ -55,8 +55,6 @@
public interface QSFragmentModule {
String QS_FGS_MANAGER_FOOTER_VIEW = "qs_fgs_manager_footer";
String QS_SECURITY_FOOTER_VIEW = "qs_security_footer";
- String QQS_FOOTER = "qqs_footer";
- String QS_FOOTER = "qs_footer";
String QS_USING_MEDIA_PLAYER = "qs_using_media_player";
/**
@@ -122,46 +120,26 @@
return view.findViewById(R.id.qs_footer);
}
- /** */
+ /**
+ * Provides a {@link FooterActionsView}.
+ *
+ * This will replace a ViewStub either in {@link QSFooterView} or in {@link QSContainerImpl}.
+ */
@Provides
- @Named(QS_FOOTER)
- static FooterActionsView providesQSFooterActionsView(@RootView View view) {
+ static FooterActionsView providesQSFooterActionsView(@RootView View view,
+ FeatureFlags featureFlags) {
+ ViewStub stub;
+ if (featureFlags.isEnabled(Flags.NEW_FOOTER)) {
+ stub = view.requireViewById(R.id.container_stub);
+ } else {
+ stub = view.requireViewById(R.id.footer_stub);
+ }
+ stub.inflate();
return view.findViewById(R.id.qs_footer_actions);
}
/** */
@Provides
- @Named(QQS_FOOTER)
- static FooterActionsView providesQQSFooterActionsView(@RootView View view) {
- return view.findViewById(R.id.qqs_footer_actions);
- }
-
- /** */
- @Provides
- @Named(QQS_FOOTER)
- static FooterActionsController providesQQSFooterActionsController(
- FooterActionsControllerBuilder footerActionsControllerBuilder,
- @Named(QQS_FOOTER) FooterActionsView qqsFooterActionsView) {
- return footerActionsControllerBuilder
- .withView(qqsFooterActionsView)
- .withButtonsVisibleWhen(ExpansionState.COLLAPSED)
- .build();
- }
-
- /** */
- @Provides
- @Named(QS_FOOTER)
- static FooterActionsController providesQSFooterActionsController(
- FooterActionsControllerBuilder footerActionsControllerBuilder,
- @Named(QS_FOOTER) FooterActionsView qsFooterActionsView) {
- return footerActionsControllerBuilder
- .withView(qsFooterActionsView)
- .withButtonsVisibleWhen(ExpansionState.EXPANDED)
- .build();
- }
-
- /** */
- @Provides
@QSScope
static QSFooter providesQSFooter(QSFooterViewController qsFooterViewController) {
qsFooterViewController.init();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt
index 1a88533..b457ebf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQSContainerController.kt
@@ -1,6 +1,8 @@
package com.android.systemui.statusbar.phone
import android.view.WindowInsets
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
import com.android.systemui.navigationbar.NavigationModeController
import com.android.systemui.plugins.qs.QS
import com.android.systemui.plugins.qs.QSContainerController
@@ -14,7 +16,8 @@
class NotificationsQSContainerController @Inject constructor(
view: NotificationsQuickSettingsContainer,
private val navigationModeController: NavigationModeController,
- private val overviewProxyService: OverviewProxyService
+ private val overviewProxyService: OverviewProxyService,
+ private val featureFlags: FeatureFlags
) : ViewController<NotificationsQuickSettingsContainer>(view), QSContainerController {
var qsExpanded = false
@@ -108,7 +111,11 @@
}
mView.setPadding(0, 0, 0, containerPadding)
mView.setNotificationsMarginBottom(notificationsMargin)
- mView.setQSScrollPaddingBottom(qsScrollPaddingBottom)
+ if (featureFlags.isEnabled(Flags.NEW_FOOTER)) {
+ mView.setQSContainerPaddingBottom(notificationsMargin)
+ } else {
+ mView.setQSScrollPaddingBottom(qsScrollPaddingBottom)
+ }
}
private fun calculateBottomSpacing(): Pair<Int, Int> {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
index cecbcdb..95e3b70 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationsQuickSettingsContainer.java
@@ -52,6 +52,7 @@
private Consumer<QS> mQSFragmentAttachedListener = qs -> {};
private QS mQs;
private View mQSScrollView;
+ private View mQSContainer;
public NotificationsQuickSettingsContainer(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -70,6 +71,7 @@
mQs = (QS) fragment;
mQSFragmentAttachedListener.accept(mQs);
mQSScrollView = mQs.getView().findViewById(R.id.expanded_qs_scroll_view);
+ mQSContainer = mQs.getView().findViewById(R.id.quick_settings_container);
}
@Override
@@ -89,6 +91,16 @@
mQSScrollView.getPaddingLeft(),
mQSScrollView.getPaddingTop(),
mQSScrollView.getPaddingRight(),
+ paddingBottom);
+ }
+ }
+
+ public void setQSContainerPaddingBottom(int paddingBottom) {
+ if (mQSContainer != null) {
+ mQSContainer.setPadding(
+ mQSContainer.getPaddingLeft(),
+ mQSContainer.getPaddingTop(),
+ mQSContainer.getPaddingRight(),
paddingBottom
);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
index 354bb51..f5fa0d0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
@@ -15,9 +15,10 @@
import com.android.systemui.Dependency
import com.android.systemui.R
import com.android.systemui.classifier.FalsingManagerFake
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
import com.android.systemui.globalactions.GlobalActionsDialogLite
import com.android.systemui.plugins.ActivityStarter
-import com.android.systemui.qs.FooterActionsController.ExpansionState
import com.android.systemui.settings.UserTracker
import com.android.systemui.statusbar.phone.MultiUserSwitchController
import com.android.systemui.statusbar.policy.DeviceProvisionedController
@@ -54,12 +55,16 @@
@Mock
private lateinit var userInfoController: UserInfoController
@Mock
+ private lateinit var multiUserSwitchControllerFactory: MultiUserSwitchController.Factory
+ @Mock
private lateinit var multiUserSwitchController: MultiUserSwitchController
@Mock
private lateinit var globalActionsDialog: GlobalActionsDialogLite
@Mock
private lateinit var uiEventLogger: UiEventLogger
@Mock
+ private lateinit var featureFlags: FeatureFlags
+
private lateinit var controller: FooterActionsController
private val metricsLogger: MetricsLogger = FakeMetricsLogger()
@@ -76,15 +81,18 @@
injectLeakCheckedDependencies(*LeakCheckedTest.ALL_SUPPORTED_CLASSES)
val fakeTunerService = Dependency.get(TunerService::class.java) as FakeTunerService
+ whenever(multiUserSwitchControllerFactory.create(any()))
+ .thenReturn(multiUserSwitchController)
+ whenever(featureFlags.isEnabled(Flags.NEW_FOOTER)).thenReturn(false)
+
view = LayoutInflater.from(context)
.inflate(R.layout.footer_actions, null) as FooterActionsView
- controller = FooterActionsController(view, activityStarter,
- userManager, userTracker, userInfoController, multiUserSwitchController,
+ controller = FooterActionsController(view, multiUserSwitchControllerFactory,
+ activityStarter, userManager, userTracker, userInfoController,
deviceProvisionedController, falsingManager, metricsLogger, fakeTunerService,
- globalActionsDialog, uiEventLogger, showPMLiteButton = true,
- buttonsVisibleState = ExpansionState.EXPANDED, fakeSettings,
- Handler(testableLooper.looper))
+ globalActionsDialog, uiEventLogger, showPMLiteButton = true, fakeSettings,
+ Handler(testableLooper.looper), featureFlags)
controller.init()
ViewUtils.attachView(view)
// View looper is the testable looper associated with the test
@@ -98,7 +106,7 @@
@Test
fun testLogPowerMenuClick() {
- controller.expanded = true
+ controller.visible = true
falsingManager.setFalseTap(false)
view.findViewById<View>(R.id.pm_lite).performClick()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java
index f43e68f..26aa37d 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QSFooterViewControllerTest.java
@@ -61,12 +61,8 @@
@Mock
private ClipboardManager mClipboardManager;
@Mock
- private QuickQSPanelController mQuickQSPanelController;
- @Mock
private TextView mBuildText;
@Mock
- private FooterActionsController mFooterActionsController;
- @Mock
private FalsingManager mFalsingManager;
@Mock
private ActivityStarter mActivityStarter;
@@ -93,8 +89,7 @@
when(mView.findViewById(android.R.id.edit)).thenReturn(mEditButton);
mController = new QSFooterViewController(mView, mUserTracker, mFalsingManager,
- mActivityStarter, mQSPanelController, mQuickQSPanelController,
- mFooterActionsController);
+ mActivityStarter, mQSPanelController);
mController.init();
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
index 59948d3..09c6d9e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
@@ -68,8 +68,6 @@
private lateinit var tileView: QSTileView
@Mock
private lateinit var quickQsBrightnessController: QuickQSBrightnessController
- @Mock
- private lateinit var footerActionsController: FooterActionsController
@Captor
private lateinit var captor: ArgumentCaptor<QSPanel.OnConfigurationChangedListener>
@@ -95,8 +93,7 @@
uiEventLogger,
qsLogger,
dumpManager,
- quickQsBrightnessController,
- footerActionsController
+ quickQsBrightnessController
)
controller.init()
@@ -128,14 +125,12 @@
}
@Test
- fun testBrightnessAndFooterVisibilityRefreshedWhenConfigurationChanged() {
+ fun testBrightnessRefreshedWhenConfigurationChanged() {
// times(2) because both controller and base controller are registering their listeners
verify(quickQSPanel, times(2)).addOnConfigurationChangedListener(captor.capture())
captor.allValues.forEach { it.onConfigurationChange(Configuration.EMPTY) }
verify(quickQsBrightnessController).refreshVisibility(anyBoolean())
- // times(2) because footer visibility is also refreshed on controller init
- verify(footerActionsController, times(2)).refreshVisibility(anyBoolean())
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt
index 77e9025..bbb2346 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationQSContainerControllerTest.kt
@@ -6,6 +6,8 @@
import android.view.WindowManagerPolicyConstants
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
import com.android.systemui.navigationbar.NavigationModeController
import com.android.systemui.navigationbar.NavigationModeController.ModeChangedListener
import com.android.systemui.recents.OverviewProxyService
@@ -46,6 +48,8 @@
private lateinit var overviewProxyService: OverviewProxyService
@Mock
private lateinit var notificationsQSContainer: NotificationsQuickSettingsContainer
+ @Mock
+ private lateinit var featureFlags: FeatureFlags
@Captor
lateinit var navigationModeCaptor: ArgumentCaptor<ModeChangedListener>
@Captor
@@ -64,7 +68,8 @@
notificationsQSContainerController = NotificationsQSContainerController(
notificationsQSContainer,
navigationModeController,
- overviewProxyService
+ overviewProxyService,
+ featureFlags
)
whenever(notificationsQSContainer.defaultNotificationsMarginBottom)
.thenReturn(NOTIFICATIONS_MARGIN)
@@ -85,6 +90,26 @@
@Test
fun testTaskbarVisibleInSplitShade() {
notificationsQSContainerController.splitShadeEnabled = true
+ useNewFooter(false)
+
+ given(taskbarVisible = true,
+ navigationMode = GESTURES_NAVIGATION,
+ insets = windowInsets().withStableBottom())
+ then(expectedContainerPadding = 0, // taskbar should disappear when shade is expanded
+ expectedNotificationsMargin = NOTIFICATIONS_MARGIN)
+
+ given(taskbarVisible = true,
+ navigationMode = BUTTONS_NAVIGATION,
+ insets = windowInsets().withStableBottom())
+ then(expectedContainerPadding = STABLE_INSET_BOTTOM,
+ expectedNotificationsMargin = NOTIFICATIONS_MARGIN)
+ }
+
+ @Test
+ fun testTaskbarVisibleInSplitShade_newFooter() {
+ notificationsQSContainerController.splitShadeEnabled = true
+ useNewFooter(true)
+
given(taskbarVisible = true,
navigationMode = GESTURES_NAVIGATION,
insets = windowInsets().withStableBottom())
@@ -102,6 +127,26 @@
fun testTaskbarNotVisibleInSplitShade() {
// when taskbar is not visible, it means we're on the home screen
notificationsQSContainerController.splitShadeEnabled = true
+ useNewFooter(false)
+
+ given(taskbarVisible = false,
+ navigationMode = GESTURES_NAVIGATION,
+ insets = windowInsets().withStableBottom())
+ then(expectedContainerPadding = 0)
+
+ 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)
+ }
+
+ @Test
+ fun testTaskbarNotVisibleInSplitShade_newFooter() {
+ // when taskbar is not visible, it means we're on the home screen
+ notificationsQSContainerController.splitShadeEnabled = true
+ useNewFooter(true)
+
given(taskbarVisible = false,
navigationMode = GESTURES_NAVIGATION,
insets = windowInsets().withStableBottom())
@@ -117,6 +162,25 @@
@Test
fun testTaskbarNotVisibleInSplitShadeWithCutout() {
notificationsQSContainerController.splitShadeEnabled = true
+ useNewFooter(false)
+
+ given(taskbarVisible = false,
+ navigationMode = GESTURES_NAVIGATION,
+ insets = windowInsets().withCutout())
+ then(expectedContainerPadding = CUTOUT_HEIGHT)
+
+ given(taskbarVisible = false,
+ navigationMode = BUTTONS_NAVIGATION,
+ insets = windowInsets().withCutout().withStableBottom())
+ then(expectedContainerPadding = 0,
+ expectedNotificationsMargin = STABLE_INSET_BOTTOM + NOTIFICATIONS_MARGIN)
+ }
+
+ @Test
+ fun testTaskbarNotVisibleInSplitShadeWithCutout_newFooter() {
+ notificationsQSContainerController.splitShadeEnabled = true
+ useNewFooter(true)
+
given(taskbarVisible = false,
navigationMode = GESTURES_NAVIGATION,
insets = windowInsets().withCutout())
@@ -132,6 +196,24 @@
@Test
fun testTaskbarVisibleInSinglePaneShade() {
notificationsQSContainerController.splitShadeEnabled = false
+ useNewFooter(false)
+
+ given(taskbarVisible = true,
+ navigationMode = GESTURES_NAVIGATION,
+ insets = windowInsets().withStableBottom())
+ then(expectedContainerPadding = 0)
+
+ given(taskbarVisible = true,
+ navigationMode = BUTTONS_NAVIGATION,
+ insets = windowInsets().withStableBottom())
+ then(expectedContainerPadding = STABLE_INSET_BOTTOM)
+ }
+
+ @Test
+ fun testTaskbarVisibleInSinglePaneShade_newFooter() {
+ notificationsQSContainerController.splitShadeEnabled = false
+ useNewFooter(true)
+
given(taskbarVisible = true,
navigationMode = GESTURES_NAVIGATION,
insets = windowInsets().withStableBottom())
@@ -146,6 +228,8 @@
@Test
fun testTaskbarNotVisibleInSinglePaneShade() {
notificationsQSContainerController.splitShadeEnabled = false
+ useNewFooter(false)
+
given(taskbarVisible = false,
navigationMode = GESTURES_NAVIGATION,
insets = emptyInsets())
@@ -159,14 +243,56 @@
given(taskbarVisible = false,
navigationMode = BUTTONS_NAVIGATION,
insets = windowInsets().withStableBottom())
- then(expectedContainerPadding = 0,
- expectedQsPadding = STABLE_INSET_BOTTOM)
+ then(expectedContainerPadding = 0, expectedQsPadding = STABLE_INSET_BOTTOM)
+ }
+
+ @Test
+ fun testTaskbarNotVisibleInSinglePaneShade_newFooter() {
+ notificationsQSContainerController.splitShadeEnabled = false
+ useNewFooter(true)
+
+ given(taskbarVisible = false,
+ navigationMode = GESTURES_NAVIGATION,
+ insets = emptyInsets())
+ then(expectedContainerPadding = 0)
+
+ given(taskbarVisible = false,
+ navigationMode = GESTURES_NAVIGATION,
+ insets = windowInsets().withCutout().withStableBottom())
+ then(expectedContainerPadding = CUTOUT_HEIGHT)
+
+ given(taskbarVisible = false,
+ navigationMode = BUTTONS_NAVIGATION,
+ insets = windowInsets().withStableBottom())
+ then(expectedContainerPadding = 0, expectedQsPadding = STABLE_INSET_BOTTOM)
}
@Test
fun testCustomizingInSinglePaneShade() {
notificationsQSContainerController.splitShadeEnabled = false
notificationsQSContainerController.setCustomizerShowing(true)
+ useNewFooter(false)
+
+ // always sets spacings to 0
+ given(taskbarVisible = false,
+ navigationMode = GESTURES_NAVIGATION,
+ insets = windowInsets().withStableBottom())
+ then(expectedContainerPadding = 0,
+ expectedNotificationsMargin = 0)
+
+ given(taskbarVisible = false,
+ navigationMode = BUTTONS_NAVIGATION,
+ insets = emptyInsets())
+ then(expectedContainerPadding = 0,
+ expectedNotificationsMargin = 0)
+ }
+
+ @Test
+ fun testCustomizingInSinglePaneShade_newFooter() {
+ notificationsQSContainerController.splitShadeEnabled = false
+ notificationsQSContainerController.setCustomizerShowing(true)
+ useNewFooter(true)
+
// always sets spacings to 0
given(taskbarVisible = false,
navigationMode = GESTURES_NAVIGATION,
@@ -185,6 +311,28 @@
fun testDetailShowingInSinglePaneShade() {
notificationsQSContainerController.splitShadeEnabled = false
notificationsQSContainerController.setDetailShowing(true)
+ useNewFooter(false)
+
+ // always sets spacings to 0
+ given(taskbarVisible = false,
+ navigationMode = GESTURES_NAVIGATION,
+ insets = windowInsets().withStableBottom())
+ then(expectedContainerPadding = 0,
+ expectedNotificationsMargin = 0)
+
+ given(taskbarVisible = false,
+ navigationMode = BUTTONS_NAVIGATION,
+ insets = emptyInsets())
+ then(expectedContainerPadding = 0,
+ expectedNotificationsMargin = 0)
+ }
+
+ @Test
+ fun testDetailShowingInSinglePaneShade_newFooter() {
+ notificationsQSContainerController.splitShadeEnabled = false
+ notificationsQSContainerController.setDetailShowing(true)
+ useNewFooter(true)
+
// always sets spacings to 0
given(taskbarVisible = false,
navigationMode = GESTURES_NAVIGATION,
@@ -202,6 +350,26 @@
@Test
fun testDetailShowingInSplitShade() {
notificationsQSContainerController.splitShadeEnabled = true
+ useNewFooter(false)
+
+ given(taskbarVisible = false,
+ navigationMode = GESTURES_NAVIGATION,
+ insets = windowInsets().withStableBottom())
+ then(expectedContainerPadding = 0)
+
+ notificationsQSContainerController.setDetailShowing(true)
+ // should not influence spacing
+ given(taskbarVisible = false,
+ navigationMode = BUTTONS_NAVIGATION,
+ insets = emptyInsets())
+ then(expectedContainerPadding = 0)
+ }
+
+ @Test
+ fun testDetailShowingInSplitShade_newFooter() {
+ notificationsQSContainerController.splitShadeEnabled = true
+ useNewFooter(true)
+
given(taskbarVisible = false,
navigationMode = GESTURES_NAVIGATION,
insets = windowInsets().withStableBottom())
@@ -246,7 +414,13 @@
verify(notificationsQSContainer)
.setPadding(anyInt(), anyInt(), anyInt(), eq(expectedContainerPadding))
verify(notificationsQSContainer).setNotificationsMarginBottom(expectedNotificationsMargin)
- verify(notificationsQSContainer).setQSScrollPaddingBottom(expectedQsPadding)
+ val newFooter = featureFlags.isEnabled(Flags.NEW_FOOTER)
+ if (newFooter) {
+ verify(notificationsQSContainer)
+ .setQSContainerPaddingBottom(expectedNotificationsMargin)
+ } else {
+ verify(notificationsQSContainer).setQSScrollPaddingBottom(expectedQsPadding)
+ }
Mockito.clearInvocations(notificationsQSContainer)
}
@@ -263,4 +437,8 @@
whenever(stableInsetBottom).thenReturn(STABLE_INSET_BOTTOM)
return this
}
+
+ private fun useNewFooter(useNewFooter: Boolean) {
+ whenever(featureFlags.isEnabled(Flags.NEW_FOOTER)).thenReturn(useNewFooter)
+ }
}
\ No newline at end of file