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