Home | History | Annotate | Download | only in bluetooth
      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 package com.android.settingslib.bluetooth;
     17 
     18 import static com.google.common.truth.Truth.assertThat;
     19 
     20 import static org.mockito.Matchers.any;
     21 import static org.mockito.Matchers.anyString;
     22 import static org.mockito.Mockito.doAnswer;
     23 import static org.mockito.Mockito.never;
     24 import static org.mockito.Mockito.spy;
     25 import static org.mockito.Mockito.verify;
     26 import static org.mockito.Mockito.when;
     27 
     28 import android.bluetooth.BluetoothAdapter;
     29 import android.bluetooth.BluetoothClass;
     30 import android.bluetooth.BluetoothDevice;
     31 import android.bluetooth.BluetoothProfile;
     32 import android.content.Context;
     33 
     34 import com.android.settingslib.R;
     35 
     36 import org.junit.Before;
     37 import org.junit.Test;
     38 import org.junit.runner.RunWith;
     39 import org.mockito.Mock;
     40 import org.mockito.MockitoAnnotations;
     41 import org.robolectric.RobolectricTestRunner;
     42 import org.robolectric.RuntimeEnvironment;
     43 import org.robolectric.annotation.Config;
     44 
     45 import java.util.Collection;
     46 
     47 @RunWith(RobolectricTestRunner.class)
     48 public class CachedBluetoothDeviceManagerTest {
     49     private final static String DEVICE_NAME_1 = "TestName_1";
     50     private final static String DEVICE_NAME_2 = "TestName_2";
     51     private final static String DEVICE_NAME_3 = "TestName_3";
     52     private final static String DEVICE_ALIAS_1 = "TestAlias_1";
     53     private final static String DEVICE_ALIAS_2 = "TestAlias_2";
     54     private final static String DEVICE_ALIAS_3 = "TestAlias_3";
     55     private final static String DEVICE_ADDRESS_1 = "AA:BB:CC:DD:EE:11";
     56     private final static String DEVICE_ADDRESS_2 = "AA:BB:CC:DD:EE:22";
     57     private final static String DEVICE_ADDRESS_3 = "AA:BB:CC:DD:EE:33";
     58     private final static String DEVICE_SUMMARY_1 = "summary 1";
     59     private final static String DEVICE_SUMMARY_2 = "summary 2";
     60     private final static String DEVICE_SUMMARY_3 = "summary 3";
     61     private final static long HISYNCID1 = 10;
     62     private final static long HISYNCID2 = 11;
     63     private final BluetoothClass DEVICE_CLASS_1 =
     64         new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_HEADPHONES);
     65     private final BluetoothClass DEVICE_CLASS_2 =
     66         new BluetoothClass(BluetoothClass.Device.AUDIO_VIDEO_HANDSFREE);
     67     @Mock
     68     private LocalBluetoothAdapter mLocalAdapter;
     69     @Mock
     70     private LocalBluetoothProfileManager mLocalProfileManager;
     71     @Mock
     72     private LocalBluetoothManager mLocalBluetoothManager;
     73     @Mock
     74     private BluetoothEventManager mBluetoothEventManager;
     75     @Mock
     76     private HeadsetProfile mHfpProfile;
     77     @Mock
     78     private A2dpProfile mA2dpProfile;
     79     @Mock
     80     private PanProfile mPanProfile;
     81     @Mock
     82     private HearingAidProfile mHearingAidProfile;
     83     @Mock
     84     private BluetoothDevice mDevice1;
     85     @Mock
     86     private BluetoothDevice mDevice2;
     87     @Mock
     88     private BluetoothDevice mDevice3;
     89     private CachedBluetoothDevice mCachedDevice1;
     90     private CachedBluetoothDevice mCachedDevice2;
     91     private CachedBluetoothDevice mCachedDevice3;
     92     private CachedBluetoothDeviceManager mCachedDeviceManager;
     93     private Context mContext;
     94     private String[] mActiveDeviceStringsArray;
     95     private String mActiveDeviceStringNone;
     96     private String mActiveDeviceStringAll;
     97     private String mActiveDeviceStringMedia;
     98     private String mActiveDeviceStringPhone;
     99 
    100     @Before
    101     public void setUp() {
    102         MockitoAnnotations.initMocks(this);
    103         mContext = RuntimeEnvironment.application;
    104         when(mDevice1.getAddress()).thenReturn(DEVICE_ADDRESS_1);
    105         when(mDevice2.getAddress()).thenReturn(DEVICE_ADDRESS_2);
    106         when(mDevice3.getAddress()).thenReturn(DEVICE_ADDRESS_3);
    107         when(mDevice1.getName()).thenReturn(DEVICE_NAME_1);
    108         when(mDevice2.getName()).thenReturn(DEVICE_NAME_2);
    109         when(mDevice3.getName()).thenReturn(DEVICE_NAME_3);
    110         when(mDevice1.getAliasName()).thenReturn(DEVICE_ALIAS_1);
    111         when(mDevice2.getAliasName()).thenReturn(DEVICE_ALIAS_2);
    112         when(mDevice3.getAliasName()).thenReturn(DEVICE_ALIAS_3);
    113         when(mDevice1.getBluetoothClass()).thenReturn(DEVICE_CLASS_1);
    114         when(mDevice2.getBluetoothClass()).thenReturn(DEVICE_CLASS_2);
    115         when(mDevice3.getBluetoothClass()).thenReturn(DEVICE_CLASS_2);
    116 
    117         when(mLocalBluetoothManager.getEventManager()).thenReturn(mBluetoothEventManager);
    118         when(mLocalAdapter.getBluetoothState()).thenReturn(BluetoothAdapter.STATE_ON);
    119         when(mHfpProfile.isProfileReady()).thenReturn(true);
    120         when(mA2dpProfile.isProfileReady()).thenReturn(true);
    121         when(mPanProfile.isProfileReady()).thenReturn(true);
    122         when(mHearingAidProfile.isProfileReady()).thenReturn(true);
    123         mCachedDeviceManager = new CachedBluetoothDeviceManager(mContext, mLocalBluetoothManager);
    124         mCachedDevice1 = spy(
    125             new CachedBluetoothDevice(mContext, mLocalAdapter, mLocalProfileManager, mDevice1));
    126         mCachedDevice2 = spy(
    127             new CachedBluetoothDevice(mContext, mLocalAdapter, mLocalProfileManager, mDevice2));
    128         mCachedDevice3 = spy(
    129             new CachedBluetoothDevice(mContext, mLocalAdapter, mLocalProfileManager, mDevice3));
    130     }
    131 
    132     /**
    133      * Test to verify addDevice().
    134      */
    135     @Test
    136     public void testAddDevice_validCachedDevices_devicesAdded() {
    137         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    138                 mLocalProfileManager, mDevice1);
    139         assertThat(cachedDevice1).isNotNull();
    140         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
    141                 mLocalProfileManager, mDevice2);
    142         assertThat(cachedDevice2).isNotNull();
    143 
    144         Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy();
    145         assertThat(devices).contains(cachedDevice1);
    146         assertThat(devices).contains(cachedDevice2);
    147 
    148         assertThat(mCachedDeviceManager.findDevice(mDevice1)).isEqualTo(cachedDevice1);
    149         assertThat(mCachedDeviceManager.findDevice(mDevice2)).isEqualTo(cachedDevice2);
    150     }
    151 
    152     /**
    153      * Test to verify getName().
    154      */
    155     @Test
    156     public void testGetName_validCachedDevice_nameFound() {
    157         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    158                 mLocalProfileManager, mDevice1);
    159         assertThat(cachedDevice1).isNotNull();
    160         assertThat(mCachedDeviceManager.getName(mDevice1)).isEqualTo(DEVICE_ALIAS_1);
    161     }
    162 
    163     /**
    164      * Test to verify onDeviceNameUpdated().
    165      */
    166     @Test
    167     public void testOnDeviceNameUpdated_validName_nameUpdated() {
    168         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    169                 mLocalProfileManager, mDevice1);
    170         assertThat(cachedDevice1).isNotNull();
    171         assertThat(cachedDevice1.getName()).isEqualTo(DEVICE_ALIAS_1);
    172 
    173         final String newAliasName = "NewAliasName";
    174         when(mDevice1.getAliasName()).thenReturn(newAliasName);
    175         mCachedDeviceManager.onDeviceNameUpdated(mDevice1);
    176         assertThat(cachedDevice1.getName()).isEqualTo(newAliasName);
    177     }
    178 
    179     /**
    180      * Test to verify clearNonBondedDevices().
    181      */
    182     @Test
    183     public void testClearNonBondedDevices_bondedAndNonBondedDevices_nonBondedDevicesCleared() {
    184         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    185                 mLocalProfileManager, mDevice1);
    186         assertThat(cachedDevice1).isNotNull();
    187         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
    188                 mLocalProfileManager, mDevice2);
    189         assertThat(cachedDevice2).isNotNull();
    190 
    191         when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
    192         when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_BONDING);
    193         mCachedDeviceManager.clearNonBondedDevices();
    194         Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy();
    195         assertThat(devices).contains(cachedDevice1);
    196         assertThat(devices).contains(cachedDevice2);
    197 
    198         when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
    199         when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
    200         mCachedDeviceManager.clearNonBondedDevices();
    201         devices = mCachedDeviceManager.getCachedDevicesCopy();
    202         assertThat(devices).contains(cachedDevice1);
    203         assertThat(devices).doesNotContain(cachedDevice2);
    204 
    205         when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
    206         when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
    207         mCachedDeviceManager.clearNonBondedDevices();
    208         devices = mCachedDeviceManager.getCachedDevicesCopy();
    209         assertThat(devices).doesNotContain(cachedDevice1);
    210         assertThat(devices).doesNotContain(cachedDevice2);
    211     }
    212 
    213     /**
    214      * Test to verify clearNonBondedDevices() for hearing aids.
    215      */
    216     @Test
    217     public void testClearNonBondedDevices_HearingAids_nonBondedHAsClearedFromCachedDevicesMap() {
    218         when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
    219         when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
    220 
    221         mCachedDevice1.setHiSyncId(HISYNCID1);
    222         mCachedDevice2.setHiSyncId(HISYNCID2);
    223         mCachedDeviceManager.mCachedDevicesMapForHearingAids.put(HISYNCID1, mCachedDevice1);
    224         mCachedDeviceManager.mCachedDevicesMapForHearingAids.put(HISYNCID2, mCachedDevice2);
    225 
    226         mCachedDeviceManager.clearNonBondedDevices();
    227 
    228         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids.values())
    229             .doesNotContain(mCachedDevice2);
    230         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids.values())
    231             .contains(mCachedDevice1);
    232     }
    233 
    234     /**
    235      * Test to verify onHiSyncIdChanged() for hearing aid devices with same HiSyncId.
    236      */
    237     @Test
    238     public void testOnHiSyncIdChanged_sameHiSyncId_populateInDifferentLists() {
    239         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    240             mLocalProfileManager, mDevice1);
    241         assertThat(cachedDevice1).isNotNull();
    242         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
    243             mLocalProfileManager, mDevice2);
    244         assertThat(cachedDevice2).isNotNull();
    245 
    246         // Since both devices do not have hiSyncId, they should be added in mCachedDevices.
    247         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(2);
    248         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty();
    249         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).isEmpty();
    250 
    251         cachedDevice1.setHiSyncId(HISYNCID1);
    252         cachedDevice2.setHiSyncId(HISYNCID1);
    253         mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1);
    254 
    255         // Since both devices have the same hiSyncId, one should remain in mCachedDevices
    256         // and the other should be removed from mCachedDevices and get added in
    257         // mHearingAidDevicesNotAddedInCache. The one that is in mCachedDevices should also be
    258         // added in mCachedDevicesMapForHearingAids.
    259         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(1);
    260         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).hasSize(1);
    261         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).hasSize(1);
    262         Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy();
    263         assertThat(devices).contains(cachedDevice2);
    264         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids)
    265             .containsKey(HISYNCID1);
    266     }
    267 
    268     /**
    269      * Test to verify onHiSyncIdChanged() for 2 hearing aid devices with same HiSyncId but one
    270      * device is connected and other is disconnected. The connected device should be chosen.
    271      */
    272     @Test
    273     public void testOnHiSyncIdChanged_sameHiSyncIdAndOneConnected_chooseConnectedDevice() {
    274         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    275             mLocalProfileManager, mDevice1);
    276         assertThat(cachedDevice1).isNotNull();
    277         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
    278             mLocalProfileManager, mDevice2);
    279         assertThat(cachedDevice2).isNotNull();
    280         cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
    281         cachedDevice2.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
    282 
    283         /* Device 1 is connected and Device 2 is disconnected */
    284         when(mHearingAidProfile.getConnectionStatus(mDevice1)).
    285             thenReturn(BluetoothProfile.STATE_CONNECTED);
    286         when(mHearingAidProfile.getConnectionStatus(mDevice2)).
    287             thenReturn(BluetoothProfile.STATE_DISCONNECTED);
    288 
    289         // Since both devices do not have hiSyncId, they should be added in mCachedDevices.
    290         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(2);
    291         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty();
    292         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).isEmpty();
    293 
    294         cachedDevice1.setHiSyncId(HISYNCID1);
    295         cachedDevice2.setHiSyncId(HISYNCID1);
    296         mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1);
    297 
    298         // Only the connected device, device 1, should be visible to UI.
    299         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice1);
    300         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).
    301             containsExactly(HISYNCID1, cachedDevice1);
    302         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).
    303             containsExactly(cachedDevice2);
    304     }
    305 
    306     /**
    307      * Test to verify onHiSyncIdChanged() for hearing aid devices with different HiSyncId.
    308      */
    309     @Test
    310     public void testOnHiSyncIdChanged_differentHiSyncId_populateInSameList() {
    311         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    312             mLocalProfileManager, mDevice1);
    313         assertThat(cachedDevice1).isNotNull();
    314         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
    315             mLocalProfileManager, mDevice2);
    316         assertThat(cachedDevice2).isNotNull();
    317 
    318         // Since both devices do not have hiSyncId, they should be added in mCachedDevices.
    319         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(2);
    320         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty();
    321         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).isEmpty();
    322 
    323         cachedDevice1.setHiSyncId(HISYNCID1);
    324         cachedDevice2.setHiSyncId(HISYNCID2);
    325         mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1);
    326         mCachedDeviceManager.onHiSyncIdChanged(HISYNCID2);
    327 
    328         // Since both devices do not have same hiSyncId, they should remain in mCachedDevices and
    329         // also be added in mCachedDevicesMapForHearingAids.
    330         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(2);
    331         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty();
    332         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).hasSize(2);
    333         Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy();
    334         assertThat(devices).contains(cachedDevice2);
    335         assertThat(devices).contains(cachedDevice1);
    336         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids.values())
    337             .contains(cachedDevice1);
    338         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids.values())
    339             .contains(cachedDevice2);
    340     }
    341 
    342     /**
    343      * Test to verify onProfileConnectionStateChanged() for single hearing aid device connection.
    344      */
    345     @Test
    346     public void testOnProfileConnectionStateChanged_singleDeviceConnected_visible() {
    347         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    348             mLocalProfileManager, mDevice1);
    349         assertThat(cachedDevice1).isNotNull();
    350         cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
    351 
    352         // Since both devices do not have hiSyncId, they should be added in mCachedDevices.
    353         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice1);
    354         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty();
    355         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).isEmpty();
    356 
    357         cachedDevice1.setHiSyncId(HISYNCID1);
    358         mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1);
    359 
    360         // Connect the Device 1
    361         mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice1,
    362             BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID);
    363 
    364         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice1);
    365         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).
    366             containsExactly(HISYNCID1, cachedDevice1);
    367         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty();
    368 
    369         // Disconnect the Device 1
    370         mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice1,
    371             BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.HEARING_AID);
    372 
    373         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice1);
    374         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).
    375             containsExactly(HISYNCID1, cachedDevice1);
    376         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty();
    377     }
    378 
    379     /**
    380      * Test to verify onProfileConnectionStateChanged() for two hearing aid devices where both
    381      * devices are disconnected and they get connected.
    382      */
    383     @Test
    384     public void testOnProfileConnectionStateChanged_twoDevicesConnected_oneDeviceVisible() {
    385         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    386             mLocalProfileManager, mDevice1);
    387         assertThat(cachedDevice1).isNotNull();
    388         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
    389             mLocalProfileManager, mDevice2);
    390         assertThat(cachedDevice2).isNotNull();
    391         cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
    392         cachedDevice2.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
    393         when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
    394         when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
    395 
    396         // Since both devices do not have hiSyncId, they should be added in mCachedDevices.
    397         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(2);
    398         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty();
    399         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).isEmpty();
    400 
    401         cachedDevice1.setHiSyncId(HISYNCID1);
    402         cachedDevice2.setHiSyncId(HISYNCID1);
    403         mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1);
    404 
    405         // There should be one cached device but can be either one.
    406         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(1);
    407 
    408         // Connect the Device 1
    409         mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice1,
    410             BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID);
    411 
    412         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice1);
    413         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).
    414             containsExactly(HISYNCID1, cachedDevice1);
    415         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).contains(cachedDevice2);
    416         assertThat(mCachedDeviceManager.mCachedDevices).contains(cachedDevice1);
    417 
    418         when(mHearingAidProfile.getConnectionStatus(mDevice1)).
    419             thenReturn(BluetoothProfile.STATE_CONNECTED);
    420         when(mHearingAidProfile.getConnectionStatus(mDevice2)).
    421             thenReturn(BluetoothProfile.STATE_DISCONNECTED);
    422 
    423         // Connect the Device 2
    424         mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice2,
    425             BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID);
    426 
    427         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(1);
    428         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).hasSize(1);
    429         assertThat(mCachedDeviceManager.mCachedDevices).hasSize(1);
    430         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).hasSize(1);
    431     }
    432 
    433     /**
    434      * Test to verify onProfileConnectionStateChanged() for two hearing aid devices where both
    435      * devices are connected and they get disconnected.
    436      */
    437     @Test
    438     public void testOnProfileConnectionStateChanged_twoDevicesDisconnected_oneDeviceVisible() {
    439         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    440             mLocalProfileManager, mDevice1);
    441         assertThat(cachedDevice1).isNotNull();
    442         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
    443             mLocalProfileManager, mDevice2);
    444         assertThat(cachedDevice2).isNotNull();
    445         cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
    446         cachedDevice2.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
    447 
    448         when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
    449         when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
    450         when(mHearingAidProfile.getConnectionStatus(mDevice1)).
    451             thenReturn(BluetoothProfile.STATE_CONNECTED);
    452         when(mHearingAidProfile.getConnectionStatus(mDevice2)).
    453             thenReturn(BluetoothProfile.STATE_CONNECTED);
    454 
    455         // Since both devices do not have hiSyncId, they should be added in mCachedDevices.
    456         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(2);
    457         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty();
    458         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).isEmpty();
    459 
    460         cachedDevice1.setHiSyncId(HISYNCID1);
    461         cachedDevice2.setHiSyncId(HISYNCID1);
    462         mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1);
    463 
    464         /* Disconnect the Device 1 */
    465         mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice1,
    466             BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.HEARING_AID);
    467 
    468         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice2);
    469         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).contains(cachedDevice1);
    470         assertThat(mCachedDeviceManager.mCachedDevices).contains(cachedDevice2);
    471         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids)
    472             .containsExactly(HISYNCID1, cachedDevice2);
    473 
    474         when(mHearingAidProfile.getConnectionStatus(mDevice1)).
    475             thenReturn(BluetoothProfile.STATE_DISCONNECTED);
    476         when(mHearingAidProfile.getConnectionStatus(mDevice2)).
    477             thenReturn(BluetoothProfile.STATE_CONNECTED);
    478 
    479         /* Disconnect the Device 2 */
    480         mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice2,
    481             BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.HEARING_AID);
    482 
    483         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(1);
    484         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).hasSize(1);
    485         assertThat(mCachedDeviceManager.mCachedDevices).hasSize(1);
    486         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).hasSize(1);
    487     }
    488 
    489     /**
    490      * Test to verify OnDeviceUnpaired() for a paired hearing Aid device pair.
    491      */
    492     @Test
    493     public void testOnDeviceUnpaired_bothHearingAidsPaired_removesItsPairFromList() {
    494         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    495             mLocalProfileManager, mDevice1);
    496         assertThat(cachedDevice1).isNotNull();
    497         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
    498             mLocalProfileManager, mDevice2);
    499         assertThat(cachedDevice2).isNotNull();
    500 
    501         cachedDevice1.setHiSyncId(HISYNCID1);
    502         cachedDevice2.setHiSyncId(HISYNCID1);
    503         mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1);
    504 
    505         // Check if one device is in mCachedDevices and one in mHearingAidDevicesNotAddedInCache.
    506         Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy();
    507         assertThat(devices).contains(cachedDevice2);
    508         assertThat(devices).doesNotContain(cachedDevice1);
    509         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).contains(cachedDevice1);
    510         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache)
    511             .doesNotContain(cachedDevice2);
    512 
    513         // Call onDeviceUnpaired for the one in mCachedDevices.
    514         mCachedDeviceManager.onDeviceUnpaired(cachedDevice2);
    515 
    516         // Check if its pair is removed from mHearingAidDevicesNotAddedInCache.
    517         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache)
    518             .doesNotContain(cachedDevice1);
    519     }
    520 
    521     /**
    522      * Test to verify OnDeviceUnpaired() for paired hearing Aid devices which are not a pair.
    523      */
    524     @Test
    525     public void testOnDeviceUnpaired_bothHearingAidsNotPaired_doesNotRemoveAnyDeviceFromList() {
    526         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    527             mLocalProfileManager, mDevice1);
    528         assertThat(cachedDevice1).isNotNull();
    529         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
    530             mLocalProfileManager, mDevice2);
    531         assertThat(cachedDevice2).isNotNull();
    532         CachedBluetoothDevice cachedDevice3 = mCachedDeviceManager.addDevice(mLocalAdapter,
    533             mLocalProfileManager, mDevice3);
    534         assertThat(cachedDevice2).isNotNull();
    535 
    536         cachedDevice1.setHiSyncId(HISYNCID1);
    537         cachedDevice2.setHiSyncId(HISYNCID1);
    538         cachedDevice3.setHiSyncId(HISYNCID2);
    539         mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1);
    540         mCachedDeviceManager.onHiSyncIdChanged(HISYNCID2);
    541 
    542         // Check if one device is in mCachedDevices and one in mHearingAidDevicesNotAddedInCache.
    543         Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy();
    544         assertThat(devices).contains(cachedDevice2);
    545         assertThat(devices).contains(cachedDevice3);
    546         assertThat(devices).doesNotContain(cachedDevice1);
    547         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).contains(cachedDevice1);
    548         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache)
    549             .doesNotContain(cachedDevice2);
    550         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache)
    551             .doesNotContain(cachedDevice3);
    552 
    553         // Call onDeviceUnpaired for the one in mCachedDevices with no pair.
    554         mCachedDeviceManager.onDeviceUnpaired(cachedDevice3);
    555 
    556         // Check if no list is changed.
    557         devices = mCachedDeviceManager.getCachedDevicesCopy();
    558         assertThat(devices).contains(cachedDevice2);
    559         assertThat(devices).contains(cachedDevice3);
    560         assertThat(devices).doesNotContain(cachedDevice1);
    561         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).contains(cachedDevice1);
    562         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache)
    563             .doesNotContain(cachedDevice2);
    564         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache)
    565             .doesNotContain(cachedDevice3);
    566     }
    567 
    568     /**
    569      * Test to verify addDevice() for hearing aid devices with same HiSyncId.
    570      */
    571     @Test
    572     public void testAddDevice_hearingAidDevicesWithSameHiSyncId_populateInDifferentLists() {
    573         doAnswer((invocation) -> mHearingAidProfile).when(mLocalProfileManager)
    574             .getHearingAidProfile();
    575         doAnswer((invocation) -> HISYNCID1).when(mHearingAidProfile).getHiSyncId(mDevice1);
    576         doAnswer((invocation) -> HISYNCID1).when(mHearingAidProfile).getHiSyncId(mDevice2);
    577 
    578         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    579             mLocalProfileManager, mDevice1);
    580         assertThat(cachedDevice1).isNotNull();
    581         // The first hearing aid device should be populated in mCachedDevice and
    582         // mCachedDevicesMapForHearingAids.
    583         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(1);
    584         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty();
    585         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).hasSize(1);
    586         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids.values())
    587             .contains(cachedDevice1);
    588 
    589         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
    590             mLocalProfileManager, mDevice2);
    591         assertThat(cachedDevice2).isNotNull();
    592         // The second hearing aid device should be populated in mHearingAidDevicesNotAddedInCache.
    593         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(1);
    594         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).hasSize(1);
    595         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).hasSize(1);
    596     }
    597 
    598     /**
    599      * Test to verify addDevice() for hearing aid devices with different HiSyncId.
    600      */
    601     @Test
    602     public void testAddDevice_hearingAidDevicesWithDifferentHiSyncId_populateInSameList() {
    603         doAnswer((invocation) -> mHearingAidProfile).when(mLocalProfileManager)
    604             .getHearingAidProfile();
    605         doAnswer((invocation) -> HISYNCID1).when(mHearingAidProfile).getHiSyncId(mDevice1);
    606         doAnswer((invocation) -> HISYNCID2).when(mHearingAidProfile).getHiSyncId(mDevice2);
    607         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    608             mLocalProfileManager, mDevice1);
    609         assertThat(cachedDevice1).isNotNull();
    610         // The first hearing aid device should be populated in mCachedDevice and
    611         // mCachedDevicesMapForHearingAids.
    612         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(1);
    613         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty();
    614         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).hasSize(1);
    615         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids.values())
    616             .contains(cachedDevice1);
    617 
    618         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
    619             mLocalProfileManager, mDevice2);
    620         assertThat(cachedDevice2).isNotNull();
    621         // The second hearing aid device should also be populated in mCachedDevice
    622         // and mCachedDevicesMapForHearingAids as its not a pair of the first one.
    623         assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(2);
    624         assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty();
    625         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).hasSize(2);
    626         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids.values())
    627             .contains(cachedDevice1);
    628         assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids.values())
    629             .contains(cachedDevice2);
    630     }
    631 
    632     /**
    633      * Test to verify getHearingAidPairDeviceSummary() for hearing aid devices with same HiSyncId.
    634      */
    635     @Test
    636     public void testGetHearingAidPairDeviceSummary_bothHearingAidsPaired_returnsSummaryOfPair() {
    637         mCachedDevice1.setHiSyncId(HISYNCID1);
    638         mCachedDevice2.setHiSyncId(HISYNCID1);
    639         mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
    640         mCachedDeviceManager.mHearingAidDevicesNotAddedInCache.add(mCachedDevice2);
    641         doAnswer((invocation) -> DEVICE_SUMMARY_1).when(mCachedDevice1).getConnectionSummary();
    642         doAnswer((invocation) -> DEVICE_SUMMARY_2).when(mCachedDevice2).getConnectionSummary();
    643 
    644         assertThat(mCachedDeviceManager.getHearingAidPairDeviceSummary(mCachedDevice1))
    645             .isEqualTo(DEVICE_SUMMARY_2);
    646     }
    647 
    648     /**
    649      * Test to verify getHearingAidPairDeviceSummary() for hearing aid devices with different
    650      * HiSyncId.
    651      */
    652     @Test
    653     public void testGetHearingAidPairDeviceSummary_bothHearingAidsNotPaired_returnsNull() {
    654         mCachedDevice1.setHiSyncId(HISYNCID1);
    655         mCachedDevice2.setHiSyncId(HISYNCID2);
    656         mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
    657         mCachedDeviceManager.mHearingAidDevicesNotAddedInCache.add(mCachedDevice2);
    658         doAnswer((invocation) -> DEVICE_SUMMARY_1).when(mCachedDevice1).getConnectionSummary();
    659         doAnswer((invocation) -> DEVICE_SUMMARY_2).when(mCachedDevice2).getConnectionSummary();
    660 
    661         assertThat(mCachedDeviceManager.getHearingAidPairDeviceSummary(mCachedDevice1))
    662             .isEqualTo(null);
    663     }
    664 
    665     /**
    666      * Test to verify updateHearingAidsDevices().
    667      */
    668     @Test
    669     public void testUpdateHearingAidDevices_hiSyncIdAvailable_setsHiSyncId() {
    670         doAnswer((invocation) -> mHearingAidProfile).when(mLocalProfileManager)
    671             .getHearingAidProfile();
    672         doAnswer((invocation) -> HISYNCID1).when(mHearingAidProfile).getHiSyncId(mDevice1);
    673         doAnswer((invocation) -> HISYNCID1).when(mHearingAidProfile).getHiSyncId(mDevice2);
    674         mCachedDeviceManager.mCachedDevices.add(mCachedDevice1);
    675         mCachedDeviceManager.mCachedDevices.add(mCachedDevice2);
    676         mCachedDeviceManager.updateHearingAidsDevices(mLocalProfileManager);
    677 
    678         // Assert that the mCachedDevice1 and mCachedDevice2 have an updated HiSyncId.
    679         assertThat(mCachedDevice1.getHiSyncId()).isEqualTo(HISYNCID1);
    680         assertThat(mCachedDevice2.getHiSyncId()).isEqualTo(HISYNCID1);
    681     }
    682 
    683     /**
    684      * Test to verify onBtClassChanged().
    685      */
    686     @Test
    687     public void testOnBtClassChanged_validBtClass_classChanged() {
    688         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    689                 mLocalProfileManager, mDevice1);
    690         assertThat(cachedDevice1).isNotNull();
    691         assertThat(cachedDevice1.getBtClass()).isEqualTo(DEVICE_CLASS_1);
    692 
    693         final BluetoothClass newBluetoothClass = DEVICE_CLASS_2;
    694         when(mDevice1.getBluetoothClass()).thenReturn(newBluetoothClass);
    695         mCachedDeviceManager.onBtClassChanged(mDevice1);
    696         assertThat(cachedDevice1.getBtClass()).isEqualTo(newBluetoothClass);
    697     }
    698 
    699     /**
    700      * Test to verify onDeviceDisappeared().
    701      */
    702     @Test
    703     public void testOnDeviceDisappeared_deviceBondedUnbonded_unbondedDeviceDisappeared() {
    704         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    705                 mLocalProfileManager, mDevice1);
    706         assertThat(cachedDevice1).isNotNull();
    707 
    708         when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
    709         assertThat(mCachedDeviceManager.onDeviceDisappeared(cachedDevice1)).isFalse();
    710 
    711         when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
    712         assertThat(mCachedDeviceManager.onDeviceDisappeared(cachedDevice1)).isTrue();
    713     }
    714 
    715     /**
    716      * Test to verify onActiveDeviceChanged().
    717      */
    718     @Test
    719     public void testOnActiveDeviceChanged_connectedDevices_activeDeviceChanged() {
    720         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    721                 mLocalProfileManager, mDevice1);
    722         assertThat(cachedDevice1).isNotNull();
    723         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
    724                 mLocalProfileManager, mDevice2);
    725         assertThat(cachedDevice2).isNotNull();
    726 
    727         when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
    728         when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
    729 
    730         // Connect both devices for A2DP and HFP
    731         cachedDevice1.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
    732         cachedDevice2.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
    733         cachedDevice1.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
    734         cachedDevice2.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
    735 
    736         // Verify that both devices are connected and none is Active
    737         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    738         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
    739         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    740         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
    741 
    742         // The first device is active for A2DP, the second device is active for HFP
    743         mCachedDeviceManager.onActiveDeviceChanged(cachedDevice1, BluetoothProfile.A2DP);
    744         mCachedDeviceManager.onActiveDeviceChanged(cachedDevice2, BluetoothProfile.HEADSET);
    745         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isTrue();
    746         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
    747         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    748         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isTrue();
    749 
    750         // The first device is active for A2DP and HFP
    751         mCachedDeviceManager.onActiveDeviceChanged(cachedDevice1, BluetoothProfile.HEADSET);
    752         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isTrue();
    753         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isTrue();
    754         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    755         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
    756 
    757         // The second device is active for A2DP and HFP
    758         mCachedDeviceManager.onActiveDeviceChanged(cachedDevice2, BluetoothProfile.A2DP);
    759         mCachedDeviceManager.onActiveDeviceChanged(cachedDevice2, BluetoothProfile.HEADSET);
    760         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    761         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
    762         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isTrue();
    763         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isTrue();
    764 
    765         // No active device for A2DP
    766         mCachedDeviceManager.onActiveDeviceChanged(null, BluetoothProfile.A2DP);
    767         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    768         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
    769         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    770         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isTrue();
    771 
    772         // No active device for HFP
    773         mCachedDeviceManager.onActiveDeviceChanged(null, BluetoothProfile.HEADSET);
    774         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    775         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
    776         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    777         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
    778     }
    779 
    780     /**
    781      * Test to verify onActiveDeviceChanged() with A2DP and Hearing Aid.
    782      */
    783     @Test
    784     public void testOnActiveDeviceChanged_withA2dpAndHearingAid() {
    785         CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter,
    786                 mLocalProfileManager, mDevice1);
    787         assertThat(cachedDevice1).isNotNull();
    788         CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter,
    789                 mLocalProfileManager, mDevice2);
    790         assertThat(cachedDevice2).isNotNull();
    791 
    792         when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
    793         when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
    794 
    795         // Connect device1 for A2DP and HFP and device2 for Hearing Aid
    796         cachedDevice1.onProfileStateChanged(mA2dpProfile, BluetoothProfile.STATE_CONNECTED);
    797         cachedDevice1.onProfileStateChanged(mHfpProfile, BluetoothProfile.STATE_CONNECTED);
    798         cachedDevice2.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED);
    799 
    800         // Verify that both devices are connected and none is Active
    801         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    802         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
    803         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEARING_AID)).isFalse();
    804         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    805         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
    806         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEARING_AID)).isFalse();
    807 
    808         // The first device is active for A2DP and HFP
    809         mCachedDeviceManager.onActiveDeviceChanged(cachedDevice1, BluetoothProfile.A2DP);
    810         mCachedDeviceManager.onActiveDeviceChanged(cachedDevice1, BluetoothProfile.HEADSET);
    811         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isTrue();
    812         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isTrue();
    813         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEARING_AID)).isFalse();
    814         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    815         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
    816         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEARING_AID)).isFalse();
    817 
    818         // The second device is active for Hearing Aid and the first device is not active
    819         mCachedDeviceManager.onActiveDeviceChanged(null, BluetoothProfile.A2DP);
    820         mCachedDeviceManager.onActiveDeviceChanged(null, BluetoothProfile.HEADSET);
    821         mCachedDeviceManager.onActiveDeviceChanged(cachedDevice2, BluetoothProfile.HEARING_AID);
    822         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    823         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
    824         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEARING_AID)).isFalse();
    825         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    826         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
    827         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEARING_AID)).isTrue();
    828 
    829         // No active device for Hearing Aid
    830         mCachedDeviceManager.onActiveDeviceChanged(null, BluetoothProfile.HEARING_AID);
    831         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    832         assertThat(cachedDevice1.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
    833         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    834         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.A2DP)).isFalse();
    835         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEADSET)).isFalse();
    836         assertThat(cachedDevice2.isActiveDevice(BluetoothProfile.HEARING_AID)).isFalse();
    837     }
    838 }
    839