1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License
15  */
16 
17 package com.android.systemui.qs.tiles
18 
19 import android.content.Context
20 import android.os.Handler
21 import android.testing.AndroidTestingRunner
22 import android.testing.TestableLooper
23 import androidx.test.filters.SmallTest
24 import com.android.internal.logging.MetricsLogger
25 import com.android.systemui.R
26 import com.android.systemui.SysuiTestCase
27 import com.android.systemui.classifier.FalsingManagerFake
28 import com.android.systemui.plugins.ActivityStarter
29 import com.android.systemui.plugins.qs.QSTile
30 import com.android.systemui.plugins.statusbar.StatusBarStateController
31 import com.android.systemui.qs.QSHost
32 import com.android.systemui.qs.QsEventLogger
33 import com.android.systemui.qs.logging.QSLogger
34 import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
35 import com.android.systemui.qs.tileimpl.QSTileImpl
36 import com.android.systemui.statusbar.policy.KeyguardStateController
37 import com.android.systemui.statusbar.policy.LocationController
38 import com.android.systemui.util.mockito.argumentCaptor
39 import com.android.systemui.util.mockito.capture
40 import com.google.common.truth.Truth.assertThat
41 import org.junit.After
42 import org.junit.Before
43 import org.junit.Test
44 import org.junit.runner.RunWith
45 import org.mockito.Mock
46 import org.mockito.Mockito.verify
47 import org.mockito.Mockito.`when`
48 import org.mockito.MockitoAnnotations
49 
50 @RunWith(AndroidTestingRunner::class)
51 @TestableLooper.RunWithLooper(setAsMainLooper = true)
52 @SmallTest
53 class LocationTileTest : SysuiTestCase() {
54 
55     @Mock
56     private lateinit var mockContext: Context
57     @Mock
58     private lateinit var qsLogger: QSLogger
59     @Mock
60     private lateinit var qsHost: QSHost
61     @Mock
62     private lateinit var metricsLogger: MetricsLogger
63     private val falsingManager = FalsingManagerFake()
64     @Mock
65     private lateinit var statusBarStateController: StatusBarStateController
66     @Mock
67     private lateinit var activityStarter: ActivityStarter
68     @Mock
69     private lateinit var locationController: LocationController
70     @Mock
71     private lateinit var keyguardStateController: KeyguardStateController
72     @Mock
73     private lateinit var panelInteractor: PanelInteractor
74     @Mock
75     private lateinit var uiEventLogger: QsEventLogger
76 
77     private lateinit var testableLooper: TestableLooper
78     private lateinit var tile: LocationTile
79 
80     @Before
81     fun setUp() {
82         MockitoAnnotations.initMocks(this)
83         testableLooper = TestableLooper.get(this)
84         `when`(qsHost.context).thenReturn(mockContext)
85 
86         tile = LocationTile(
87             qsHost,
88             uiEventLogger,
89             testableLooper.looper,
90             Handler(testableLooper.looper),
91             falsingManager,
92             metricsLogger,
93             statusBarStateController,
94             activityStarter,
95             qsLogger,
96             locationController,
97             keyguardStateController,
98             panelInteractor,
99         )
100     }
101 
102     @After
103     fun tearDown() {
104         tile.destroy()
105         testableLooper.processAllMessages()
106     }
107 
108     @Test
109     fun testIcon_whenDisabled_isOffState() {
110         val state = QSTile.BooleanState()
111         `when`(locationController.isLocationEnabled).thenReturn(false)
112 
113         tile.handleUpdateState(state, /* arg= */ null)
114 
115         assertThat(state.icon)
116             .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_location_icon_off))
117     }
118 
119     @Test
120     fun testIcon_whenEnabled_isOnState() {
121         val state = QSTile.BooleanState()
122         `when`(locationController.isLocationEnabled).thenReturn(true)
123 
124         tile.handleUpdateState(state, /* arg= */ null)
125 
126         assertThat(state.icon)
127             .isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_location_icon_on))
128     }
129 
130     @Test
131     fun testClickWhenLockedWillCallOpenPanels() {
132         `when`(keyguardStateController.isMethodSecure).thenReturn(true)
133         `when`(keyguardStateController.isShowing).thenReturn(true)
134 
135         tile.handleClick(null)
136 
137         val captor = argumentCaptor<Runnable>()
138         verify(activityStarter).postQSRunnableDismissingKeyguard(capture(captor))
139         captor.value.run()
140 
141         verify(panelInteractor).openPanels()
142     }
143 }
144