Loading packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +1 −0 Original line number Diff line number Diff line Loading @@ -505,5 +505,6 @@ public class BluetoothEventManager { callback.onProfileConnectionStateChanged(device, state, bluetoothProfile); } } mDeviceManager.onProfileConnectionStateChanged(device, state, bluetoothProfile); } } packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java +96 −7 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.settingslib.bluetooth; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.util.Log; Loading Loading @@ -323,16 +324,31 @@ public class CachedBluetoothDeviceManager { if (cachedDevice.getHiSyncId() == hiSyncId) { if (firstMatchedIndex != -1) { /* Found the second one */ mCachedDevices.remove(i); mHearingAidDevicesNotAddedInCache.add(cachedDevice); int indexToRemoveFromUi; CachedBluetoothDevice deviceToRemoveFromUi; // Since the hiSyncIds have been updated for a connected pair of hearing aids, // we remove the entry of one the hearing aids from the UI. Unless the // hiSyncId get updated, the system does not know its a hearing aid, so we add // hiSyncId get updated, the system does not know it is a hearing aid, so we add // both the hearing aids as separate entries in the UI first, then remove one // of them after the hiSyncId is populated. log("onHiSyncIdChanged: removed device=" + cachedDevice + ", with hiSyncId=" + hiSyncId); mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice); // of them after the hiSyncId is populated. We will choose the device that // is not connected to be removed. if (cachedDevice.isConnected()) { indexToRemoveFromUi = firstMatchedIndex; deviceToRemoveFromUi = mCachedDevices.get(firstMatchedIndex); mCachedDevicesMapForHearingAids.put(hiSyncId, cachedDevice); } else { indexToRemoveFromUi = i; deviceToRemoveFromUi = cachedDevice; mCachedDevicesMapForHearingAids.put(hiSyncId, mCachedDevices.get(firstMatchedIndex)); } mCachedDevices.remove(indexToRemoveFromUi); mHearingAidDevicesNotAddedInCache.add(deviceToRemoveFromUi); log("onHiSyncIdChanged: removed from UI device=" + deviceToRemoveFromUi + ", with hiSyncId=" + hiSyncId); mBtManager.getEventManager().dispatchDeviceRemoved(deviceToRemoveFromUi); break; } else { mCachedDevicesMapForHearingAids.put(hiSyncId, cachedDevice); Loading @@ -342,6 +358,72 @@ public class CachedBluetoothDeviceManager { } } private CachedBluetoothDevice getHearingAidOtherDevice(CachedBluetoothDevice thisDevice, long hiSyncId) { if (hiSyncId == BluetoothHearingAid.HI_SYNC_ID_INVALID) { return null; } // Searched the lists for the other side device with the matching hiSyncId. for (CachedBluetoothDevice notCachedDevice : mHearingAidDevicesNotAddedInCache) { if ((hiSyncId == notCachedDevice.getHiSyncId()) && (!Objects.equals(notCachedDevice, thisDevice))) { return notCachedDevice; } } CachedBluetoothDevice cachedDevice = mCachedDevicesMapForHearingAids.get(hiSyncId); if (!Objects.equals(cachedDevice, thisDevice)) { return cachedDevice; } return null; } private void hearingAidSwitchDisplayDevice(CachedBluetoothDevice toDisplayDevice, CachedBluetoothDevice toHideDevice, long hiSyncId) { log("hearingAidSwitchDisplayDevice: toDisplayDevice=" + toDisplayDevice + ", toHideDevice=" + toHideDevice); // Remove the "toHideDevice" device from the UI. mHearingAidDevicesNotAddedInCache.add(toHideDevice); mCachedDevices.remove(toHideDevice); mBtManager.getEventManager().dispatchDeviceRemoved(toHideDevice); // Add the "toDisplayDevice" device to the UI. mHearingAidDevicesNotAddedInCache.remove(toDisplayDevice); mCachedDevices.add(toDisplayDevice); mCachedDevicesMapForHearingAids.put(hiSyncId, toDisplayDevice); mBtManager.getEventManager().dispatchDeviceAdded(toDisplayDevice); } public synchronized void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state, int bluetoothProfile) { if (bluetoothProfile == BluetoothProfile.HEARING_AID && cachedDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID && cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) { long hiSyncId = cachedDevice.getHiSyncId(); CachedBluetoothDevice otherDevice = getHearingAidOtherDevice(cachedDevice, hiSyncId); if (otherDevice == null) { // no other side device. Nothing to do. return; } if (state == BluetoothProfile.STATE_CONNECTED && mHearingAidDevicesNotAddedInCache.contains(cachedDevice)) { hearingAidSwitchDisplayDevice(cachedDevice, otherDevice, hiSyncId); } else if (state == BluetoothProfile.STATE_DISCONNECTED && otherDevice.isConnected()) { CachedBluetoothDevice mapDevice = mCachedDevicesMapForHearingAids.get(hiSyncId); if ((mapDevice != null) && (Objects.equals(cachedDevice, mapDevice))) { hearingAidSwitchDisplayDevice(otherDevice, cachedDevice, hiSyncId); } } } } public synchronized void onDeviceUnpaired(CachedBluetoothDevice device) { final long hiSyncId = device.getHiSyncId(); Loading @@ -353,9 +435,16 @@ public class CachedBluetoothDeviceManager { // TODO: Look for more cleanups on unpairing the device. mHearingAidDevicesNotAddedInCache.remove(i); if (device == cachedDevice) continue; log("onDeviceUnpaired: Unpair device=" + cachedDevice); cachedDevice.unpair(); } } CachedBluetoothDevice mappedDevice = mCachedDevicesMapForHearingAids.get(hiSyncId); if ((mappedDevice != null) && (!Objects.equals(device, mappedDevice))) { log("onDeviceUnpaired: Unpair mapped device=" + mappedDevice); mappedDevice.unpair(); } } public synchronized void dispatchAudioModeChanged() { Loading packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java +3 −0 Original line number Diff line number Diff line Loading @@ -98,5 +98,8 @@ public class BluetoothEventManagerTest { verify(mBluetoothCallback).onProfileConnectionStateChanged(mCachedBluetoothDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); verify(mCachedDeviceManager).onProfileConnectionStateChanged(mCachedBluetoothDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); } } packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java +189 −5 Original line number Diff line number Diff line Loading @@ -235,7 +235,7 @@ public class CachedBluetoothDeviceManagerTest { * Test to verify onHiSyncIdChanged() for hearing aid devices with same HiSyncId. */ @Test public void testOnDeviceAdded_sameHiSyncId_populateInDifferentLists() { public void testOnHiSyncIdChanged_sameHiSyncId_populateInDifferentLists() { CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice1); assertThat(cachedDevice1).isNotNull(); Loading @@ -261,16 +261,53 @@ public class CachedBluetoothDeviceManagerTest { assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).hasSize(1); Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy(); assertThat(devices).contains(cachedDevice2); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids.values()) .contains(cachedDevice2); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).contains(cachedDevice1); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids) .containsKey(HISYNCID1); } /** * Test to verify onHiSyncIdChanged() for 2 hearing aid devices with same HiSyncId but one * device is connected and other is disconnected. The connected device should be chosen. */ @Test public void testOnHiSyncIdChanged_sameHiSyncIdAndOneConnected_chooseConnectedDevice() { CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice1); assertThat(cachedDevice1).isNotNull(); CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice2); assertThat(cachedDevice2).isNotNull(); cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); cachedDevice2.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); /* Device 1 is connected and Device 2 is disconnected */ when(mHearingAidProfile.getConnectionStatus(mDevice1)). thenReturn(BluetoothProfile.STATE_CONNECTED); when(mHearingAidProfile.getConnectionStatus(mDevice2)). thenReturn(BluetoothProfile.STATE_DISCONNECTED); // Since both devices do not have hiSyncId, they should be added in mCachedDevices. assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(2); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty(); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).isEmpty(); cachedDevice1.setHiSyncId(HISYNCID1); cachedDevice2.setHiSyncId(HISYNCID1); mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1); // Only the connected device, device 1, should be visible to UI. assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice1); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids). containsExactly(HISYNCID1, cachedDevice1); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache). containsExactly(cachedDevice2); } /** * Test to verify onHiSyncIdChanged() for hearing aid devices with different HiSyncId. */ @Test public void testOnDeviceAdded_differentHiSyncId_populateInSameList() { public void testOnHiSyncIdChanged_differentHiSyncId_populateInSameList() { CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice1); assertThat(cachedDevice1).isNotNull(); Loading Loading @@ -302,6 +339,153 @@ public class CachedBluetoothDeviceManagerTest { .contains(cachedDevice2); } /** * Test to verify onProfileConnectionStateChanged() for single hearing aid device connection. */ @Test public void testOnProfileConnectionStateChanged_singleDeviceConnected_visible() { CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice1); assertThat(cachedDevice1).isNotNull(); cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); // Since both devices do not have hiSyncId, they should be added in mCachedDevices. assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice1); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty(); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).isEmpty(); cachedDevice1.setHiSyncId(HISYNCID1); mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1); // Connect the Device 1 mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice1, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID); assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice1); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids). containsExactly(HISYNCID1, cachedDevice1); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty(); // Disconnect the Device 1 mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice1, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.HEARING_AID); assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice1); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids). containsExactly(HISYNCID1, cachedDevice1); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty(); } /** * Test to verify onProfileConnectionStateChanged() for two hearing aid devices where both * devices are disconnected and they get connected. */ @Test public void testOnProfileConnectionStateChanged_twoDevicesConnected_oneDeviceVisible() { CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice1); assertThat(cachedDevice1).isNotNull(); CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice2); assertThat(cachedDevice2).isNotNull(); cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); cachedDevice2.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); // Since both devices do not have hiSyncId, they should be added in mCachedDevices. assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(2); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty(); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).isEmpty(); cachedDevice1.setHiSyncId(HISYNCID1); cachedDevice2.setHiSyncId(HISYNCID1); mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1); // There should be one cached device but can be either one. assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(1); // Connect the Device 1 mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice1, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID); assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice1); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids). containsExactly(HISYNCID1, cachedDevice1); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).contains(cachedDevice2); assertThat(mCachedDeviceManager.mCachedDevices).contains(cachedDevice1); when(mHearingAidProfile.getConnectionStatus(mDevice1)). thenReturn(BluetoothProfile.STATE_CONNECTED); when(mHearingAidProfile.getConnectionStatus(mDevice2)). thenReturn(BluetoothProfile.STATE_DISCONNECTED); // Connect the Device 2 mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice2, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID); assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(1); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).hasSize(1); assertThat(mCachedDeviceManager.mCachedDevices).hasSize(1); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).hasSize(1); } /** * Test to verify onProfileConnectionStateChanged() for two hearing aid devices where both * devices are connected and they get disconnected. */ @Test public void testOnProfileConnectionStateChanged_twoDevicesDisconnected_oneDeviceVisible() { CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice1); assertThat(cachedDevice1).isNotNull(); CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice2); assertThat(cachedDevice2).isNotNull(); cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); cachedDevice2.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); when(mHearingAidProfile.getConnectionStatus(mDevice1)). thenReturn(BluetoothProfile.STATE_CONNECTED); when(mHearingAidProfile.getConnectionStatus(mDevice2)). thenReturn(BluetoothProfile.STATE_CONNECTED); // Since both devices do not have hiSyncId, they should be added in mCachedDevices. assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(2); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty(); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).isEmpty(); cachedDevice1.setHiSyncId(HISYNCID1); cachedDevice2.setHiSyncId(HISYNCID1); mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1); /* Disconnect the Device 1 */ mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice1, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.HEARING_AID); assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice2); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).contains(cachedDevice1); assertThat(mCachedDeviceManager.mCachedDevices).contains(cachedDevice2); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids) .containsExactly(HISYNCID1, cachedDevice2); when(mHearingAidProfile.getConnectionStatus(mDevice1)). thenReturn(BluetoothProfile.STATE_DISCONNECTED); when(mHearingAidProfile.getConnectionStatus(mDevice2)). thenReturn(BluetoothProfile.STATE_CONNECTED); /* Disconnect the Device 2 */ mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice2, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.HEARING_AID); assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(1); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).hasSize(1); assertThat(mCachedDeviceManager.mCachedDevices).hasSize(1); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).hasSize(1); } /** * Test to verify OnDeviceUnpaired() for a paired hearing Aid device pair. */ Loading Loading
packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +1 −0 Original line number Diff line number Diff line Loading @@ -505,5 +505,6 @@ public class BluetoothEventManager { callback.onProfileConnectionStateChanged(device, state, bluetoothProfile); } } mDeviceManager.onProfileConnectionStateChanged(device, state, bluetoothProfile); } }
packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java +96 −7 Original line number Diff line number Diff line Loading @@ -19,6 +19,7 @@ package com.android.settingslib.bluetooth; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothProfile; import android.content.Context; import android.util.Log; Loading Loading @@ -323,16 +324,31 @@ public class CachedBluetoothDeviceManager { if (cachedDevice.getHiSyncId() == hiSyncId) { if (firstMatchedIndex != -1) { /* Found the second one */ mCachedDevices.remove(i); mHearingAidDevicesNotAddedInCache.add(cachedDevice); int indexToRemoveFromUi; CachedBluetoothDevice deviceToRemoveFromUi; // Since the hiSyncIds have been updated for a connected pair of hearing aids, // we remove the entry of one the hearing aids from the UI. Unless the // hiSyncId get updated, the system does not know its a hearing aid, so we add // hiSyncId get updated, the system does not know it is a hearing aid, so we add // both the hearing aids as separate entries in the UI first, then remove one // of them after the hiSyncId is populated. log("onHiSyncIdChanged: removed device=" + cachedDevice + ", with hiSyncId=" + hiSyncId); mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice); // of them after the hiSyncId is populated. We will choose the device that // is not connected to be removed. if (cachedDevice.isConnected()) { indexToRemoveFromUi = firstMatchedIndex; deviceToRemoveFromUi = mCachedDevices.get(firstMatchedIndex); mCachedDevicesMapForHearingAids.put(hiSyncId, cachedDevice); } else { indexToRemoveFromUi = i; deviceToRemoveFromUi = cachedDevice; mCachedDevicesMapForHearingAids.put(hiSyncId, mCachedDevices.get(firstMatchedIndex)); } mCachedDevices.remove(indexToRemoveFromUi); mHearingAidDevicesNotAddedInCache.add(deviceToRemoveFromUi); log("onHiSyncIdChanged: removed from UI device=" + deviceToRemoveFromUi + ", with hiSyncId=" + hiSyncId); mBtManager.getEventManager().dispatchDeviceRemoved(deviceToRemoveFromUi); break; } else { mCachedDevicesMapForHearingAids.put(hiSyncId, cachedDevice); Loading @@ -342,6 +358,72 @@ public class CachedBluetoothDeviceManager { } } private CachedBluetoothDevice getHearingAidOtherDevice(CachedBluetoothDevice thisDevice, long hiSyncId) { if (hiSyncId == BluetoothHearingAid.HI_SYNC_ID_INVALID) { return null; } // Searched the lists for the other side device with the matching hiSyncId. for (CachedBluetoothDevice notCachedDevice : mHearingAidDevicesNotAddedInCache) { if ((hiSyncId == notCachedDevice.getHiSyncId()) && (!Objects.equals(notCachedDevice, thisDevice))) { return notCachedDevice; } } CachedBluetoothDevice cachedDevice = mCachedDevicesMapForHearingAids.get(hiSyncId); if (!Objects.equals(cachedDevice, thisDevice)) { return cachedDevice; } return null; } private void hearingAidSwitchDisplayDevice(CachedBluetoothDevice toDisplayDevice, CachedBluetoothDevice toHideDevice, long hiSyncId) { log("hearingAidSwitchDisplayDevice: toDisplayDevice=" + toDisplayDevice + ", toHideDevice=" + toHideDevice); // Remove the "toHideDevice" device from the UI. mHearingAidDevicesNotAddedInCache.add(toHideDevice); mCachedDevices.remove(toHideDevice); mBtManager.getEventManager().dispatchDeviceRemoved(toHideDevice); // Add the "toDisplayDevice" device to the UI. mHearingAidDevicesNotAddedInCache.remove(toDisplayDevice); mCachedDevices.add(toDisplayDevice); mCachedDevicesMapForHearingAids.put(hiSyncId, toDisplayDevice); mBtManager.getEventManager().dispatchDeviceAdded(toDisplayDevice); } public synchronized void onProfileConnectionStateChanged(CachedBluetoothDevice cachedDevice, int state, int bluetoothProfile) { if (bluetoothProfile == BluetoothProfile.HEARING_AID && cachedDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID && cachedDevice.getBondState() == BluetoothDevice.BOND_BONDED) { long hiSyncId = cachedDevice.getHiSyncId(); CachedBluetoothDevice otherDevice = getHearingAidOtherDevice(cachedDevice, hiSyncId); if (otherDevice == null) { // no other side device. Nothing to do. return; } if (state == BluetoothProfile.STATE_CONNECTED && mHearingAidDevicesNotAddedInCache.contains(cachedDevice)) { hearingAidSwitchDisplayDevice(cachedDevice, otherDevice, hiSyncId); } else if (state == BluetoothProfile.STATE_DISCONNECTED && otherDevice.isConnected()) { CachedBluetoothDevice mapDevice = mCachedDevicesMapForHearingAids.get(hiSyncId); if ((mapDevice != null) && (Objects.equals(cachedDevice, mapDevice))) { hearingAidSwitchDisplayDevice(otherDevice, cachedDevice, hiSyncId); } } } } public synchronized void onDeviceUnpaired(CachedBluetoothDevice device) { final long hiSyncId = device.getHiSyncId(); Loading @@ -353,9 +435,16 @@ public class CachedBluetoothDeviceManager { // TODO: Look for more cleanups on unpairing the device. mHearingAidDevicesNotAddedInCache.remove(i); if (device == cachedDevice) continue; log("onDeviceUnpaired: Unpair device=" + cachedDevice); cachedDevice.unpair(); } } CachedBluetoothDevice mappedDevice = mCachedDevicesMapForHearingAids.get(hiSyncId); if ((mappedDevice != null) && (!Objects.equals(device, mappedDevice))) { log("onDeviceUnpaired: Unpair mapped device=" + mappedDevice); mappedDevice.unpair(); } } public synchronized void dispatchAudioModeChanged() { Loading
packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/BluetoothEventManagerTest.java +3 −0 Original line number Diff line number Diff line Loading @@ -98,5 +98,8 @@ public class BluetoothEventManagerTest { verify(mBluetoothCallback).onProfileConnectionStateChanged(mCachedBluetoothDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); verify(mCachedDeviceManager).onProfileConnectionStateChanged(mCachedBluetoothDevice, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP); } }
packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java +189 −5 Original line number Diff line number Diff line Loading @@ -235,7 +235,7 @@ public class CachedBluetoothDeviceManagerTest { * Test to verify onHiSyncIdChanged() for hearing aid devices with same HiSyncId. */ @Test public void testOnDeviceAdded_sameHiSyncId_populateInDifferentLists() { public void testOnHiSyncIdChanged_sameHiSyncId_populateInDifferentLists() { CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice1); assertThat(cachedDevice1).isNotNull(); Loading @@ -261,16 +261,53 @@ public class CachedBluetoothDeviceManagerTest { assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).hasSize(1); Collection<CachedBluetoothDevice> devices = mCachedDeviceManager.getCachedDevicesCopy(); assertThat(devices).contains(cachedDevice2); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids.values()) .contains(cachedDevice2); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).contains(cachedDevice1); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids) .containsKey(HISYNCID1); } /** * Test to verify onHiSyncIdChanged() for 2 hearing aid devices with same HiSyncId but one * device is connected and other is disconnected. The connected device should be chosen. */ @Test public void testOnHiSyncIdChanged_sameHiSyncIdAndOneConnected_chooseConnectedDevice() { CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice1); assertThat(cachedDevice1).isNotNull(); CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice2); assertThat(cachedDevice2).isNotNull(); cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); cachedDevice2.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); /* Device 1 is connected and Device 2 is disconnected */ when(mHearingAidProfile.getConnectionStatus(mDevice1)). thenReturn(BluetoothProfile.STATE_CONNECTED); when(mHearingAidProfile.getConnectionStatus(mDevice2)). thenReturn(BluetoothProfile.STATE_DISCONNECTED); // Since both devices do not have hiSyncId, they should be added in mCachedDevices. assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(2); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty(); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).isEmpty(); cachedDevice1.setHiSyncId(HISYNCID1); cachedDevice2.setHiSyncId(HISYNCID1); mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1); // Only the connected device, device 1, should be visible to UI. assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice1); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids). containsExactly(HISYNCID1, cachedDevice1); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache). containsExactly(cachedDevice2); } /** * Test to verify onHiSyncIdChanged() for hearing aid devices with different HiSyncId. */ @Test public void testOnDeviceAdded_differentHiSyncId_populateInSameList() { public void testOnHiSyncIdChanged_differentHiSyncId_populateInSameList() { CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice1); assertThat(cachedDevice1).isNotNull(); Loading Loading @@ -302,6 +339,153 @@ public class CachedBluetoothDeviceManagerTest { .contains(cachedDevice2); } /** * Test to verify onProfileConnectionStateChanged() for single hearing aid device connection. */ @Test public void testOnProfileConnectionStateChanged_singleDeviceConnected_visible() { CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice1); assertThat(cachedDevice1).isNotNull(); cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); // Since both devices do not have hiSyncId, they should be added in mCachedDevices. assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice1); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty(); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).isEmpty(); cachedDevice1.setHiSyncId(HISYNCID1); mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1); // Connect the Device 1 mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice1, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID); assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice1); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids). containsExactly(HISYNCID1, cachedDevice1); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty(); // Disconnect the Device 1 mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice1, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.HEARING_AID); assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice1); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids). containsExactly(HISYNCID1, cachedDevice1); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty(); } /** * Test to verify onProfileConnectionStateChanged() for two hearing aid devices where both * devices are disconnected and they get connected. */ @Test public void testOnProfileConnectionStateChanged_twoDevicesConnected_oneDeviceVisible() { CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice1); assertThat(cachedDevice1).isNotNull(); CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice2); assertThat(cachedDevice2).isNotNull(); cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); cachedDevice2.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); // Since both devices do not have hiSyncId, they should be added in mCachedDevices. assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(2); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty(); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).isEmpty(); cachedDevice1.setHiSyncId(HISYNCID1); cachedDevice2.setHiSyncId(HISYNCID1); mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1); // There should be one cached device but can be either one. assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(1); // Connect the Device 1 mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice1, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID); assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice1); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids). containsExactly(HISYNCID1, cachedDevice1); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).contains(cachedDevice2); assertThat(mCachedDeviceManager.mCachedDevices).contains(cachedDevice1); when(mHearingAidProfile.getConnectionStatus(mDevice1)). thenReturn(BluetoothProfile.STATE_CONNECTED); when(mHearingAidProfile.getConnectionStatus(mDevice2)). thenReturn(BluetoothProfile.STATE_DISCONNECTED); // Connect the Device 2 mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice2, BluetoothProfile.STATE_CONNECTED, BluetoothProfile.HEARING_AID); assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(1); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).hasSize(1); assertThat(mCachedDeviceManager.mCachedDevices).hasSize(1); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).hasSize(1); } /** * Test to verify onProfileConnectionStateChanged() for two hearing aid devices where both * devices are connected and they get disconnected. */ @Test public void testOnProfileConnectionStateChanged_twoDevicesDisconnected_oneDeviceVisible() { CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice1); assertThat(cachedDevice1).isNotNull(); CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mLocalAdapter, mLocalProfileManager, mDevice2); assertThat(cachedDevice2).isNotNull(); cachedDevice1.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); cachedDevice2.onProfileStateChanged(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED); when(mHearingAidProfile.getConnectionStatus(mDevice1)). thenReturn(BluetoothProfile.STATE_CONNECTED); when(mHearingAidProfile.getConnectionStatus(mDevice2)). thenReturn(BluetoothProfile.STATE_CONNECTED); // Since both devices do not have hiSyncId, they should be added in mCachedDevices. assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(2); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).isEmpty(); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).isEmpty(); cachedDevice1.setHiSyncId(HISYNCID1); cachedDevice2.setHiSyncId(HISYNCID1); mCachedDeviceManager.onHiSyncIdChanged(HISYNCID1); /* Disconnect the Device 1 */ mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice1, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.HEARING_AID); assertThat(mCachedDeviceManager.getCachedDevicesCopy()).containsExactly(cachedDevice2); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).contains(cachedDevice1); assertThat(mCachedDeviceManager.mCachedDevices).contains(cachedDevice2); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids) .containsExactly(HISYNCID1, cachedDevice2); when(mHearingAidProfile.getConnectionStatus(mDevice1)). thenReturn(BluetoothProfile.STATE_DISCONNECTED); when(mHearingAidProfile.getConnectionStatus(mDevice2)). thenReturn(BluetoothProfile.STATE_CONNECTED); /* Disconnect the Device 2 */ mCachedDeviceManager.onProfileConnectionStateChanged(cachedDevice2, BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.HEARING_AID); assertThat(mCachedDeviceManager.getCachedDevicesCopy()).hasSize(1); assertThat(mCachedDeviceManager.mHearingAidDevicesNotAddedInCache).hasSize(1); assertThat(mCachedDeviceManager.mCachedDevices).hasSize(1); assertThat(mCachedDeviceManager.mCachedDevicesMapForHearingAids).hasSize(1); } /** * Test to verify OnDeviceUnpaired() for a paired hearing Aid device pair. */ Loading