From 7a1d17b921e1500d633836da10665fc0f4edb04a Mon Sep 17 00:00:00 2001 From: Peter Kalauskas Date: Tue, 16 Nov 2021 15:15:53 -0800 Subject: [PATCH] Update QS footer when multi-user setting changed Test: adb shell settings put global user_switcher_enabled 1 Test: com.android.systemui.qs.FooterActionsControllerTest Bug: 201567807 Change-Id: I84921cdda38efce4666e50df063983fd511320d5 --- .../systemui/qs/FooterActionsController.kt | 22 +++++++++++-- .../qs/FooterActionsControllerBuilder.kt | 14 ++++++-- .../qs/FooterActionsControllerTest.kt | 33 +++++++++++++++++-- 3 files changed, 62 insertions(+), 7 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt index 98b914672112e..fce0c0c95e573 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt @@ -17,8 +17,10 @@ package com.android.systemui.qs import android.content.Intent +import android.os.Handler import android.os.UserManager import android.provider.Settings +import android.provider.Settings.Global.USER_SWITCHER_ENABLED import android.view.View import android.widget.Toast import androidx.annotation.VisibleForTesting @@ -35,6 +37,7 @@ 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.settings.UserTracker import com.android.systemui.statusbar.phone.MultiUserSwitchController import com.android.systemui.statusbar.phone.SettingsButton import com.android.systemui.statusbar.policy.DeviceProvisionedController @@ -42,6 +45,7 @@ import com.android.systemui.statusbar.policy.UserInfoController import com.android.systemui.statusbar.policy.UserInfoController.OnUserInfoChangedListener import com.android.systemui.tuner.TunerService import com.android.systemui.util.ViewController +import com.android.systemui.util.settings.GlobalSettings import javax.inject.Inject import javax.inject.Named @@ -55,6 +59,7 @@ class FooterActionsController @Inject constructor( private val qsPanelController: QSPanelController, private val activityStarter: ActivityStarter, private val userManager: UserManager, + private val userTracker: UserTracker, private val userInfoController: UserInfoController, private val multiUserSwitchController: MultiUserSwitchController, private val deviceProvisionedController: DeviceProvisionedController, @@ -64,7 +69,9 @@ class FooterActionsController @Inject constructor( private val globalActionsDialog: GlobalActionsDialogLite, private val uiEventLogger: UiEventLogger, @Named(PM_LITE_ENABLED) private val showPMLiteButton: Boolean, - private val buttonsVisibleState: ExpansionState + private val buttonsVisibleState: ExpansionState, + private val globalSetting: GlobalSettings, + private val handler: Handler ) : ViewController(view) { enum class ExpansionState { COLLAPSED, EXPANDED } @@ -83,6 +90,16 @@ class FooterActionsController @Inject constructor( mView.onUserInfoChanged(picture, isGuestUser) } + private val multiUserSetting = + object : SettingObserver( + globalSetting, handler, USER_SWITCHER_ENABLED, userTracker.userId) { + override fun handleValueChanged(value: Int, observedChange: Boolean) { + if (observedChange) { + updateView() + } + } + } + private val onClickListener = View.OnClickListener { v -> // Don't do anything until views are unhidden. Don't do anything if the tap looks // suspicious. @@ -182,6 +199,7 @@ class FooterActionsController @Inject constructor( return } this.listening = listening + multiUserSetting.isListening = listening if (this.listening) { userInfoController.addCallback(onUserInfoChangedListener) updateView() @@ -215,4 +233,4 @@ class FooterActionsController @Inject constructor( } private fun isTunerEnabled() = tunerService.isTunerEnabled -} \ No newline at end of file +} diff --git a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsControllerBuilder.kt b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsControllerBuilder.kt index f6c89a9c66a2f..dd4dc87d8a9f8 100644 --- a/packages/SystemUI/src/com/android/systemui/qs/FooterActionsControllerBuilder.kt +++ b/packages/SystemUI/src/com/android/systemui/qs/FooterActionsControllerBuilder.kt @@ -16,18 +16,22 @@ 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 @@ -35,6 +39,7 @@ class FooterActionsControllerBuilder @Inject constructor( private val qsPanelController: QSPanelController, 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, @@ -43,7 +48,9 @@ class FooterActionsControllerBuilder @Inject constructor( private val tunerService: TunerService, private val globalActionsDialog: GlobalActionsDialogLite, private val uiEventLogger: UiEventLogger, - @Named(QSFlagsModule.PM_LITE_ENABLED) private val showPMLiteButton: Boolean + @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 @@ -60,8 +67,9 @@ class FooterActionsControllerBuilder @Inject constructor( fun build(): FooterActionsController { return FooterActionsController(view, qsPanelController, activityStarter, userManager, - userInfoController, multiUserSwitchControllerFactory.create(view), + userTracker, userInfoController, multiUserSwitchControllerFactory.create(view), deviceProvisionedController, falsingManager, metricsLogger, tunerService, - globalActionsDialog, uiEventLogger, showPMLiteButton, buttonsVisibleState) + globalActionsDialog, uiEventLogger, showPMLiteButton, buttonsVisibleState, + globalSettings, handler) } } \ No newline at end of file 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 d2bba361b1f82..26f04fc4e7b58 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt @@ -1,6 +1,8 @@ package com.android.systemui.qs +import android.os.Handler import android.os.UserManager +import android.provider.Settings import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.testing.ViewUtils @@ -16,10 +18,12 @@ import com.android.systemui.classifier.FalsingManagerFake 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 import com.android.systemui.statusbar.policy.UserInfoController import com.android.systemui.tuner.TunerService +import com.android.systemui.util.settings.FakeSettings import com.android.systemui.utils.leaks.FakeTunerService import com.android.systemui.utils.leaks.LeakCheckedTest import com.google.common.truth.Truth.assertThat @@ -42,6 +46,8 @@ class FooterActionsControllerTest : LeakCheckedTest() { @Mock private lateinit var userManager: UserManager @Mock + private lateinit var userTracker: UserTracker + @Mock private lateinit var activityStarter: ActivityStarter @Mock private lateinit var deviceProvisionedController: DeviceProvisionedController @@ -62,11 +68,13 @@ class FooterActionsControllerTest : LeakCheckedTest() { private lateinit var view: FooterActionsView private val falsingManager: FalsingManagerFake = FalsingManagerFake() private lateinit var testableLooper: TestableLooper + private lateinit var fakeSettings: FakeSettings @Before fun setUp() { MockitoAnnotations.initMocks(this) testableLooper = TestableLooper.get(this) + fakeSettings = FakeSettings() injectLeakCheckedDependencies(*LeakCheckedTest.ALL_SUPPORTED_CLASSES) val fakeTunerService = Dependency.get(TunerService::class.java) as FakeTunerService @@ -74,10 +82,11 @@ class FooterActionsControllerTest : LeakCheckedTest() { .inflate(R.layout.footer_actions, null) as FooterActionsView controller = FooterActionsController(view, qsPanelController, activityStarter, - userManager, userInfoController, multiUserSwitchController, + userManager, userTracker, userInfoController, multiUserSwitchController, deviceProvisionedController, falsingManager, metricsLogger, fakeTunerService, globalActionsDialog, uiEventLogger, showPMLiteButton = true, - buttonsVisibleState = ExpansionState.EXPANDED) + buttonsVisibleState = ExpansionState.EXPANDED, fakeSettings, + Handler(testableLooper.looper)) controller.init() ViewUtils.attachView(view) // View looper is the testable looper associated with the test @@ -122,4 +131,24 @@ class FooterActionsControllerTest : LeakCheckedTest() { assertThat(multiUserSwitch.visibility).isEqualTo(View.VISIBLE) } + + @Test + fun testMultiUserSwitchUpdatedWhenSettingChanged() { + // When expanded, listening is true + controller.setListening(true) + testableLooper.processAllMessages() + + val multiUserSwitch = view.requireViewById(R.id.multi_user_switch) + assertThat(multiUserSwitch.visibility).isNotEqualTo(View.VISIBLE) + + // The setting is only used as an indicator for whether the view should refresh. The actual + // value of the setting is ignored; isMultiUserEnabled is the source of truth + whenever(multiUserSwitchController.isMultiUserEnabled).thenReturn(true) + + // Changing the value of USER_SWITCHER_ENABLED should cause the view to update + fakeSettings.putIntForUser(Settings.Global.USER_SWITCHER_ENABLED, 1, userTracker.userId) + testableLooper.processAllMessages() + + assertThat(multiUserSwitch.visibility).isEqualTo(View.VISIBLE) + } } \ No newline at end of file