From 484bc7428dee6ffcc2909d1dfa9c5355aeda7c90 Mon Sep 17 00:00:00 2001 From: Angela Wang Date: Tue, 20 Jun 2023 11:12:09 +0000 Subject: Initialize hearing aid info if the device matches hearing aid scan filters We only show connected hearing devices in the hearing devices page now. When user pairing a device from pairing page and back to the hearing devices page after the device is bonded, it's confusing no device shown in the list because we can't get hearing aid info and thus don't know it's a hearing aid while the profiles are not connected yet. Init the device with empty hearing aid info if it matches the scan filter. By doing this we can know it's a hearing aid before hearing aid related profiles are connected and can show the connecting hearing aid devices in the a11y hearing devices page to avoid confusion. Bug: 283268686 Test: atest CachedBluetoothDeviceTest Test: atest CachedBluetoothDeviceManagerTest Test: atest HearingAidDeviceMangerTest Change-Id: I3d3916f85a90c3f610a1d59ae244126788de0b2d Merged-In: I3d3916f85a90c3f610a1d59ae244126788de0b2d --- .../bluetooth/CachedBluetoothDevice.java | 6 +--- .../bluetooth/CachedBluetoothDeviceManager.java | 16 ++++++++-- .../bluetooth/HearingAidDeviceManager.java | 21 +++++++++++- .../bluetooth/HearingAidDeviceManagerTest.java | 37 ++++++++++++++++++++-- 4 files changed, 70 insertions(+), 10 deletions(-) diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index f522fd13c9f8..2118d2cbf4b3 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -356,11 +356,7 @@ public class CachedBluetoothDevice implements Comparable connectDevice(); } - public HearingAidInfo getHearingAidInfo() { - return mHearingAidInfo; - } - - public void setHearingAidInfo(HearingAidInfo hearingAidInfo) { + void setHearingAidInfo(HearingAidInfo hearingAidInfo) { mHearingAidInfo = hearingAidInfo; } diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java index 0c1b793102bf..441d3a52b97f 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java @@ -20,6 +20,7 @@ import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothCsipSetCoordinator; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothProfile; +import android.bluetooth.le.ScanFilter; import android.content.Context; import android.util.Log; @@ -114,10 +115,21 @@ public class CachedBluetoothDeviceManager { /** * Create and return a new {@link CachedBluetoothDevice}. This assumes * that {@link #findDevice} has already been called and returned null. - * @param device the address of the new Bluetooth device + * @param device the new Bluetooth device * @return the newly created CachedBluetoothDevice object */ public CachedBluetoothDevice addDevice(BluetoothDevice device) { + return addDevice(device, /*leScanFilters=*/null); + } + + /** + * Create and return a new {@link CachedBluetoothDevice}. This assumes + * that {@link #findDevice} has already been called and returned null. + * @param device the new Bluetooth device + * @param leScanFilters the BLE scan filters which the device matched + * @return the newly created CachedBluetoothDevice object + */ + public CachedBluetoothDevice addDevice(BluetoothDevice device, List leScanFilters) { CachedBluetoothDevice newDevice; final LocalBluetoothProfileManager profileManager = mBtManager.getProfileManager(); synchronized (this) { @@ -125,7 +137,7 @@ public class CachedBluetoothDeviceManager { if (newDevice == null) { newDevice = new CachedBluetoothDevice(mContext, profileManager, device); mCsipDeviceManager.initCsipDeviceIfNeeded(newDevice); - mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(newDevice); + mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(newDevice, leScanFilters); if (!mCsipDeviceManager.setMemberDeviceIfNeeded(newDevice) && !mHearingAidDeviceManager.setSubDeviceIfNeeded(newDevice)) { mCachedDevices.add(newDevice); diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java index e5e57824f6ef..efba953e3c6b 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/HearingAidDeviceManager.java @@ -18,10 +18,13 @@ package com.android.settingslib.bluetooth; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothUuid; +import android.bluetooth.le.ScanFilter; import android.content.ContentResolver; import android.content.Context; import android.media.AudioDeviceAttributes; import android.media.audiopolicy.AudioProductStrategy; +import android.os.ParcelUuid; import android.provider.Settings; import android.util.Log; @@ -59,7 +62,8 @@ public class HearingAidDeviceManager { mRoutingHelper = routingHelper; } - void initHearingAidDeviceIfNeeded(CachedBluetoothDevice newDevice) { + void initHearingAidDeviceIfNeeded(CachedBluetoothDevice newDevice, + List leScanFilters) { long hiSyncId = getHiSyncId(newDevice.getDevice()); if (isValidHiSyncId(hiSyncId)) { // Once hiSyncId is valid, assign hearing aid info @@ -68,6 +72,21 @@ public class HearingAidDeviceManager { .setAshaDeviceMode(getDeviceMode(newDevice.getDevice())) .setHiSyncId(hiSyncId); newDevice.setHearingAidInfo(infoBuilder.build()); + } else if (leScanFilters != null && !newDevice.isHearingAidDevice()) { + // If the device is added with hearing aid scan filter during pairing, set an empty + // hearing aid info to indicate it's a hearing aid device. The info will be updated + // when corresponding profiles connected. + for (ScanFilter leScanFilter: leScanFilters) { + final ParcelUuid serviceUuid = leScanFilter.getServiceUuid(); + final ParcelUuid serviceDataUuid = leScanFilter.getServiceDataUuid(); + if (BluetoothUuid.HEARING_AID.equals(serviceUuid) + || BluetoothUuid.HAS.equals(serviceUuid) + || BluetoothUuid.HEARING_AID.equals(serviceDataUuid) + || BluetoothUuid.HAS.equals(serviceDataUuid)) { + newDevice.setHearingAidInfo(new HearingAidInfo.Builder().build()); + break; + } + } } } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java index 0d5de88cc394..56c8c5a8e549 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/HearingAidDeviceManagerTest.java @@ -33,6 +33,8 @@ import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHearingAid; import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothUuid; +import android.bluetooth.le.ScanFilter; import android.content.Context; import android.media.AudioAttributes; import android.media.AudioDeviceAttributes; @@ -147,7 +149,7 @@ public class HearingAidDeviceManagerTest { HearingAidProfile.DeviceSide.SIDE_RIGHT); assertThat(mCachedDevice1.getHiSyncId()).isNotEqualTo(HISYNCID1); - mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(mCachedDevice1); + mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(mCachedDevice1, null); assertThat(mCachedDevice1.getHiSyncId()).isEqualTo(HISYNCID1); assertThat(mCachedDevice1.getDeviceMode()).isEqualTo( @@ -164,11 +166,42 @@ public class HearingAidDeviceManagerTest { when(mHearingAidProfile.getHiSyncId(mDevice1)).thenReturn( BluetoothHearingAid.HI_SYNC_ID_INVALID); - mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(mCachedDevice1); + mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(mCachedDevice1, null); verify(mCachedDevice1, never()).setHearingAidInfo(any(HearingAidInfo.class)); } + /** + * Test initHearingAidDeviceIfNeeded, an invalid HiSyncId and hearing aid scan filter, set an + * empty hearing aid info on the device. + */ + @Test + public void initHearingAidDeviceIfNeeded_hearingAidScanFilter_setHearingAidInfo() { + when(mHearingAidProfile.getHiSyncId(mDevice1)).thenReturn( + BluetoothHearingAid.HI_SYNC_ID_INVALID); + final ScanFilter scanFilter = new ScanFilter.Builder() + .setServiceData(BluetoothUuid.HEARING_AID, new byte[]{0}).build(); + + mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(mCachedDevice1, List.of(scanFilter)); + + assertThat(mCachedDevice1.isHearingAidDevice()).isTrue(); + } + + /** + * Test initHearingAidDeviceIfNeeded, an invalid HiSyncId and random scan filter, not to set + * hearing aid info on the device. + */ + @Test + public void initHearingAidDeviceIfNeeded_randomScanFilter_notToSetHearingAidInfo() { + when(mHearingAidProfile.getHiSyncId(mDevice1)).thenReturn( + BluetoothHearingAid.HI_SYNC_ID_INVALID); + final ScanFilter scanFilter = new ScanFilter.Builder().build(); + + mHearingAidDeviceManager.initHearingAidDeviceIfNeeded(mCachedDevice1, List.of(scanFilter)); + + assertThat(mCachedDevice1.isHearingAidDevice()).isFalse(); + } + /** * Test setSubDeviceIfNeeded, a device with same HiSyncId will be set as sub device */ -- cgit v1.2.3-59-g8ed1b