blob: f09aab97a2190ed1e939935e545cc908163c5420 [file] [log] [blame]
Fabian Kozynskif10b6ab2019-12-27 09:31:04 -05001/*
2 * Copyright (C) 2020 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
17package com.android.systemui.controls.management
18
19import android.content.ComponentName
20import android.content.pm.ServiceInfo
21import android.testing.AndroidTestingRunner
22import androidx.test.filters.SmallTest
23import com.android.settingslib.applications.ServiceListing
24import com.android.settingslib.widget.CandidateInfo
25import com.android.systemui.SysuiTestCase
26import com.android.systemui.util.concurrency.FakeExecutor
27import com.android.systemui.util.time.FakeSystemClock
28import org.junit.After
29import org.junit.Assert.assertEquals
30import org.junit.Assert.assertTrue
31import org.junit.Before
32import org.junit.Test
33import org.junit.runner.RunWith
34import org.mockito.ArgumentCaptor
35import org.mockito.Mock
36import org.mockito.Mockito
37import org.mockito.Mockito.`when`
38import org.mockito.Mockito.never
39import org.mockito.Mockito.reset
40import org.mockito.Mockito.verify
41import org.mockito.MockitoAnnotations
42
43@SmallTest
44@RunWith(AndroidTestingRunner::class)
45class ControlsListingControllerImplTest : SysuiTestCase() {
46
47 companion object {
48 private const val TEST_LABEL = "TEST_LABEL"
49 private const val TEST_PERMISSION = "permission"
50 fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
51 fun <T> any(): T = Mockito.any<T>()
52 }
53
54 @Mock
55 private lateinit var mockSL: ServiceListing
56 @Mock
57 private lateinit var mockCallback: ControlsListingController.ControlsListingCallback
58 @Mock
59 private lateinit var mockCallbackOther: ControlsListingController.ControlsListingCallback
60 @Mock
61 private lateinit var serviceInfo: ServiceInfo
62 @Mock
63 private lateinit var componentName: ComponentName
64
65 private val executor = FakeExecutor(FakeSystemClock())
66
67 private lateinit var controller: ControlsListingControllerImpl
68
69 private var serviceListingCallbackCaptor =
70 ArgumentCaptor.forClass(ServiceListing.Callback::class.java)
71
72 @Before
73 fun setUp() {
74 MockitoAnnotations.initMocks(this)
75
76 `when`(serviceInfo.componentName).thenReturn(componentName)
77
78 controller = ControlsListingControllerImpl(mContext, executor, mockSL)
79 verify(mockSL).addCallback(capture(serviceListingCallbackCaptor))
80 }
81
82 @After
83 fun tearDown() {
84 executor.advanceClockToLast()
85 executor.runAllReady()
86 }
87
88 @Test
89 fun testNoServices_notListening() {
90 assertTrue(controller.getCurrentServices().isEmpty())
91 }
92
93 @Test
94 fun testStartListening_onFirstCallback() {
95 controller.addCallback(mockCallback)
96 executor.runAllReady()
97
98 verify(mockSL).setListening(true)
99 }
100
101 @Test
102 fun testStartListening_onlyOnce() {
103 controller.addCallback(mockCallback)
104 controller.addCallback(mockCallbackOther)
105
106 executor.runAllReady()
107
108 verify(mockSL).setListening(true)
109 }
110
111 @Test
112 fun testStopListening_callbackRemoved() {
113 controller.addCallback(mockCallback)
114
115 executor.runAllReady()
116
117 controller.removeCallback(mockCallback)
118
119 executor.runAllReady()
120
121 verify(mockSL).setListening(false)
122 }
123
124 @Test
125 fun testStopListening_notWhileRemainingCallbacks() {
126 controller.addCallback(mockCallback)
127 controller.addCallback(mockCallbackOther)
128
129 executor.runAllReady()
130
131 controller.removeCallback(mockCallback)
132
133 executor.runAllReady()
134
135 verify(mockSL, never()).setListening(false)
136 }
137
138 @Test
139 fun testReloadOnFirstCallbackAdded() {
140 controller.addCallback(mockCallback)
141 executor.runAllReady()
142
143 verify(mockSL).reload()
144 }
145
146 @Test
147 fun testCallbackCalledWhenAdded() {
148 `when`(mockSL.reload()).then {
149 serviceListingCallbackCaptor.value.onServicesReloaded(emptyList())
150 }
151
152 controller.addCallback(mockCallback)
153 executor.runAllReady()
154 verify(mockCallback).onServicesUpdated(any())
155 reset(mockCallback)
156
157 controller.addCallback(mockCallbackOther)
158 executor.runAllReady()
159 verify(mockCallbackOther).onServicesUpdated(any())
160 verify(mockCallback, never()).onServicesUpdated(any())
161 }
162
163 @Test
164 fun testCallbackGetsList() {
165 val list = listOf(serviceInfo)
166 controller.addCallback(mockCallback)
167 controller.addCallback(mockCallbackOther)
168
169 @Suppress("unchecked_cast")
170 val captor: ArgumentCaptor<List<CandidateInfo>> =
171 ArgumentCaptor.forClass(List::class.java) as ArgumentCaptor<List<CandidateInfo>>
172
173 executor.runAllReady()
174 reset(mockCallback)
175 reset(mockCallbackOther)
176
177 serviceListingCallbackCaptor.value.onServicesReloaded(list)
178
179 executor.runAllReady()
180 verify(mockCallback).onServicesUpdated(capture(captor))
181 assertEquals(1, captor.value.size)
182 assertEquals(componentName.flattenToString(), captor.value[0].key)
183
184 verify(mockCallbackOther).onServicesUpdated(capture(captor))
185 assertEquals(1, captor.value.size)
186 assertEquals(componentName.flattenToString(), captor.value[0].key)
187 }
188}