1 /* 2 * Copyright (C) 2016 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.server.telecom.tests; 18 19 import static android.media.AudioDeviceInfo.TYPE_BUILTIN_SPEAKER; 20 21 import static org.junit.Assert.assertEquals; 22 import static org.junit.Assert.assertFalse; 23 import static org.junit.Assert.assertNull; 24 import static org.junit.Assert.assertTrue; 25 import static org.mockito.ArgumentMatchers.isNull; 26 import static org.mockito.ArgumentMatchers.nullable; 27 import static org.mockito.ArgumentMatchers.any; 28 import static org.mockito.ArgumentMatchers.eq; 29 import static org.mockito.Mockito.atLeastOnce; 30 import static org.mockito.Mockito.mock; 31 import static org.mockito.Mockito.never; 32 import static org.mockito.Mockito.times; 33 import static org.mockito.Mockito.verify; 34 import static org.mockito.Mockito.when; 35 36 import android.bluetooth.BluetoothAdapter; 37 import android.bluetooth.BluetoothDevice; 38 import android.bluetooth.BluetoothHeadset; 39 import android.bluetooth.BluetoothHearingAid; 40 import android.bluetooth.BluetoothLeAudio; 41 import android.bluetooth.BluetoothProfile; 42 import android.content.Intent; 43 import android.media.AudioDeviceInfo; 44 import android.media.AudioManager; 45 import android.os.Bundle; 46 import android.os.Parcel; 47 48 import androidx.test.filters.SmallTest; 49 50 import com.android.server.telecom.CallAudioCommunicationDeviceTracker; 51 import com.android.server.telecom.bluetooth.BluetoothDeviceManager; 52 import com.android.server.telecom.bluetooth.BluetoothRouteManager; 53 import com.android.server.telecom.bluetooth.BluetoothStateReceiver; 54 55 import org.junit.After; 56 import org.junit.Before; 57 import org.junit.Test; 58 import org.junit.runner.RunWith; 59 import org.junit.runners.JUnit4; 60 import org.mockito.ArgumentCaptor; 61 import org.mockito.Mock; 62 63 import static org.mockito.Mockito.reset; 64 import java.util.ArrayList; 65 import java.util.Arrays; 66 import java.util.List; 67 import java.util.concurrent.Executor; 68 69 @RunWith(JUnit4.class) 70 public class BluetoothDeviceManagerTest extends TelecomTestCase { 71 private static final String DEVICE_ADDRESS_1 = "00:00:00:00:00:01"; 72 73 @Mock BluetoothRouteManager mRouteManager; 74 @Mock BluetoothHeadset mBluetoothHeadset; 75 @Mock BluetoothAdapter mAdapter; 76 @Mock BluetoothHearingAid mBluetoothHearingAid; 77 @Mock BluetoothLeAudio mBluetoothLeAudio; 78 @Mock AudioManager mockAudioManager; 79 @Mock AudioDeviceInfo mSpeakerInfo; 80 @Mock Executor mExecutor; 81 82 BluetoothDeviceManager mBluetoothDeviceManager; 83 BluetoothProfile.ServiceListener serviceListenerUnderTest; 84 BluetoothStateReceiver receiverUnderTest; 85 CallAudioCommunicationDeviceTracker mCommunicationDeviceTracker; 86 ArgumentCaptor<BluetoothLeAudio.Callback> leAudioCallbacksTest; 87 88 private BluetoothDevice device1; 89 private BluetoothDevice device2; 90 private BluetoothDevice device3; 91 private BluetoothDevice device4; 92 private BluetoothDevice device5; 93 private BluetoothDevice device6; 94 95 @Override 96 @Before setUp()97 public void setUp() throws Exception { 98 super.setUp(); 99 device1 = makeBluetoothDevice("00:00:00:00:00:01"); 100 // hearing aid 101 device2 = makeBluetoothDevice("00:00:00:00:00:02"); 102 device3 = makeBluetoothDevice("00:00:00:00:00:03"); 103 // hearing aid 104 device4 = makeBluetoothDevice("00:00:00:00:00:04"); 105 // le audio 106 device5 = makeBluetoothDevice("00:00:00:00:00:05"); 107 device6 = makeBluetoothDevice("00:00:00:00:00:06"); 108 109 when(mBluetoothHearingAid.getHiSyncId(device2)).thenReturn(100L); 110 when(mBluetoothHearingAid.getHiSyncId(device4)).thenReturn(100L); 111 112 mContext = mComponentContextFixture.getTestDouble().getApplicationContext(); 113 mCommunicationDeviceTracker = new CallAudioCommunicationDeviceTracker(mContext); 114 mBluetoothDeviceManager = new BluetoothDeviceManager(mContext, mAdapter, 115 mCommunicationDeviceTracker, mFeatureFlags); 116 mBluetoothDeviceManager.setBluetoothRouteManager(mRouteManager); 117 mCommunicationDeviceTracker.setBluetoothRouteManager(mRouteManager); 118 119 mockAudioManager = mContext.getSystemService(AudioManager.class); 120 mExecutor = mContext.getMainExecutor(); 121 122 ArgumentCaptor<BluetoothProfile.ServiceListener> serviceCaptor = 123 ArgumentCaptor.forClass(BluetoothProfile.ServiceListener.class); 124 verify(mAdapter).getProfileProxy(eq(mContext), 125 serviceCaptor.capture(), eq(BluetoothProfile.HEADSET)); 126 serviceListenerUnderTest = serviceCaptor.getValue(); 127 128 receiverUnderTest = new BluetoothStateReceiver(mBluetoothDeviceManager, 129 mRouteManager, mCommunicationDeviceTracker, mFeatureFlags); 130 131 mBluetoothDeviceManager.setHeadsetServiceForTesting(mBluetoothHeadset); 132 mBluetoothDeviceManager.setHearingAidServiceForTesting(mBluetoothHearingAid); 133 134 leAudioCallbacksTest = 135 ArgumentCaptor.forClass(BluetoothLeAudio.Callback.class); 136 mBluetoothDeviceManager.setLeAudioServiceForTesting(mBluetoothLeAudio); 137 verify(mBluetoothLeAudio).registerCallback(any(), leAudioCallbacksTest.capture()); 138 139 when(mSpeakerInfo.getType()).thenReturn(TYPE_BUILTIN_SPEAKER); 140 when(mFeatureFlags.callAudioCommunicationDeviceRefactor()).thenReturn(false); 141 } 142 143 @Override 144 @After tearDown()145 public void tearDown() throws Exception { 146 super.tearDown(); 147 } 148 149 @SmallTest 150 @Test testSingleDeviceConnectAndDisconnect()151 public void testSingleDeviceConnectAndDisconnect() { 152 receiverUnderTest.onReceive(mContext, 153 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device1, 154 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 155 assertEquals(1, mBluetoothDeviceManager.getNumConnectedDevices()); 156 receiverUnderTest.onReceive(mContext, 157 buildConnectionActionIntent(BluetoothHeadset.STATE_DISCONNECTED, device1, 158 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 159 assertEquals(0, mBluetoothDeviceManager.getNumConnectedDevices()); 160 } 161 162 @SmallTest 163 @Test testAddDeviceFailsWhenServicesAreNull()164 public void testAddDeviceFailsWhenServicesAreNull() { 165 mBluetoothDeviceManager.setHeadsetServiceForTesting(null); 166 mBluetoothDeviceManager.setHearingAidServiceForTesting(null); 167 168 receiverUnderTest.onReceive(mContext, 169 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device1, 170 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 171 receiverUnderTest.onReceive(mContext, 172 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device2, 173 BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID)); 174 receiverUnderTest.onReceive(mContext, 175 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, 176 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 177 178 assertEquals(0, mBluetoothDeviceManager.getNumConnectedDevices()); 179 } 180 181 @SmallTest 182 @Test testMultiDeviceConnectAndDisconnect()183 public void testMultiDeviceConnectAndDisconnect() { 184 receiverUnderTest.onReceive(mContext, 185 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device1, 186 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 187 receiverUnderTest.onReceive(mContext, 188 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device2, 189 BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID)); 190 receiverUnderTest.onReceive(mContext, 191 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, 192 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 193 leAudioCallbacksTest.getValue().onGroupNodeAdded(device5, 1); 194 when(mBluetoothLeAudio.getGroupId(device5)).thenReturn(1); 195 when(mBluetoothLeAudio.getConnectedGroupLeadDevice(1)).thenReturn(device5); 196 197 receiverUnderTest.onReceive(mContext, 198 buildConnectionActionIntent(BluetoothHeadset.STATE_DISCONNECTED, device1, 199 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 200 receiverUnderTest.onReceive(mContext, 201 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device6, 202 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 203 leAudioCallbacksTest.getValue().onGroupNodeAdded(device6, 2); 204 when(mBluetoothLeAudio.getConnectedGroupLeadDevice(2)).thenReturn(device6); 205 when(mBluetoothLeAudio.getGroupId(device6)).thenReturn(1); 206 receiverUnderTest.onReceive(mContext, 207 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device3, 208 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 209 receiverUnderTest.onReceive(mContext, 210 buildConnectionActionIntent(BluetoothHeadset.STATE_DISCONNECTED, device5, 211 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 212 assertEquals(3, mBluetoothDeviceManager.getNumConnectedDevices()); 213 receiverUnderTest.onReceive(mContext, 214 buildConnectionActionIntent(BluetoothHeadset.STATE_DISCONNECTED, device3, 215 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 216 receiverUnderTest.onReceive(mContext, 217 buildConnectionActionIntent(BluetoothHeadset.STATE_DISCONNECTED, device6, 218 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 219 assertEquals(1, mBluetoothDeviceManager.getNumConnectedDevices()); 220 } 221 222 @SmallTest 223 @Test testLeAudioMissedGroupCallbackBeforeConnected()224 public void testLeAudioMissedGroupCallbackBeforeConnected() { 225 /* This should be called on connection state changed */ 226 when(mBluetoothLeAudio.getGroupId(device5)).thenReturn(1); 227 when(mBluetoothLeAudio.getGroupId(device6)).thenReturn(1); 228 229 receiverUnderTest.onReceive(mContext, 230 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, 231 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 232 receiverUnderTest.onReceive(mContext, 233 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device6, 234 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 235 when(mBluetoothLeAudio.getConnectedGroupLeadDevice(1)).thenReturn(device5); 236 assertEquals(1, mBluetoothDeviceManager.getNumConnectedDevices()); 237 assertEquals(1, mBluetoothDeviceManager.getUniqueConnectedDevices().size()); 238 } 239 240 @SmallTest 241 @Test testLeAudioGroupAvailableBeforeConnect()242 public void testLeAudioGroupAvailableBeforeConnect() { 243 /* Device is known (e.g. from storage) */ 244 leAudioCallbacksTest.getValue().onGroupNodeAdded(device5, 1); 245 leAudioCallbacksTest.getValue().onGroupNodeAdded(device6, 1); 246 /* Make sure getGroupId is not called for known devices */ 247 verify(mBluetoothLeAudio, never()).getGroupId(device5); 248 verify(mBluetoothLeAudio, never()).getGroupId(device6); 249 250 receiverUnderTest.onReceive(mContext, 251 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, 252 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 253 receiverUnderTest.onReceive(mContext, 254 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device6, 255 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 256 when(mBluetoothLeAudio.getConnectedGroupLeadDevice(1)).thenReturn(device5); 257 assertEquals(1, mBluetoothDeviceManager.getNumConnectedDevices()); 258 assertEquals(1, mBluetoothDeviceManager.getUniqueConnectedDevices().size()); 259 } 260 261 @SmallTest 262 @Test testHearingAidDedup()263 public void testHearingAidDedup() { 264 receiverUnderTest.onReceive(mContext, 265 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device1, 266 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 267 receiverUnderTest.onReceive(mContext, 268 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device2, 269 BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID)); 270 receiverUnderTest.onReceive(mContext, 271 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device4, 272 BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID)); 273 assertEquals(3, mBluetoothDeviceManager.getNumConnectedDevices()); 274 assertEquals(2, mBluetoothDeviceManager.getUniqueConnectedDevices().size()); 275 } 276 277 @SmallTest 278 @Test testLeAudioDedup()279 public void testLeAudioDedup() { 280 receiverUnderTest.onReceive(mContext, 281 buildConnectionActionIntent(BluetoothProfile.STATE_CONNECTED, device1, 282 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 283 receiverUnderTest.onReceive(mContext, 284 buildConnectionActionIntent(BluetoothProfile.STATE_CONNECTED, device5, 285 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 286 leAudioCallbacksTest.getValue().onGroupNodeAdded(device5, 1); 287 receiverUnderTest.onReceive(mContext, 288 buildConnectionActionIntent(BluetoothProfile.STATE_CONNECTED, device6, 289 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 290 leAudioCallbacksTest.getValue().onGroupNodeAdded(device6, 1); 291 when(mBluetoothLeAudio.getConnectedGroupLeadDevice(1)).thenReturn(device5); 292 when(mBluetoothLeAudio.getGroupId(device5)).thenReturn(1); 293 when(mBluetoothLeAudio.getGroupId(device6)).thenReturn(1); 294 assertEquals(2, mBluetoothDeviceManager.getNumConnectedDevices()); 295 assertEquals(2, mBluetoothDeviceManager.getUniqueConnectedDevices().size()); 296 } 297 298 @SmallTest 299 @Test testHeadsetServiceDisconnect()300 public void testHeadsetServiceDisconnect() { 301 receiverUnderTest.onReceive(mContext, 302 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device1, 303 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 304 receiverUnderTest.onReceive(mContext, 305 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device3, 306 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 307 receiverUnderTest.onReceive(mContext, 308 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device2, 309 BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID)); 310 serviceListenerUnderTest.onServiceDisconnected(BluetoothProfile.HEADSET); 311 312 verify(mRouteManager).onActiveDeviceChanged(isNull(), 313 eq(BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 314 verify(mRouteManager).onDeviceLost(device1.getAddress()); 315 verify(mRouteManager).onDeviceLost(device3.getAddress()); 316 verify(mRouteManager, never()).onDeviceLost(device2.getAddress()); 317 assertNull(mBluetoothDeviceManager.getBluetoothHeadset()); 318 assertEquals(1, mBluetoothDeviceManager.getNumConnectedDevices()); 319 } 320 321 @SmallTest 322 @Test testHearingAidServiceDisconnect()323 public void testHearingAidServiceDisconnect() { 324 receiverUnderTest.onReceive(mContext, 325 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device1, 326 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 327 receiverUnderTest.onReceive(mContext, 328 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device3, 329 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 330 receiverUnderTest.onReceive(mContext, 331 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device2, 332 BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID)); 333 serviceListenerUnderTest.onServiceDisconnected(BluetoothProfile.HEARING_AID); 334 335 verify(mRouteManager).onActiveDeviceChanged(isNull(), 336 eq(BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID)); 337 verify(mRouteManager).onDeviceLost(device2.getAddress()); 338 verify(mRouteManager, never()).onDeviceLost(device1.getAddress()); 339 verify(mRouteManager, never()).onDeviceLost(device3.getAddress()); 340 assertNull(mBluetoothDeviceManager.getBluetoothHearingAid()); 341 assertEquals(2, mBluetoothDeviceManager.getNumConnectedDevices()); 342 } 343 344 @SmallTest 345 @Test testLeAudioServiceDisconnect()346 public void testLeAudioServiceDisconnect() { 347 receiverUnderTest.onReceive(mContext, 348 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device1, 349 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 350 receiverUnderTest.onReceive(mContext, 351 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device3, 352 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 353 receiverUnderTest.onReceive(mContext, 354 buildConnectionActionIntent(BluetoothLeAudio.STATE_CONNECTED, device5, 355 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 356 serviceListenerUnderTest.onServiceDisconnected(BluetoothProfile.LE_AUDIO); 357 358 verify(mRouteManager).onActiveDeviceChanged(isNull(), 359 eq(BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 360 verify(mRouteManager).onDeviceLost(device5.getAddress()); 361 verify(mRouteManager, never()).onDeviceLost(device1.getAddress()); 362 verify(mRouteManager, never()).onDeviceLost(device3.getAddress()); 363 assertNull(mBluetoothDeviceManager.getLeAudioService()); 364 assertEquals(2, mBluetoothDeviceManager.getNumConnectedDevices()); 365 } 366 367 @SmallTest 368 @Test testHearingAidChangesIgnoredWhenNotInCall()369 public void testHearingAidChangesIgnoredWhenNotInCall() { 370 receiverUnderTest.setIsInCall(false); 371 receiverUnderTest.onReceive(mContext, 372 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device2, 373 BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID)); 374 Intent activeDeviceChangedIntent = 375 new Intent(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED); 376 activeDeviceChangedIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device2); 377 receiverUnderTest.onReceive(mContext, activeDeviceChangedIntent); 378 379 verify(mRouteManager).onActiveDeviceChanged(device2, 380 BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID); 381 verify(mRouteManager, never()).sendMessage(BluetoothRouteManager.BT_AUDIO_IS_ON); 382 } 383 384 @SmallTest 385 @Test testLeAudioGroupChangesIgnoredWhenNotInCall()386 public void testLeAudioGroupChangesIgnoredWhenNotInCall() { 387 receiverUnderTest.setIsInCall(false); 388 receiverUnderTest.onReceive(mContext, 389 buildConnectionActionIntent(BluetoothLeAudio.STATE_CONNECTED, device5, 390 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 391 Intent activeDeviceChangedIntent = 392 new Intent(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED); 393 activeDeviceChangedIntent.putExtra(BluetoothDevice.EXTRA_DEVICE, device5); 394 receiverUnderTest.onReceive(mContext, activeDeviceChangedIntent); 395 396 verify(mRouteManager).onActiveDeviceChanged(device5, 397 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO); 398 verify(mRouteManager, never()).sendMessage(BluetoothRouteManager.BT_AUDIO_IS_ON); 399 } 400 401 @SmallTest 402 @Test testConnectDisconnectAudioHeadset()403 public void testConnectDisconnectAudioHeadset() { 404 receiverUnderTest.onReceive(mContext, 405 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device1, 406 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 407 when(mAdapter.setActiveDevice(nullable(BluetoothDevice.class), 408 eq(BluetoothAdapter.ACTIVE_DEVICE_ALL))).thenReturn(true); 409 mBluetoothDeviceManager.connectAudio(device1.getAddress(), false); 410 verify(mAdapter).setActiveDevice(eq(device1), 411 eq(BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL)); 412 verify(mAdapter, never()).setActiveDevice(nullable(BluetoothDevice.class), 413 eq(BluetoothAdapter.ACTIVE_DEVICE_ALL)); 414 mBluetoothDeviceManager.disconnectAudio(); 415 verify(mBluetoothHeadset).disconnectAudio(); 416 } 417 418 @SmallTest 419 @Test testConnectDisconnectAudioHearingAid()420 public void testConnectDisconnectAudioHearingAid() { 421 receiverUnderTest.setIsInCall(true); 422 receiverUnderTest.onReceive(mContext, 423 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, 424 BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID)); 425 leAudioCallbacksTest.getValue().onGroupNodeAdded(device5, 1); 426 when(mAdapter.setActiveDevice(nullable(BluetoothDevice.class), 427 eq(BluetoothAdapter.ACTIVE_DEVICE_ALL))).thenReturn(true); 428 429 AudioDeviceInfo mockAudioDeviceInfo = createMockAudioDeviceInfo(device5.getAddress(), 430 AudioDeviceInfo.TYPE_HEARING_AID); 431 List<AudioDeviceInfo> devices = new ArrayList<>(); 432 devices.add(mockAudioDeviceInfo); 433 434 when(mockAudioManager.getAvailableCommunicationDevices()) 435 .thenReturn(devices); 436 when(mockAudioManager.setCommunicationDevice(eq(mockAudioDeviceInfo))) 437 .thenReturn(true); 438 439 mBluetoothDeviceManager.connectAudio(device5.getAddress(), false); 440 verify(mAdapter).setActiveDevice(device5, BluetoothAdapter.ACTIVE_DEVICE_ALL); 441 verify(mBluetoothHeadset, never()).connectAudio(); 442 verify(mAdapter, never()).setActiveDevice(nullable(BluetoothDevice.class), 443 eq(BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL)); 444 445 receiverUnderTest.onReceive(mContext, buildActiveDeviceChangeActionIntent(device5, 446 BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID)); 447 448 when(mockAudioManager.getCommunicationDevice()).thenReturn(mockAudioDeviceInfo); 449 mBluetoothDeviceManager.disconnectAudio(); 450 verify(mockAudioManager, atLeastOnce()).clearCommunicationDevice(); 451 } 452 453 @SmallTest 454 @Test testConnectDisconnectAudioLeAudio()455 public void testConnectDisconnectAudioLeAudio() { 456 receiverUnderTest.setIsInCall(true); 457 receiverUnderTest.onReceive(mContext, 458 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, 459 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 460 leAudioCallbacksTest.getValue().onGroupNodeAdded(device5, 1); 461 when(mAdapter.setActiveDevice(nullable(BluetoothDevice.class), 462 eq(BluetoothAdapter.ACTIVE_DEVICE_ALL))).thenReturn(true); 463 464 AudioDeviceInfo mockAudioDeviceInfo = createMockAudioDeviceInfo(device5.getAddress(), 465 AudioDeviceInfo.TYPE_BLE_HEADSET); 466 List<AudioDeviceInfo> devices = new ArrayList<>(); 467 devices.add(mockAudioDeviceInfo); 468 469 when(mockAudioManager.getAvailableCommunicationDevices()) 470 .thenReturn(devices); 471 when(mockAudioManager.setCommunicationDevice(mockAudioDeviceInfo)) 472 .thenReturn(true); 473 474 mBluetoothDeviceManager.connectAudio(device5.getAddress(), false); 475 verify(mAdapter).setActiveDevice(device5, BluetoothAdapter.ACTIVE_DEVICE_ALL); 476 verify(mBluetoothHeadset, never()).connectAudio(); 477 verify(mAdapter, never()).setActiveDevice(nullable(BluetoothDevice.class), 478 eq(BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL)); 479 verify(mAdapter, never()).setActiveDevice(nullable(BluetoothDevice.class), 480 eq(BluetoothAdapter.ACTIVE_DEVICE_AUDIO)); 481 482 receiverUnderTest.onReceive(mContext, buildActiveDeviceChangeActionIntent(device5, 483 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 484 485 mBluetoothDeviceManager.disconnectAudio(); 486 verify(mockAudioManager, atLeastOnce()).clearCommunicationDevice(); 487 } 488 489 @SmallTest 490 @Test testConnectEarbudLeAudio()491 public void testConnectEarbudLeAudio() { 492 receiverUnderTest.setIsInCall(true); 493 receiverUnderTest.onReceive(mContext, 494 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, 495 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 496 leAudioCallbacksTest.getValue().onGroupNodeAdded(device5, 1); 497 receiverUnderTest.onReceive(mContext, 498 buildConnectionActionIntent(BluetoothLeAudio.STATE_CONNECTED, device6, 499 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 500 leAudioCallbacksTest.getValue().onGroupNodeAdded(device6, 1); 501 when(mAdapter.setActiveDevice(nullable(BluetoothDevice.class), 502 eq(BluetoothAdapter.ACTIVE_DEVICE_ALL))).thenReturn(true); 503 mBluetoothDeviceManager.connectAudio(device5.getAddress(), false); 504 verify(mAdapter).setActiveDevice(device5, BluetoothAdapter.ACTIVE_DEVICE_ALL); 505 verify(mBluetoothHeadset, never()).connectAudio(); 506 verify(mAdapter, never()).setActiveDevice(nullable(BluetoothDevice.class), 507 eq(BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL)); 508 verify(mAdapter, never()).setActiveDevice(nullable(BluetoothDevice.class), 509 eq(BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL)); 510 511 when(mAdapter.getActiveDevices(eq(BluetoothProfile.LE_AUDIO))) 512 .thenReturn(Arrays.asList(device5, device6)); 513 514 receiverUnderTest.onReceive(mContext, 515 buildConnectionActionIntent(BluetoothHeadset.STATE_DISCONNECTED, device5, 516 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 517 518 mBluetoothDeviceManager.connectAudio(device6.getAddress(), false); 519 verify(mAdapter).setActiveDevice(device6, BluetoothAdapter.ACTIVE_DEVICE_ALL); 520 } 521 522 @SmallTest 523 @Test testConnectMultipleLeAudioDevices()524 public void testConnectMultipleLeAudioDevices() { 525 when(mFeatureFlags.callAudioCommunicationDeviceRefactor()).thenReturn(true); 526 receiverUnderTest.setIsInCall(true); 527 receiverUnderTest.onReceive(mContext, 528 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device1, 529 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 530 leAudioCallbacksTest.getValue().onGroupNodeAdded(device1, 1); 531 receiverUnderTest.onReceive(mContext, 532 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device2, 533 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 534 leAudioCallbacksTest.getValue().onGroupNodeAdded(device2, 1); 535 when(mAdapter.setActiveDevice(nullable(BluetoothDevice.class), 536 eq(BluetoothAdapter.ACTIVE_DEVICE_ALL))).thenReturn(true); 537 538 List<AudioDeviceInfo> devices = new ArrayList<>(); 539 AudioDeviceInfo leAudioDevice1 = createMockAudioDeviceInfo(device1.getAddress(), 540 AudioDeviceInfo.TYPE_BLE_HEADSET); 541 AudioDeviceInfo leAudioDevice2 = createMockAudioDeviceInfo(device2.getAddress(), 542 AudioDeviceInfo.TYPE_BLE_HEADSET); 543 devices.add(leAudioDevice1); 544 devices.add(leAudioDevice2); 545 546 when(mockAudioManager.getAvailableCommunicationDevices()) 547 .thenReturn(devices); 548 when(mockAudioManager.setCommunicationDevice(any(AudioDeviceInfo.class))) 549 .thenReturn(true); 550 551 // Connect LE audio device 552 mBluetoothDeviceManager.connectAudio(device1.getAddress(), false); 553 verify(mAdapter).setActiveDevice(device1, BluetoothAdapter.ACTIVE_DEVICE_ALL); 554 verify(mBluetoothHeadset, never()).connectAudio(); 555 verify(mAdapter, never()).setActiveDevice(nullable(BluetoothDevice.class), 556 eq(BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL)); 557 // Verify that we set the communication device for device 1 558 verify(mockAudioManager).setCommunicationDevice(leAudioDevice1); 559 560 // Change active device to other LE audio device 561 receiverUnderTest.onReceive(mContext, buildActiveDeviceChangeActionIntent(device2, 562 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 563 564 // Verify call to clearLeAudioCommunicationDevice 565 verify(mRouteManager).onAudioLost(eq(DEVICE_ADDRESS_1)); 566 // Verify that we set the communication device for device2 567 verify(mockAudioManager).setCommunicationDevice(leAudioDevice2); 568 } 569 570 @SmallTest 571 @Test testClearCommunicationDeviceOnActiveDeviceChange()572 public void testClearCommunicationDeviceOnActiveDeviceChange() { 573 when(mFeatureFlags.callAudioCommunicationDeviceRefactor()).thenReturn(true); 574 receiverUnderTest.setIsInCall(true); 575 576 List<AudioDeviceInfo> devices = new ArrayList<>(); 577 AudioDeviceInfo leAudioDevice1 = createMockAudioDeviceInfo(device1.getAddress(), 578 AudioDeviceInfo.TYPE_BLE_HEADSET); 579 devices.add(leAudioDevice1); 580 581 when(mockAudioManager.getAvailableCommunicationDevices()) 582 .thenReturn(devices); 583 when(mockAudioManager.setCommunicationDevice(any(AudioDeviceInfo.class))) 584 .thenReturn(true); 585 586 // Pretend that the speaker device is currently the requested device set for communication. 587 // This test ensures that the set/clear communication logic for audio switching in/out of BT 588 // is properly working when the receiver processes an active device change intent. 589 mCommunicationDeviceTracker.setTestCommunicationDevice(TYPE_BUILTIN_SPEAKER); 590 591 // Notify that LE audio device has been turned on 592 receiverUnderTest.onReceive(mContext, buildActiveDeviceChangeActionIntent(device1, 593 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 594 // Verify call to clear speaker communication device 595 verify(mockAudioManager).clearCommunicationDevice(); 596 // Verify that LE audio communication device was set after clearing the speaker device 597 verify(mockAudioManager).setCommunicationDevice(leAudioDevice1); 598 } 599 600 @SmallTest 601 @Test testConnectDualModeEarbud()602 public void testConnectDualModeEarbud() { 603 when(mFeatureFlags.callAudioCommunicationDeviceRefactor()).thenReturn(true); 604 receiverUnderTest.setIsInCall(true); 605 606 // LE Audio earbuds connected 607 receiverUnderTest.onReceive(mContext, 608 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, 609 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 610 leAudioCallbacksTest.getValue().onGroupNodeAdded(device5, 1); 611 receiverUnderTest.onReceive(mContext, 612 buildConnectionActionIntent(BluetoothLeAudio.STATE_CONNECTED, device6, 613 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 614 leAudioCallbacksTest.getValue().onGroupNodeAdded(device6, 1); 615 // HFP device connected 616 receiverUnderTest.onReceive(mContext, 617 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, 618 BluetoothDeviceManager.DEVICE_TYPE_HEADSET)); 619 when(mAdapter.setActiveDevice(nullable(BluetoothDevice.class), 620 eq(BluetoothAdapter.ACTIVE_DEVICE_ALL))).thenReturn(true); 621 622 AudioDeviceInfo mockAudioDevice5Info = createMockAudioDeviceInfo(device5.getAddress(), 623 AudioDeviceInfo.TYPE_BLE_HEADSET); 624 AudioDeviceInfo mockAudioDevice6Info = createMockAudioDeviceInfo(device6.getAddress(), 625 AudioDeviceInfo.TYPE_BLE_HEADSET); 626 when(mockAudioDevice5Info.getType()).thenReturn(AudioDeviceInfo.TYPE_BLE_HEADSET); 627 when(mockAudioDevice6Info.getType()).thenReturn(AudioDeviceInfo.TYPE_BLE_HEADSET); 628 List<AudioDeviceInfo> devices = new ArrayList<>(); 629 devices.add(mockAudioDevice5Info); 630 devices.add(mockAudioDevice6Info); 631 632 when(mockAudioManager.getAvailableCommunicationDevices()) 633 .thenReturn(devices); 634 when(mockAudioManager.setCommunicationDevice(mockAudioDevice5Info)) 635 .thenReturn(true); 636 637 Bundle hfpPreferred = new Bundle(); 638 hfpPreferred.putInt(BluetoothAdapter.AUDIO_MODE_DUPLEX, BluetoothProfile.HEADSET); 639 Bundle leAudioPreferred = new Bundle(); 640 leAudioPreferred.putInt(BluetoothAdapter.AUDIO_MODE_DUPLEX, BluetoothProfile.LE_AUDIO); 641 642 // TEST 1: LE Audio preferred for DUPLEX 643 when(mAdapter.getPreferredAudioProfiles(device5)).thenReturn(leAudioPreferred); 644 when(mAdapter.getPreferredAudioProfiles(device6)).thenReturn(leAudioPreferred); 645 mBluetoothDeviceManager.connectAudio(device5.getAddress(), false); 646 verify(mAdapter, times(1)).setActiveDevice(device5, BluetoothAdapter.ACTIVE_DEVICE_ALL); 647 verify(mBluetoothHeadset, never()).connectAudio(); 648 verify(mAdapter, never()).setActiveDevice(nullable(BluetoothDevice.class), 649 eq(BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL)); 650 verify(mockAudioManager).setCommunicationDevice(mockAudioDevice5Info); 651 652 when(mAdapter.getActiveDevices(eq(BluetoothProfile.LE_AUDIO))) 653 .thenReturn(Arrays.asList(device5, device6)); 654 655 // Check disconnect during a call 656 devices.remove(mockAudioDevice5Info); 657 receiverUnderTest.onReceive(mContext, 658 buildConnectionActionIntent(BluetoothHeadset.STATE_DISCONNECTED, device5, 659 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 660 leAudioCallbacksTest.getValue().onGroupNodeRemoved(device5, 1); 661 662 mBluetoothDeviceManager.connectAudio(device6.getAddress(), false); 663 verify(mAdapter).setActiveDevice(device6, BluetoothAdapter.ACTIVE_DEVICE_ALL); 664 verify(mBluetoothHeadset, never()).connectAudio(); 665 verify(mAdapter, never()).setActiveDevice(nullable(BluetoothDevice.class), 666 eq(BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL)); 667 verify(mockAudioManager, times(1)).clearCommunicationDevice(); 668 669 // Reconnect other LE Audio earbud 670 devices.add(mockAudioDevice5Info); 671 receiverUnderTest.onReceive(mContext, 672 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device5, 673 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 674 leAudioCallbacksTest.getValue().onGroupNodeAdded(device5, 1); 675 676 // Disconnects audio 677 mBluetoothDeviceManager.disconnectAudio(); 678 verify(mockAudioManager, times(2)).clearCommunicationDevice(); 679 verify(mBluetoothHeadset, times(1)).disconnectAudio(); 680 681 // TEST 2: HFP preferred for DUPLEX 682 when(mAdapter.getPreferredAudioProfiles(device5)).thenReturn(hfpPreferred); 683 when(mAdapter.getPreferredAudioProfiles(device6)).thenReturn(hfpPreferred); 684 when(mAdapter.setActiveDevice(nullable(BluetoothDevice.class), 685 eq(BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL))).thenReturn(true); 686 mBluetoothDeviceManager.connectAudio(device5.getAddress(), false); 687 verify(mAdapter).setActiveDevice(device5, BluetoothAdapter.ACTIVE_DEVICE_PHONE_CALL); 688 verify(mAdapter, times(1)).setActiveDevice(device5, 689 BluetoothAdapter.ACTIVE_DEVICE_ALL); 690 verify(mBluetoothHeadset).connectAudio(); 691 mBluetoothDeviceManager.disconnectAudio(); 692 verify(mBluetoothHeadset, times(2)).disconnectAudio(); 693 } 694 695 @SmallTest 696 @Test testClearHearingAidCommunicationDeviceLegacy()697 public void testClearHearingAidCommunicationDeviceLegacy() { 698 assertClearHearingAidOrLeCommunicationDevice(false, AudioDeviceInfo.TYPE_HEARING_AID); 699 } 700 701 @SmallTest 702 @Test testClearHearingAidCommunicationDeviceWithFlag()703 public void testClearHearingAidCommunicationDeviceWithFlag() { 704 when(mFeatureFlags.callAudioCommunicationDeviceRefactor()).thenReturn(true); 705 assertClearHearingAidOrLeCommunicationDevice(true, AudioDeviceInfo.TYPE_HEARING_AID); 706 } 707 708 @SmallTest 709 @Test testClearLeAudioCommunicationDeviceLegacy()710 public void testClearLeAudioCommunicationDeviceLegacy() { 711 assertClearHearingAidOrLeCommunicationDevice(false, AudioDeviceInfo.TYPE_BLE_HEADSET); 712 } 713 714 @SmallTest 715 @Test testClearLeAudioCommunicationDeviceWithFlag()716 public void testClearLeAudioCommunicationDeviceWithFlag() { 717 when(mFeatureFlags.callAudioCommunicationDeviceRefactor()).thenReturn(true); 718 assertClearHearingAidOrLeCommunicationDevice(true, AudioDeviceInfo.TYPE_BLE_HEADSET); 719 } 720 721 @SmallTest 722 @Test testConnectedDevicesDoNotContainDuplicateDevices()723 public void testConnectedDevicesDoNotContainDuplicateDevices() { 724 BluetoothDevice hfpDevice = mock(BluetoothDevice.class); 725 when(hfpDevice.getAddress()).thenReturn("00:00:00:00:00:00"); 726 when(hfpDevice.getType()).thenReturn(BluetoothDeviceManager.DEVICE_TYPE_HEADSET); 727 BluetoothDevice leDevice = mock(BluetoothDevice.class); 728 when(hfpDevice.getAddress()).thenReturn("00:00:00:00:00:00"); 729 when(hfpDevice.getType()).thenReturn(BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO); 730 731 mBluetoothDeviceManager.onDeviceConnected(hfpDevice, 732 BluetoothDeviceManager.DEVICE_TYPE_HEADSET); 733 mBluetoothDeviceManager.onDeviceConnected(leDevice, 734 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO); 735 736 assertEquals(1, mBluetoothDeviceManager.getNumConnectedDevices()); 737 } 738 739 @SmallTest 740 @Test testInBandRingingEnabledForLeDevice()741 public void testInBandRingingEnabledForLeDevice() { 742 when(mBluetoothHeadset.isInbandRingingEnabled()).thenReturn(false); 743 when(mBluetoothLeAudio.isInbandRingtoneEnabled(1)).thenReturn(true); 744 when(mBluetoothLeAudio.getGroupId(eq(device3))).thenReturn(1); 745 receiverUnderTest.onReceive(mContext, 746 buildConnectionActionIntent(BluetoothHeadset.STATE_CONNECTED, device3, 747 BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO)); 748 leAudioCallbacksTest.getValue().onGroupNodeAdded(device3, 1); 749 when(mRouteManager.getBluetoothAudioConnectedDevice()).thenReturn(device3); 750 when(mRouteManager.isCachedLeAudioDevice(eq(device3))).thenReturn(true); 751 when(mBluetoothLeAudio.getConnectedGroupLeadDevice(1)).thenReturn(device3); 752 when(mRouteManager.getMostRecentlyReportedActiveDevice()).thenReturn(device3); 753 assertEquals(1, mBluetoothDeviceManager.getNumConnectedDevices()); 754 assertTrue(mBluetoothDeviceManager.isInbandRingingEnabled()); 755 } 756 757 @SmallTest 758 @Test testRegisterLeAudioCallbackNoPostpone()759 public void testRegisterLeAudioCallbackNoPostpone() { 760 reset(mBluetoothLeAudio); 761 when(mFeatureFlags.postponeRegisterToLeaudio()).thenReturn(false); 762 serviceListenerUnderTest.onServiceConnected(BluetoothProfile.LE_AUDIO, 763 (BluetoothProfile) mBluetoothLeAudio); 764 // Second time on purpose 765 serviceListenerUnderTest.onServiceConnected(BluetoothProfile.LE_AUDIO, 766 (BluetoothProfile) mBluetoothLeAudio); 767 verify(mExecutor, times(0)).execute(any()); 768 verify(mBluetoothLeAudio, times(1)).registerCallback(any(Executor.class), 769 any(BluetoothLeAudio.Callback.class)); 770 } 771 772 @SmallTest 773 @Test testRegisterLeAudioCallbackWithPostpone()774 public void testRegisterLeAudioCallbackWithPostpone() { 775 reset(mBluetoothLeAudio); 776 when(mFeatureFlags.postponeRegisterToLeaudio()).thenReturn(true); 777 serviceListenerUnderTest.onServiceConnected(BluetoothProfile.LE_AUDIO, 778 (BluetoothProfile) mBluetoothLeAudio); 779 verify(mExecutor, times(1)).execute(any()); 780 } 781 assertClearHearingAidOrLeCommunicationDevice( boolean flagEnabled, int device_type )782 private void assertClearHearingAidOrLeCommunicationDevice( 783 boolean flagEnabled, int device_type 784 ) { 785 AudioDeviceInfo mockAudioDeviceInfo = mock(AudioDeviceInfo.class); 786 when(mockAudioDeviceInfo.getAddress()).thenReturn(DEVICE_ADDRESS_1); 787 when(mockAudioDeviceInfo.getType()).thenReturn(device_type); 788 List<AudioDeviceInfo> devices = new ArrayList<>(); 789 devices.add(mockAudioDeviceInfo); 790 791 when(mockAudioManager.getAvailableCommunicationDevices()) 792 .thenReturn(devices); 793 when(mockAudioManager.setCommunicationDevice(eq(mockAudioDeviceInfo))) 794 .thenReturn(true); 795 796 if (flagEnabled) { 797 BluetoothDevice btDevice = device_type == AudioDeviceInfo.TYPE_BLE_HEADSET 798 ? device1 : null; 799 mCommunicationDeviceTracker.setCommunicationDevice(device_type, btDevice); 800 } else { 801 if (device_type == AudioDeviceInfo.TYPE_BLE_HEADSET) { 802 mBluetoothDeviceManager.setLeAudioCommunicationDevice(); 803 } else { 804 mBluetoothDeviceManager.setHearingAidCommunicationDevice(); 805 } 806 } 807 when(mockAudioManager.getCommunicationDevice()).thenReturn(mSpeakerInfo); 808 if (flagEnabled) { 809 mCommunicationDeviceTracker.clearCommunicationDevice(device_type); 810 assertFalse(mCommunicationDeviceTracker.isAudioDeviceSetForType(device_type)); 811 } else { 812 if (device_type == AudioDeviceInfo.TYPE_BLE_HEADSET) { 813 mBluetoothDeviceManager.clearLeAudioCommunicationDevice(); 814 assertFalse(mBluetoothDeviceManager.isLeAudioCommunicationDevice()); 815 } else { 816 mBluetoothDeviceManager.clearHearingAidCommunicationDevice(); 817 assertFalse(mBluetoothDeviceManager.isHearingAidSetAsCommunicationDevice()); 818 } 819 } 820 verify(mRouteManager).onAudioLost(eq(DEVICE_ADDRESS_1)); 821 } 822 createMockAudioDeviceInfo(String address, int audioType)823 private AudioDeviceInfo createMockAudioDeviceInfo(String address, int audioType) { 824 AudioDeviceInfo mockAudioDeviceInfo = mock(AudioDeviceInfo.class); 825 when(mockAudioDeviceInfo.getType()).thenReturn(audioType); 826 if (address != null) { 827 when(mockAudioDeviceInfo.getAddress()).thenReturn(address); 828 } 829 return mockAudioDeviceInfo; 830 } 831 buildConnectionActionIntent(int state, BluetoothDevice device, int deviceType)832 private Intent buildConnectionActionIntent(int state, BluetoothDevice device, int deviceType) { 833 String intentString; 834 835 switch (deviceType) { 836 case BluetoothDeviceManager.DEVICE_TYPE_HEADSET: 837 intentString = BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED; 838 break; 839 case BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID: 840 intentString = BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED; 841 break; 842 case BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO: 843 intentString = BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED; 844 break; 845 default: 846 return null; 847 } 848 849 Intent i = new Intent(intentString); 850 i.putExtra(BluetoothHeadset.EXTRA_STATE, state); 851 i.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 852 return i; 853 } 854 855 buildActiveDeviceChangeActionIntent(BluetoothDevice device, int deviceType)856 private Intent buildActiveDeviceChangeActionIntent(BluetoothDevice device, int deviceType) { 857 String intentString; 858 859 switch (deviceType) { 860 case BluetoothDeviceManager.DEVICE_TYPE_HEADSET: 861 intentString = BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED; 862 break; 863 case BluetoothDeviceManager.DEVICE_TYPE_HEARING_AID: 864 intentString = BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED; 865 break; 866 case BluetoothDeviceManager.DEVICE_TYPE_LE_AUDIO: 867 intentString = BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED; 868 break; 869 default: 870 return null; 871 } 872 873 Intent i = new Intent(intentString); 874 i.putExtra(BluetoothDevice.EXTRA_DEVICE, device); 875 i.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT 876 | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); 877 return i; 878 } 879 makeBluetoothDevice(String address)880 private BluetoothDevice makeBluetoothDevice(String address) { 881 Parcel p1 = Parcel.obtain(); 882 p1.writeString(address); 883 p1.setDataPosition(0); 884 BluetoothDevice device = BluetoothDevice.CREATOR.createFromParcel(p1); 885 p1.recycle(); 886 return device; 887 } 888 } 889