1 /* 2 * Copyright (C) 2018 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.settings.sound; 18 19 20 import static android.media.AudioManager.DEVICE_OUT_BLUETOOTH_SCO; 21 import static android.media.AudioManager.STREAM_RING; 22 import static android.media.AudioManager.STREAM_VOICE_CALL; 23 import static android.media.AudioSystem.DEVICE_OUT_ALL_SCO; 24 import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP; 25 import static android.media.AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET; 26 import static android.media.AudioSystem.DEVICE_OUT_HEARING_AID; 27 import static android.media.AudioSystem.STREAM_MUSIC; 28 29 import static com.android.settings.core.BasePreferenceController.AVAILABLE; 30 import static com.android.settings.core.BasePreferenceController.CONDITIONALLY_UNAVAILABLE; 31 32 import static com.google.common.truth.Truth.assertThat; 33 34 import static org.mockito.ArgumentMatchers.any; 35 import static org.mockito.Mockito.mock; 36 import static org.mockito.Mockito.spy; 37 import static org.mockito.Mockito.verify; 38 import static org.mockito.Mockito.when; 39 40 import static org.robolectric.Shadows.shadowOf; 41 42 import android.bluetooth.BluetoothAdapter; 43 import android.bluetooth.BluetoothDevice; 44 import android.bluetooth.BluetoothManager; 45 import android.content.pm.PackageManager; 46 import android.content.BroadcastReceiver; 47 import android.content.Context; 48 import android.content.IntentFilter; 49 import android.support.v7.preference.ListPreference; 50 import android.support.v7.preference.PreferenceManager; 51 import android.support.v7.preference.PreferenceScreen; 52 import android.util.FeatureFlagUtils; 53 54 import com.android.settings.R; 55 import com.android.settings.core.FeatureFlags; 56 import com.android.settings.testutils.SettingsRobolectricTestRunner; 57 import com.android.settings.testutils.shadow.ShadowAudioManager; 58 import com.android.settings.testutils.shadow.ShadowBluetoothUtils; 59 import com.android.settings.testutils.shadow.ShadowMediaRouter; 60 import com.android.settingslib.bluetooth.A2dpProfile; 61 import com.android.settingslib.bluetooth.BluetoothCallback; 62 import com.android.settingslib.bluetooth.BluetoothEventManager; 63 import com.android.settingslib.bluetooth.HeadsetProfile; 64 import com.android.settingslib.bluetooth.HearingAidProfile; 65 import com.android.settingslib.bluetooth.LocalBluetoothManager; 66 import com.android.settingslib.bluetooth.LocalBluetoothProfileManager; 67 68 import org.junit.After; 69 import org.junit.Before; 70 import org.junit.Test; 71 import org.junit.runner.RunWith; 72 import org.mockito.Mock; 73 import org.mockito.MockitoAnnotations; 74 import org.robolectric.RuntimeEnvironment; 75 import org.robolectric.annotation.Config; 76 import org.robolectric.shadow.api.Shadow; 77 import org.robolectric.shadows.ShadowBluetoothDevice; 78 import org.robolectric.shadows.ShadowPackageManager; 79 80 import java.util.ArrayList; 81 import java.util.List; 82 83 @RunWith(SettingsRobolectricTestRunner.class) 84 @Config(shadows = { 85 ShadowAudioManager.class, 86 ShadowMediaRouter.class, 87 ShadowBluetoothUtils.class, 88 ShadowBluetoothDevice.class} 89 ) 90 public class AudioOutputSwitchPreferenceControllerTest { 91 private static final String TEST_KEY = "Test_Key"; 92 private static final String TEST_DEVICE_NAME_1 = "Test_A2DP_BT_Device_NAME_1"; 93 private static final String TEST_DEVICE_NAME_2 = "Test_A2DP_BT_Device_NAME_2"; 94 private static final String TEST_DEVICE_ADDRESS_1 = "00:A1:A1:A1:A1:A1"; 95 private static final String TEST_DEVICE_ADDRESS_2 = "00:B2:B2:B2:B2:B2"; 96 private static final String TEST_DEVICE_ADDRESS_3 = "00:C3:C3:C3:C3:C3"; 97 private final static long HISYNCID1 = 10; 98 private final static long HISYNCID2 = 11; 99 100 @Mock 101 private LocalBluetoothManager mLocalManager; 102 @Mock 103 private BluetoothEventManager mBluetoothEventManager; 104 @Mock 105 private LocalBluetoothProfileManager mLocalBluetoothProfileManager; 106 @Mock 107 private A2dpProfile mA2dpProfile; 108 @Mock 109 private HeadsetProfile mHeadsetProfile; 110 @Mock 111 private HearingAidProfile mHearingAidProfile; 112 113 private Context mContext; 114 private PreferenceScreen mScreen; 115 private ListPreference mPreference; 116 private ShadowAudioManager mShadowAudioManager; 117 private ShadowMediaRouter mShadowMediaRouter; 118 private BluetoothManager mBluetoothManager; 119 private BluetoothAdapter mBluetoothAdapter; 120 private BluetoothDevice mBluetoothDevice; 121 private BluetoothDevice mLeftBluetoothHapDevice; 122 private BluetoothDevice mRightBluetoothHapDevice; 123 private LocalBluetoothManager mLocalBluetoothManager; 124 private AudioSwitchPreferenceController mController; 125 private List<BluetoothDevice> mProfileConnectedDevices; 126 private List<BluetoothDevice> mHearingAidActiveDevices; 127 private List<BluetoothDevice> mEmptyDevices; 128 private ShadowPackageManager mPackageManager; 129 130 @Before setUp()131 public void setUp() { 132 MockitoAnnotations.initMocks(this); 133 mContext = spy(RuntimeEnvironment.application); 134 135 mShadowAudioManager = ShadowAudioManager.getShadow(); 136 mShadowMediaRouter = ShadowMediaRouter.getShadow(); 137 138 ShadowBluetoothUtils.sLocalBluetoothManager = mLocalManager; 139 mLocalBluetoothManager = ShadowBluetoothUtils.getLocalBtManager(mContext); 140 141 when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager); 142 when(mLocalBluetoothManager.getProfileManager()).thenReturn(mLocalBluetoothProfileManager); 143 when(mLocalBluetoothProfileManager.getA2dpProfile()).thenReturn(mA2dpProfile); 144 when(mLocalBluetoothProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); 145 when(mLocalBluetoothProfileManager.getHeadsetProfile()).thenReturn(mHeadsetProfile); 146 mPackageManager = Shadow.extract(mContext.getPackageManager()); 147 mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, true); 148 149 mBluetoothManager = new BluetoothManager(mContext); 150 mBluetoothAdapter = mBluetoothManager.getAdapter(); 151 152 mBluetoothDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_1)); 153 when(mBluetoothDevice.getName()).thenReturn(TEST_DEVICE_NAME_1); 154 when(mBluetoothDevice.isConnected()).thenReturn(true); 155 156 mLeftBluetoothHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2)); 157 when(mLeftBluetoothHapDevice.isConnected()).thenReturn(true); 158 mRightBluetoothHapDevice = spy(mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_3)); 159 when(mRightBluetoothHapDevice.isConnected()).thenReturn(true); 160 161 mController = new AudioSwitchPreferenceControllerTestable(mContext, TEST_KEY); 162 mScreen = spy(new PreferenceScreen(mContext, null)); 163 mPreference = new ListPreference(mContext); 164 mProfileConnectedDevices = new ArrayList<>(); 165 mHearingAidActiveDevices = new ArrayList<>(2); 166 mEmptyDevices = new ArrayList<>(2); 167 168 when(mScreen.getPreferenceManager()).thenReturn(mock(PreferenceManager.class)); 169 when(mScreen.getContext()).thenReturn(mContext); 170 when(mScreen.findPreference(mController.getPreferenceKey())).thenReturn(mPreference); 171 mScreen.addPreference(mPreference); 172 mController.displayPreference(mScreen); 173 } 174 175 @After tearDown()176 public void tearDown() { 177 mShadowAudioManager.reset(); 178 mShadowMediaRouter.reset(); 179 ShadowBluetoothUtils.reset(); 180 } 181 182 @Test constructor_notSupportBluetooth_shouldReturnBeforeUsingLocalBluetoothManager()183 public void constructor_notSupportBluetooth_shouldReturnBeforeUsingLocalBluetoothManager() { 184 ShadowBluetoothUtils.reset(); 185 mLocalBluetoothManager = ShadowBluetoothUtils.getLocalBtManager(mContext); 186 187 AudioSwitchPreferenceController controller = new AudioSwitchPreferenceControllerTestable( 188 mContext, TEST_KEY); 189 controller.onStart(); 190 controller.onStop(); 191 192 assertThat(mLocalBluetoothManager).isNull(); 193 } 194 195 @Test getAvailabilityStatus_disableFlagNoBluetoothFeature_returnUnavailable()196 public void getAvailabilityStatus_disableFlagNoBluetoothFeature_returnUnavailable() { 197 FeatureFlagUtils.setEnabled(mContext, FeatureFlags.AUDIO_SWITCHER_SETTINGS, false); 198 mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, false); 199 200 assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE); 201 } 202 203 @Test getAvailabilityStatus_disableFlagWithBluetoothFeature_returnUnavailable()204 public void getAvailabilityStatus_disableFlagWithBluetoothFeature_returnUnavailable() { 205 FeatureFlagUtils.setEnabled(mContext, FeatureFlags.AUDIO_SWITCHER_SETTINGS, false); 206 mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, true); 207 208 209 assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE); 210 } 211 212 @Test getAvailabilityStatus_enableFlagWithBluetoothFeature_returnAvailable()213 public void getAvailabilityStatus_enableFlagWithBluetoothFeature_returnAvailable() { 214 FeatureFlagUtils.setEnabled(mContext, FeatureFlags.AUDIO_SWITCHER_SETTINGS, true); 215 mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, true); 216 217 assertThat(mController.getAvailabilityStatus()).isEqualTo(AVAILABLE); 218 } 219 220 @Test getAvailabilityStatus_enableFlagNoBluetoothFeature_returnUnavailable()221 public void getAvailabilityStatus_enableFlagNoBluetoothFeature_returnUnavailable() { 222 FeatureFlagUtils.setEnabled(mContext, FeatureFlags.AUDIO_SWITCHER_SETTINGS, true); 223 mPackageManager.setSystemFeature(PackageManager.FEATURE_BLUETOOTH, false); 224 225 assertThat(mController.getAvailabilityStatus()).isEqualTo(CONDITIONALLY_UNAVAILABLE); 226 } 227 228 @Test onStart_shouldRegisterCallbackAndRegisterReceiver()229 public void onStart_shouldRegisterCallbackAndRegisterReceiver() { 230 mController.onStart(); 231 232 verify(mLocalBluetoothManager.getEventManager()).registerCallback( 233 any(BluetoothCallback.class)); 234 verify(mContext).registerReceiver(any(BroadcastReceiver.class), any(IntentFilter.class)); 235 verify(mLocalBluetoothManager).setForegroundActivity(mContext); 236 } 237 238 @Test onStop_shouldUnregisterCallbackAndUnregisterReceiver()239 public void onStop_shouldUnregisterCallbackAndUnregisterReceiver() { 240 mController.onStart(); 241 mController.onStop(); 242 243 verify(mLocalBluetoothManager.getEventManager()).unregisterCallback( 244 any(BluetoothCallback.class)); 245 verify(mContext).unregisterReceiver(any(BroadcastReceiver.class)); 246 verify(mLocalBluetoothManager).setForegroundActivity(null); 247 } 248 249 @Test onPreferenceChange_toThisDevice_shouldSetDefaultSummary()250 public void onPreferenceChange_toThisDevice_shouldSetDefaultSummary() { 251 mController.mConnectedDevices.clear(); 252 mController.mConnectedDevices.add(mBluetoothDevice); 253 254 mController.onPreferenceChange(mPreference, 255 mContext.getText(R.string.media_output_default_summary)); 256 257 assertThat(mPreference.getSummary()).isEqualTo( 258 mContext.getText(R.string.media_output_default_summary)); 259 } 260 261 /** 262 * One Bluetooth devices are available, and select the device. 263 * Preference summary should be device name. 264 */ 265 @Test onPreferenceChange_toBtDevice_shouldSetBtDeviceName()266 public void onPreferenceChange_toBtDevice_shouldSetBtDeviceName() { 267 mController.mConnectedDevices.clear(); 268 mController.mConnectedDevices.add(mBluetoothDevice); 269 270 mController.onPreferenceChange(mPreference, TEST_DEVICE_ADDRESS_1); 271 272 assertThat(mPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME_1); 273 } 274 275 /** 276 * More than one Bluetooth devices are available, and select second device. 277 * Preference summary should be second device name. 278 */ 279 @Test onPreferenceChange_toBtDevices_shouldSetSecondBtDeviceName()280 public void onPreferenceChange_toBtDevices_shouldSetSecondBtDeviceName() { 281 ShadowBluetoothDevice shadowBluetoothDevice; 282 BluetoothDevice secondBluetoothDevice; 283 secondBluetoothDevice = mBluetoothAdapter.getRemoteDevice(TEST_DEVICE_ADDRESS_2); 284 shadowBluetoothDevice = shadowOf(secondBluetoothDevice); 285 shadowBluetoothDevice.setName(TEST_DEVICE_NAME_2); 286 mController.mConnectedDevices.clear(); 287 mController.mConnectedDevices.add(mBluetoothDevice); 288 mController.mConnectedDevices.add(secondBluetoothDevice); 289 290 mController.onPreferenceChange(mPreference, TEST_DEVICE_ADDRESS_2); 291 292 assertThat(mPreference.getSummary()).isEqualTo(TEST_DEVICE_NAME_2); 293 } 294 295 /** 296 * mConnectedDevices is empty. 297 * onPreferenceChange should return false. 298 */ 299 @Test onPreferenceChange_connectedDeviceIsNull_shouldReturnFalse()300 public void onPreferenceChange_connectedDeviceIsNull_shouldReturnFalse() { 301 mController.mConnectedDevices.clear(); 302 303 assertThat(mController.onPreferenceChange(mPreference, TEST_DEVICE_ADDRESS_1)).isFalse(); 304 } 305 306 /** 307 * Audio stream output to bluetooth sco headset which is the subset of all sco device. 308 * isStreamFromOutputDevice should return true. 309 */ 310 @Test isStreamFromOutputDevice_outputDeviceIsBtScoHeadset_shouldReturnTrue()311 public void isStreamFromOutputDevice_outputDeviceIsBtScoHeadset_shouldReturnTrue() { 312 mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_SCO_HEADSET); 313 314 assertThat(mController.isStreamFromOutputDevice(STREAM_MUSIC, DEVICE_OUT_ALL_SCO)).isTrue(); 315 } 316 317 /** 318 * Audio stream is not STREAM_MUSIC or STREAM_VOICE_CALL. 319 * findActiveDevice should return null. 320 */ 321 @Test findActiveDevice_streamIsRing_shouldReturnNull()322 public void findActiveDevice_streamIsRing_shouldReturnNull() { 323 assertThat(mController.findActiveDevice(STREAM_RING)).isNull(); 324 } 325 326 /** 327 * Audio stream is STREAM_MUSIC and output device is A2dp bluetooth device. 328 * findActiveDevice should return A2dp active device. 329 */ 330 @Test findActiveDevice_streamMusicToA2dpDevice_shouldReturnActiveA2dpDevice()331 public void findActiveDevice_streamMusicToA2dpDevice_shouldReturnActiveA2dpDevice() { 332 mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_A2DP); 333 mHearingAidActiveDevices.clear(); 334 mHearingAidActiveDevices.add(mLeftBluetoothHapDevice); 335 when(mHeadsetProfile.getActiveDevice()).thenReturn(mLeftBluetoothHapDevice); 336 when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice); 337 when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices); 338 339 assertThat(mController.findActiveDevice(STREAM_MUSIC)).isEqualTo(mBluetoothDevice); 340 } 341 342 /** 343 * Audio stream is STREAM_VOICE_CALL and output device is Hands free profile bluetooth device. 344 * findActiveDevice should return Hands free profile active device. 345 */ 346 @Test findActiveDevice_streamVoiceCallToHfpDevice_shouldReturnActiveHfpDevice()347 public void findActiveDevice_streamVoiceCallToHfpDevice_shouldReturnActiveHfpDevice() { 348 mShadowAudioManager.setOutputDevice(DEVICE_OUT_BLUETOOTH_SCO); 349 mHearingAidActiveDevices.clear(); 350 mHearingAidActiveDevices.add(mLeftBluetoothHapDevice); 351 when(mHeadsetProfile.getActiveDevice()).thenReturn(mBluetoothDevice); 352 when(mA2dpProfile.getActiveDevice()).thenReturn(mLeftBluetoothHapDevice); 353 when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices); 354 355 assertThat(mController.findActiveDevice(STREAM_VOICE_CALL)).isEqualTo(mBluetoothDevice); 356 } 357 358 /** 359 * Audio stream is STREAM_MUSIC or STREAM_VOICE_CALL and output device is hearing aid profile 360 * bluetooth device. And left side of HAP device is active. 361 * findActiveDevice should return hearing aid device active device. 362 */ 363 @Test findActiveDevice_streamToHapDeviceLeftActiveDevice_shouldReturnActiveHapDevice()364 public void findActiveDevice_streamToHapDeviceLeftActiveDevice_shouldReturnActiveHapDevice() { 365 mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID); 366 mController.mConnectedDevices.clear(); 367 mController.mConnectedDevices.add(mBluetoothDevice); 368 mController.mConnectedDevices.add(mLeftBluetoothHapDevice); 369 mHearingAidActiveDevices.clear(); 370 mHearingAidActiveDevices.add(mLeftBluetoothHapDevice); 371 mHearingAidActiveDevices.add(null); 372 when(mHeadsetProfile.getActiveDevice()).thenReturn(mBluetoothDevice); 373 when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice); 374 when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices); 375 376 assertThat(mController.findActiveDevice(STREAM_MUSIC)).isEqualTo(mLeftBluetoothHapDevice); 377 assertThat(mController.findActiveDevice(STREAM_VOICE_CALL)).isEqualTo( 378 mLeftBluetoothHapDevice); 379 } 380 381 /** 382 * Audio stream is STREAM_MUSIC or STREAM_VOICE_CALL and output device is hearing aid profile 383 * bluetooth device. And right side of HAP device is active. 384 * findActiveDevice should return hearing aid device active device. 385 */ 386 @Test findActiveDevice_streamToHapDeviceRightActiveDevice_shouldReturnActiveHapDevice()387 public void findActiveDevice_streamToHapDeviceRightActiveDevice_shouldReturnActiveHapDevice() { 388 mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID); 389 mController.mConnectedDevices.clear(); 390 mController.mConnectedDevices.add(mBluetoothDevice); 391 mController.mConnectedDevices.add(mRightBluetoothHapDevice); 392 mHearingAidActiveDevices.clear(); 393 mHearingAidActiveDevices.add(null); 394 mHearingAidActiveDevices.add(mRightBluetoothHapDevice); 395 mHearingAidActiveDevices.add(mRightBluetoothHapDevice); 396 when(mHeadsetProfile.getActiveDevice()).thenReturn(mBluetoothDevice); 397 when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice); 398 when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices); 399 400 assertThat(mController.findActiveDevice(STREAM_MUSIC)).isEqualTo(mRightBluetoothHapDevice); 401 assertThat(mController.findActiveDevice(STREAM_VOICE_CALL)).isEqualTo( 402 mRightBluetoothHapDevice); 403 } 404 405 /** 406 * Audio stream is STREAM_MUSIC or STREAM_VOICE_CALL and output device is hearing aid 407 * profile bluetooth device. And both are active device. 408 * findActiveDevice should return only return the active device in mConnectedDevices. 409 */ 410 @Test findActiveDevice_streamToHapDeviceTwoActiveDevice_shouldReturnActiveHapDevice()411 public void findActiveDevice_streamToHapDeviceTwoActiveDevice_shouldReturnActiveHapDevice() { 412 mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID); 413 mController.mConnectedDevices.clear(); 414 mController.mConnectedDevices.add(mBluetoothDevice); 415 mController.mConnectedDevices.add(mRightBluetoothHapDevice); 416 mHearingAidActiveDevices.clear(); 417 mHearingAidActiveDevices.add(mLeftBluetoothHapDevice); 418 mHearingAidActiveDevices.add(mRightBluetoothHapDevice); 419 when(mHeadsetProfile.getActiveDevice()).thenReturn(mBluetoothDevice); 420 when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice); 421 when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices); 422 423 assertThat(mController.findActiveDevice(STREAM_MUSIC)).isEqualTo(mRightBluetoothHapDevice); 424 assertThat(mController.findActiveDevice(STREAM_VOICE_CALL)).isEqualTo( 425 mRightBluetoothHapDevice); 426 } 427 428 /** 429 * Audio stream is STREAM_MUSIC or STREAM_VOICE_CALL and output device is hearing aid 430 * profile bluetooth device. And none of them are active. 431 * findActiveDevice should return null. 432 */ 433 @Test findActiveDevice_streamToOtherDevice_shouldReturnActiveHapDevice()434 public void findActiveDevice_streamToOtherDevice_shouldReturnActiveHapDevice() { 435 mShadowAudioManager.setOutputDevice(DEVICE_OUT_HEARING_AID); 436 mController.mConnectedDevices.clear(); 437 mController.mConnectedDevices.add(mBluetoothDevice); 438 mController.mConnectedDevices.add(mLeftBluetoothHapDevice); 439 mHearingAidActiveDevices.clear(); 440 when(mHeadsetProfile.getActiveDevice()).thenReturn(mBluetoothDevice); 441 when(mA2dpProfile.getActiveDevice()).thenReturn(mBluetoothDevice); 442 when(mHearingAidProfile.getActiveDevices()).thenReturn(mHearingAidActiveDevices); 443 444 assertThat(mController.findActiveDevice(STREAM_MUSIC)).isNull(); 445 assertThat(mController.findActiveDevice(STREAM_VOICE_CALL)).isNull(); 446 } 447 448 /** 449 * Two hearing aid devices with different HisyncId 450 * getConnectedHearingAidDevices should add both device to list. 451 */ 452 @Test getConnectedHearingAidDevices_deviceHisyncIdIsDifferent_shouldAddBothToList()453 public void getConnectedHearingAidDevices_deviceHisyncIdIsDifferent_shouldAddBothToList() { 454 mEmptyDevices.clear(); 455 mProfileConnectedDevices.clear(); 456 mProfileConnectedDevices.add(mLeftBluetoothHapDevice); 457 mProfileConnectedDevices.add(mRightBluetoothHapDevice); 458 when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices); 459 when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1); 460 when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID2); 461 462 mEmptyDevices.addAll(mController.getConnectedHearingAidDevices()); 463 464 assertThat(mEmptyDevices).containsExactly(mLeftBluetoothHapDevice, 465 mRightBluetoothHapDevice); 466 } 467 468 /** 469 * Two hearing aid devices with same HisyncId 470 * getConnectedHearingAidDevices should only add first device to list. 471 */ 472 @Test getConnectedHearingAidDevices_deviceHisyncIdIsSame_shouldAddOneToList()473 public void getConnectedHearingAidDevices_deviceHisyncIdIsSame_shouldAddOneToList() { 474 mEmptyDevices.clear(); 475 mProfileConnectedDevices.clear(); 476 mProfileConnectedDevices.add(mLeftBluetoothHapDevice); 477 mProfileConnectedDevices.add(mRightBluetoothHapDevice); 478 when(mHearingAidProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices); 479 when(mHearingAidProfile.getHiSyncId(mLeftBluetoothHapDevice)).thenReturn(HISYNCID1); 480 when(mHearingAidProfile.getHiSyncId(mRightBluetoothHapDevice)).thenReturn(HISYNCID1); 481 482 mEmptyDevices.addAll(mController.getConnectedHearingAidDevices()); 483 484 assertThat(mEmptyDevices).containsExactly(mLeftBluetoothHapDevice); 485 } 486 487 /** 488 * One A2dp device is connected. 489 * getConnectedA2dpDevices should add this device to list. 490 */ 491 @Test getConnectedA2dpDevices_oneConnectedA2dpDevice_shouldAddDeviceToList()492 public void getConnectedA2dpDevices_oneConnectedA2dpDevice_shouldAddDeviceToList() { 493 mEmptyDevices.clear(); 494 mProfileConnectedDevices.clear(); 495 mProfileConnectedDevices.add(mBluetoothDevice); 496 when(mA2dpProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices); 497 498 mEmptyDevices.addAll(mController.getConnectedA2dpDevices()); 499 500 assertThat(mEmptyDevices).containsExactly(mBluetoothDevice); 501 } 502 503 /** 504 * More than one A2dp devices are connected. 505 * getConnectedA2dpDevices should add all devices to list. 506 */ 507 @Test getConnectedA2dpDevices_moreThanOneConnectedA2dpDevice_shouldAddDeviceToList()508 public void getConnectedA2dpDevices_moreThanOneConnectedA2dpDevice_shouldAddDeviceToList() { 509 mEmptyDevices.clear(); 510 mProfileConnectedDevices.clear(); 511 mProfileConnectedDevices.add(mBluetoothDevice); 512 mProfileConnectedDevices.add(mLeftBluetoothHapDevice); 513 when(mA2dpProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices); 514 515 mEmptyDevices.addAll(mController.getConnectedA2dpDevices()); 516 517 assertThat(mEmptyDevices).containsExactly(mBluetoothDevice, mLeftBluetoothHapDevice); 518 } 519 520 /** 521 * One hands free profile device is connected. 522 * getConnectedA2dpDevices should add this device to list. 523 */ 524 @Test getConnectedHfpDevices_oneConnectedHfpDevice_shouldAddDeviceToList()525 public void getConnectedHfpDevices_oneConnectedHfpDevice_shouldAddDeviceToList() { 526 mEmptyDevices.clear(); 527 mProfileConnectedDevices.clear(); 528 mProfileConnectedDevices.add(mBluetoothDevice); 529 when(mHeadsetProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices); 530 531 mEmptyDevices.addAll(mController.getConnectedHfpDevices()); 532 533 assertThat(mEmptyDevices).containsExactly(mBluetoothDevice); 534 } 535 536 /** 537 * More than one hands free profile devices are connected. 538 * getConnectedA2dpDevices should add all devices to list. 539 */ 540 @Test getConnectedHfpDevices_moreThanOneConnectedHfpDevice_shouldAddDeviceToList()541 public void getConnectedHfpDevices_moreThanOneConnectedHfpDevice_shouldAddDeviceToList() { 542 mEmptyDevices.clear(); 543 mProfileConnectedDevices.clear(); 544 mProfileConnectedDevices.add(mBluetoothDevice); 545 mProfileConnectedDevices.add(mLeftBluetoothHapDevice); 546 when(mHeadsetProfile.getConnectedDevices()).thenReturn(mProfileConnectedDevices); 547 548 mEmptyDevices.addAll(mController.getConnectedHfpDevices()); 549 550 assertThat(mEmptyDevices).containsExactly(mBluetoothDevice, mLeftBluetoothHapDevice); 551 } 552 553 private class AudioSwitchPreferenceControllerTestable extends 554 AudioSwitchPreferenceController { AudioSwitchPreferenceControllerTestable(Context context, String key)555 AudioSwitchPreferenceControllerTestable(Context context, String key) { 556 super(context, key); 557 } 558 559 @Override setActiveBluetoothDevice(BluetoothDevice device)560 public void setActiveBluetoothDevice(BluetoothDevice device) { 561 } 562 563 @Override getPreferenceKey()564 public String getPreferenceKey() { 565 return TEST_KEY; 566 } 567 } 568 }