Merge changes I8d360d47,Iebf877d8 into udc-dev
* changes: AudioService: BT dual mode support AudioService: synchronize BT_SCO on and A2DP or LE suspended states
This commit is contained in:
@@ -3730,7 +3730,12 @@ public class AudioManager {
|
||||
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||
@RequiresPermission(Manifest.permission.BLUETOOTH_STACK)
|
||||
public void setA2dpSuspended(boolean enable) {
|
||||
AudioSystem.setParameters("A2dpSuspended=" + enable);
|
||||
final IAudioService service = getService();
|
||||
try {
|
||||
service.setA2dpSuspended(enable);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3743,7 +3748,12 @@ public class AudioManager {
|
||||
@SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
|
||||
@RequiresPermission(Manifest.permission.BLUETOOTH_STACK)
|
||||
public void setLeAudioSuspended(boolean enable) {
|
||||
AudioSystem.setParameters("LeAudioSuspended=" + enable);
|
||||
final IAudioService service = getService();
|
||||
try {
|
||||
service.setLeAudioSuspended(enable);
|
||||
} catch (RemoteException e) {
|
||||
throw e.rethrowFromSystemServer();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1237,6 +1237,9 @@ public class AudioSystem
|
||||
public static final Set<Integer> DEVICE_IN_ALL_SCO_SET;
|
||||
/** @hide */
|
||||
public static final Set<Integer> DEVICE_IN_ALL_USB_SET;
|
||||
/** @hide */
|
||||
public static final Set<Integer> DEVICE_IN_ALL_BLE_SET;
|
||||
|
||||
static {
|
||||
DEVICE_IN_ALL_SET = new HashSet<>();
|
||||
DEVICE_IN_ALL_SET.add(DEVICE_IN_COMMUNICATION);
|
||||
@@ -1276,6 +1279,66 @@ public class AudioSystem
|
||||
DEVICE_IN_ALL_USB_SET.add(DEVICE_IN_USB_ACCESSORY);
|
||||
DEVICE_IN_ALL_USB_SET.add(DEVICE_IN_USB_DEVICE);
|
||||
DEVICE_IN_ALL_USB_SET.add(DEVICE_IN_USB_HEADSET);
|
||||
|
||||
DEVICE_IN_ALL_BLE_SET = new HashSet<>();
|
||||
DEVICE_IN_ALL_BLE_SET.add(DEVICE_IN_BLE_HEADSET);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static boolean isBluetoothDevice(int deviceType) {
|
||||
return isBluetoothA2dpOutDevice(deviceType)
|
||||
|| isBluetoothScoDevice(deviceType)
|
||||
|| isBluetoothLeDevice(deviceType);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static boolean isBluetoothOutDevice(int deviceType) {
|
||||
return isBluetoothA2dpOutDevice(deviceType)
|
||||
|| isBluetoothScoOutDevice(deviceType)
|
||||
|| isBluetoothLeOutDevice(deviceType);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static boolean isBluetoothInDevice(int deviceType) {
|
||||
return isBluetoothScoInDevice(deviceType)
|
||||
|| isBluetoothLeInDevice(deviceType);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static boolean isBluetoothA2dpOutDevice(int deviceType) {
|
||||
return DEVICE_OUT_ALL_A2DP_SET.contains(deviceType);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static boolean isBluetoothScoOutDevice(int deviceType) {
|
||||
return DEVICE_OUT_ALL_SCO_SET.contains(deviceType);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static boolean isBluetoothScoInDevice(int deviceType) {
|
||||
return DEVICE_IN_ALL_SCO_SET.contains(deviceType);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static boolean isBluetoothScoDevice(int deviceType) {
|
||||
return isBluetoothScoOutDevice(deviceType)
|
||||
|| isBluetoothScoInDevice(deviceType);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static boolean isBluetoothLeOutDevice(int deviceType) {
|
||||
return DEVICE_OUT_ALL_BLE_SET.contains(deviceType);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static boolean isBluetoothLeInDevice(int deviceType) {
|
||||
return DEVICE_IN_ALL_BLE_SET.contains(deviceType);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
public static boolean isBluetoothLeDevice(int deviceType) {
|
||||
return isBluetoothLeOutDevice(deviceType)
|
||||
|| isBluetoothLeInDevice(deviceType);
|
||||
}
|
||||
|
||||
/** @hide */
|
||||
|
||||
@@ -231,6 +231,12 @@ interface IAudioService {
|
||||
|
||||
void setBluetoothScoOn(boolean on);
|
||||
|
||||
@EnforcePermission("BLUETOOTH_STACK")
|
||||
void setA2dpSuspended(boolean on);
|
||||
|
||||
@EnforcePermission("BLUETOOTH_STACK")
|
||||
void setLeAudioSuspended(boolean enable);
|
||||
|
||||
boolean isBluetoothScoOn();
|
||||
|
||||
void setBluetoothA2dpOn(boolean on);
|
||||
|
||||
@@ -87,14 +87,14 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
private final @NonNull Context mContext;
|
||||
|
||||
/** ID for Communication strategy retrieved form audio policy manager */
|
||||
private int mCommunicationStrategyId = -1;
|
||||
/*package*/ int mCommunicationStrategyId = -1;
|
||||
|
||||
/** ID for Accessibility strategy retrieved form audio policy manager */
|
||||
private int mAccessibilityStrategyId = -1;
|
||||
|
||||
|
||||
/** Active communication device reported by audio policy manager */
|
||||
private AudioDeviceInfo mActiveCommunicationDevice;
|
||||
/*package*/ AudioDeviceInfo mActiveCommunicationDevice;
|
||||
/** Last preferred device set for communication strategy */
|
||||
private AudioDeviceAttributes mPreferredCommunicationDevice;
|
||||
|
||||
@@ -204,6 +204,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
private void init() {
|
||||
setupMessaging(mContext);
|
||||
|
||||
initAudioHalBluetoothState();
|
||||
initRoutingStrategyIds();
|
||||
mPreferredCommunicationDevice = null;
|
||||
updateActiveCommunicationDevice();
|
||||
@@ -749,6 +750,19 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
mIsLeOutput = false;
|
||||
}
|
||||
|
||||
BtDeviceInfo(@NonNull BtDeviceInfo src, int state) {
|
||||
mDevice = src.mDevice;
|
||||
mState = state;
|
||||
mProfile = src.mProfile;
|
||||
mSupprNoisy = src.mSupprNoisy;
|
||||
mVolume = src.mVolume;
|
||||
mIsLeOutput = src.mIsLeOutput;
|
||||
mEventSource = src.mEventSource;
|
||||
mAudioSystemDevice = src.mAudioSystemDevice;
|
||||
mMusicDevice = src.mMusicDevice;
|
||||
mCodec = src.mCodec;
|
||||
}
|
||||
|
||||
// redefine equality op so we can match messages intended for this device
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
@@ -815,7 +829,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
* @param info struct with the (dis)connection information
|
||||
*/
|
||||
/*package*/ void queueOnBluetoothActiveDeviceChanged(@NonNull BtDeviceChangedData data) {
|
||||
if (data.mInfo.getProfile() == BluetoothProfile.A2DP && data.mPreviousDevice != null
|
||||
if (data.mPreviousDevice != null
|
||||
&& data.mPreviousDevice.equals(data.mNewDevice)) {
|
||||
final String name = TextUtils.emptyIfNull(data.mNewDevice.getName());
|
||||
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE + MediaMetrics.SEPARATOR
|
||||
@@ -824,7 +838,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
.set(MediaMetrics.Property.STATUS, data.mInfo.getProfile())
|
||||
.record();
|
||||
synchronized (mDeviceStateLock) {
|
||||
postBluetoothA2dpDeviceConfigChange(data.mNewDevice);
|
||||
postBluetoothDeviceConfigChange(createBtDeviceInfo(data, data.mNewDevice,
|
||||
BluetoothProfile.STATE_CONNECTED));
|
||||
}
|
||||
} else {
|
||||
synchronized (mDeviceStateLock) {
|
||||
@@ -845,10 +860,100 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Current Bluetooth SCO audio active state indicated by BtHelper via setBluetoothScoOn().
|
||||
*/
|
||||
// Current Bluetooth SCO audio active state indicated by BtHelper via setBluetoothScoOn().
|
||||
@GuardedBy("mDeviceStateLock")
|
||||
private boolean mBluetoothScoOn;
|
||||
// value of BT_SCO parameter currently applied to audio HAL.
|
||||
@GuardedBy("mDeviceStateLock")
|
||||
private boolean mBluetoothScoOnApplied;
|
||||
|
||||
// A2DP suspend state requested by AudioManager.setA2dpSuspended() API.
|
||||
@GuardedBy("mDeviceStateLock")
|
||||
private boolean mBluetoothA2dpSuspendedExt;
|
||||
// A2DP suspend state requested by AudioDeviceInventory.
|
||||
@GuardedBy("mDeviceStateLock")
|
||||
private boolean mBluetoothA2dpSuspendedInt;
|
||||
// value of BT_A2dpSuspendedSCO parameter currently applied to audio HAL.
|
||||
@GuardedBy("mDeviceStateLock")
|
||||
private boolean mBluetoothA2dpSuspendedApplied;
|
||||
|
||||
// LE Audio suspend state requested by AudioManager.setLeAudioSuspended() API.
|
||||
@GuardedBy("mDeviceStateLock")
|
||||
private boolean mBluetoothLeSuspendedExt;
|
||||
// LE Audio suspend state requested by AudioDeviceInventory.
|
||||
@GuardedBy("mDeviceStateLock")
|
||||
private boolean mBluetoothLeSuspendedInt;
|
||||
// value of LeAudioSuspended parameter currently applied to audio HAL.
|
||||
@GuardedBy("mDeviceStateLock")
|
||||
private boolean mBluetoothLeSuspendedApplied;
|
||||
|
||||
private void initAudioHalBluetoothState() {
|
||||
mBluetoothScoOnApplied = false;
|
||||
AudioSystem.setParameters("BT_SCO=off");
|
||||
mBluetoothA2dpSuspendedApplied = false;
|
||||
AudioSystem.setParameters("A2dpSuspended=false");
|
||||
mBluetoothLeSuspendedApplied = false;
|
||||
AudioSystem.setParameters("LeAudioSuspended=false");
|
||||
}
|
||||
|
||||
@GuardedBy("mDeviceStateLock")
|
||||
private void updateAudioHalBluetoothState() {
|
||||
if (mBluetoothScoOn != mBluetoothScoOnApplied) {
|
||||
if (AudioService.DEBUG_COMM_RTE) {
|
||||
Log.v(TAG, "updateAudioHalBluetoothState() mBluetoothScoOn: "
|
||||
+ mBluetoothScoOn + ", mBluetoothScoOnApplied: " + mBluetoothScoOnApplied);
|
||||
}
|
||||
if (mBluetoothScoOn) {
|
||||
if (!mBluetoothA2dpSuspendedApplied) {
|
||||
AudioSystem.setParameters("A2dpSuspended=true");
|
||||
mBluetoothA2dpSuspendedApplied = true;
|
||||
}
|
||||
if (!mBluetoothLeSuspendedApplied) {
|
||||
AudioSystem.setParameters("LeAudioSuspended=true");
|
||||
mBluetoothLeSuspendedApplied = true;
|
||||
}
|
||||
AudioSystem.setParameters("BT_SCO=on");
|
||||
} else {
|
||||
AudioSystem.setParameters("BT_SCO=off");
|
||||
}
|
||||
mBluetoothScoOnApplied = mBluetoothScoOn;
|
||||
}
|
||||
if (!mBluetoothScoOnApplied) {
|
||||
if ((mBluetoothA2dpSuspendedExt || mBluetoothA2dpSuspendedInt)
|
||||
!= mBluetoothA2dpSuspendedApplied) {
|
||||
if (AudioService.DEBUG_COMM_RTE) {
|
||||
Log.v(TAG, "updateAudioHalBluetoothState() mBluetoothA2dpSuspendedExt: "
|
||||
+ mBluetoothA2dpSuspendedExt
|
||||
+ ", mBluetoothA2dpSuspendedInt: " + mBluetoothA2dpSuspendedInt
|
||||
+ ", mBluetoothA2dpSuspendedApplied: "
|
||||
+ mBluetoothA2dpSuspendedApplied);
|
||||
}
|
||||
mBluetoothA2dpSuspendedApplied =
|
||||
mBluetoothA2dpSuspendedExt || mBluetoothA2dpSuspendedInt;
|
||||
if (mBluetoothA2dpSuspendedApplied) {
|
||||
AudioSystem.setParameters("A2dpSuspended=true");
|
||||
} else {
|
||||
AudioSystem.setParameters("A2dpSuspended=false");
|
||||
}
|
||||
}
|
||||
if ((mBluetoothLeSuspendedExt || mBluetoothLeSuspendedInt)
|
||||
!= mBluetoothLeSuspendedApplied) {
|
||||
if (AudioService.DEBUG_COMM_RTE) {
|
||||
Log.v(TAG, "updateAudioHalBluetoothState() mBluetoothLeSuspendedExt: "
|
||||
+ mBluetoothLeSuspendedExt
|
||||
+ ", mBluetoothLeSuspendedInt: " + mBluetoothLeSuspendedInt
|
||||
+ ", mBluetoothLeSuspendedApplied: " + mBluetoothLeSuspendedApplied);
|
||||
}
|
||||
mBluetoothLeSuspendedApplied =
|
||||
mBluetoothLeSuspendedExt || mBluetoothLeSuspendedInt;
|
||||
if (mBluetoothLeSuspendedApplied) {
|
||||
AudioSystem.setParameters("LeAudioSuspended=true");
|
||||
} else {
|
||||
AudioSystem.setParameters("LeAudioSuspended=false");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ void setBluetoothScoOn(boolean on, String eventSource) {
|
||||
if (AudioService.DEBUG_COMM_RTE) {
|
||||
@@ -856,10 +961,67 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
}
|
||||
synchronized (mDeviceStateLock) {
|
||||
mBluetoothScoOn = on;
|
||||
updateAudioHalBluetoothState();
|
||||
postUpdateCommunicationRouteClient(eventSource);
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ void setA2dpSuspended(boolean enable, boolean internal, String eventSource) {
|
||||
if (AudioService.DEBUG_COMM_RTE) {
|
||||
Log.v(TAG, "setA2dpSuspended source: " + eventSource + ", enable: "
|
||||
+ enable + ", internal: " + internal
|
||||
+ ", mBluetoothA2dpSuspendedInt: " + mBluetoothA2dpSuspendedInt
|
||||
+ ", mBluetoothA2dpSuspendedExt: " + mBluetoothA2dpSuspendedExt);
|
||||
}
|
||||
synchronized (mDeviceStateLock) {
|
||||
if (internal) {
|
||||
mBluetoothA2dpSuspendedInt = enable;
|
||||
} else {
|
||||
mBluetoothA2dpSuspendedExt = enable;
|
||||
}
|
||||
updateAudioHalBluetoothState();
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ void clearA2dpSuspended() {
|
||||
if (AudioService.DEBUG_COMM_RTE) {
|
||||
Log.v(TAG, "clearA2dpSuspended");
|
||||
}
|
||||
synchronized (mDeviceStateLock) {
|
||||
mBluetoothA2dpSuspendedInt = false;
|
||||
mBluetoothA2dpSuspendedExt = false;
|
||||
updateAudioHalBluetoothState();
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ void setLeAudioSuspended(boolean enable, boolean internal, String eventSource) {
|
||||
if (AudioService.DEBUG_COMM_RTE) {
|
||||
Log.v(TAG, "setLeAudioSuspended source: " + eventSource + ", enable: "
|
||||
+ enable + ", internal: " + internal
|
||||
+ ", mBluetoothLeSuspendedInt: " + mBluetoothA2dpSuspendedInt
|
||||
+ ", mBluetoothLeSuspendedExt: " + mBluetoothA2dpSuspendedExt);
|
||||
}
|
||||
synchronized (mDeviceStateLock) {
|
||||
if (internal) {
|
||||
mBluetoothLeSuspendedInt = enable;
|
||||
} else {
|
||||
mBluetoothLeSuspendedExt = enable;
|
||||
}
|
||||
updateAudioHalBluetoothState();
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ void clearLeAudioSuspended() {
|
||||
if (AudioService.DEBUG_COMM_RTE) {
|
||||
Log.v(TAG, "clearLeAudioSuspended");
|
||||
}
|
||||
synchronized (mDeviceStateLock) {
|
||||
mBluetoothLeSuspendedInt = false;
|
||||
mBluetoothLeSuspendedExt = false;
|
||||
updateAudioHalBluetoothState();
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ AudioRoutesInfo startWatchingRoutes(IAudioRoutesObserver observer) {
|
||||
synchronized (mDeviceStateLock) {
|
||||
return mDeviceInventory.startWatchingRoutes(observer);
|
||||
@@ -902,8 +1064,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
new AudioModeInfo(mode, pid, uid));
|
||||
}
|
||||
|
||||
/*package*/ void postBluetoothA2dpDeviceConfigChange(@NonNull BluetoothDevice device) {
|
||||
sendLMsgNoDelay(MSG_L_A2DP_DEVICE_CONFIG_CHANGE, SENDMSG_QUEUE, device);
|
||||
/*package*/ void postBluetoothDeviceConfigChange(@NonNull BtDeviceInfo info) {
|
||||
sendLMsgNoDelay(MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE, SENDMSG_QUEUE, info);
|
||||
}
|
||||
|
||||
/*package*/ void startBluetoothScoForClient(IBinder cb, int pid, int scoAudioMode,
|
||||
@@ -1160,6 +1322,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
sendIMsgNoDelay(MSG_I_SCO_AUDIO_STATE_CHANGED, SENDMSG_QUEUE, state);
|
||||
}
|
||||
|
||||
/*package*/ void postNotifyPreferredAudioProfileApplied(BluetoothDevice btDevice) {
|
||||
sendLMsgNoDelay(MSG_L_NOTIFY_PREFERRED_AUDIOPROFILE_APPLIED, SENDMSG_QUEUE, btDevice);
|
||||
}
|
||||
|
||||
/*package*/ static final class CommunicationDeviceInfo {
|
||||
final @NonNull IBinder mCb; // Identifies the requesting client for death handler
|
||||
final int mPid; // Requester process ID
|
||||
@@ -1235,9 +1401,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ boolean handleDeviceConnection(AudioDeviceAttributes attributes, boolean connect) {
|
||||
/*package*/ boolean handleDeviceConnection(AudioDeviceAttributes attributes,
|
||||
boolean connect, @Nullable BluetoothDevice btDevice) {
|
||||
synchronized (mDeviceStateLock) {
|
||||
return mDeviceInventory.handleDeviceConnection(attributes, connect, false /*for test*/);
|
||||
return mDeviceInventory.handleDeviceConnection(
|
||||
attributes, connect, false /*for test*/, btDevice);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1478,13 +1646,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
(String) msg.obj, msg.arg1);
|
||||
}
|
||||
break;
|
||||
case MSG_L_A2DP_DEVICE_CONFIG_CHANGE:
|
||||
final BluetoothDevice btDevice = (BluetoothDevice) msg.obj;
|
||||
case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE:
|
||||
synchronized (mDeviceStateLock) {
|
||||
final int a2dpCodec = mBtHelper.getA2dpCodec(btDevice);
|
||||
mDeviceInventory.onBluetoothA2dpDeviceConfigChange(
|
||||
new BtHelper.BluetoothA2dpDeviceInfo(btDevice, -1, a2dpCodec),
|
||||
BtHelper.EVENT_DEVICE_CONFIG_CHANGE);
|
||||
mDeviceInventory.onBluetoothDeviceConfigChange(
|
||||
(BtDeviceInfo) msg.obj, BtHelper.EVENT_DEVICE_CONFIG_CHANGE);
|
||||
}
|
||||
break;
|
||||
case MSG_BROADCAST_AUDIO_BECOMING_NOISY:
|
||||
@@ -1642,6 +1807,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
final int capturePreset = msg.arg1;
|
||||
mDeviceInventory.onSaveClearPreferredDevicesForCapturePreset(capturePreset);
|
||||
} break;
|
||||
case MSG_L_NOTIFY_PREFERRED_AUDIOPROFILE_APPLIED: {
|
||||
final BluetoothDevice btDevice = (BluetoothDevice) msg.obj;
|
||||
BtHelper.onNotifyPreferredAudioProfileApplied(btDevice);
|
||||
} break;
|
||||
default:
|
||||
Log.wtf(TAG, "Invalid message " + msg.what);
|
||||
}
|
||||
@@ -1677,7 +1846,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
private static final int MSG_IL_BTA2DP_TIMEOUT = 10;
|
||||
|
||||
// process change of A2DP device configuration, obj is BluetoothDevice
|
||||
private static final int MSG_L_A2DP_DEVICE_CONFIG_CHANGE = 11;
|
||||
private static final int MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE = 11;
|
||||
|
||||
private static final int MSG_BROADCAST_AUDIO_BECOMING_NOISY = 12;
|
||||
private static final int MSG_REPORT_NEW_ROUTES = 13;
|
||||
@@ -1717,13 +1886,15 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
private static final int MSG_IL_SAVE_REMOVE_NDEF_DEVICE_FOR_STRATEGY = 48;
|
||||
private static final int MSG_IL_BTLEAUDIO_TIMEOUT = 49;
|
||||
|
||||
private static final int MSG_L_NOTIFY_PREFERRED_AUDIOPROFILE_APPLIED = 50;
|
||||
|
||||
private static boolean isMessageHandledUnderWakelock(int msgId) {
|
||||
switch(msgId) {
|
||||
case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE:
|
||||
case MSG_L_SET_BT_ACTIVE_DEVICE:
|
||||
case MSG_IL_BTA2DP_TIMEOUT:
|
||||
case MSG_IL_BTLEAUDIO_TIMEOUT:
|
||||
case MSG_L_A2DP_DEVICE_CONFIG_CHANGE:
|
||||
case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE:
|
||||
case MSG_TOGGLE_HDMI:
|
||||
case MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT:
|
||||
case MSG_L_HEARING_AID_DEVICE_CONNECTION_CHANGE_EXT:
|
||||
@@ -1815,7 +1986,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
case MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE:
|
||||
case MSG_IL_BTA2DP_TIMEOUT:
|
||||
case MSG_IL_BTLEAUDIO_TIMEOUT:
|
||||
case MSG_L_A2DP_DEVICE_CONFIG_CHANGE:
|
||||
case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE:
|
||||
if (sLastDeviceConnectMsgTime >= time) {
|
||||
// add a little delay to make sure messages are ordered as expected
|
||||
time = sLastDeviceConnectMsgTime + 30;
|
||||
@@ -1835,7 +2006,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
static {
|
||||
MESSAGES_MUTE_MUSIC = new HashSet<>();
|
||||
MESSAGES_MUTE_MUSIC.add(MSG_L_SET_BT_ACTIVE_DEVICE);
|
||||
MESSAGES_MUTE_MUSIC.add(MSG_L_A2DP_DEVICE_CONFIG_CHANGE);
|
||||
MESSAGES_MUTE_MUSIC.add(MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE);
|
||||
MESSAGES_MUTE_MUSIC.add(MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT);
|
||||
MESSAGES_MUTE_MUSIC.add(MSG_IIL_SET_FORCE_BT_A2DP_USE);
|
||||
}
|
||||
@@ -1856,7 +2027,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
// Do not mute on bluetooth event if music is playing on a wired headset.
|
||||
if ((message == MSG_L_SET_BT_ACTIVE_DEVICE
|
||||
|| message == MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT
|
||||
|| message == MSG_L_A2DP_DEVICE_CONFIG_CHANGE)
|
||||
|| message == MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE)
|
||||
&& AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0)
|
||||
&& hasIntersection(mDeviceInventory.DEVICE_OVERRIDE_A2DP_ROUTE_ON_PLUG_SET,
|
||||
mAudioService.getDeviceSetForStream(AudioSystem.STREAM_MUSIC))) {
|
||||
@@ -1992,27 +2163,22 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
"updateCommunicationRoute, preferredCommunicationDevice: "
|
||||
+ preferredCommunicationDevice + " eventSource: " + eventSource)));
|
||||
|
||||
if (preferredCommunicationDevice == null
|
||||
|| preferredCommunicationDevice.getType() != AudioDeviceInfo.TYPE_BLUETOOTH_SCO) {
|
||||
AudioSystem.setParameters("BT_SCO=off");
|
||||
} else {
|
||||
AudioSystem.setParameters("BT_SCO=on");
|
||||
}
|
||||
if (preferredCommunicationDevice == null) {
|
||||
AudioDeviceAttributes defaultDevice = getDefaultCommunicationDevice();
|
||||
if (defaultDevice != null) {
|
||||
setPreferredDevicesForStrategySync(
|
||||
mDeviceInventory.setPreferredDevicesForStrategy(
|
||||
mCommunicationStrategyId, Arrays.asList(defaultDevice));
|
||||
setPreferredDevicesForStrategySync(
|
||||
mDeviceInventory.setPreferredDevicesForStrategy(
|
||||
mAccessibilityStrategyId, Arrays.asList(defaultDevice));
|
||||
} else {
|
||||
removePreferredDevicesForStrategySync(mCommunicationStrategyId);
|
||||
removePreferredDevicesForStrategySync(mAccessibilityStrategyId);
|
||||
mDeviceInventory.removePreferredDevicesForStrategy(mCommunicationStrategyId);
|
||||
mDeviceInventory.removePreferredDevicesForStrategy(mAccessibilityStrategyId);
|
||||
}
|
||||
mDeviceInventory.applyConnectedDevicesRoles();
|
||||
} else {
|
||||
setPreferredDevicesForStrategySync(
|
||||
mDeviceInventory.setPreferredDevicesForStrategy(
|
||||
mCommunicationStrategyId, Arrays.asList(preferredCommunicationDevice));
|
||||
setPreferredDevicesForStrategySync(
|
||||
mDeviceInventory.setPreferredDevicesForStrategy(
|
||||
mAccessibilityStrategyId, Arrays.asList(preferredCommunicationDevice));
|
||||
}
|
||||
onUpdatePhoneStrategyDevice(preferredCommunicationDevice);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6376,6 +6376,26 @@ public class AudioService extends IAudioService.Stub
|
||||
mDeviceBroker.setBluetoothScoOn(on, eventSource);
|
||||
}
|
||||
|
||||
/** @see AudioManager#setA2dpSuspended(boolean) */
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK)
|
||||
public void setA2dpSuspended(boolean enable) {
|
||||
super.setA2dpSuspended_enforcePermission();
|
||||
final String eventSource = new StringBuilder("setA2dpSuspended(").append(enable)
|
||||
.append(") from u/pid:").append(Binder.getCallingUid()).append("/")
|
||||
.append(Binder.getCallingPid()).toString();
|
||||
mDeviceBroker.setA2dpSuspended(enable, false /*internal*/, eventSource);
|
||||
}
|
||||
|
||||
/** @see AudioManager#setA2dpSuspended(boolean) */
|
||||
@android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK)
|
||||
public void setLeAudioSuspended(boolean enable) {
|
||||
super.setLeAudioSuspended_enforcePermission();
|
||||
final String eventSource = new StringBuilder("setLeAudioSuspended(").append(enable)
|
||||
.append(") from u/pid:").append(Binder.getCallingUid()).append("/")
|
||||
.append(Binder.getCallingPid()).toString();
|
||||
mDeviceBroker.setLeAudioSuspended(enable, false /*internal*/, eventSource);
|
||||
}
|
||||
|
||||
/** @see AudioManager#isBluetoothScoOn()
|
||||
* Note that it doesn't report internal state, but state seen by apps (which may have
|
||||
* called setBluetoothScoOn() */
|
||||
|
||||
@@ -435,7 +435,7 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback,
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link AudioSystem#removeDevicesRoleForCapturePreset(int, int, int[], String[])}
|
||||
* Same as {@link AudioSystem#removeDevicesRoleForCapturePreset(int, int, List)}
|
||||
* @param capturePreset
|
||||
* @param role
|
||||
* @param devicesToRemove
|
||||
@@ -447,6 +447,19 @@ public class AudioSystemAdapter implements AudioSystem.RoutingUpdateCallback,
|
||||
return AudioSystem.removeDevicesRoleForCapturePreset(capturePreset, role, devicesToRemove);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link AudioSystem#addDevicesRoleForCapturePreset(int, int, List)}
|
||||
* @param capturePreset the capture preset to configure
|
||||
* @param role the role of the devices
|
||||
* @param devices the list of devices to be added as role for the given capture preset
|
||||
* @return {@link #SUCCESS} if successfully add
|
||||
*/
|
||||
public int addDevicesRoleForCapturePreset(
|
||||
int capturePreset, int role, @NonNull List<AudioDeviceAttributes> devices) {
|
||||
invalidateRoutingCache();
|
||||
return AudioSystem.addDevicesRoleForCapturePreset(capturePreset, role, devices);
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as {@link AudioSystem#}
|
||||
* @param capturePreset
|
||||
|
||||
@@ -33,6 +33,7 @@ import android.media.AudioManager;
|
||||
import android.media.AudioSystem;
|
||||
import android.media.BluetoothProfileConnectionInfo;
|
||||
import android.os.Binder;
|
||||
import android.os.Bundle;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.text.TextUtils;
|
||||
@@ -150,60 +151,12 @@ public class BtHelper {
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
/*package*/ static class BluetoothA2dpDeviceInfo {
|
||||
private final @NonNull BluetoothDevice mBtDevice;
|
||||
private final int mVolume;
|
||||
private final @AudioSystem.AudioFormatNativeEnumForBtCodec int mCodec;
|
||||
|
||||
BluetoothA2dpDeviceInfo(@NonNull BluetoothDevice btDevice) {
|
||||
this(btDevice, -1, AudioSystem.AUDIO_FORMAT_DEFAULT);
|
||||
}
|
||||
|
||||
BluetoothA2dpDeviceInfo(@NonNull BluetoothDevice btDevice, int volume, int codec) {
|
||||
mBtDevice = btDevice;
|
||||
mVolume = volume;
|
||||
mCodec = codec;
|
||||
}
|
||||
|
||||
public @NonNull BluetoothDevice getBtDevice() {
|
||||
return mBtDevice;
|
||||
}
|
||||
|
||||
public int getVolume() {
|
||||
return mVolume;
|
||||
}
|
||||
|
||||
public @AudioSystem.AudioFormatNativeEnumForBtCodec int getCodec() {
|
||||
return mCodec;
|
||||
}
|
||||
|
||||
// redefine equality op so we can match messages intended for this device
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) {
|
||||
return false;
|
||||
}
|
||||
if (this == o) {
|
||||
return true;
|
||||
}
|
||||
if (o instanceof BluetoothA2dpDeviceInfo) {
|
||||
return mBtDevice.equals(((BluetoothA2dpDeviceInfo) o).getBtDevice());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// A2DP device events
|
||||
/*package*/ static final int EVENT_DEVICE_CONFIG_CHANGE = 0;
|
||||
/*package*/ static final int EVENT_ACTIVE_DEVICE_CHANGE = 1;
|
||||
|
||||
/*package*/ static String a2dpDeviceEventToString(int event) {
|
||||
/*package*/ static String deviceEventToString(int event) {
|
||||
switch (event) {
|
||||
case EVENT_DEVICE_CONFIG_CHANGE: return "DEVICE_CONFIG_CHANGE";
|
||||
case EVENT_ACTIVE_DEVICE_CHANGE: return "ACTIVE_DEVICE_CHANGE";
|
||||
default:
|
||||
return new String("invalid event:" + event);
|
||||
}
|
||||
@@ -492,8 +445,8 @@ public class BtHelper {
|
||||
/*package*/ synchronized void resetBluetoothSco() {
|
||||
mScoAudioState = SCO_STATE_INACTIVE;
|
||||
broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_DISCONNECTED);
|
||||
AudioSystem.setParameters("A2dpSuspended=false");
|
||||
AudioSystem.setParameters("LeAudioSuspended=false");
|
||||
mDeviceBroker.clearA2dpSuspended();
|
||||
mDeviceBroker.clearLeAudioSuspended();
|
||||
mDeviceBroker.setBluetoothScoOn(false, "resetBluetoothSco");
|
||||
}
|
||||
|
||||
@@ -620,11 +573,12 @@ public class BtHelper {
|
||||
return btHeadsetDeviceToAudioDevice(mBluetoothHeadsetDevice);
|
||||
}
|
||||
|
||||
private AudioDeviceAttributes btHeadsetDeviceToAudioDevice(BluetoothDevice btDevice) {
|
||||
private static AudioDeviceAttributes btHeadsetDeviceToAudioDevice(BluetoothDevice btDevice) {
|
||||
if (btDevice == null) {
|
||||
return new AudioDeviceAttributes(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, "");
|
||||
}
|
||||
String address = btDevice.getAddress();
|
||||
String name = getName(btDevice);
|
||||
if (!BluetoothAdapter.checkBluetoothAddress(address)) {
|
||||
address = "";
|
||||
}
|
||||
@@ -646,7 +600,7 @@ public class BtHelper {
|
||||
+ " btClass: " + (btClass == null ? "Unknown" : btClass)
|
||||
+ " nativeType: " + nativeType + " address: " + address);
|
||||
}
|
||||
return new AudioDeviceAttributes(nativeType, address);
|
||||
return new AudioDeviceAttributes(nativeType, address, name);
|
||||
}
|
||||
|
||||
private boolean handleBtScoActiveDeviceChange(BluetoothDevice btDevice, boolean isActive) {
|
||||
@@ -655,12 +609,9 @@ public class BtHelper {
|
||||
}
|
||||
int inDevice = AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET;
|
||||
AudioDeviceAttributes audioDevice = btHeadsetDeviceToAudioDevice(btDevice);
|
||||
String btDeviceName = getName(btDevice);
|
||||
boolean result = false;
|
||||
if (isActive) {
|
||||
result |= mDeviceBroker.handleDeviceConnection(new AudioDeviceAttributes(
|
||||
audioDevice.getInternalType(), audioDevice.getAddress(), btDeviceName),
|
||||
isActive);
|
||||
result |= mDeviceBroker.handleDeviceConnection(audioDevice, isActive, btDevice);
|
||||
} else {
|
||||
int[] outDeviceTypes = {
|
||||
AudioSystem.DEVICE_OUT_BLUETOOTH_SCO,
|
||||
@@ -669,14 +620,14 @@ public class BtHelper {
|
||||
};
|
||||
for (int outDeviceType : outDeviceTypes) {
|
||||
result |= mDeviceBroker.handleDeviceConnection(new AudioDeviceAttributes(
|
||||
outDeviceType, audioDevice.getAddress(), btDeviceName),
|
||||
isActive);
|
||||
outDeviceType, audioDevice.getAddress(), audioDevice.getName()),
|
||||
isActive, btDevice);
|
||||
}
|
||||
}
|
||||
// handleDeviceConnection() && result to make sure the method get executed
|
||||
result = mDeviceBroker.handleDeviceConnection(new AudioDeviceAttributes(
|
||||
inDevice, audioDevice.getAddress(), btDeviceName),
|
||||
isActive) && result;
|
||||
inDevice, audioDevice.getAddress(), audioDevice.getName()),
|
||||
isActive, btDevice) && result;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -973,6 +924,30 @@ public class BtHelper {
|
||||
}
|
||||
}
|
||||
|
||||
/*package */ static int getProfileFromType(int deviceType) {
|
||||
if (AudioSystem.isBluetoothA2dpOutDevice(deviceType)) {
|
||||
return BluetoothProfile.A2DP;
|
||||
} else if (AudioSystem.isBluetoothScoDevice(deviceType)) {
|
||||
return BluetoothProfile.HEADSET;
|
||||
} else if (AudioSystem.isBluetoothLeDevice(deviceType)) {
|
||||
return BluetoothProfile.LE_AUDIO;
|
||||
}
|
||||
return 0; // 0 is not a valid profile
|
||||
}
|
||||
|
||||
/*package */ static Bundle getPreferredAudioProfiles(String address) {
|
||||
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
|
||||
return adapter.getPreferredAudioProfiles(adapter.getRemoteDevice(address));
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies Bluetooth framework that new preferred audio profiles for Bluetooth devices
|
||||
* have been applied.
|
||||
*/
|
||||
public static void onNotifyPreferredAudioProfileApplied(BluetoothDevice btDevice) {
|
||||
BluetoothAdapter.getDefaultAdapter().notifyActiveDeviceChangeApplied(btDevice);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string equivalent for the btDeviceClass class.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user