diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 9583a59148fce..010d7384330cc 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -161,6 +161,8 @@ public class CachedBluetoothDevice implements Comparable mDevice = device; fillData(); mHiSyncId = BluetoothHearingAid.HI_SYNC_ID_INVALID; + mDeviceSide = HearingAidProfile.DeviceSide.SIDE_INVALID; + mDeviceMode = HearingAidProfile.DeviceMode.MODE_INVALID; mGroupId = BluetoothCsipSetCoordinator.GROUP_ID_INVALID; initDrawableCache(); mUnpairing = false; @@ -363,10 +365,6 @@ public class CachedBluetoothDevice implements Comparable mHiSyncId = id; } - public boolean isHearingAidDevice() { - return mHiSyncId != BluetoothHearingAid.HI_SYNC_ID_INVALID; - } - /** * Mark the discovered device as member of coordinated set. * @@ -784,8 +782,6 @@ public class CachedBluetoothDevice implements Comparable ParcelUuid[] localUuids = new ParcelUuid[uuidsList.size()]; uuidsList.toArray(localUuids); - if (localUuids == null) return false; - /* * Now we know if the device supports PBAP, update permissions... */ @@ -1371,14 +1367,40 @@ public class CachedBluetoothDevice implements Comparable } /** - * @return {@code true} if {@code cachedBluetoothDevice} is Hearing Aid device + * @return {@code true} if {@code cachedBluetoothDevice} is ASHA hearing aid device */ - public boolean isConnectedHearingAidDevice() { + public boolean isConnectedAshaHearingAidDevice() { HearingAidProfile hearingAidProfile = mProfileManager.getHearingAidProfile(); return hearingAidProfile != null && hearingAidProfile.getConnectionStatus(mDevice) == BluetoothProfile.STATE_CONNECTED; } + /** + * @return {@code true} if {@code cachedBluetoothDevice} is HAP device + */ + public boolean isConnectedHapClientDevice() { + HapClientProfile hapClientProfile = mProfileManager.getHapClientProfile(); + return hapClientProfile != null && hapClientProfile.getConnectionStatus(mDevice) + == BluetoothProfile.STATE_CONNECTED; + } + + /** + * @return {@code true} if {@code cachedBluetoothDevice} is LeAudio hearing aid device + */ + public boolean isConnectedLeAudioHearingAidDevice() { + return isConnectedHapClientDevice() && isConnectedLeAudioDevice(); + } + + /** + * @return {@code true} if {@code cachedBluetoothDevice} is hearing aid device + * + * The device may be an ASHA hearing aid that supports {@link HearingAidProfile} or a LeAudio + * hearing aid that supports {@link HapClientProfile} and {@link LeAudioProfile}. + */ + public boolean isHearingAidDevice() { + return isConnectedAshaHearingAidDevice() || isConnectedLeAudioHearingAidDevice(); + } + /** * @return {@code true} if {@code cachedBluetoothDevice} is LeAudio device */ diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java index fb861da0a7f0e..4e9073ce5a61e 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java @@ -21,6 +21,7 @@ import android.bluetooth.BluetoothA2dpSink; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothCsipSetCoordinator; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothHapClient; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothHeadsetClient; import android.bluetooth.BluetoothHearingAid; @@ -103,6 +104,7 @@ public class LocalBluetoothProfileManager { private PbapClientProfile mPbapClientProfile; private PbapServerProfile mPbapProfile; private HearingAidProfile mHearingAidProfile; + private HapClientProfile mHapClientProfile; private CsipSetCoordinatorProfile mCsipSetCoordinatorProfile; private LeAudioProfile mLeAudioProfile; private LocalBluetoothLeBroadcast mLeAudioBroadcast; @@ -189,6 +191,12 @@ public class LocalBluetoothProfileManager { addProfile(mHearingAidProfile, HearingAidProfile.NAME, BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED); } + if (mHapClientProfile == null && supportedList.contains(BluetoothProfile.HAP_CLIENT)) { + if (DEBUG) Log.d(TAG, "Adding local HAP_CLIENT profile"); + mHapClientProfile = new HapClientProfile(mContext, mDeviceManager, this); + addProfile(mHapClientProfile, HapClientProfile.NAME, + BluetoothHapClient.ACTION_HAP_CONNECTION_STATE_CHANGED); + } if (mHidProfile == null && supportedList.contains(BluetoothProfile.HID_HOST)) { if (DEBUG) Log.d(TAG, "Adding local HID_HOST profile"); mHidProfile = new HidProfile(mContext, mDeviceManager, this); @@ -524,6 +532,10 @@ public class LocalBluetoothProfileManager { return mHearingAidProfile; } + public HapClientProfile getHapClientProfile() { + return mHapClientProfile; + } + public LeAudioProfile getLeAudioProfile() { return mLeAudioProfile; } @@ -675,6 +687,11 @@ public class LocalBluetoothProfileManager { removedProfiles.remove(mHearingAidProfile); } + if (mHapClientProfile != null && ArrayUtils.contains(uuids, BluetoothUuid.HAS)) { + profiles.add(mHapClientProfile); + removedProfiles.remove(mHapClientProfile); + } + if (mSapProfile != null && ArrayUtils.contains(uuids, BluetoothUuid.SAP)) { profiles.add(mSapProfile); removedProfiles.remove(mSapProfile); diff --git a/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java b/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java index df6929e114eea..b3a52b9ec7884 100644 --- a/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/media/MediaDeviceUtils.java @@ -16,6 +16,7 @@ package com.android.settingslib.media; import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothHearingAid; import android.media.MediaRoute2Info; import com.android.settingslib.bluetooth.CachedBluetoothDevice; @@ -32,7 +33,9 @@ public class MediaDeviceUtils { */ public static String getId(CachedBluetoothDevice cachedDevice) { if (cachedDevice.isHearingAidDevice()) { - return Long.toString(cachedDevice.getHiSyncId()); + if (cachedDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID) { + return Long.toString(cachedDevice.getHiSyncId()); + } } return cachedDevice.getAddress(); } diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java index 79e99387b2fa0..864725ba600c8 100644 --- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java +++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java @@ -74,6 +74,10 @@ public class CachedBluetoothDeviceTest { @Mock private HearingAidProfile mHearingAidProfile; @Mock + private HapClientProfile mHapClientProfile; + @Mock + private LeAudioProfile mLeAudioProfile; + @Mock private BluetoothDevice mDevice; @Mock private BluetoothDevice mSubDevice; @@ -859,21 +863,21 @@ public class CachedBluetoothDeviceTest { } @Test - public void isConnectedHearingAidDevice_connected_returnTrue() { + public void isConnectedAshaHearingAidDevice_connected_returnTrue() { when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); when(mHearingAidProfile.getConnectionStatus(mDevice)). thenReturn(BluetoothProfile.STATE_CONNECTED); - assertThat(mCachedDevice.isConnectedHearingAidDevice()).isTrue(); + assertThat(mCachedDevice.isConnectedAshaHearingAidDevice()).isTrue(); } @Test - public void isConnectedHearingAidDevice_disconnected_returnFalse() { + public void isConnectedAshaHearingAidDevice_disconnected_returnFalse() { when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); when(mHearingAidProfile.getConnectionStatus(mDevice)). thenReturn(BluetoothProfile.STATE_DISCONNECTED); - assertThat(mCachedDevice.isConnectedHearingAidDevice()).isFalse(); + assertThat(mCachedDevice.isConnectedAshaHearingAidDevice()).isFalse(); } @Test @@ -891,10 +895,10 @@ public class CachedBluetoothDeviceTest { } @Test - public void isConnectedHearingAidDevice_profileIsNull_returnFalse() { + public void isConnectedAshaHearingAidDevice_profileIsNull_returnFalse() { when(mProfileManager.getHearingAidProfile()).thenReturn(null); - assertThat(mCachedDevice.isConnectedHearingAidDevice()).isFalse(); + assertThat(mCachedDevice.isConnectedAshaHearingAidDevice()).isFalse(); } @Test @@ -987,11 +991,11 @@ public class CachedBluetoothDeviceTest { @Test public void getConnectionSummary_profileConnectedFail_showErrorMessage() { - final A2dpProfile profle = mock(A2dpProfile.class); - mCachedDevice.onProfileStateChanged(profle, BluetoothProfile.STATE_CONNECTED); + final A2dpProfile profile = mock(A2dpProfile.class); + mCachedDevice.onProfileStateChanged(profile, BluetoothProfile.STATE_CONNECTED); mCachedDevice.setProfileConnectedStatus(BluetoothProfile.A2DP, true); - when(profle.getConnectionStatus(mDevice)).thenReturn(BluetoothProfile.STATE_CONNECTED); + when(profile.getConnectionStatus(mDevice)).thenReturn(BluetoothProfile.STATE_CONNECTED); assertThat(mCachedDevice.getConnectionSummary()).isEqualTo( mContext.getString(R.string.profile_connect_timeout_subtext)); @@ -1069,4 +1073,37 @@ public class CachedBluetoothDeviceTest { assertThat(mSubCachedDevice.mDevice).isEqualTo(mDevice); assertThat(mCachedDevice.getMemberDevice().contains(mSubCachedDevice)).isTrue(); } + + @Test + public void isConnectedHearingAidDevice_isConnectedAshaHearingAidDevice_returnTrue() { + when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); + + updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_CONNECTED); + + assertThat(mCachedDevice.isHearingAidDevice()).isTrue(); + } + + @Test + public void isConnectedHearingAidDevice_isConnectedLeAudioHearingAidDevice_returnTrue() { + when(mProfileManager.getHapClientProfile()).thenReturn(mHapClientProfile); + when(mProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile); + + updateProfileStatus(mHapClientProfile, BluetoothProfile.STATE_CONNECTED); + updateProfileStatus(mLeAudioProfile, BluetoothProfile.STATE_CONNECTED); + + assertThat(mCachedDevice.isHearingAidDevice()).isTrue(); + } + + @Test + public void isConnectedHearingAidDevice_isNotAnyConnectedHearingAidDevice_returnFalse() { + when(mProfileManager.getHearingAidProfile()).thenReturn(mHearingAidProfile); + when(mProfileManager.getHapClientProfile()).thenReturn(mHapClientProfile); + when(mProfileManager.getLeAudioProfile()).thenReturn(mLeAudioProfile); + + updateProfileStatus(mHearingAidProfile, BluetoothProfile.STATE_DISCONNECTED); + updateProfileStatus(mHapClientProfile, BluetoothProfile.STATE_DISCONNECTED); + updateProfileStatus(mLeAudioProfile, BluetoothProfile.STATE_DISCONNECTED); + + assertThat(mCachedDevice.isHearingAidDevice()).isFalse(); + } }