diff options
| author | 2021-10-15 09:55:05 +0000 | |
|---|---|---|
| committer | 2021-10-15 09:55:05 +0000 | |
| commit | ba8a56e93d618856d61181695a7248cc9dbb4cb9 (patch) | |
| tree | e45f5af7b4f51a5ba7a53cf3c3f63ca09f9a39f6 | |
| parent | 31a3297733d55e561e4dd863a6c4d787f8caf736 (diff) | |
| parent | c0aa3b32763e393afd42cd36dbade934d7e9fd36 (diff) | |
Merge "settingslib/bluetooth: Add LeAudio support"
6 files changed, 376 insertions, 2 deletions
diff --git a/packages/SettingsLib/res/drawable/ic_bt_le_audio.xml b/packages/SettingsLib/res/drawable/ic_bt_le_audio.xml new file mode 100644 index 000000000000..5b52a04e1cf6 --- /dev/null +++ b/packages/SettingsLib/res/drawable/ic_bt_le_audio.xml @@ -0,0 +1,31 @@ +<!-- + Copyright 2021 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0" + android:tint="?android:attr/colorControlNormal" > + <path + android:pathData="M18.2,1L9.8,1C8.81,1 8,1.81 8,2.8v14.4c0,0.99 0.81,1.79 1.8,1.79l8.4,0.01c0.99,0 1.8,-0.81 1.8,-1.8L20,2.8c0,-0.99 -0.81,-1.8 -1.8,-1.8zM14,3c1.1,0 2,0.89 2,2s-0.9,2 -2,2 -2,-0.89 -2,-2 0.9,-2 2,-2zM14,16.5c-2.21,0 -4,-1.79 -4,-4s1.79,-4 4,-4 4,1.79 4,4 -1.79,4 -4,4z" + android:fillColor="#FFFFFFFF"/> + <path + android:pathData="M14,12.5m-2.5,0a2.5,2.5 0,1 1,5 0a2.5,2.5 0,1 1,-5 0" + android:fillColor="#FFFFFFFF"/> + <path + android:pathData="M6,5H4v16c0,1.1 0.89,2 2,2h10v-2H6V5z" + android:fillColor="#FFFFFFFF"/> +</vector> diff --git a/packages/SettingsLib/res/values/strings.xml b/packages/SettingsLib/res/values/strings.xml index 6b840bd7901d..a56c49088b67 100644 --- a/packages/SettingsLib/res/values/strings.xml +++ b/packages/SettingsLib/res/values/strings.xml @@ -257,8 +257,12 @@ <!-- Bluetooth settings. The user-visible string that is used whenever referring to the Hearing Aid profile. --> <string name="bluetooth_profile_hearing_aid">Hearing Aids</string> + <!-- Bluetooth settings. The user-visible string that is used whenever referring to the LE_AUDIO profile. --> + <string name="bluetooth_profile_le_audio">LE_AUDIO</string> <!-- Bluetooth settings. Connection options screen. The summary for the Hearing Aid checkbox preference when Hearing Aid is connected. --> <string name="bluetooth_hearing_aid_profile_summary_connected">Connected to Hearing Aids</string> + <!-- Bluetooth settings. Connection options screen. The summary for the LE_AUDIO checkbox preference when LE_AUDIO is connected. --> + <string name="bluetooth_le_audio_profile_summary_connected">Connected to LE_AUDIO</string> <!-- Bluetooth settings. Connection options screen. The summary for the A2DP checkbox preference when A2DP is connected. --> <string name="bluetooth_a2dp_profile_summary_connected">Connected to media audio</string> @@ -299,6 +303,8 @@ <string name="bluetooth_hid_profile_summary_use_for">Use for input</string> <!-- Bluetooth settings. Connection options screen. The summary for the Hearing Aid checkbox preference that describes how checking it will set the Hearing Aid profile as preferred. --> <string name="bluetooth_hearing_aid_profile_summary_use_for">Use for Hearing Aids</string> + <!-- Bluetooth settings. Connection options screen. The summary for the LE_AUDIO checkbox preference that describes how checking it will set the LE_AUDIO profile as preferred. --> + <string name="bluetooth_le_audio_profile_summary_use_for">Use for LE_AUDIO</string> <!-- Button text for accepting an incoming pairing request. [CHAR LIMIT=20] --> <string name="bluetooth_pairing_accept">Pair</string> diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java index cf57ebf6fadb..58d2185ea9e9 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java @@ -22,6 +22,7 @@ import android.bluetooth.BluetoothCsipSetCoordinator; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothHearingAid; +import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothProfile; import android.content.BroadcastReceiver; import android.content.Context; @@ -116,6 +117,8 @@ public class BluetoothEventManager { addHandler(BluetoothHeadset.ACTION_ACTIVE_DEVICE_CHANGED, new ActiveDeviceChangedHandler()); addHandler(BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED, new ActiveDeviceChangedHandler()); + addHandler(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED, + new ActiveDeviceChangedHandler()); // Headset state changed broadcasts addHandler(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED, @@ -452,6 +455,9 @@ public class BluetoothEventManager { bluetoothProfile = BluetoothProfile.HEADSET; } else if (Objects.equals(action, BluetoothHearingAid.ACTION_ACTIVE_DEVICE_CHANGED)) { bluetoothProfile = BluetoothProfile.HEARING_AID; + } else if (Objects.equals(action, + BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED)) { + bluetoothProfile = BluetoothProfile.LE_AUDIO; } else { Log.w(TAG, "ActiveDeviceChangedHandler: unknown action " + action); return; diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java index 243194188727..021ba2247e67 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java @@ -21,6 +21,7 @@ import android.bluetooth.BluetoothClass; import android.bluetooth.BluetoothCsipSetCoordinator; import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHearingAid; +import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothUuid; import android.content.Context; @@ -109,10 +110,12 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private boolean mIsActiveDeviceA2dp = false; private boolean mIsActiveDeviceHeadset = false; private boolean mIsActiveDeviceHearingAid = false; + private boolean mIsActiveDeviceLeAudio = false; // Media profile connect state private boolean mIsA2dpProfileConnectedFail = false; private boolean mIsHeadsetProfileConnectedFail = false; private boolean mIsHearingAidProfileConnectedFail = false; + private boolean mIsLeAudioProfileConnectedFail = false; // Group second device for Hearing Aid private CachedBluetoothDevice mSubDevice; // Group member devices for the coordinated set @@ -133,6 +136,9 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> case BluetoothProfile.HEARING_AID: mIsHearingAidProfileConnectedFail = true; break; + case BluetoothProfile.LE_AUDIO: + mIsLeAudioProfileConnectedFail = true; + break; default: Log.w(TAG, "handleMessage(): unknown message : " + msg.what); break; @@ -266,6 +272,9 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> case BluetoothProfile.HEARING_AID: mIsHearingAidProfileConnectedFail = isFailed; break; + case BluetoothProfile.LE_AUDIO: + mIsLeAudioProfileConnectedFail = isFailed; + break; default: Log.w(TAG, "setProfileConnectedStatus(): unknown profile id : " + profileId); break; @@ -541,6 +550,13 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> result = true; } } + LeAudioProfile leAudioProfile = mProfileManager.getLeAudioProfile(); + if ((leAudioProfile != null) && isConnectedProfile(leAudioProfile)) { + if (leAudioProfile.setActiveDevice(getDevice())) { + Log.i(TAG, "OnPreferenceClickListener: LeAudio active device=" + this); + result = true; + } + } return result; } @@ -619,6 +635,10 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> changed = (mIsActiveDeviceHearingAid != isActive); mIsActiveDeviceHearingAid = isActive; break; + case BluetoothProfile.LE_AUDIO: + changed = (mIsActiveDeviceLeAudio != isActive); + mIsActiveDeviceLeAudio = isActive; + break; default: Log.w(TAG, "onActiveDeviceChanged: unknown profile " + bluetoothProfile + " isActive " + isActive); @@ -650,6 +670,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> return mIsActiveDeviceHeadset; case BluetoothProfile.HEARING_AID: return mIsActiveDeviceHearingAid; + case BluetoothProfile.LE_AUDIO: + return mIsActiveDeviceLeAudio; default: Log.w(TAG, "getActiveDevice: unknown profile " + bluetoothProfile); break; @@ -744,6 +766,10 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> if (hearingAidProfile != null) { mIsActiveDeviceHearingAid = hearingAidProfile.getActiveDevices().contains(mDevice); } + LeAudioProfile leAudio = mProfileManager.getLeAudioProfile(); + if (leAudio != null) { + mIsActiveDeviceLeAudio = leAudio.getActiveDevices().contains(mDevice); + } } /** @@ -984,6 +1010,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> boolean a2dpConnected = true; // A2DP is connected boolean hfpConnected = true; // HFP is connected boolean hearingAidConnected = true; // Hearing Aid is connected + boolean leAudioConnected = true; // LeAudio is connected int leftBattery = -1; int rightBattery = -1; @@ -1015,6 +1042,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> hfpConnected = false; } else if (profile instanceof HearingAidProfile) { hearingAidConnected = false; + } else if (profile instanceof LeAudioProfile) { + leAudioConnected = false; } } break; @@ -1057,7 +1086,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> // 1. Hearing Aid device active. // 2. Headset device active with in-calling state. // 3. A2DP device active without in-calling state. - if (a2dpConnected || hfpConnected || hearingAidConnected) { + // 4. Le Audio device active + if (a2dpConnected || hfpConnected || hearingAidConnected || leAudioConnected) { final boolean isOnCall = Utils.isAudioModeOngoingCall(mContext); if ((mIsActiveDeviceHearingAid) || (mIsActiveDeviceHeadset && isOnCall) @@ -1092,7 +1122,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> private boolean isProfileConnectedFail() { return mIsA2dpProfileConnectedFail || mIsHearingAidProfileConnectedFail - || (!isConnectedSapDevice() && mIsHeadsetProfileConnectedFail); + || (!isConnectedSapDevice() && mIsHeadsetProfileConnectedFail) + || mIsLeAudioProfileConnectedFail; } /** @@ -1103,6 +1134,7 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> boolean a2dpNotConnected = false; // A2DP is preferred but not connected boolean hfpNotConnected = false; // HFP is preferred but not connected boolean hearingAidNotConnected = false; // Hearing Aid is preferred but not connected + boolean leAudioNotConnected = false; // LeAudio is preferred but not connected synchronized (mProfileLock) { for (LocalBluetoothProfile profile : getProfiles()) { @@ -1128,6 +1160,8 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> hfpNotConnected = true; } else if (profile instanceof HearingAidProfile) { hearingAidNotConnected = true; + } else if (profile instanceof LeAudioProfile) { + leAudioNotConnected = true; } } break; @@ -1166,6 +1200,11 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> return mContext.getString(R.string.bluetooth_connected, activeDeviceString); } + if (!leAudioNotConnected && mIsActiveDeviceLeAudio) { + activeDeviceString = activeDeviceStringsArray[1]; + return mContext.getString(R.string.bluetooth_connected, activeDeviceString); + } + if (profileConnected) { if (a2dpNotConnected && hfpNotConnected) { if (batteryLevelPercentageString != null) { @@ -1235,6 +1274,15 @@ public class CachedBluetoothDevice implements Comparable<CachedBluetoothDevice> BluetoothProfile.STATE_CONNECTED; } + /** + * @return {@code true} if {@code cachedBluetoothDevice} is LeAudio device + */ + public boolean isConnectedLeAudioDevice() { + LeAudioProfile leAudio = mProfileManager.getLeAudioProfile(); + return leAudio != null && leAudio.getConnectionStatus(mDevice) == + BluetoothProfile.STATE_CONNECTED; + } + private boolean isConnectedSapDevice() { SapProfile sapProfile = mProfileManager.getSapProfile(); return sapProfile != null && sapProfile.getConnectionStatus(mDevice) diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LeAudioProfile.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LeAudioProfile.java new file mode 100644 index 000000000000..209507ac7088 --- /dev/null +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LeAudioProfile.java @@ -0,0 +1,264 @@ +/* Copyright 2021 HIMSA II K/S - www.himsa.com. Represented by EHIMA +- www.ehima.com +*/ + +/* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +package com.android.settingslib.bluetooth; + +import static android.bluetooth.BluetoothAdapter.ACTIVE_DEVICE_ALL; +import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_ALLOWED; +import static android.bluetooth.BluetoothProfile.CONNECTION_POLICY_FORBIDDEN; + +import android.bluetooth.BluetoothLeAudio; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothClass; +import android.bluetooth.BluetoothCodecConfig; +import android.bluetooth.BluetoothCodecStatus; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothProfile; +import android.bluetooth.BluetoothUuid; +import android.content.Context; +import android.os.Build; +import android.os.ParcelUuid; +import android.util.Log; + +import androidx.annotation.RequiresApi; + +import com.android.internal.annotations.VisibleForTesting; +import com.android.settingslib.R; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class LeAudioProfile implements LocalBluetoothProfile { + private static final String TAG = "LeAudioProfile"; + private static boolean DEBUG = true; + + private Context mContext; + + private BluetoothLeAudio mService; + private boolean mIsProfileReady; + + private final CachedBluetoothDeviceManager mDeviceManager; + + static final String NAME = "LE_AUDIO"; + private final LocalBluetoothProfileManager mProfileManager; + private final BluetoothAdapter mBluetoothAdapter; + + // Order of this profile in device profiles list + private static final int ORDINAL = 1; + + // These callbacks run on the main thread. + private final class LeAudioServiceListener + implements BluetoothProfile.ServiceListener { + + @RequiresApi(Build.VERSION_CODES.S) + public void onServiceConnected(int profile, BluetoothProfile proxy) { + if (DEBUG) { + Log.d(TAG,"Bluetooth service connected"); + } + mService = (BluetoothLeAudio) proxy; + // We just bound to the service, so refresh the UI for any connected LeAudio devices. + List<BluetoothDevice> deviceList = mService.getConnectedDevices(); + while (!deviceList.isEmpty()) { + BluetoothDevice nextDevice = deviceList.remove(0); + CachedBluetoothDevice device = mDeviceManager.findDevice(nextDevice); + // we may add a new device here, but generally this should not happen + if (device == null) { + if (DEBUG) { + Log.d(TAG, "LeAudioProfile found new device: " + nextDevice); + } + device = mDeviceManager.addDevice(nextDevice); + } + device.onProfileStateChanged(LeAudioProfile.this, + BluetoothProfile.STATE_CONNECTED); + device.refresh(); + } + + mProfileManager.callServiceConnectedListeners(); + mIsProfileReady = true; + } + + public void onServiceDisconnected(int profile) { + if (DEBUG) { + Log.d(TAG,"Bluetooth service disconnected"); + } + mProfileManager.callServiceDisconnectedListeners(); + mIsProfileReady = false; + } + } + + public boolean isProfileReady() { + return mIsProfileReady; + } + + @Override + public int getProfileId() { + return BluetoothProfile.LE_AUDIO; + } + + LeAudioProfile(Context context, CachedBluetoothDeviceManager deviceManager, + LocalBluetoothProfileManager profileManager) { + mContext = context; + mDeviceManager = deviceManager; + mProfileManager = profileManager; + + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + mBluetoothAdapter.getProfileProxy( + context, new LeAudioServiceListener(), + BluetoothProfile.LE_AUDIO); + } + + public boolean accessProfileEnabled() { + return true; + } + + public boolean isAutoConnectable() { + return true; + } + + public List<BluetoothDevice> getConnectedDevices() { + if (mService == null) { + return new ArrayList<BluetoothDevice>(0); + } + return mService.getDevicesMatchingConnectionStates( + new int[] {BluetoothProfile.STATE_CONNECTED, + BluetoothProfile.STATE_CONNECTING, + BluetoothProfile.STATE_DISCONNECTING}); + } + + /* + * @hide + */ + public boolean connect(BluetoothDevice device) { + if (mService == null) { + return false; + } + return mService.connect(device); + } + + /* + * @hide + */ + public boolean disconnect(BluetoothDevice device) { + if (mService == null) { + return false; + } + return mService.disconnect(device); + } + + public int getConnectionStatus(BluetoothDevice device) { + if (mService == null) { + return BluetoothProfile.STATE_DISCONNECTED; + } + return mService.getConnectionState(device); + } + + public boolean setActiveDevice(BluetoothDevice device) { + if (mBluetoothAdapter == null) { + return false; + } + return device == null + ? mBluetoothAdapter.removeActiveDevice(ACTIVE_DEVICE_ALL) + : mBluetoothAdapter.setActiveDevice(device, ACTIVE_DEVICE_ALL); + } + + public List<BluetoothDevice> getActiveDevices() { + if (mService == null) { + return new ArrayList<>(); + } + return mService.getActiveDevices(); + } + + @Override + public boolean isEnabled(BluetoothDevice device) { + if (mService == null || device == null) { + return false; + } + return mService.getConnectionPolicy(device) > CONNECTION_POLICY_FORBIDDEN; + } + + @Override + public int getConnectionPolicy(BluetoothDevice device) { + if (mService == null || device == null) { + return CONNECTION_POLICY_FORBIDDEN; + } + return mService.getConnectionPolicy(device); + } + + @Override + public boolean setEnabled(BluetoothDevice device, boolean enabled) { + boolean isEnabled = false; + if (mService == null || device == null) { + return false; + } + if (enabled) { + if (mService.getConnectionPolicy(device) < CONNECTION_POLICY_ALLOWED) { + isEnabled = mService.setConnectionPolicy(device, CONNECTION_POLICY_ALLOWED); + } + } else { + isEnabled = mService.setConnectionPolicy(device, CONNECTION_POLICY_FORBIDDEN); + } + + return isEnabled; + } + + public String toString() { + return NAME; + } + + public int getOrdinal() { + return ORDINAL; + } + + public int getNameResource(BluetoothDevice device) { + return R.string.bluetooth_profile_le_audio; + } + + public int getSummaryResourceForDevice(BluetoothDevice device) { + int state = getConnectionStatus(device); + switch (state) { + case BluetoothProfile.STATE_DISCONNECTED: + return R.string.bluetooth_le_audio_profile_summary_use_for; + + case BluetoothProfile.STATE_CONNECTED: + return R.string.bluetooth_le_audio_profile_summary_connected; + + default: + return BluetoothUtils.getConnectionStateSummary(state); + } + } + + public int getDrawableResource(BluetoothClass btClass) { + return R.drawable.ic_bt_le_audio; + } + + @RequiresApi(Build.VERSION_CODES.S) + protected void finalize() { + if (DEBUG) { + Log.d(TAG, "finalize()"); + } + if (mService != null) { + try { + BluetoothAdapter.getDefaultAdapter().closeProfileProxy(BluetoothProfile.LE_AUDIO, + mService); + mService = null; + }catch (Throwable t) { + Log.w(TAG, "Error cleaning up LeAudio proxy", t); + } + } + } +} diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java index bcb345584ff3..334792048105 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothProfileManager.java @@ -24,6 +24,7 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothHeadset; import android.bluetooth.BluetoothHeadsetClient; import android.bluetooth.BluetoothHearingAid; +import android.bluetooth.BluetoothLeAudio; import android.bluetooth.BluetoothHidDevice; import android.bluetooth.BluetoothHidHost; import android.bluetooth.BluetoothMap; @@ -102,6 +103,7 @@ public class LocalBluetoothProfileManager { private PbapServerProfile mPbapProfile; private HearingAidProfile mHearingAidProfile; private CsipSetCoordinatorProfile mCsipSetCoordinatorProfile; + private LeAudioProfile mLeAudioProfile; private SapProfile mSapProfile; private VolumeControlProfile mVolumeControlProfile; @@ -232,6 +234,14 @@ public class LocalBluetoothProfileManager { // Note: no event handler for VCP, only for being connectable. mProfileNameMap.put(VolumeControlProfile.NAME, mVolumeControlProfile); } + if (mLeAudioProfile == null && supportedList.contains(BluetoothProfile.LE_AUDIO)) { + if (DEBUG) { + Log.d(TAG, "Adding local LE_AUDIO profile"); + } + mLeAudioProfile = new LeAudioProfile(mContext, mDeviceManager, this); + addProfile(mLeAudioProfile, LeAudioProfile.NAME, + BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED); + } if (mCsipSetCoordinatorProfile == null && supportedList.contains(BluetoothProfile.CSIP_SET_COORDINATOR)) { if (DEBUG) { @@ -487,6 +497,10 @@ public class LocalBluetoothProfileManager { return mHearingAidProfile; } + public LeAudioProfile getLeAudioProfile() { + return mLeAudioProfile; + } + SapProfile getSapProfile() { return mSapProfile; } @@ -614,6 +628,11 @@ public class LocalBluetoothProfileManager { removedProfiles.remove(mHearingAidProfile); } + if (ArrayUtils.contains(uuids, BluetoothUuid.LE_AUDIO) && mLeAudioProfile != null) { + profiles.add(mLeAudioProfile); + removedProfiles.remove(mLeAudioProfile); + } + if (mSapProfile != null && ArrayUtils.contains(uuids, BluetoothUuid.SAP)) { profiles.add(mSapProfile); removedProfiles.remove(mSapProfile); |