blob: 9b40c5e87b791a8040d44d639b013636e2128da2 [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
Fabian Kozynski7988bd42020-01-30 12:21:52 -050020import android.content.Context
21import android.content.ContextWrapper
Fabian Kozynskif10b6ab2019-12-27 09:31:04 -050022import android.content.pm.ServiceInfo
Fabian Kozynski7988bd42020-01-30 12:21:52 -050023import android.os.UserHandle
Fabian Kozynskif10b6ab2019-12-27 09:31:04 -050024import android.testing.AndroidTestingRunner
25import androidx.test.filters.SmallTest
26import com.android.settingslib.applications.ServiceListing
Fabian Kozynskif10b6ab2019-12-27 09:31:04 -050027import com.android.systemui.SysuiTestCase
Fabian Kozynski7988bd42020-01-30 12:21:52 -050028import com.android.systemui.controls.ControlsServiceInfo
Fabian Kozynskif10b6ab2019-12-27 09:31:04 -050029import com.android.systemui.util.concurrency.FakeExecutor
30import com.android.systemui.util.time.FakeSystemClock
31import org.junit.After
32import org.junit.Assert.assertEquals
Fabian Kozynskif10b6ab2019-12-27 09:31:04 -050033import org.junit.Before
34import org.junit.Test
35import org.junit.runner.RunWith
36import org.mockito.ArgumentCaptor
37import org.mockito.Mock
38import org.mockito.Mockito
39import org.mockito.Mockito.`when`
Fabian Kozynski35086732020-03-10 14:25:32 -040040import org.mockito.Mockito.inOrder
Fabian Kozynski1a478622020-05-04 14:21:31 -040041import org.mockito.Mockito.mock
Fabian Kozynskif10b6ab2019-12-27 09:31:04 -050042import org.mockito.Mockito.never
43import org.mockito.Mockito.reset
44import org.mockito.Mockito.verify
45import org.mockito.MockitoAnnotations
Fabian Kozynski1a478622020-05-04 14:21:31 -040046import java.util.concurrent.Executor
Fabian Kozynskif10b6ab2019-12-27 09:31:04 -050047
48@SmallTest
49@RunWith(AndroidTestingRunner::class)
50class ControlsListingControllerImplTest : SysuiTestCase() {
51
52 companion object {
53 private const val TEST_LABEL = "TEST_LABEL"
54 private const val TEST_PERMISSION = "permission"
55 fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
56 fun <T> any(): T = Mockito.any<T>()
57 }
58
59 @Mock
60 private lateinit var mockSL: ServiceListing
61 @Mock
62 private lateinit var mockCallback: ControlsListingController.ControlsListingCallback
63 @Mock
64 private lateinit var mockCallbackOther: ControlsListingController.ControlsListingCallback
65 @Mock
66 private lateinit var serviceInfo: ServiceInfo
67 @Mock
68 private lateinit var componentName: ComponentName
69
70 private val executor = FakeExecutor(FakeSystemClock())
71
72 private lateinit var controller: ControlsListingControllerImpl
73
74 private var serviceListingCallbackCaptor =
75 ArgumentCaptor.forClass(ServiceListing.Callback::class.java)
76
Fabian Kozynski7988bd42020-01-30 12:21:52 -050077 private val user = mContext.userId
78 private val otherUser = user + 1
79
Fabian Kozynskif10b6ab2019-12-27 09:31:04 -050080 @Before
81 fun setUp() {
82 MockitoAnnotations.initMocks(this)
83
84 `when`(serviceInfo.componentName).thenReturn(componentName)
85
Fabian Kozynski7988bd42020-01-30 12:21:52 -050086 val wrapper = object : ContextWrapper(mContext) {
87 override fun createContextAsUser(user: UserHandle, flags: Int): Context {
88 return baseContext
89 }
90 }
91
92 controller = ControlsListingControllerImpl(wrapper, executor, { mockSL })
Fabian Kozynskif10b6ab2019-12-27 09:31:04 -050093 verify(mockSL).addCallback(capture(serviceListingCallbackCaptor))
94 }
95
96 @After
97 fun tearDown() {
98 executor.advanceClockToLast()
99 executor.runAllReady()
100 }
101
102 @Test
Fabian Kozynski35086732020-03-10 14:25:32 -0400103 fun testInitialStateListening() {
104 verify(mockSL).setListening(true)
105 verify(mockSL).reload()
106 }
107
108 @Test
Fabian Kozynski1a478622020-05-04 14:21:31 -0400109 fun testImmediateListingReload_doesNotCrash() {
110 val exec = Executor { it.run() }
111 val mockServiceListing = mock(ServiceListing::class.java)
112 var callback: ServiceListing.Callback? = null
113 `when`(mockServiceListing.addCallback(any<ServiceListing.Callback>())).then {
114 callback = it.getArgument(0)
115 Unit
116 }
117 `when`(mockServiceListing.reload()).then {
118 callback?.onServicesReloaded(listOf(serviceInfo))
119 }
120 ControlsListingControllerImpl(mContext, exec, { mockServiceListing })
121 }
122
123 @Test
Fabian Kozynski7988bd42020-01-30 12:21:52 -0500124 fun testStartsOnUser() {
125 assertEquals(user, controller.currentUserId)
126 }
127
128 @Test
Fabian Kozynskif10b6ab2019-12-27 09:31:04 -0500129 fun testCallbackCalledWhenAdded() {
Fabian Kozynskif10b6ab2019-12-27 09:31:04 -0500130 controller.addCallback(mockCallback)
131 executor.runAllReady()
132 verify(mockCallback).onServicesUpdated(any())
133 reset(mockCallback)
134
135 controller.addCallback(mockCallbackOther)
136 executor.runAllReady()
137 verify(mockCallbackOther).onServicesUpdated(any())
138 verify(mockCallback, never()).onServicesUpdated(any())
139 }
140
141 @Test
142 fun testCallbackGetsList() {
143 val list = listOf(serviceInfo)
144 controller.addCallback(mockCallback)
145 controller.addCallback(mockCallbackOther)
146
147 @Suppress("unchecked_cast")
Fabian Kozynski7988bd42020-01-30 12:21:52 -0500148 val captor: ArgumentCaptor<List<ControlsServiceInfo>> =
149 ArgumentCaptor.forClass(List::class.java)
150 as ArgumentCaptor<List<ControlsServiceInfo>>
Fabian Kozynskif10b6ab2019-12-27 09:31:04 -0500151
152 executor.runAllReady()
153 reset(mockCallback)
154 reset(mockCallbackOther)
155
156 serviceListingCallbackCaptor.value.onServicesReloaded(list)
157
158 executor.runAllReady()
159 verify(mockCallback).onServicesUpdated(capture(captor))
160 assertEquals(1, captor.value.size)
161 assertEquals(componentName.flattenToString(), captor.value[0].key)
162
163 verify(mockCallbackOther).onServicesUpdated(capture(captor))
164 assertEquals(1, captor.value.size)
165 assertEquals(componentName.flattenToString(), captor.value[0].key)
166 }
Fabian Kozynski7988bd42020-01-30 12:21:52 -0500167
168 @Test
169 fun testChangeUser() {
170 controller.changeUser(UserHandle.of(otherUser))
171 executor.runAllReady()
172 assertEquals(otherUser, controller.currentUserId)
Fabian Kozynski35086732020-03-10 14:25:32 -0400173
174 val inOrder = inOrder(mockSL)
175 inOrder.verify(mockSL).setListening(false)
176 inOrder.verify(mockSL).addCallback(any()) // We add a callback because we replaced the SL
177 inOrder.verify(mockSL).setListening(true)
178 inOrder.verify(mockSL).reload()
Fabian Kozynski7988bd42020-01-30 12:21:52 -0500179 }
Fabian Kozynskif10b6ab2019-12-27 09:31:04 -0500180}