1 package com.android.systemui.media.nearby
2 
3 import android.media.INearbyMediaDevicesProvider
4 import android.media.INearbyMediaDevicesUpdateCallback
5 import androidx.test.ext.junit.runners.AndroidJUnit4
6 import androidx.test.filters.SmallTest
7 import com.android.systemui.SysuiTestCase
8 import android.media.NearbyDevice
9 import android.os.IBinder
10 import com.android.systemui.statusbar.CommandQueue
11 import com.google.common.truth.Truth.assertThat
12 import org.junit.Before
13 import org.junit.Test
14 import org.junit.runner.RunWith
15 import org.mockito.ArgumentCaptor
16 import org.mockito.Mock
17 import org.mockito.Mockito.anyInt
18 import org.mockito.Mockito.never
19 import org.mockito.Mockito.reset
20 import org.mockito.Mockito.times
21 import org.mockito.Mockito.verify
22 import org.mockito.MockitoAnnotations
23 
24 @SmallTest
25 @RunWith(AndroidJUnit4::class)
26 class NearbyMediaDevicesManagerTest : SysuiTestCase() {
27 
28     private lateinit var manager: NearbyMediaDevicesManager
29     @Mock
30     private lateinit var logger: NearbyMediaDevicesLogger
31     @Mock
32     private lateinit var commandQueue: CommandQueue
33     private lateinit var commandQueueCallbacks: CommandQueue.Callbacks
34 
35     @Before
setUpnull36     fun setUp() {
37         MockitoAnnotations.initMocks(this)
38         manager = NearbyMediaDevicesManager(commandQueue, logger)
39         manager.start()
40 
41         val callbackCaptor = ArgumentCaptor.forClass(CommandQueue.Callbacks::class.java)
42         verify(commandQueue).addCallback(callbackCaptor.capture())
43         commandQueueCallbacks = callbackCaptor.value!!
44     }
45 
46     @Test
registerNearbyDevicesCallback_noProviderRegistered_noCrashnull47     fun registerNearbyDevicesCallback_noProviderRegistered_noCrash() {
48         // No assert, just needs no crash
49         manager.registerNearbyDevicesCallback(object : INearbyMediaDevicesUpdateCallback.Stub() {
50             override fun onDevicesUpdated(nearbyDevices: List<NearbyDevice>) {}
51         })
52     }
53 
54     @Test
registerNearbyDevicesCallback_providerRegistered_providerReceivesCallbacknull55     fun registerNearbyDevicesCallback_providerRegistered_providerReceivesCallback() {
56         val provider = TestProvider()
57         commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider)
58 
59         val callback = object : INearbyMediaDevicesUpdateCallback.Stub() {
60             override fun onDevicesUpdated(nearbyDevices: List<NearbyDevice>) {}
61         }
62 
63         manager.registerNearbyDevicesCallback(callback)
64 
65         assertThat(provider.lastRegisteredCallback).isEqualTo(callback)
66     }
67 
68     @Test
registerNearbyDevicesCallback_multipleProviders_allProvidersReceiveCallbacknull69     fun registerNearbyDevicesCallback_multipleProviders_allProvidersReceiveCallback() {
70         val provider1 = TestProvider()
71         val provider2 = TestProvider()
72         commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider1)
73         commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider2)
74 
75         val callback = object : INearbyMediaDevicesUpdateCallback.Stub() {
76             override fun onDevicesUpdated(nearbyDevices: List<NearbyDevice>) {}
77         }
78 
79         manager.registerNearbyDevicesCallback(callback)
80 
81         assertThat(provider1.lastRegisteredCallback).isEqualTo(callback)
82         assertThat(provider2.lastRegisteredCallback).isEqualTo(callback)
83     }
84 
85     @Test
unregisterNearbyDevicesCallback_noProviderRegistered_noCrashnull86     fun unregisterNearbyDevicesCallback_noProviderRegistered_noCrash() {
87         // No assert, just needs no crash
88         manager.unregisterNearbyDevicesCallback(object : INearbyMediaDevicesUpdateCallback.Stub() {
89             override fun onDevicesUpdated(nearbyDevices: List<NearbyDevice>) {}
90         })
91     }
92 
93     @Test
unregisterNearbyDevicesCallback_providerRegistered_providerReceivesCallbacknull94     fun unregisterNearbyDevicesCallback_providerRegistered_providerReceivesCallback() {
95         val provider = TestProvider()
96         commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider)
97 
98         val callback = object : INearbyMediaDevicesUpdateCallback.Stub() {
99             override fun onDevicesUpdated(nearbyDevices: List<NearbyDevice>) {}
100         }
101 
102         manager.unregisterNearbyDevicesCallback(callback)
103 
104         assertThat(provider.lastUnregisteredCallback).isEqualTo(callback)
105     }
106 
107     @Test
unregisterNearbyDevicesCallback_multipleProviders_allProvidersReceiveCallbacknull108     fun unregisterNearbyDevicesCallback_multipleProviders_allProvidersReceiveCallback() {
109         val provider1 = TestProvider()
110         val provider2 = TestProvider()
111         commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider1)
112         commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider2)
113 
114         val callback = object : INearbyMediaDevicesUpdateCallback.Stub() {
115             override fun onDevicesUpdated(nearbyDevices: List<NearbyDevice>) {}
116         }
117 
118         manager.unregisterNearbyDevicesCallback(callback)
119 
120         assertThat(provider1.lastUnregisteredCallback).isEqualTo(callback)
121         assertThat(provider2.lastUnregisteredCallback).isEqualTo(callback)
122     }
123 
124     @Test
newProviderRegisteredAfterCallbacksRegistered_providerGetsPreviouslyRegisteredCallbacksnull125     fun newProviderRegisteredAfterCallbacksRegistered_providerGetsPreviouslyRegisteredCallbacks() {
126         // Start off with an existing provider and callback
127         val provider1 = TestProvider()
128         commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider1)
129         val callback = object : INearbyMediaDevicesUpdateCallback.Stub() {
130             override fun onDevicesUpdated(nearbyDevices: List<NearbyDevice>) {}
131         }
132         manager.registerNearbyDevicesCallback(callback)
133 
134         // Add a new provider
135         val provider2 = TestProvider()
136         commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider2)
137 
138         // Verify the new provider received the previously-registered callbacks
139         assertThat(provider2.lastRegisteredCallback).isEqualTo(callback)
140     }
141 
142     @Test
providerUnregistered_doesNotReceiveNewCallbacknull143     fun providerUnregistered_doesNotReceiveNewCallback() {
144         val provider = TestProvider()
145         commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider)
146         commandQueueCallbacks.unregisterNearbyMediaDevicesProvider(provider)
147 
148         val callback = object : INearbyMediaDevicesUpdateCallback.Stub() {
149             override fun onDevicesUpdated(nearbyDevices: List<NearbyDevice>) {}
150         }
151         manager.registerNearbyDevicesCallback(callback)
152 
153         assertThat(provider.lastRegisteredCallback).isEqualTo(null)
154     }
155 
156     @Test
providerRegistered_isLoggednull157     fun providerRegistered_isLogged() {
158         commandQueueCallbacks.registerNearbyMediaDevicesProvider(TestProvider())
159 
160         verify(logger).logProviderRegistered(numProviders = 1)
161     }
162 
163     @Test
providerRegisteredTwice_onlyLoggedOncenull164     fun providerRegisteredTwice_onlyLoggedOnce() {
165         val provider = TestProvider()
166 
167         commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider)
168         commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider)
169 
170         verify(logger, times(1)).logProviderRegistered(numProviders = 1)
171     }
172 
173     @Test
multipleProvidersRegistered_isLoggednull174     fun multipleProvidersRegistered_isLogged() {
175         commandQueueCallbacks.registerNearbyMediaDevicesProvider(TestProvider())
176         commandQueueCallbacks.registerNearbyMediaDevicesProvider(TestProvider())
177         reset(logger)
178 
179         commandQueueCallbacks.registerNearbyMediaDevicesProvider(TestProvider())
180 
181         verify(logger).logProviderRegistered(numProviders = 3)
182     }
183 
184     @Test
providerUnregistered_isLoggednull185     fun providerUnregistered_isLogged() {
186         val provider = TestProvider()
187         commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider)
188 
189         commandQueueCallbacks.unregisterNearbyMediaDevicesProvider(provider)
190 
191         verify(logger).logProviderUnregistered(numProviders = 0)
192     }
193 
194     @Test
multipleProvidersRegisteredThenUnregistered_isLoggednull195     fun multipleProvidersRegisteredThenUnregistered_isLogged() {
196         val provider = TestProvider()
197         commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider)
198         commandQueueCallbacks.registerNearbyMediaDevicesProvider(TestProvider())
199         commandQueueCallbacks.registerNearbyMediaDevicesProvider(TestProvider())
200 
201         commandQueueCallbacks.unregisterNearbyMediaDevicesProvider(provider)
202 
203         verify(logger).logProviderUnregistered(numProviders = 2)
204     }
205 
206     @Test
providerUnregisteredButNeverRegistered_notLoggednull207     fun providerUnregisteredButNeverRegistered_notLogged() {
208         commandQueueCallbacks.unregisterNearbyMediaDevicesProvider(TestProvider())
209 
210         verify(logger, never()).logProviderRegistered(anyInt())
211     }
212 
213     @Test
providerBinderDied_isLoggednull214     fun providerBinderDied_isLogged() {
215         val provider = TestProvider()
216         commandQueueCallbacks.registerNearbyMediaDevicesProvider(provider)
217 
218         provider.deathRecipient!!.binderDied(provider)
219 
220         verify(logger).logProviderBinderDied(numProviders = 0)
221     }
222 
223     private class TestProvider : INearbyMediaDevicesProvider.Stub() {
224         var lastRegisteredCallback: INearbyMediaDevicesUpdateCallback? = null
225         var lastUnregisteredCallback: INearbyMediaDevicesUpdateCallback? = null
226         var deathRecipient: IBinder.DeathRecipient? = null
227 
registerNearbyDevicesCallbacknull228         override fun registerNearbyDevicesCallback(
229             callback: INearbyMediaDevicesUpdateCallback
230         ) {
231             lastRegisteredCallback = callback
232         }
233 
unregisterNearbyDevicesCallbacknull234         override fun unregisterNearbyDevicesCallback(
235             callback: INearbyMediaDevicesUpdateCallback
236         ) {
237             lastUnregisteredCallback = callback
238         }
239 
asBindernull240         override fun asBinder(): IBinder {
241             return this
242         }
243 
linkToDeathnull244         override fun linkToDeath(recipient: IBinder.DeathRecipient, flags: Int) {
245             deathRecipient = recipient
246         }
247     }
248 }
249