• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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.tileimpl
18 
19 import android.content.Context
20 import android.graphics.drawable.Drawable
21 import android.service.quicksettings.Tile
22 import android.testing.AndroidTestingRunner
23 import android.testing.TestableLooper
24 import android.text.TextUtils
25 import android.view.View
26 import android.view.accessibility.AccessibilityNodeInfo
27 import android.widget.TextView
28 import androidx.test.filters.SmallTest
29 import com.android.systemui.R
30 import com.android.systemui.SysuiTestCase
31 import com.android.systemui.plugins.qs.QSIconView
32 import com.android.systemui.plugins.qs.QSTile
33 import com.google.common.truth.Truth.assertThat
34 import org.junit.Before
35 import org.junit.Test
36 import org.junit.runner.RunWith
37 import org.mockito.Mock
38 import org.mockito.MockitoAnnotations
39 
40 @RunWith(AndroidTestingRunner::class)
41 @SmallTest
42 @TestableLooper.RunWithLooper(setAsMainLooper = true)
43 class QSTileViewImplTest : SysuiTestCase() {
44 
45     @Mock
46     private lateinit var iconView: QSIconView
47     @Mock
48     private lateinit var customDrawable: Drawable
49 
50     private lateinit var tileView: FakeTileView
51     private lateinit var customDrawableView: View
52     private lateinit var chevronView: View
53 
54     @Before
setUpnull55     fun setUp() {
56         MockitoAnnotations.initMocks(this)
57         context.ensureTestableResources()
58 
59         tileView = FakeTileView(context, iconView, false)
60         customDrawableView = tileView.requireViewById(R.id.customDrawable)
61         chevronView = tileView.requireViewById(R.id.chevron)
62     }
63 
64     @Test
testSecondaryLabelNotModified_unavailablenull65     fun testSecondaryLabelNotModified_unavailable() {
66         val state = QSTile.State()
67         val testString = "TEST STRING"
68         state.state = Tile.STATE_UNAVAILABLE
69         state.secondaryLabel = testString
70 
71         tileView.changeState(state)
72 
73         assertThat(state.secondaryLabel as CharSequence).isEqualTo(testString)
74     }
75 
76     @Test
testSecondaryLabelNotModified_booleanInactivenull77     fun testSecondaryLabelNotModified_booleanInactive() {
78         val state = QSTile.BooleanState()
79         val testString = "TEST STRING"
80         state.state = Tile.STATE_INACTIVE
81         state.secondaryLabel = testString
82 
83         tileView.changeState(state)
84 
85         assertThat(state.secondaryLabel as CharSequence).isEqualTo(testString)
86     }
87 
88     @Test
testSecondaryLabelNotModified_booleanActivenull89     fun testSecondaryLabelNotModified_booleanActive() {
90         val state = QSTile.BooleanState()
91         val testString = "TEST STRING"
92         state.state = Tile.STATE_ACTIVE
93         state.secondaryLabel = testString
94 
95         tileView.changeState(state)
96 
97         assertThat(state.secondaryLabel as CharSequence).isEqualTo(testString)
98     }
99 
100     @Test
testSecondaryLabelNotModified_availableNotBoolean_inactivenull101     fun testSecondaryLabelNotModified_availableNotBoolean_inactive() {
102         val state = QSTile.State()
103         state.state = Tile.STATE_INACTIVE
104         state.secondaryLabel = ""
105 
106         tileView.changeState(state)
107 
108         assertThat(TextUtils.isEmpty(state.secondaryLabel)).isTrue()
109     }
110 
111     @Test
testSecondaryLabelNotModified_availableNotBoolean_activenull112     fun testSecondaryLabelNotModified_availableNotBoolean_active() {
113         val state = QSTile.State()
114         state.state = Tile.STATE_ACTIVE
115         state.secondaryLabel = ""
116 
117         tileView.changeState(state)
118 
119         assertThat(TextUtils.isEmpty(state.secondaryLabel)).isTrue()
120     }
121 
122     @Test
testSecondaryLabelDescription_unavailable_defaultnull123     fun testSecondaryLabelDescription_unavailable_default() {
124         val state = QSTile.State()
125         state.state = Tile.STATE_UNAVAILABLE
126         state.secondaryLabel = ""
127 
128         tileView.changeState(state)
129 
130         assertThat(state.secondaryLabel as CharSequence).isEqualTo(
131             context.getString(R.string.tile_unavailable)
132         )
133     }
134 
135     @Test
testSecondaryLabelDescription_booleanInactive_defaultnull136     fun testSecondaryLabelDescription_booleanInactive_default() {
137         val state = QSTile.BooleanState()
138         state.state = Tile.STATE_INACTIVE
139         state.secondaryLabel = ""
140 
141         tileView.changeState(state)
142 
143         assertThat(state.secondaryLabel as CharSequence).isEqualTo(
144             context.getString(R.string.switch_bar_off)
145         )
146     }
147 
148     @Test
testSecondaryLabelDescription_booleanActive_defaultnull149     fun testSecondaryLabelDescription_booleanActive_default() {
150         val state = QSTile.BooleanState()
151         state.state = Tile.STATE_ACTIVE
152         state.secondaryLabel = ""
153 
154         tileView.changeState(state)
155 
156         assertThat(state.secondaryLabel as CharSequence).isEqualTo(
157             context.getString(R.string.switch_bar_on)
158         )
159     }
160 
161     @Test
testShowCustomDrawableViewBooleanStatenull162     fun testShowCustomDrawableViewBooleanState() {
163         val state = QSTile.BooleanState()
164         state.sideViewCustomDrawable = customDrawable
165 
166         tileView.changeState(state)
167 
168         assertThat(customDrawableView.visibility).isEqualTo(View.VISIBLE)
169         assertThat(chevronView.visibility).isEqualTo(View.GONE)
170     }
171 
172     @Test
testShowCustomDrawableViewNonBooleanStatenull173     fun testShowCustomDrawableViewNonBooleanState() {
174         val state = QSTile.State()
175         state.sideViewCustomDrawable = customDrawable
176 
177         tileView.changeState(state)
178 
179         assertThat(customDrawableView.visibility).isEqualTo(View.VISIBLE)
180         assertThat(chevronView.visibility).isEqualTo(View.GONE)
181     }
182 
183     @Test
testShowCustomDrawableViewBooleanStateForceChevronnull184     fun testShowCustomDrawableViewBooleanStateForceChevron() {
185         val state = QSTile.BooleanState()
186         state.sideViewCustomDrawable = customDrawable
187         state.forceExpandIcon = true
188 
189         tileView.changeState(state)
190 
191         assertThat(customDrawableView.visibility).isEqualTo(View.VISIBLE)
192         assertThat(chevronView.visibility).isEqualTo(View.GONE)
193     }
194 
195     @Test
testShowChevronNonBooleanStatenull196     fun testShowChevronNonBooleanState() {
197         val state = QSTile.State()
198 
199         tileView.changeState(state)
200 
201         assertThat(customDrawableView.visibility).isEqualTo(View.GONE)
202         assertThat(chevronView.visibility).isEqualTo(View.VISIBLE)
203     }
204 
205     @Test
testShowChevronBooleanStateForcheShownull206     fun testShowChevronBooleanStateForcheShow() {
207         val state = QSTile.BooleanState()
208         state.forceExpandIcon = true
209 
210         tileView.changeState(state)
211 
212         assertThat(customDrawableView.visibility).isEqualTo(View.GONE)
213         assertThat(chevronView.visibility).isEqualTo(View.VISIBLE)
214     }
215 
216     @Test
testNoImageShownnull217     fun testNoImageShown() {
218         val state = QSTile.BooleanState()
219 
220         tileView.changeState(state)
221 
222         assertThat(customDrawableView.visibility).isEqualTo(View.GONE)
223         assertThat(chevronView.visibility).isEqualTo(View.GONE)
224     }
225 
226     @Test
testUseStateStringsForKnownSpec_Booleannull227     fun testUseStateStringsForKnownSpec_Boolean() {
228         val state = QSTile.BooleanState()
229         val spec = "internet"
230         state.spec = spec
231 
232         val unavailableString = "${spec}_unavailable"
233         val offString = "${spec}_off"
234         val onString = "${spec}_on"
235 
236         context.orCreateTestableResources.addOverride(R.array.tile_states_internet, arrayOf(
237             unavailableString,
238             offString,
239             onString
240         ))
241 
242         // State UNAVAILABLE
243         state.secondaryLabel = ""
244         state.state = Tile.STATE_UNAVAILABLE
245         tileView.changeState(state)
246         assertThat((tileView.secondaryLabel as TextView).text).isEqualTo(unavailableString)
247 
248         // State INACTIVE
249         state.secondaryLabel = ""
250         state.state = Tile.STATE_INACTIVE
251         tileView.changeState(state)
252         assertThat((tileView.secondaryLabel as TextView).text).isEqualTo(offString)
253 
254         // State ACTIVE
255         state.secondaryLabel = ""
256         state.state = Tile.STATE_ACTIVE
257         tileView.changeState(state)
258         assertThat((tileView.secondaryLabel as TextView).text).isEqualTo(onString)
259     }
260 
261     @Test
testCollectionItemInfoHasPositionnull262     fun testCollectionItemInfoHasPosition() {
263         val position = 5
264         tileView.setPosition(position)
265 
266         val info = AccessibilityNodeInfo(tileView)
267         tileView.onInitializeAccessibilityNodeInfo(info)
268 
269         assertThat(info.collectionItemInfo.rowIndex).isEqualTo(position)
270         assertThat(info.collectionItemInfo.rowSpan).isEqualTo(1)
271         assertThat(info.collectionItemInfo.columnIndex).isEqualTo(0)
272         assertThat(info.collectionItemInfo.columnSpan).isEqualTo(1)
273     }
274 
275     @Test
testCollectionItemInfoNoPositionnull276     fun testCollectionItemInfoNoPosition() {
277         val info = AccessibilityNodeInfo(tileView)
278         tileView.onInitializeAccessibilityNodeInfo(info)
279 
280         assertThat(info.collectionItemInfo).isNull()
281     }
282 
283     @Test
testDisabledByPolicyInactive_usesUnavailableColorsnull284     fun testDisabledByPolicyInactive_usesUnavailableColors() {
285         val stateDisabledByPolicy = QSTile.State()
286         stateDisabledByPolicy.state = Tile.STATE_INACTIVE
287         stateDisabledByPolicy.disabledByPolicy = true
288 
289         val stateUnavailable = QSTile.State()
290         stateUnavailable.state = Tile.STATE_UNAVAILABLE
291 
292         tileView.changeState(stateDisabledByPolicy)
293         val colorsDisabledByPolicy = tileView.getCurrentColors()
294 
295         tileView.changeState(stateUnavailable)
296         val colorsUnavailable = tileView.getCurrentColors()
297 
298         assertThat(colorsDisabledByPolicy).containsExactlyElementsIn(colorsUnavailable)
299     }
300 
301     @Test
testDisabledByPolicyActive_usesUnavailableColorsnull302     fun testDisabledByPolicyActive_usesUnavailableColors() {
303         val stateDisabledByPolicy = QSTile.State()
304         stateDisabledByPolicy.state = Tile.STATE_ACTIVE
305         stateDisabledByPolicy.disabledByPolicy = true
306 
307         val stateUnavailable = QSTile.State()
308         stateUnavailable.state = Tile.STATE_UNAVAILABLE
309 
310         tileView.changeState(stateDisabledByPolicy)
311         val colorsDisabledByPolicy = tileView.getCurrentColors()
312 
313         tileView.changeState(stateUnavailable)
314         val colorsUnavailable = tileView.getCurrentColors()
315 
316         assertThat(colorsDisabledByPolicy).containsExactlyElementsIn(colorsUnavailable)
317     }
318 
319     @Test
testDisabledByPolicy_secondaryLabelTextnull320     fun testDisabledByPolicy_secondaryLabelText() {
321         val testA11yLabel = "TEST_LABEL"
322         context.orCreateTestableResources
323                 .addOverride(
324                         R.string.accessibility_tile_disabled_by_policy_action_description,
325                         testA11yLabel
326                 )
327 
328         val stateDisabledByPolicy = QSTile.State()
329         stateDisabledByPolicy.state = Tile.STATE_INACTIVE
330         stateDisabledByPolicy.disabledByPolicy = true
331 
332         tileView.changeState(stateDisabledByPolicy)
333 
334         val info = AccessibilityNodeInfo(tileView)
335         tileView.onInitializeAccessibilityNodeInfo(info)
336         assertThat(
337                 info.actionList.find {
338                         it.id == AccessibilityNodeInfo.AccessibilityAction.ACTION_CLICK.id
339                 }?.label
340         ).isEqualTo(testA11yLabel)
341     }
342 
343     @Test
testDisabledByPolicy_unavailableInStateDescriptionnull344     fun testDisabledByPolicy_unavailableInStateDescription() {
345         val state = QSTile.BooleanState()
346         val spec = "internet"
347         state.spec = spec
348         state.disabledByPolicy = true
349         state.state = Tile.STATE_INACTIVE
350 
351         val unavailableString = "${spec}_unavailable"
352         val offString = "${spec}_off"
353         val onString = "${spec}_on"
354 
355         context.orCreateTestableResources.addOverride(R.array.tile_states_internet, arrayOf(
356                 unavailableString,
357                 offString,
358                 onString
359         ))
360 
361         tileView.changeState(state)
362         assertThat(tileView.stateDescription?.contains(unavailableString)).isTrue()
363     }
364 
365     class FakeTileView(
366         context: Context,
367         icon: QSIconView,
368         collapsed: Boolean
369     ) : QSTileViewImpl(context, icon, collapsed) {
changeStatenull370         fun changeState(state: QSTile.State) {
371             handleStateChanged(state)
372         }
373     }
374 }
375