• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 package com.android.systemui.broadcast
18 
19 import android.content.BroadcastReceiver
20 import android.content.Context
21 import android.content.Intent
22 import android.content.IntentFilter
23 import android.os.UserHandle
24 import android.test.suitebuilder.annotation.SmallTest
25 import android.testing.AndroidTestingRunner
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.mockito.any
31 import com.android.systemui.util.mockito.capture
32 import com.android.systemui.util.mockito.eq
33 import com.android.systemui.util.time.FakeSystemClock
34 import org.junit.Assert.assertFalse
35 import org.junit.Assert.assertTrue
36 import org.junit.Before
37 import org.junit.Test
38 import org.junit.runner.RunWith
39 import org.mockito.ArgumentCaptor
40 import org.mockito.ArgumentMatchers.anyInt
41 import org.mockito.ArgumentMatchers.anyString
42 import org.mockito.Captor
43 import org.mockito.Mock
44 import org.mockito.Mockito
45 import org.mockito.Mockito.mock
46 import org.mockito.Mockito.never
47 import org.mockito.Mockito.verify
48 import org.mockito.MockitoAnnotations
49 import java.lang.IllegalArgumentException
50 import java.lang.IllegalStateException
51 import java.util.concurrent.Executor
52 
53 @RunWith(AndroidTestingRunner::class)
54 @TestableLooper.RunWithLooper
55 @SmallTest
56 class ActionReceiverTest : SysuiTestCase() {
57 
58     companion object {
59         private const val ACTION1 = "TEST_ACTION1"
60         private const val ACTION2 = "TEST_ACTION2"
61         private const val CATEGORY = "TEST_CATEGORY"
62         private val USER = UserHandle.of(0)
sameNotNullnull63         private fun <T : Any> sameNotNull(arg: T): T = Mockito.same(arg) ?: arg
64 
65         fun IntentFilter.matchesOther(it: IntentFilter): Boolean {
66             val actions = actionsIterator()?.asSequence()?.toSet() ?: emptySet()
67             val categories = categoriesIterator()?.asSequence()?.toSet() ?: emptySet()
68             return (it.actionsIterator()?.asSequence()?.toSet() ?: emptySet()) == actions &&
69                     (it.categoriesIterator()?.asSequence()?.toSet() ?: emptySet()) == categories &&
70                     it.countDataAuthorities() == 0 &&
71                     it.countDataPaths() == 0 &&
72                     it.countDataSchemes() == 0 &&
73                     it.countDataTypes() == 0 &&
74                     it.countMimeGroups() == 0 &&
75                     it.priority == 0
76         }
77     }
78 
79     @Mock
80     private lateinit var registerFunction: BroadcastReceiver.(IntentFilter) -> Unit
81     @Mock
82     private lateinit var unregisterFunction: BroadcastReceiver.() -> Unit
83     @Mock
84     private lateinit var receiver1: BroadcastReceiver
85     @Mock
86     private lateinit var receiver2: BroadcastReceiver
87     @Mock
88     private lateinit var logger: BroadcastDispatcherLogger
89     @Captor
90     private lateinit var intentFilterCaptor: ArgumentCaptor<IntentFilter>
91 
92     private lateinit var executor: FakeExecutor
93     private lateinit var actionReceiver: ActionReceiver
<lambda>null94     private val directExecutor = Executor { it.run() }
95 
96     @Before
setUpnull97     fun setUp() {
98         MockitoAnnotations.initMocks(this)
99         executor = FakeExecutor(FakeSystemClock())
100 
101         actionReceiver = ActionReceiver(
102                 ACTION1,
103                 USER.identifier,
104                 registerFunction,
105                 unregisterFunction,
106                 executor,
107                 logger
108         )
109     }
110 
111     @Test
testStartsUnregisterednull112     fun testStartsUnregistered() {
113         assertFalse(actionReceiver.registered)
114         verify(registerFunction, never()).invoke(sameNotNull(actionReceiver),
115                 any(IntentFilter::class.java))
116     }
117 
118     @Test
testRegistersOnFirstAddnull119     fun testRegistersOnFirstAdd() {
120         val receiverData = ReceiverData(receiver1, IntentFilter(ACTION1), directExecutor, USER)
121 
122         actionReceiver.addReceiverData(receiverData)
123 
124         assertTrue(actionReceiver.registered)
125         verify(registerFunction).invoke(sameNotNull(actionReceiver), capture(intentFilterCaptor))
126 
127         assertTrue(IntentFilter(ACTION1).matchesOther(intentFilterCaptor.value))
128     }
129 
130     @Test
testRegistersOnlyOncenull131     fun testRegistersOnlyOnce() {
132         val receiverData1 = ReceiverData(receiver1, IntentFilter(ACTION1), directExecutor, USER)
133         val receiverData2 = ReceiverData(receiver2, IntentFilter(ACTION1), directExecutor, USER)
134 
135         actionReceiver.addReceiverData(receiverData1)
136         actionReceiver.addReceiverData(receiverData2)
137 
138         verify(registerFunction).invoke(sameNotNull(actionReceiver), any(IntentFilter::class.java))
139     }
140 
141     @Test
testRemovingLastReceiverUnregistersnull142     fun testRemovingLastReceiverUnregisters() {
143         val receiverData = ReceiverData(receiver1, IntentFilter(ACTION1), directExecutor, USER)
144 
145         actionReceiver.addReceiverData(receiverData)
146 
147         actionReceiver.removeReceiver(receiver1)
148 
149         assertFalse(actionReceiver.registered)
150         verify(unregisterFunction).invoke(sameNotNull(actionReceiver))
151     }
152 
153     @Test
testRemovingWhileOtherReceiversDoesntUnregisternull154     fun testRemovingWhileOtherReceiversDoesntUnregister() {
155         val receiverData1 = ReceiverData(receiver1, IntentFilter(ACTION1), directExecutor, USER)
156         val receiverData2 = ReceiverData(receiver2, IntentFilter(ACTION1), directExecutor, USER)
157 
158         actionReceiver.addReceiverData(receiverData1)
159         actionReceiver.addReceiverData(receiverData2)
160 
161         actionReceiver.removeReceiver(receiver1)
162 
163         assertTrue(actionReceiver.registered)
164         verify(unregisterFunction, never()).invoke(any(BroadcastReceiver::class.java))
165     }
166 
167     @Test
testReceiverHasCategoriesnull168     fun testReceiverHasCategories() {
169         val filter = IntentFilter(ACTION1)
170         filter.addCategory(CATEGORY)
171 
172         val receiverData = ReceiverData(receiver1, filter, directExecutor, USER)
173 
174         actionReceiver.addReceiverData(receiverData)
175 
176         verify(registerFunction).invoke(sameNotNull(actionReceiver), capture(intentFilterCaptor))
177         assertTrue(intentFilterCaptor.value.hasCategory(CATEGORY))
178     }
179 
180     @Test(expected = IllegalArgumentException::class)
testNotRegisteredWithWrongAction_throwsExceptionnull181     fun testNotRegisteredWithWrongAction_throwsException() {
182         val receiverData = ReceiverData(receiver1, IntentFilter(ACTION2), directExecutor, USER)
183 
184         actionReceiver.addReceiverData(receiverData)
185     }
186 
187     @Test
testReceiverGetsBroadcastnull188     fun testReceiverGetsBroadcast() {
189         val receiverData = ReceiverData(receiver1, IntentFilter(ACTION1), directExecutor, USER)
190         actionReceiver.addReceiverData(receiverData)
191 
192         val intent = Intent(ACTION1)
193 
194         actionReceiver.onReceive(mContext, intent)
195 
196         executor.runAllReady()
197 
198         verify(receiver1).onReceive(any(Context::class.java), sameNotNull(intent))
199     }
200 
201     @Test
testReceiverGetsPendingResultnull202     fun testReceiverGetsPendingResult() {
203         val receiverData = ReceiverData(receiver1, IntentFilter(ACTION1), directExecutor, USER)
204         actionReceiver.addReceiverData(receiverData)
205 
206         val intent = Intent(ACTION1)
207         val pendingResult = mock(BroadcastReceiver.PendingResult::class.java)
208 
209         actionReceiver.pendingResult = pendingResult
210         actionReceiver.onReceive(mContext, intent)
211 
212         executor.runAllReady()
213         verify(receiver1).pendingResult = pendingResult
214     }
215 
216     @Test
testBroadcastIsDispatchedInExecutornull217     fun testBroadcastIsDispatchedInExecutor() {
218         val executor = FakeExecutor(FakeSystemClock())
219         val receiverData = ReceiverData(receiver1, IntentFilter(ACTION1), executor, USER)
220         actionReceiver.addReceiverData(receiverData)
221 
222         val intent = Intent(ACTION1)
223         actionReceiver.onReceive(mContext, intent)
224 
225         this.executor.runAllReady()
226 
227         verify(receiver1, never()).onReceive(mContext, intent)
228 
229         executor.runAllReady()
230         // Dispatched after executor is processed
231         verify(receiver1).onReceive(mContext, intent)
232     }
233 
234     @Test
testBroadcastReceivedDispatched_loggernull235     fun testBroadcastReceivedDispatched_logger() {
236         val receiverData = ReceiverData(receiver1, IntentFilter(ACTION1), directExecutor, USER)
237 
238         actionReceiver.addReceiverData(receiverData)
239 
240         val intent = Intent(ACTION1)
241         actionReceiver.onReceive(mContext, intent)
242         verify(logger).logBroadcastReceived(anyInt(), eq(USER.identifier), eq(intent))
243 
244         verify(logger, never()).logBroadcastDispatched(anyInt(), anyString(),
245                 any(BroadcastReceiver::class.java))
246 
247         executor.runAllReady()
248 
249         verify(logger).logBroadcastDispatched(anyInt(), eq(ACTION1), sameNotNull(receiver1))
250     }
251 
252     @Test(expected = IllegalStateException::class)
testBroadcastWithWrongAction_throwsExceptionnull253     fun testBroadcastWithWrongAction_throwsException() {
254         actionReceiver.onReceive(mContext, Intent(ACTION2))
255     }
256 }