1 /*
2  * Copyright (C) 2019 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.broadcast
18 
19 import android.content.BroadcastReceiver
20 import android.content.Context
21 import android.content.IntentFilter
22 import android.os.Handler
23 import android.os.UserHandle
24 import androidx.test.ext.junit.runners.AndroidJUnit4
25 import androidx.test.filters.SmallTest
26 import android.testing.TestableLooper
27 import com.android.systemui.SysuiTestCase
28 import com.android.systemui.broadcast.logging.BroadcastDispatcherLogger
29 import com.android.systemui.util.concurrency.FakeExecutor
30 import com.android.systemui.util.time.FakeSystemClock
31 import junit.framework.Assert.assertFalse
32 import junit.framework.Assert.assertNotNull
33 import junit.framework.Assert.assertNotSame
34 import org.junit.Before
35 import org.junit.Test
36 import org.junit.runner.RunWith
37 import org.mockito.ArgumentCaptor
38 import org.mockito.Mock
39 import org.mockito.Mockito
40 import org.mockito.Mockito.mock
41 import org.mockito.Mockito.nullable
42 import org.mockito.Mockito.verify
43 import org.mockito.MockitoAnnotations
44 import java.util.concurrent.Executor
45 
46 @RunWith(AndroidJUnit4::class)
47 @TestableLooper.RunWithLooper
48 @SmallTest
49 class UserBroadcastDispatcherTest : SysuiTestCase() {
50 
51     companion object {
52         private const val ACTION_1 = "com.android.systemui.tests.ACTION_1"
53         private const val ACTION_2 = "com.android.systemui.tests.ACTION_2"
54         private const val USER_ID = 0
55         private const val FLAG = 3
56         private val USER_HANDLE = UserHandle.of(USER_ID)
57 
capturenull58         fun <T> capture(argumentCaptor: ArgumentCaptor<T>): T = argumentCaptor.capture()
59         fun <T> any(): T = Mockito.any()
60         fun <T> eq(v: T) = Mockito.eq(v) ?: v
61     }
62 
63     @Mock
64     private lateinit var broadcastReceiver: BroadcastReceiver
65     @Mock
66     private lateinit var broadcastReceiverOther: BroadcastReceiver
67     @Mock
68     private lateinit var mockContext: Context
69     @Mock
70     private lateinit var logger: BroadcastDispatcherLogger
71     @Mock
72     private lateinit var removalPendingStore: PendingRemovalStore
73 
74     private lateinit var testableLooper: TestableLooper
75     private lateinit var userBroadcastDispatcher: UserBroadcastDispatcher
76     private lateinit var intentFilter: IntentFilter
77     private lateinit var intentFilterOther: IntentFilter
78     private lateinit var handler: Handler
79     private lateinit var fakeExecutor: FakeExecutor
80 
81     @Before
82     fun setUp() {
83         MockitoAnnotations.initMocks(this)
84         testableLooper = TestableLooper.get(this)
85         handler = Handler(testableLooper.looper)
86         fakeExecutor = FakeExecutor(FakeSystemClock())
87 
88         userBroadcastDispatcher = object : UserBroadcastDispatcher(
89                 mockContext,
90                 USER_ID,
91                 testableLooper.looper,
92                 mock(Executor::class.java),
93                 logger,
94                 removalPendingStore
95         ) {
96             override fun createActionReceiver(
97                 action: String,
98                 permission: String?,
99                 flags: Int
100             ): ActionReceiver {
101                 return mock(ActionReceiver::class.java)
102             }
103         }
104     }
105 
106     @Test
testSingleReceiverRegisterednull107     fun testSingleReceiverRegistered() {
108         intentFilter = IntentFilter(ACTION_1)
109         val receiverData = ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE)
110 
111         userBroadcastDispatcher.registerReceiver(receiverData, FLAG)
112         testableLooper.processAllMessages()
113 
114         val actionReceiver = userBroadcastDispatcher.getActionReceiver(ACTION_1, FLAG)
115         assertNotNull(actionReceiver)
116         verify(actionReceiver)?.addReceiverData(receiverData)
117     }
118 
119     @Test
testDifferentActionReceiversForDifferentFlagsnull120     fun testDifferentActionReceiversForDifferentFlags() {
121         intentFilter = IntentFilter(ACTION_1)
122         val receiverData = ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE)
123 
124         val flag1 = 0
125         val flag2 = 1
126 
127         userBroadcastDispatcher.registerReceiver(receiverData, flag1)
128         userBroadcastDispatcher.registerReceiver(receiverData, flag2)
129         testableLooper.processAllMessages()
130 
131         assertNotSame(
132                 userBroadcastDispatcher.getActionReceiver(ACTION_1, flag1),
133                 userBroadcastDispatcher.getActionReceiver(ACTION_1, flag2)
134         )
135     }
136 
137     @Test
testDifferentActionReceiversForDifferentPermissionsnull138     fun testDifferentActionReceiversForDifferentPermissions() {
139         intentFilter = IntentFilter(ACTION_1)
140         val receiverData1 =
141             ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE, "PERMISSION1")
142         val receiverData2 =
143             ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE, "PERMISSION2")
144 
145         userBroadcastDispatcher.registerReceiver(receiverData1, 0)
146         userBroadcastDispatcher.registerReceiver(receiverData2, 0)
147         testableLooper.processAllMessages()
148 
149         assertNotSame(
150             userBroadcastDispatcher.getActionReceiver(ACTION_1, 0, "PERMISSION1"),
151             userBroadcastDispatcher.getActionReceiver(ACTION_1, 0, "PERMISSION2")
152         )
153     }
154 
155     @Test
testSingleReceiverRegistered_loggingnull156     fun testSingleReceiverRegistered_logging() {
157         intentFilter = IntentFilter(ACTION_1)
158 
159         userBroadcastDispatcher.registerReceiver(
160                 ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE), FLAG)
161         testableLooper.processAllMessages()
162 
163         verify(logger).logReceiverRegistered(USER_HANDLE.identifier, broadcastReceiver, FLAG)
164     }
165 
166     @Test
testSingleReceiverUnregisterednull167     fun testSingleReceiverUnregistered() {
168         intentFilter = IntentFilter(ACTION_1)
169 
170         userBroadcastDispatcher.registerReceiver(
171                 ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE), FLAG)
172         testableLooper.processAllMessages()
173 
174         userBroadcastDispatcher.unregisterReceiver(broadcastReceiver)
175         testableLooper.processAllMessages()
176 
177         val actionReceiver = userBroadcastDispatcher.getActionReceiver(ACTION_1, FLAG)
178         assertNotNull(actionReceiver)
179         verify(actionReceiver)?.removeReceiver(broadcastReceiver)
180     }
181 
182     @Test
testSingleReceiverUnregistered_loggernull183     fun testSingleReceiverUnregistered_logger() {
184         intentFilter = IntentFilter(ACTION_1)
185 
186         userBroadcastDispatcher.registerReceiver(
187                 ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE), FLAG)
188         testableLooper.processAllMessages()
189 
190         userBroadcastDispatcher.unregisterReceiver(broadcastReceiver)
191         testableLooper.processAllMessages()
192 
193         verify(logger).logReceiverUnregistered(USER_HANDLE.identifier, broadcastReceiver)
194     }
195 
196     @Test
testRemoveReceiverReferencesnull197     fun testRemoveReceiverReferences() {
198         intentFilter = IntentFilter(ACTION_1)
199         userBroadcastDispatcher.registerReceiver(
200                 ReceiverData(broadcastReceiver, intentFilter, fakeExecutor, USER_HANDLE), FLAG)
201 
202         intentFilterOther = IntentFilter(ACTION_1)
203         intentFilterOther.addAction(ACTION_2)
204         userBroadcastDispatcher.registerReceiver(
205                 ReceiverData(
206                         broadcastReceiverOther,
207                         intentFilterOther,
208                         fakeExecutor,
209                         USER_HANDLE
210                 ), FLAG
211         )
212 
213         userBroadcastDispatcher.unregisterReceiver(broadcastReceiver)
214         testableLooper.processAllMessages()
215         fakeExecutor.runAllReady()
216 
217         assertFalse(userBroadcastDispatcher.isReceiverReferenceHeld(broadcastReceiver))
218     }
219 
220     @Test
testCreateActionReceiver_registerWithFlagnull221     fun testCreateActionReceiver_registerWithFlag() {
222         val uBR = UserBroadcastDispatcher(
223                 mockContext,
224                 USER_ID,
225                 testableLooper.looper,
226                 fakeExecutor,
227                 logger,
228                 removalPendingStore
229         )
230         uBR.registerReceiver(
231                 ReceiverData(
232                         broadcastReceiver,
233                         IntentFilter(ACTION_1),
234                         fakeExecutor,
235                         USER_HANDLE
236                 ),
237                 FLAG
238         )
239 
240         testableLooper.processAllMessages()
241         fakeExecutor.runAllReady()
242 
243         verify(mockContext).registerReceiverAsUser(
244                 any(), any(), any(), nullable(String::class.java), any(), eq(FLAG))
245     }
246 
247     @Test
testCreateActionReceiver_registerWithPermissionnull248     fun testCreateActionReceiver_registerWithPermission() {
249         val permission = "CUSTOM_PERMISSION"
250         val uBR = UserBroadcastDispatcher(
251             mockContext,
252             USER_ID,
253             testableLooper.looper,
254             fakeExecutor,
255             logger,
256             removalPendingStore
257         )
258         uBR.registerReceiver(
259             ReceiverData(
260                 broadcastReceiver,
261                 IntentFilter(ACTION_1),
262                 fakeExecutor,
263                 USER_HANDLE,
264                 permission
265             ),
266             FLAG
267         )
268 
269         testableLooper.processAllMessages()
270         fakeExecutor.runAllReady()
271 
272         verify(mockContext).registerReceiverAsUser(
273             any(), any(), any(), eq(permission), any(), eq(FLAG))
274     }
275 
UserBroadcastDispatchernull276     private fun UserBroadcastDispatcher.getActionReceiver(
277         action: String,
278         flags: Int,
279         permission: String? = null
280     ): ActionReceiver? {
281         return actionsToActionsReceivers.get(
282             UserBroadcastDispatcher.ReceiverProperties(
283                 action,
284                 flags,
285                 permission
286             )
287         )
288     }
289 }
290