server/audio: Add LeAudio support

This patch adds handling active device and set volume

Bug: 150670922
Tag: #feature
Sponsor: jpawlowski@
Test: Manual
Change-Id: I50a966ed2f199464381ff561fd83342b0a9b08a9
This commit is contained in:
Grzegorz Kołodziejczyk 2021-10-13 08:49:17 +00:00 committed by Łukasz Rymanowski
parent f822fdf129
commit ad46dc5b5e
7 changed files with 237 additions and 6 deletions

View File

@ -106,7 +106,7 @@ public final class MediaRoute2Info implements Parcelable {
@IntDef({
TYPE_UNKNOWN, TYPE_BUILTIN_SPEAKER, TYPE_WIRED_HEADSET,
TYPE_WIRED_HEADPHONES, TYPE_BLUETOOTH_A2DP, TYPE_HDMI, TYPE_USB_DEVICE,
TYPE_USB_ACCESSORY, TYPE_DOCK, TYPE_USB_HEADSET, TYPE_HEARING_AID,
TYPE_USB_ACCESSORY, TYPE_DOCK, TYPE_USB_HEADSET, TYPE_HEARING_AID, TYPE_BLE_HEADSET,
TYPE_REMOTE_TV, TYPE_REMOTE_SPEAKER, TYPE_GROUP})
@Retention(RetentionPolicy.SOURCE)
public @interface Type {}
@ -201,6 +201,14 @@ public final class MediaRoute2Info implements Parcelable {
*/
public static final int TYPE_HEARING_AID = AudioDeviceInfo.TYPE_HEARING_AID;
/**
* A route type describing a BLE HEADSET.
*
* @see #getType
* @hide
*/
public static final int TYPE_BLE_HEADSET = AudioDeviceInfo.TYPE_BLE_HEADSET;
/**
* A route type indicating the presentation of the media is happening on a TV.
*

View File

@ -22,6 +22,7 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.BluetoothLeAudio;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
@ -503,6 +504,18 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
/*package*/ static final class BleVolumeInfo {
final int mIndex;
final int mMaxIndex;
final int mStreamType;
BleVolumeInfo(int index, int maxIndex, int streamType) {
mIndex = index;
mMaxIndex = maxIndex;
mStreamType = streamType;
}
};
/*package*/ static final class BtDeviceConnectionInfo {
final @NonNull BluetoothDevice mDevice;
final @AudioService.BtProfileConnectionState int mState;
@ -711,6 +724,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
sendIIMsgNoDelay(MSG_II_SET_HEARING_AID_VOLUME, SENDMSG_REPLACE, index, streamType);
}
/*package*/ void postSetLeAudioVolumeIndex(int index, int maxIndex, int streamType) {
BleVolumeInfo info = new BleVolumeInfo(index, maxIndex, streamType);
sendLMsgNoDelay(MSG_II_SET_LE_AUDIO_OUT_VOLUME, SENDMSG_REPLACE, info);
}
/*package*/ void postSetModeOwnerPid(int pid, int mode) {
sendIIMsgNoDelay(MSG_I_SET_MODE_OWNER_PID, SENDMSG_REPLACE, pid, mode);
}
@ -851,6 +869,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
return mAudioService.getVssVolumeForDevice(streamType, device);
}
/*package*/ int getMaxVssVolumeForStream(int streamType) {
return mAudioService.getMaxVssVolumeForStream(streamType);
}
/*package*/ int getDeviceForStream(int streamType) {
return mAudioService.getDeviceForStream(streamType);
}
@ -962,6 +984,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
sendMsgNoDelay(MSG_DISCONNECT_BT_HEARING_AID, SENDMSG_QUEUE);
}
/*package*/ void postDisconnectLeAudio() {
sendMsgNoDelay(MSG_DISCONNECT_BT_LE_AUDIO, SENDMSG_QUEUE);
}
/*package*/ void postDisconnectHeadset() {
sendMsgNoDelay(MSG_DISCONNECT_BT_HEADSET, SENDMSG_QUEUE);
}
@ -983,6 +1009,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
hearingAidProfile);
}
/*package*/ void postBtLeAudioProfileConnected(BluetoothLeAudio leAudioProfile) {
sendLMsgNoDelay(MSG_L_BT_SERVICE_CONNECTED_PROFILE_LE_AUDIO, SENDMSG_QUEUE,
leAudioProfile);
}
/*package*/ void postCommunicationRouteClientDied(CommunicationRouteClient client) {
sendLMsgNoDelay(MSG_L_COMMUNICATION_ROUTE_CLIENT_DIED, SENDMSG_QUEUE, client);
}
@ -1321,6 +1352,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
mBtHelper.setHearingAidVolume(msg.arg1, msg.arg2);
}
break;
case MSG_II_SET_LE_AUDIO_OUT_VOLUME: {
final BleVolumeInfo info = (BleVolumeInfo) msg.obj;
synchronized (mDeviceStateLock) {
mBtHelper.setLeAudioVolume(info.mIndex, info.mMaxIndex, info.mStreamType);
}
} break;
case MSG_I_SET_AVRCP_ABSOLUTE_VOLUME:
synchronized (mDeviceStateLock) {
mBtHelper.setAvrcpAbsoluteVolumeIndex(msg.arg1);
@ -1384,6 +1421,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
break;
case MSG_DISCONNECT_BT_LE_AUDIO:
synchronized(mDeviceStateLock) {
mDeviceInventory.disconnectLeAudio();
}
break;
case MSG_L_BT_SERVICE_CONNECTED_PROFILE_A2DP:
synchronized (mDeviceStateLock) {
mBtHelper.onA2dpProfileConnected((BluetoothA2dp) msg.obj);
@ -1399,6 +1441,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
mBtHelper.onHearingAidProfileConnected((BluetoothHearingAid) msg.obj);
}
break;
case MSG_L_BT_SERVICE_CONNECTED_PROFILE_LE_AUDIO:
synchronized(mDeviceStateLock) {
mBtHelper.onLeAudioProfileConnected((BluetoothLeAudio) msg.obj);
}
break;
case MSG_L_BT_SERVICE_CONNECTED_PROFILE_HEADSET:
synchronized (mSetModeLock) {
synchronized (mDeviceStateLock) {
@ -1586,6 +1634,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
private static final int MSG_IL_SET_LE_AUDIO_IN_CONNECTION_STATE = 43;
private static final int MSG_L_LE_AUDIO_DEVICE_OUT_CONNECTION_CHANGE_EXT = 44;
private static final int MSG_L_LE_AUDIO_DEVICE_IN_CONNECTION_CHANGE_EXT = 45;
// process set volume for Le Audio, obj is BleVolumeInfo
private static final int MSG_II_SET_LE_AUDIO_OUT_VOLUME = 46;
private static final int MSG_L_BT_SERVICE_CONNECTED_PROFILE_LE_AUDIO = 47;
private static final int MSG_DISCONNECT_BT_LE_AUDIO = 48;
private static boolean isMessageHandledUnderWakelock(int msgId) {
switch(msgId) {

View File

@ -887,6 +887,28 @@ public class AudioDeviceInventory {
}
}
/*package*/ void disconnectLeAudio() {
synchronized (mDevicesLock) {
final ArraySet<String> toRemove = new ArraySet<>();
// Disconnect ALL DEVICE_OUT_BLE_HEADSET devices
mConnectedDevices.values().forEach(deviceInfo -> {
if (deviceInfo.mDeviceType == AudioSystem.DEVICE_OUT_BLE_HEADSET) {
toRemove.add(deviceInfo.mDeviceAddress);
}
});
new MediaMetrics.Item(mMetricsId + "disconnectLeAudio")
.record();
if (toRemove.size() > 0) {
final int delay = checkSendBecomingNoisyIntentInt(
AudioSystem.DEVICE_OUT_BLE_HEADSET, 0, AudioSystem.DEVICE_NONE);
toRemove.stream().forEach(deviceAddress ->
makeLeAudioDeviceUnavailable(deviceAddress,
AudioSystem.DEVICE_OUT_BLE_HEADSET)
);
}
}
}
// must be called before removing the device from mConnectedDevices
// musicDevice argument is used when not AudioSystem.DEVICE_NONE instead of querying
// from AudioSystem
@ -1195,6 +1217,10 @@ public class AudioDeviceInventory {
return;
}
final int leAudioVolIndex = mDeviceBroker.getVssVolumeForDevice(streamType,
AudioSystem.DEVICE_OUT_BLE_HEADSET);
final int maxIndex = mDeviceBroker.getMaxVssVolumeForStream(streamType);
mDeviceBroker.postSetLeAudioVolumeIndex(leAudioVolIndex, maxIndex, streamType);
mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "makeLeAudioDeviceAvailable");
}
@ -1243,6 +1269,7 @@ public class AudioDeviceInventory {
BECOMING_NOISY_INTENT_DEVICES_SET.add(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET);
BECOMING_NOISY_INTENT_DEVICES_SET.add(AudioSystem.DEVICE_OUT_LINE);
BECOMING_NOISY_INTENT_DEVICES_SET.add(AudioSystem.DEVICE_OUT_HEARING_AID);
BECOMING_NOISY_INTENT_DEVICES_SET.add(AudioSystem.DEVICE_OUT_BLE_HEADSET);
BECOMING_NOISY_INTENT_DEVICES_SET.addAll(AudioSystem.DEVICE_OUT_ALL_A2DP_SET);
BECOMING_NOISY_INTENT_DEVICES_SET.addAll(AudioSystem.DEVICE_OUT_ALL_USB_SET);
BECOMING_NOISY_INTENT_DEVICES_SET.addAll(AudioSystem.DEVICE_OUT_ALL_BLE_SET);

View File

@ -334,6 +334,10 @@ public class AudioService extends IAudioService.Stub
return mStreamStates[stream].getIndex(device);
}
/*package*/ int getMaxVssVolumeForStream(int stream) {
return mStreamStates[stream].getMaxIndex();
}
private SettingsObserver mSettingsObserver;
private AtomicInteger mMode = new AtomicInteger(AudioSystem.MODE_NORMAL);
@ -2952,6 +2956,16 @@ public class AudioService extends IAudioService.Stub
mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(newIndex / 10);
}
if (device == AudioSystem.DEVICE_OUT_BLE_HEADSET
&& streamType == getBluetoothContextualVolumeStream()) {
if (DEBUG_VOL) {
Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index="
+ newIndex + " stream=" + streamType);
}
mDeviceBroker.postSetLeAudioVolumeIndex(newIndex,
mStreamStates[streamType].getMaxIndex(), streamType);
}
// Check if volume update should be send to Hearing Aid
if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
// only modify the hearing aid attenuation when the stream to modify matches
@ -3580,6 +3594,16 @@ public class AudioService extends IAudioService.Stub
mDeviceBroker.postSetAvrcpAbsoluteVolumeIndex(index / 10);
}
if (device == AudioSystem.DEVICE_OUT_BLE_HEADSET
&& streamType == getBluetoothContextualVolumeStream()) {
if (DEBUG_VOL) {
Log.d(TAG, "adjustSreamVolume postSetLeAudioVolumeIndex index="
+ index + " stream=" + streamType);
}
mDeviceBroker.postSetLeAudioVolumeIndex(index,
mStreamStates[streamType].getMaxIndex(), streamType);
}
if (device == AudioSystem.DEVICE_OUT_HEARING_AID
&& streamType == getBluetoothContextualVolumeStream()) {
Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index

View File

@ -155,6 +155,7 @@ public class AudioServiceEvents {
static final int VOL_MODE_CHANGE_HEARING_AID = 7;
static final int VOL_SET_GROUP_VOL = 8;
static final int VOL_MUTE_STREAM_INT = 9;
static final int VOL_SET_LE_AUDIO_VOL = 10;
final int mOp;
final int mStream;
@ -310,6 +311,13 @@ public class AudioServiceEvents {
.set(MediaMetrics.Property.INDEX, mVal1)
.record();
return;
case VOL_SET_LE_AUDIO_VOL:
new MediaMetrics.Item(mMetricsId)
.set(MediaMetrics.Property.EVENT, "setLeAudioVolume")
.set(MediaMetrics.Property.INDEX, mVal1)
.set(MediaMetrics.Property.MAX_INDEX, mVal2)
.record();
return;
case VOL_SET_AVRCP_VOL:
new MediaMetrics.Item(mMetricsId)
.set(MediaMetrics.Property.EVENT, "setAvrcpVolume")
@ -382,6 +390,11 @@ public class AudioServiceEvents {
.append(" index:").append(mVal1)
.append(" gain dB:").append(mVal2)
.toString();
case VOL_SET_LE_AUDIO_VOL:
return new StringBuilder("setLeAudioVolume:")
.append(" index:").append(mVal1)
.append(" gain dB:").append(mVal2)
.toString();
case VOL_SET_AVRCP_VOL:
return new StringBuilder("setAvrcpVolume:")
.append(" index:").append(mVal1)

View File

@ -25,6 +25,7 @@ import android.bluetooth.BluetoothCodecStatus;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothLeAudio;
import android.bluetooth.BluetoothProfile;
import android.content.Intent;
import android.media.AudioDeviceAttributes;
@ -63,6 +64,8 @@ public class BtHelper {
private @Nullable BluetoothHearingAid mHearingAid;
private @Nullable BluetoothLeAudio mLeAudio;
// Reference to BluetoothA2dp to query for AbsoluteVolume.
private @Nullable BluetoothA2dp mA2dp;
@ -106,6 +109,8 @@ public class BtHelper {
private static final int SCO_MODE_MAX = 2;
private static final int BT_HEARING_AID_GAIN_MIN = -128;
private static final int BT_LE_AUDIO_MIN_VOL = 0;
private static final int BT_LE_AUDIO_MAX_VOL = 255;
/**
* Returns a string representation of the scoAudioMode.
@ -235,6 +240,8 @@ public class BtHelper {
mBluetoothProfileServiceListener, BluetoothProfile.A2DP);
adapter.getProfileProxy(mDeviceBroker.getContext(),
mBluetoothProfileServiceListener, BluetoothProfile.HEARING_AID);
adapter.getProfileProxy(mDeviceBroker.getContext(),
mBluetoothProfileServiceListener, BluetoothProfile.LE_AUDIO);
}
}
@ -389,6 +396,26 @@ public class BtHelper {
return requestScoState(BluetoothHeadset.STATE_AUDIO_DISCONNECTED, SCO_MODE_VIRTUAL_CALL);
}
/*package*/ synchronized void setLeAudioVolume(int index, int maxIndex, int streamType) {
if (mLeAudio == null) {
if (AudioService.DEBUG_VOL) {
Log.i(TAG, "setLeAudioVolume: null mLeAudio");
}
return;
}
/* leaudio expect volume value in range 0 to 255
*/
int volume = (index * (BT_LE_AUDIO_MAX_VOL - BT_LE_AUDIO_MIN_VOL)) / maxIndex ;
if (AudioService.DEBUG_VOL) {
Log.i(TAG, "setLeAudioVolume: calling mLeAudio.setVolume idx="
+ index + " volume=" + volume);
}
AudioService.sVolumeLogger.log(new AudioServiceEvents.VolumeEvent(
AudioServiceEvents.VolumeEvent.VOL_SET_LE_AUDIO_VOL, index, maxIndex));
mLeAudio.setVolume(volume);
}
/*package*/ synchronized void setHearingAidVolume(int index, int streamType) {
if (mHearingAid == null) {
if (AudioService.DEBUG_VOL) {
@ -428,6 +455,7 @@ public class BtHelper {
mDeviceBroker.postDisconnectA2dpSink();
mDeviceBroker.postDisconnectHeadset();
mDeviceBroker.postDisconnectHearingAid();
mDeviceBroker.postDisconnectLeAudio();
}
// @GuardedBy("AudioDeviceBroker.mSetModeLock")
@ -488,6 +516,23 @@ public class BtHelper {
/*eventSource*/ "mBluetoothProfileServiceListener");
}
/*package*/ synchronized void onLeAudioProfileConnected(BluetoothLeAudio leAudio) {
mLeAudio = leAudio;
final List<BluetoothDevice> deviceList = mLeAudio.getConnectedDevices();
if (deviceList.isEmpty()) {
return;
}
final BluetoothDevice btDevice = deviceList.get(0);
final @BluetoothProfile.BtProfileState int state =
mLeAudio.getConnectionState(btDevice);
mDeviceBroker.postBluetoothLeAudioOutDeviceConnectionState(
btDevice, state,
/*suppressNoisyIntent*/ false,
/*musicDevice android.media.AudioSystem.DEVICE_NONE,*/
/*eventSource*/ "mBluetoothProfileServiceListener");
}
// @GuardedBy("AudioDeviceBroker.mSetModeLock")
@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
/*package*/ synchronized void onHeadsetProfileConnected(BluetoothHeadset headset) {
@ -655,6 +700,13 @@ public class BtHelper {
mDeviceBroker.postBtHearingAidProfileConnected(
(BluetoothHearingAid) proxy);
break;
case BluetoothProfile.LE_AUDIO:
AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
"BT profile service: connecting LE_AUDIO profile"));
mDeviceBroker.postBtLeAudioProfileConnected(
(BluetoothLeAudio) proxy);
break;
default:
break;
}
@ -677,6 +729,9 @@ public class BtHelper {
case BluetoothProfile.HEARING_AID:
mDeviceBroker.postDisconnectHearingAid();
break;
case BluetoothProfile.LE_AUDIO:
mDeviceBroker.postDisconnectLeAudio();
break;
default:
break;
@ -899,6 +954,7 @@ public class BtHelper {
pw.println(prefix + "mScoAudioState: " + scoAudioStateToString(mScoAudioState));
pw.println(prefix + "mScoAudioMode: " + scoAudioModeToString(mScoAudioMode));
pw.println("\n" + prefix + "mHearingAid: " + mHearingAid);
pw.println("\n" + prefix + "mLeAudio: " + mLeAudio);
pw.println(prefix + "mA2dp: " + mA2dp);
pw.println(prefix + "mAvrcpAbsVolSupported: " + mAvrcpAbsVolSupported);
}

View File

@ -26,6 +26,7 @@ import android.bluetooth.BluetoothA2dp;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothHearingAid;
import android.bluetooth.BluetoothLeAudio;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
@ -56,6 +57,7 @@ class BluetoothRouteProvider {
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
private static final String HEARING_AID_ROUTE_ID_PREFIX = "HEARING_AID_";
private static final String LE_AUDIO_ROUTE_ID_PREFIX = "LE_AUDIO_";
@SuppressWarnings("WeakerAccess") /* synthetic access */
// Maps hardware address to BluetoothRouteInfo
@ -66,6 +68,8 @@ class BluetoothRouteProvider {
BluetoothA2dp mA2dpProfile;
@SuppressWarnings("WeakerAccess") /* synthetic access */
BluetoothHearingAid mHearingAidProfile;
@SuppressWarnings("WeakerAccess") /* synthetic access */
BluetoothLeAudio mLeAudioProfile;
// Route type -> volume map
private final SparseIntArray mVolumeMap = new SparseIntArray();
@ -108,6 +112,7 @@ class BluetoothRouteProvider {
public void start(UserHandle user) {
mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.A2DP);
mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEARING_AID);
mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.LE_AUDIO);
// Bluetooth on/off broadcasts
addEventReceiver(BluetoothAdapter.ACTION_STATE_CHANGED, new AdapterStateChangedReceiver());
@ -119,6 +124,10 @@ class BluetoothRouteProvider {
deviceStateChangedReceiver);
addEventReceiver(BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED,
deviceStateChangedReceiver);
addEventReceiver(BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED,
deviceStateChangedReceiver);
addEventReceiver(BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED,
deviceStateChangedReceiver);
mContext.registerReceiverAsUser(mBroadcastReceiver, user,
mIntentFilter, null, null);
@ -240,6 +249,8 @@ class BluetoothRouteProvider {
| AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES
| AudioManager.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER)) != 0) {
routeType = MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
} else if ((devices & (AudioManager.DEVICE_OUT_BLE_HEADSET)) != 0) {
routeType = MediaRoute2Info.TYPE_BLE_HEADSET;
} else {
return false;
}
@ -288,6 +299,12 @@ class BluetoothRouteProvider {
routeId = HEARING_AID_ROUTE_ID_PREFIX + mHearingAidProfile.getHiSyncId(device);
type = MediaRoute2Info.TYPE_HEARING_AID;
}
if (mLeAudioProfile != null
&& mLeAudioProfile.getConnectedDevices().contains(device)) {
newBtRoute.connectedProfiles.put(BluetoothProfile.LE_AUDIO, true);
routeId = LE_AUDIO_ROUTE_ID_PREFIX + mLeAudioProfile.getGroupId(device);
type = MediaRoute2Info.TYPE_BLE_HEADSET;
}
// Current volume will be set when connected.
newBtRoute.route = new MediaRoute2Info.Builder(routeId, deviceName)
@ -358,11 +375,7 @@ class BluetoothRouteProvider {
}
}
private void addActiveHearingAidDevices(BluetoothDevice device) {
if (DEBUG) {
Log.d(TAG, "Setting active hearing aid devices. device=" + device);
}
private void addActiveDevices(BluetoothDevice device) {
// Let the given device be the first active device
BluetoothRouteInfo activeBtRoute = mBluetoothRoutes.get(device.getAddress());
addActiveRoute(activeBtRoute);
@ -376,6 +389,21 @@ class BluetoothRouteProvider {
}
}
}
private void addActiveHearingAidDevices(BluetoothDevice device) {
if (DEBUG) {
Log.d(TAG, "Setting active hearing aid devices. device=" + device);
}
addActiveDevices(device);
}
private void addActiveLeAudioDevices(BluetoothDevice device) {
if (DEBUG) {
Log.d(TAG, "Setting active le audio devices. device=" + device);
}
addActiveDevices(device);
}
interface BluetoothRoutesUpdatedListener {
void onBluetoothRoutesUpdated(@NonNull List<MediaRoute2Info> routes);
@ -392,6 +420,11 @@ class BluetoothRouteProvider {
if (connectedProfiles.get(BluetoothProfile.HEARING_AID, false)) {
return MediaRoute2Info.TYPE_HEARING_AID;
}
if (connectedProfiles.get(BluetoothProfile.LE_AUDIO, false)) {
return MediaRoute2Info.TYPE_BLE_HEADSET;
}
return MediaRoute2Info.TYPE_BLUETOOTH_A2DP;
}
}
@ -410,6 +443,10 @@ class BluetoothRouteProvider {
mHearingAidProfile = (BluetoothHearingAid) proxy;
activeDevices = mHearingAidProfile.getActiveDevices();
break;
case BluetoothProfile.LE_AUDIO:
mLeAudioProfile = (BluetoothLeAudio) proxy;
activeDevices = mLeAudioProfile.getActiveDevices();
break;
default:
return;
}
@ -434,6 +471,9 @@ class BluetoothRouteProvider {
case BluetoothProfile.HEARING_AID:
mHearingAidProfile = null;
break;
case BluetoothProfile.LE_AUDIO:
mLeAudioProfile = null;
break;
default:
return;
}
@ -490,12 +530,22 @@ class BluetoothRouteProvider {
}
notifyBluetoothRoutesUpdated();
break;
case BluetoothLeAudio.ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED:
clearActiveRoutesWithType(MediaRoute2Info.TYPE_BLE_HEADSET);
if (device != null) {
addActiveLeAudioDevices(device);
}
notifyBluetoothRoutesUpdated();
break;
case BluetoothA2dp.ACTION_CONNECTION_STATE_CHANGED:
handleConnectionStateChanged(BluetoothProfile.A2DP, intent, device);
break;
case BluetoothHearingAid.ACTION_CONNECTION_STATE_CHANGED:
handleConnectionStateChanged(BluetoothProfile.HEARING_AID, intent, device);
break;
case BluetoothLeAudio.ACTION_LE_AUDIO_CONNECTION_STATE_CHANGED:
handleConnectionStateChanged(BluetoothProfile.LE_AUDIO, intent, device);
break;
}
}