le_audio: Introduce connection state handling for LE Audio group
Patch implements connection state handling for LE Audio device group. Tag: #feature Test: Set LE audio device as active Sponsor: jpawlowski@ Bug: 150670922 Change-Id: I11222ca07e265ac8b6dc3c21650874ebeffa473c
This commit is contained in:
committed by
Jakub Pawlowski
parent
538771303d
commit
59b2baa872
@@ -96,6 +96,77 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
||||
public static final String ACTION_LE_AUDIO_ACTIVE_DEVICE_CHANGED =
|
||||
"android.bluetooth.action.LE_AUDIO_ACTIVE_DEVICE_CHANGED";
|
||||
|
||||
/**
|
||||
* Intent used to broadcast group node status information.
|
||||
*
|
||||
* <p>This intent will have 3 extra:
|
||||
* <ul>
|
||||
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
|
||||
* be null if no device is active. </li>
|
||||
* <li> {@link #EXTRA_LE_AUDIO_GROUP_ID} - Group id. </li>
|
||||
* <li> {@link #EXTRA_LE_AUDIO_GROUP_NODE_STATUS} - Group node status. </li>
|
||||
* </ul>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
|
||||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||||
public static final String ACTION_LE_AUDIO_GROUP_NODE_STATUS_CHANGED =
|
||||
"android.bluetooth.action.LE_AUDIO_GROUP_NODE_STATUS_CHANGED";
|
||||
|
||||
|
||||
/**
|
||||
* Intent used to broadcast group status information.
|
||||
*
|
||||
* <p>This intent will have 4 extra:
|
||||
* <ul>
|
||||
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
|
||||
* be null if no device is active. </li>
|
||||
* <li> {@link #EXTRA_LE_AUDIO_GROUP_ID} - Group id. </li>
|
||||
* <li> {@link #EXTRA_LE_AUDIO_GROUP_STATUS} - Group status. </li>
|
||||
* </ul>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
|
||||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||||
public static final String ACTION_LE_AUDIO_GROUP_STATUS_CHANGED =
|
||||
"android.bluetooth.action.LE_AUDIO_GROUP_STATUS_CHANGED";
|
||||
|
||||
/**
|
||||
* Intent used to broadcast group audio configuration changed information.
|
||||
*
|
||||
* <p>This intent will have 5 extra:
|
||||
* <ul>
|
||||
* <li> {@link #EXTRA_LE_AUDIO_GROUP_ID} - Group id. </li>
|
||||
* <li> {@link #EXTRA_LE_AUDIO_DIRECTION} - Direction as bit mask. </li>
|
||||
* <li> {@link #EXTRA_LE_AUDIO_SINK_LOCATION} - Sink location as per Bluetooth Assigned
|
||||
* Numbers </li>
|
||||
* <li> {@link #EXTRA_LE_AUDIO_SOURCE_LOCATION} - Source location as per Bluetooth Assigned
|
||||
* Numbers </li>
|
||||
* <li> {@link #EXTRA_LE_AUDIO_AVAILABLE_CONTEXTS} - Available contexts for group as per
|
||||
* Bluetooth Assigned Numbers </li>
|
||||
* </ul>
|
||||
*
|
||||
* @hide
|
||||
*/
|
||||
@RequiresPermission(Manifest.permission.BLUETOOTH_PRIVILEGED)
|
||||
@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
|
||||
public static final String ACTION_LE_AUDIO_CONF_CHANGED =
|
||||
"android.bluetooth.action.LE_AUDIO_CONF_CHANGED";
|
||||
|
||||
/**
|
||||
* Indicates conversation between humans as, for example, in telephony or video calls.
|
||||
* @hide
|
||||
*/
|
||||
public static final int CONTEXT_TYPE_COMMUNICATION = 0x0002;
|
||||
|
||||
/**
|
||||
* Indicates media as, for example, in music, public radio, podcast or video soundtrack.
|
||||
* @hide
|
||||
*/
|
||||
public static final int CONTEXT_TYPE_MEDIA = 0x0004;
|
||||
|
||||
/**
|
||||
* This represents an invalid group ID.
|
||||
*
|
||||
@@ -103,6 +174,71 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
|
||||
*/
|
||||
public static final int GROUP_ID_INVALID = IBluetoothLeAudio.LE_AUDIO_GROUP_ID_INVALID;
|
||||
|
||||
/**
|
||||
* Contains group id.
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_LE_AUDIO_GROUP_ID =
|
||||
"android.bluetooth.extra.LE_AUDIO_GROUP_ID";
|
||||
|
||||
/**
|
||||
* Contains group node status, can be any of
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li> {@link #GROUP_NODE_ADDED} </li>
|
||||
* <li> {@link #GROUP_NODE_REMOVED} </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_LE_AUDIO_GROUP_NODE_STATUS =
|
||||
"android.bluetooth.extra.LE_AUDIO_GROUP_NODE_STATUS";
|
||||
|
||||
/**
|
||||
* Contains group status, can be any of
|
||||
*
|
||||
* <p>
|
||||
* <ul>
|
||||
* <li> {@link #GROUP_STATUS_IDLE} </li>
|
||||
* <li> {@link #GROUP_STATUS_STREAMING} </li>
|
||||
* <li> {@link #GROUP_STATUS_SUSPENDED} </li>
|
||||
* <li> {@link #GROUP_STATUS_RECONFIGURED} </li>
|
||||
* <li> {@link #GROUP_STATUS_DESTROYED} </li>
|
||||
* </ul>
|
||||
* <p>
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_LE_AUDIO_GROUP_STATUS =
|
||||
"android.bluetooth.extra.LE_AUDIO_GROUP_STATUS";
|
||||
|
||||
/**
|
||||
* Contains bit mask for direction, bit 0 set when Sink, bit 1 set when Source.
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_LE_AUDIO_DIRECTION =
|
||||
"android.bluetooth.extra.LE_AUDIO_DIRECTION";
|
||||
|
||||
/**
|
||||
* Contains source location as per Bluetooth Assigned Numbers
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_LE_AUDIO_SOURCE_LOCATION =
|
||||
"android.bluetooth.extra.LE_AUDIO_SOURCE_LOCATION";
|
||||
|
||||
/**
|
||||
* Contains sink location as per Bluetooth Assigned Numbers
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_LE_AUDIO_SINK_LOCATION =
|
||||
"android.bluetooth.extra.LE_AUDIO_SINK_LOCATION";
|
||||
|
||||
/**
|
||||
* Contains available context types for group as per Bluetooth Assigned Numbers
|
||||
* @hide
|
||||
*/
|
||||
public static final String EXTRA_LE_AUDIO_AVAILABLE_CONTEXTS =
|
||||
"android.bluetooth.extra.LE_AUDIO_AVAILABLE_CONTEXTS";
|
||||
|
||||
private final BluetoothAdapter mAdapter;
|
||||
private final AttributionSource mAttributionSource;
|
||||
private final BluetoothProfileConnector<IBluetoothLeAudio> mProfileConnector =
|
||||
|
||||
@@ -5791,6 +5791,40 @@ public class AudioManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate Le Audio output device connection state change and eventually suppress
|
||||
* the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent.
|
||||
* @param device Bluetooth device connected/disconnected
|
||||
* @param state new connection state (BluetoothProfile.STATE_xxx)
|
||||
* @param suppressNoisyIntent if true the
|
||||
* {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent will not be sent.
|
||||
* {@hide}
|
||||
*/
|
||||
public void setBluetoothLeAudioOutDeviceConnectionState(BluetoothDevice device, int state,
|
||||
boolean suppressNoisyIntent) {
|
||||
final IAudioService service = getService();
|
||||
try {
|
||||
service.setBluetoothLeAudioOutDeviceConnectionState(device, state, suppressNoisyIntent);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate Le Audio input connection state change.
|
||||
* @param device Bluetooth device connected/disconnected
|
||||
* @param state new connection state (BluetoothProfile.STATE_xxx)
|
||||
* {@hide}
|
||||
*/
|
||||
public void setBluetoothLeAudioInDeviceConnectionState(BluetoothDevice device, int state) {
|
||||
final IAudioService service = getService();
|
||||
try {
|
||||
service.setBluetoothLeAudioInDeviceConnectionState(device, state);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicate A2DP source or sink connection state change and eventually suppress
|
||||
* the {@link AudioManager.ACTION_AUDIO_BECOMING_NOISY} intent.
|
||||
|
||||
@@ -273,6 +273,11 @@ interface IAudioService {
|
||||
void setBluetoothHearingAidDeviceConnectionState(in BluetoothDevice device,
|
||||
int state, boolean suppressNoisyIntent, int musicDevice);
|
||||
|
||||
void setBluetoothLeAudioOutDeviceConnectionState(in BluetoothDevice device, int state,
|
||||
boolean suppressNoisyIntent);
|
||||
|
||||
void setBluetoothLeAudioInDeviceConnectionState(in BluetoothDevice device, int state);
|
||||
|
||||
void setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(in BluetoothDevice device,
|
||||
int state, int profile, boolean suppressNoisyIntent, int a2dpVolume);
|
||||
|
||||
|
||||
@@ -632,6 +632,37 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
sendLMsgNoDelay(MSG_L_HEARING_AID_DEVICE_CONNECTION_CHANGE_EXT, SENDMSG_QUEUE, info);
|
||||
}
|
||||
|
||||
private static final class LeAudioDeviceConnectionInfo {
|
||||
final @NonNull BluetoothDevice mDevice;
|
||||
final @AudioService.BtProfileConnectionState int mState;
|
||||
final boolean mSupprNoisy;
|
||||
final @NonNull String mEventSource;
|
||||
|
||||
LeAudioDeviceConnectionInfo(@NonNull BluetoothDevice device,
|
||||
@AudioService.BtProfileConnectionState int state,
|
||||
boolean suppressNoisyIntent, @NonNull String eventSource) {
|
||||
mDevice = device;
|
||||
mState = state;
|
||||
mSupprNoisy = suppressNoisyIntent;
|
||||
mEventSource = eventSource;
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ void postBluetoothLeAudioOutDeviceConnectionState(
|
||||
@NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state,
|
||||
boolean suppressNoisyIntent, @NonNull String eventSource) {
|
||||
final LeAudioDeviceConnectionInfo info = new LeAudioDeviceConnectionInfo(
|
||||
device, state, suppressNoisyIntent, eventSource);
|
||||
sendLMsgNoDelay(MSG_L_LE_AUDIO_DEVICE_OUT_CONNECTION_CHANGE_EXT, SENDMSG_QUEUE, info);
|
||||
}
|
||||
|
||||
/*package*/ void postBluetoothLeAudioInDeviceConnectionState(
|
||||
@NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state,
|
||||
@NonNull String eventSource) {
|
||||
final LeAudioDeviceConnectionInfo info = new LeAudioDeviceConnectionInfo(
|
||||
device, state, false, eventSource);
|
||||
sendLMsgNoDelay(MSG_L_LE_AUDIO_DEVICE_IN_CONNECTION_CHANGE_EXT, SENDMSG_QUEUE, info);
|
||||
}
|
||||
|
||||
/**
|
||||
* Current Bluetooth SCO audio active state indicated by BtHelper via setBluetoothScoOn().
|
||||
@@ -902,6 +933,23 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
delay);
|
||||
}
|
||||
|
||||
/*package*/ void postSetLeAudioOutConnectionState(
|
||||
@AudioService.BtProfileConnectionState int state,
|
||||
@NonNull BluetoothDevice device, int delay) {
|
||||
sendILMsg(MSG_IL_SET_LE_AUDIO_OUT_CONNECTION_STATE, SENDMSG_QUEUE,
|
||||
state,
|
||||
device,
|
||||
delay);
|
||||
}
|
||||
|
||||
/*package*/ void postSetLeAudioInConnectionState(
|
||||
@AudioService.BtProfileConnectionState int state,
|
||||
@NonNull BluetoothDevice device) {
|
||||
sendILMsgNoDelay(MSG_IL_SET_LE_AUDIO_IN_CONNECTION_STATE, SENDMSG_QUEUE,
|
||||
state,
|
||||
device);
|
||||
}
|
||||
|
||||
/*package*/ void postDisconnectA2dp() {
|
||||
sendMsgNoDelay(MSG_DISCONNECT_A2DP, SENDMSG_QUEUE);
|
||||
}
|
||||
@@ -1223,7 +1271,20 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
synchronized (mDeviceStateLock) {
|
||||
mDeviceInventory.onSetHearingAidConnectionState(
|
||||
(BluetoothDevice) msg.obj, msg.arg1,
|
||||
mAudioService.getHearingAidStreamType());
|
||||
mAudioService.getBluetoothContextualVolumeStream());
|
||||
}
|
||||
break;
|
||||
case MSG_IL_SET_LE_AUDIO_OUT_CONNECTION_STATE:
|
||||
synchronized (mDeviceStateLock) {
|
||||
mDeviceInventory.onSetLeAudioOutConnectionState(
|
||||
(BluetoothDevice) msg.obj, msg.arg1,
|
||||
mAudioService.getBluetoothContextualVolumeStream());
|
||||
}
|
||||
break;
|
||||
case MSG_IL_SET_LE_AUDIO_IN_CONNECTION_STATE:
|
||||
synchronized (mDeviceStateLock) {
|
||||
mDeviceInventory.onSetLeAudioInConnectionState(
|
||||
(BluetoothDevice) msg.obj, msg.arg1);
|
||||
}
|
||||
break;
|
||||
case MSG_BT_HEADSET_CNCT_FAILED:
|
||||
@@ -1415,6 +1476,31 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
final int capturePreset = msg.arg1;
|
||||
mDeviceInventory.onSaveClearPreferredDevicesForCapturePreset(capturePreset);
|
||||
} break;
|
||||
case MSG_L_LE_AUDIO_DEVICE_OUT_CONNECTION_CHANGE_EXT: {
|
||||
final LeAudioDeviceConnectionInfo info =
|
||||
(LeAudioDeviceConnectionInfo) msg.obj;
|
||||
AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
|
||||
"setLeAudioDeviceOutConnectionState state=" + info.mState
|
||||
+ " addr=" + info.mDevice.getAddress()
|
||||
+ " supprNoisy=" + info.mSupprNoisy
|
||||
+ " src=" + info.mEventSource)).printLog(TAG));
|
||||
synchronized (mDeviceStateLock) {
|
||||
mDeviceInventory.setBluetoothLeAudioOutDeviceConnectionState(
|
||||
info.mDevice, info.mState, info.mSupprNoisy);
|
||||
}
|
||||
} break;
|
||||
case MSG_L_LE_AUDIO_DEVICE_IN_CONNECTION_CHANGE_EXT: {
|
||||
final LeAudioDeviceConnectionInfo info =
|
||||
(LeAudioDeviceConnectionInfo) msg.obj;
|
||||
AudioService.sDeviceLogger.log((new AudioEventLogger.StringEvent(
|
||||
"setLeAudioDeviceInConnectionState state=" + info.mState
|
||||
+ " addr=" + info.mDevice.getAddress()
|
||||
+ " src=" + info.mEventSource)).printLog(TAG));
|
||||
synchronized (mDeviceStateLock) {
|
||||
mDeviceInventory.setBluetoothLeAudioInDeviceConnectionState(info.mDevice,
|
||||
info.mState);
|
||||
}
|
||||
} break;
|
||||
default:
|
||||
Log.wtf(TAG, "Invalid message " + msg.what);
|
||||
}
|
||||
@@ -1496,6 +1582,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
private static final int MSG_IL_SET_PREF_DEVICES_FOR_STRATEGY = 40;
|
||||
private static final int MSG_I_REMOVE_PREF_DEVICES_FOR_STRATEGY = 41;
|
||||
|
||||
private static final int MSG_IL_SET_LE_AUDIO_OUT_CONNECTION_STATE = 42;
|
||||
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;
|
||||
|
||||
private static boolean isMessageHandledUnderWakelock(int msgId) {
|
||||
switch(msgId) {
|
||||
case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE:
|
||||
@@ -1511,6 +1602,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
case MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION:
|
||||
case MSG_L_HEARING_AID_DEVICE_CONNECTION_CHANGE_EXT:
|
||||
case MSG_CHECK_MUTE_MUSIC:
|
||||
case MSG_L_LE_AUDIO_DEVICE_OUT_CONNECTION_CHANGE_EXT:
|
||||
case MSG_L_LE_AUDIO_DEVICE_IN_CONNECTION_CHANGE_EXT:
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
|
||||
@@ -20,6 +20,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.Intent;
|
||||
import android.media.AudioDeviceAttributes;
|
||||
@@ -421,6 +422,45 @@ public class AudioDeviceInventory {
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ void onSetLeAudioConnectionState(BluetoothDevice btDevice,
|
||||
@AudioService.BtProfileConnectionState int state, int streamType, int device) {
|
||||
String address = btDevice.getAddress();
|
||||
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
|
||||
address = "";
|
||||
}
|
||||
AudioService.sDeviceLogger.log(new AudioEventLogger.StringEvent(
|
||||
"onSetLeAudioConnectionState addr=" + address));
|
||||
|
||||
synchronized (mDevicesLock) {
|
||||
DeviceInfo di = null;
|
||||
boolean isConnected = false;
|
||||
|
||||
String key = DeviceInfo.makeDeviceListKey(device, btDevice.getAddress());
|
||||
di = mConnectedDevices.get(key);
|
||||
isConnected = di != null;
|
||||
|
||||
if (isConnected && state != BluetoothProfile.STATE_CONNECTED) {
|
||||
makeLeAudioDeviceUnavailable(address, device);
|
||||
} else if (!isConnected && state == BluetoothProfile.STATE_CONNECTED) {
|
||||
makeLeAudioDeviceAvailable(address, BtHelper.getName(btDevice), streamType,
|
||||
device, "onSetLeAudioConnectionState");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ void onSetLeAudioOutConnectionState(BluetoothDevice btDevice,
|
||||
@AudioService.BtProfileConnectionState int state, int streamType) {
|
||||
// TODO: b/198610537 clarify DEVICE_OUT_BLE_HEADSET vs DEVICE_OUT_BLE_SPEAKER criteria
|
||||
onSetLeAudioConnectionState(btDevice, state, streamType,
|
||||
AudioSystem.DEVICE_OUT_BLE_HEADSET);
|
||||
}
|
||||
|
||||
/*package*/ void onSetLeAudioInConnectionState(BluetoothDevice btDevice,
|
||||
@AudioService.BtProfileConnectionState int state) {
|
||||
onSetLeAudioConnectionState(btDevice, state, AudioSystem.STREAM_DEFAULT,
|
||||
AudioSystem.DEVICE_IN_BLE_HEADSET);
|
||||
}
|
||||
|
||||
@GuardedBy("AudioDeviceBroker.mDeviceStateLock")
|
||||
/*package*/ void onBluetoothA2dpActiveDeviceChange(
|
||||
@NonNull BtHelper.BluetoothA2dpDeviceInfo btInfo, int event) {
|
||||
@@ -946,6 +986,28 @@ public class AudioDeviceInventory {
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ int setBluetoothLeAudioOutDeviceConnectionState(
|
||||
@NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state,
|
||||
boolean suppressNoisyIntent) {
|
||||
synchronized (mDevicesLock) {
|
||||
/* Active device become null and it's previous device is not connected anymore */
|
||||
int delay = 0;
|
||||
if (!suppressNoisyIntent) {
|
||||
int intState = (state == BluetoothLeAudio.STATE_CONNECTED) ? 1 : 0;
|
||||
delay = checkSendBecomingNoisyIntentInt(AudioSystem.DEVICE_OUT_BLE_HEADSET,
|
||||
intState, AudioSystem.DEVICE_NONE);
|
||||
}
|
||||
mDeviceBroker.postSetLeAudioOutConnectionState(state, device, delay);
|
||||
return delay;
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ void setBluetoothLeAudioInDeviceConnectionState(
|
||||
@NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state) {
|
||||
synchronized (mDevicesLock) {
|
||||
mDeviceBroker.postSetLeAudioInConnectionState(state, device);
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------
|
||||
// Internal utilities
|
||||
@@ -1117,6 +1179,36 @@ public class AudioDeviceInventory {
|
||||
.record();
|
||||
}
|
||||
|
||||
@GuardedBy("mDevicesLock")
|
||||
private void makeLeAudioDeviceAvailable(String address, String name, int streamType, int device,
|
||||
String eventSource) {
|
||||
if (device != AudioSystem.DEVICE_NONE) {
|
||||
AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_AVAILABLE,
|
||||
address, name, AudioSystem.AUDIO_FORMAT_DEFAULT);
|
||||
mConnectedDevices.put(DeviceInfo.makeDeviceListKey(device, address),
|
||||
new DeviceInfo(device, name, address, AudioSystem.AUDIO_FORMAT_DEFAULT));
|
||||
mDeviceBroker.postAccessoryPlugMediaUnmute(device);
|
||||
}
|
||||
|
||||
if (streamType == AudioSystem.STREAM_DEFAULT) {
|
||||
// No need to update volume for input devices
|
||||
return;
|
||||
}
|
||||
|
||||
mDeviceBroker.postApplyVolumeOnDevice(streamType, device, "makeLeAudioDeviceAvailable");
|
||||
}
|
||||
|
||||
@GuardedBy("mDevicesLock")
|
||||
private void makeLeAudioDeviceUnavailable(String address, int device) {
|
||||
if (device != AudioSystem.DEVICE_NONE) {
|
||||
AudioSystem.setDeviceConnectionState(device, AudioSystem.DEVICE_STATE_UNAVAILABLE,
|
||||
address, "", AudioSystem.AUDIO_FORMAT_DEFAULT);
|
||||
mConnectedDevices.remove(DeviceInfo.makeDeviceListKey(device, address));
|
||||
}
|
||||
|
||||
setCurrentAudioRouteNameIfPossible(null, false /*fromA2dp*/);
|
||||
}
|
||||
|
||||
@GuardedBy("mDevicesLock")
|
||||
private void setCurrentAudioRouteNameIfPossible(String name, boolean fromA2dp) {
|
||||
synchronized (mCurAudioRoutes) {
|
||||
@@ -1153,6 +1245,7 @@ public class AudioDeviceInventory {
|
||||
BECOMING_NOISY_INTENT_DEVICES_SET.add(AudioSystem.DEVICE_OUT_HEARING_AID);
|
||||
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);
|
||||
}
|
||||
|
||||
// must be called before removing the device from mConnectedDevices
|
||||
|
||||
@@ -2956,7 +2956,7 @@ public class AudioService extends IAudioService.Stub
|
||||
if (device == AudioSystem.DEVICE_OUT_HEARING_AID) {
|
||||
// only modify the hearing aid attenuation when the stream to modify matches
|
||||
// the one expected by the hearing aid
|
||||
if (streamType == getHearingAidStreamType()) {
|
||||
if (streamType == getBluetoothContextualVolumeStream()) {
|
||||
if (DEBUG_VOL) {
|
||||
Log.d(TAG, "adjustSreamVolume postSetHearingAidVolumeIndex index="
|
||||
+ newIndex + " stream=" + streamType);
|
||||
@@ -3306,11 +3306,11 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ int getHearingAidStreamType() {
|
||||
return getHearingAidStreamType(mMode.get());
|
||||
/*package*/ int getBluetoothContextualVolumeStream() {
|
||||
return getBluetoothContextualVolumeStream(mMode.get());
|
||||
}
|
||||
|
||||
private int getHearingAidStreamType(int mode) {
|
||||
private int getBluetoothContextualVolumeStream(int mode) {
|
||||
switch (mode) {
|
||||
case AudioSystem.MODE_IN_COMMUNICATION:
|
||||
case AudioSystem.MODE_IN_CALL:
|
||||
@@ -3467,7 +3467,7 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
|
||||
private void updateHearingAidVolumeOnVoiceActivityUpdate() {
|
||||
final int streamType = getHearingAidStreamType();
|
||||
final int streamType = getBluetoothContextualVolumeStream();
|
||||
final int index = getStreamVolume(streamType);
|
||||
sVolumeLogger.log(new VolumeEvent(VolumeEvent.VOL_VOICE_ACTIVITY_HEARING_AID,
|
||||
mVoicePlaybackActive.get(), streamType, index));
|
||||
@@ -3499,7 +3499,7 @@ public class AudioService extends IAudioService.Stub
|
||||
return;
|
||||
}
|
||||
|
||||
int streamType = getHearingAidStreamType(newMode);
|
||||
int streamType = getBluetoothContextualVolumeStream(newMode);
|
||||
|
||||
final Set<Integer> deviceTypes = AudioSystem.generateAudioDeviceTypesSet(
|
||||
mAudioSystem.getDevicesForStream(streamType));
|
||||
@@ -3581,7 +3581,7 @@ public class AudioService extends IAudioService.Stub
|
||||
}
|
||||
|
||||
if (device == AudioSystem.DEVICE_OUT_HEARING_AID
|
||||
&& streamType == getHearingAidStreamType()) {
|
||||
&& streamType == getBluetoothContextualVolumeStream()) {
|
||||
Log.i(TAG, "setStreamVolume postSetHearingAidVolumeIndex index=" + index
|
||||
+ " stream=" + streamType);
|
||||
mDeviceBroker.postSetHearingAidVolumeIndex(index, streamType);
|
||||
@@ -6255,6 +6255,38 @@ public class AudioService extends IAudioService.Stub
|
||||
device, state, suppressNoisyIntent, musicDevice, "AudioService");
|
||||
}
|
||||
|
||||
private void setBluetoothLeAudioDeviceConnectionState(@NonNull BluetoothDevice device,
|
||||
@BtProfileConnectionState int state) {
|
||||
if (device == null) {
|
||||
throw new IllegalArgumentException("Illegal null device");
|
||||
}
|
||||
if (state != BluetoothProfile.STATE_CONNECTED
|
||||
&& state != BluetoothProfile.STATE_DISCONNECTED) {
|
||||
throw new IllegalArgumentException("Illegal BluetoothProfile state for device "
|
||||
+ " (dis)connection, got " + state);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* See AudioManager.setBluetoothLeAudioOutDeviceConnectionState()
|
||||
*/
|
||||
public void setBluetoothLeAudioOutDeviceConnectionState(
|
||||
@NonNull BluetoothDevice device, @BtProfileConnectionState int state,
|
||||
boolean suppressNoisyIntent) {
|
||||
setBluetoothLeAudioDeviceConnectionState(device, state);
|
||||
mDeviceBroker.postBluetoothLeAudioOutDeviceConnectionState(device, state,
|
||||
suppressNoisyIntent, "AudioService");
|
||||
}
|
||||
|
||||
/**
|
||||
* See AudioManager.setBluetoothLeAudioInDeviceConnectionState()
|
||||
*/
|
||||
public void setBluetoothLeAudioInDeviceConnectionState(
|
||||
@NonNull BluetoothDevice device, @BtProfileConnectionState int state) {
|
||||
setBluetoothLeAudioDeviceConnectionState(device, state);
|
||||
mDeviceBroker.postBluetoothLeAudioInDeviceConnectionState(device, state, "AudioService");
|
||||
}
|
||||
|
||||
/**
|
||||
* See AudioManager.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent()
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user