1 package com.android.systemui.qs
2 
3 import android.os.UserManager
4 import android.testing.AndroidTestingRunner
5 import android.testing.TestableLooper
6 import android.testing.ViewUtils
7 import android.view.LayoutInflater
8 import android.view.View
9 import androidx.test.filters.SmallTest
10 import com.android.internal.logging.MetricsLogger
11 import com.android.internal.logging.UiEventLogger
12 import com.android.internal.logging.testing.FakeMetricsLogger
13 import com.android.systemui.Dependency
14 import com.android.systemui.R
15 import com.android.systemui.classifier.FalsingManagerFake
16 import com.android.systemui.globalactions.GlobalActionsDialogLite
17 import com.android.systemui.plugins.ActivityStarter
18 import com.android.systemui.qs.FooterActionsController.ExpansionState
19 import com.android.systemui.statusbar.phone.MultiUserSwitchController
20 import com.android.systemui.statusbar.policy.DeviceProvisionedController
21 import com.android.systemui.statusbar.policy.UserInfoController
22 import com.android.systemui.tuner.TunerService
23 import com.android.systemui.utils.leaks.FakeTunerService
24 import com.android.systemui.utils.leaks.LeakCheckedTest
25 import com.google.common.truth.Truth.assertThat
26 import org.junit.After
27 import org.junit.Before
28 import org.junit.Test
29 import org.junit.runner.RunWith
30 import org.mockito.ArgumentMatchers.any
31 import org.mockito.ArgumentMatchers.anyBoolean
32 import org.mockito.Mock
33 import org.mockito.Mockito
34 import org.mockito.Mockito.verify
35 import org.mockito.MockitoAnnotations
36 import org.mockito.Mockito.`when` as whenever
37 
38 @SmallTest
39 @TestableLooper.RunWithLooper
40 @RunWith(AndroidTestingRunner::class)
41 class FooterActionsControllerTest : LeakCheckedTest() {
42     @Mock
43     private lateinit var userManager: UserManager
44     @Mock
45     private lateinit var activityStarter: ActivityStarter
46     @Mock
47     private lateinit var deviceProvisionedController: DeviceProvisionedController
48     @Mock
49     private lateinit var userInfoController: UserInfoController
50     @Mock
51     private lateinit var qsPanelController: QSPanelController
52     @Mock
53     private lateinit var multiUserSwitchController: MultiUserSwitchController
54     @Mock
55     private lateinit var globalActionsDialog: GlobalActionsDialogLite
56     @Mock
57     private lateinit var uiEventLogger: UiEventLogger
58     @Mock
59     private lateinit var controller: FooterActionsController
60 
61     private val metricsLogger: MetricsLogger = FakeMetricsLogger()
62     private lateinit var view: FooterActionsView
63     private val falsingManager: FalsingManagerFake = FalsingManagerFake()
64     private lateinit var testableLooper: TestableLooper
65 
66     @Before
67     fun setUp() {
68         MockitoAnnotations.initMocks(this)
69         testableLooper = TestableLooper.get(this)
70         injectLeakCheckedDependencies(*LeakCheckedTest.ALL_SUPPORTED_CLASSES)
71         val fakeTunerService = Dependency.get(TunerService::class.java) as FakeTunerService
72 
73         view = LayoutInflater.from(context)
74                 .inflate(R.layout.footer_actions, null) as FooterActionsView
75 
76         controller = FooterActionsController(view, qsPanelController, activityStarter,
77                 userManager, userInfoController, multiUserSwitchController,
78                 deviceProvisionedController, falsingManager, metricsLogger, fakeTunerService,
79                 globalActionsDialog, uiEventLogger, showPMLiteButton = true,
80                 buttonsVisibleState = ExpansionState.EXPANDED)
81         controller.init()
82         ViewUtils.attachView(view)
83         // View looper is the testable looper associated with the test
84         testableLooper.processAllMessages()
85     }
86 
87     @After
88     fun tearDown() {
89         ViewUtils.detachView(view)
90     }
91 
92     @Test
93     fun testLogPowerMenuClick() {
94         controller.expanded = true
95         falsingManager.setFalseTap(false)
96 
97         view.findViewById<View>(R.id.pm_lite).performClick()
98         // Verify clicks are logged
99         verify(uiEventLogger, Mockito.times(1))
100                 .log(GlobalActionsDialogLite.GlobalActionsEvent.GA_OPEN_QS)
101     }
102 
103     @Test
104     fun testSettings_UserNotSetup() {
105         whenever(deviceProvisionedController.isCurrentUserSetup).thenReturn(false)
106         view.findViewById<View>(R.id.settings_button).performClick()
107         // Verify Settings wasn't launched.
108         verify<ActivityStarter>(activityStarter, Mockito.never()).startActivity(any(), anyBoolean())
109     }
110 
111     @Test
112     fun testMultiUserSwitchUpdatedWhenExpansionStarts() {
113         // When expansion starts, listening is set to true
114         val multiUserSwitch = view.requireViewById<View>(R.id.multi_user_switch)
115 
116         assertThat(multiUserSwitch.visibility).isNotEqualTo(View.VISIBLE)
117 
118         whenever(multiUserSwitchController.isMultiUserEnabled).thenReturn(true)
119 
120         controller.setListening(true)
121         testableLooper.processAllMessages()
122 
123         assertThat(multiUserSwitch.visibility).isEqualTo(View.VISIBLE)
124     }
125 }