AudioDeviceBroker: avoid acquiring mDeviceStateLock when not necessary
Do not lock mDeviceStateLock whne calling BtHelper.getCodecWithFallback()
to void cross deadlocks with BT service.
Also make mBluetoothA2dpEnabled an atomic boolean and do not lock
mDeviceStateLock when accessing it.
Also remove dead code isAvrcpAbsoluteVolumeSupported()
Bug: 324420709
Bug: 329911879
Test: make
Change-Id: Ie8d824e53fd4076e90a81076f1974354fef4dd13
Merged-In: Ie8d824e53fd4076e90a81076f1974354fef4dd13
(cherry picked from commit a4a848f58b0c7f1cc19a0d8dd537929467da1d17)
diff --git a/services/core/java/com/android/server/audio/AudioDeviceBroker.java b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
index d435c24..3531cba 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceBroker.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceBroker.java
@@ -127,8 +127,7 @@
private final Object mDeviceStateLock = new Object();
// Request to override default use of A2DP for media.
- @GuardedBy("mDeviceStateLock")
- private boolean mBluetoothA2dpEnabled;
+ private AtomicBoolean mBluetoothA2dpEnabled = new AtomicBoolean(false);
// lock always taken when accessing AudioService.mSetModeDeathHandlers
// TODO do not "share" the lock between AudioService and BtHelpr, see b/123769055
@@ -275,17 +274,8 @@
}
/*package*/ void setBluetoothA2dpOn_Async(boolean on, String source) {
- synchronized (mDeviceStateLock) {
- if (mBluetoothA2dpEnabled == on) {
- return;
- }
- mBluetoothA2dpEnabled = on;
- mBrokerHandler.removeMessages(MSG_IIL_SET_FORCE_BT_A2DP_USE);
- sendIILMsgNoDelay(MSG_IIL_SET_FORCE_BT_A2DP_USE, SENDMSG_QUEUE,
- AudioSystem.FOR_MEDIA,
- mBluetoothA2dpEnabled ? AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP,
- source);
- }
+ mBluetoothA2dpEnabled.set(on);
+ sendLMsgNoDelay(MSG_L_SET_FORCE_BT_A2DP_USE, SENDMSG_REPLACE, source);
}
/**
@@ -1223,16 +1213,8 @@
}
}
- /*package*/ boolean isAvrcpAbsoluteVolumeSupported() {
- synchronized (mDeviceStateLock) {
- return mBtHelper.isAvrcpAbsoluteVolumeSupported();
- }
- }
-
/*package*/ boolean isBluetoothA2dpOn() {
- synchronized (mDeviceStateLock) {
- return mBluetoothA2dpEnabled;
- }
+ return mBluetoothA2dpEnabled.get();
}
/*package*/ void postSetAvrcpAbsoluteVolumeIndex(int index) {
@@ -1602,15 +1584,12 @@
.append(") from u/pid:").append(Binder.getCallingUid()).append("/")
.append(Binder.getCallingPid()).append(" src:").append(source).toString();
- synchronized (mDeviceStateLock) {
- mBluetoothA2dpEnabled = on;
- mBrokerHandler.removeMessages(MSG_IIL_SET_FORCE_BT_A2DP_USE);
- onSetForceUse(
- AudioSystem.FOR_MEDIA,
- mBluetoothA2dpEnabled ? AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP,
- fromA2dp,
- eventSource);
- }
+ mBluetoothA2dpEnabled.set(on);
+ onSetForceUse(
+ AudioSystem.FOR_MEDIA,
+ on ? AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP,
+ fromA2dp,
+ eventSource);
}
/*package*/ boolean handleDeviceConnection(@NonNull AudioDeviceAttributes attributes,
@@ -1659,9 +1638,7 @@
}
/*package*/ boolean getBluetoothA2dpEnabled() {
- synchronized (mDeviceStateLock) {
- return mBluetoothA2dpEnabled;
- }
+ return mBluetoothA2dpEnabled.get();
}
/*package*/ int getLeAudioDeviceGroupId(BluetoothDevice device) {
@@ -1822,9 +1799,12 @@
}
break;
case MSG_IIL_SET_FORCE_USE: // intended fall-through
- case MSG_IIL_SET_FORCE_BT_A2DP_USE:
- onSetForceUse(msg.arg1, msg.arg2,
- (msg.what == MSG_IIL_SET_FORCE_BT_A2DP_USE), (String) msg.obj);
+ onSetForceUse(msg.arg1, msg.arg2, false, (String) msg.obj);
+ break;
+ case MSG_L_SET_FORCE_BT_A2DP_USE:
+ int forcedUsage = mBluetoothA2dpEnabled.get()
+ ? AudioSystem.FORCE_NONE : AudioSystem.FORCE_NO_BT_A2DP;
+ onSetForceUse(AudioSystem.FOR_MEDIA, forcedUsage, true, (String) msg.obj);
break;
case MSG_REPORT_NEW_ROUTES:
case MSG_REPORT_NEW_ROUTES_A2DP:
@@ -1832,21 +1812,21 @@
mDeviceInventory.onReportNewRoutes();
}
break;
- case MSG_L_SET_BT_ACTIVE_DEVICE:
- synchronized (mSetModeLock) {
- synchronized (mDeviceStateLock) {
- final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj;
- if (btInfo.mState == BluetoothProfile.STATE_CONNECTED
- && !mBtHelper.isProfilePoxyConnected(btInfo.mProfile)) {
- AudioService.sDeviceLogger.enqueue((new EventLogger.StringEvent(
- "msg: MSG_L_SET_BT_ACTIVE_DEVICE "
- + "received with null profile proxy: "
- + btInfo)).printLog(TAG));
- } else {
- final Pair<Integer, Boolean> codecAndChanged =
- mBtHelper.getCodecWithFallback(btInfo.mDevice,
- btInfo.mProfile, btInfo.mIsLeOutput,
- "MSG_L_SET_BT_ACTIVE_DEVICE");
+ case MSG_L_SET_BT_ACTIVE_DEVICE: {
+ final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj;
+ if (btInfo.mState == BluetoothProfile.STATE_CONNECTED
+ && !mBtHelper.isProfilePoxyConnected(btInfo.mProfile)) {
+ AudioService.sDeviceLogger.enqueue((new EventLogger.StringEvent(
+ "msg: MSG_L_SET_BT_ACTIVE_DEVICE "
+ + "received with null profile proxy: "
+ + btInfo)).printLog(TAG));
+ } else {
+ final Pair<Integer, Boolean> codecAndChanged =
+ mBtHelper.getCodecWithFallback(btInfo.mDevice,
+ btInfo.mProfile, btInfo.mIsLeOutput,
+ "MSG_L_SET_BT_ACTIVE_DEVICE");
+ synchronized (mSetModeLock) {
+ synchronized (mDeviceStateLock) {
mDeviceInventory.onSetBtActiveDevice(btInfo,
codecAndChanged.first,
(btInfo.mProfile != BluetoothProfile.LE_AUDIO
@@ -1854,14 +1834,16 @@
? mAudioService.getBluetoothContextualVolumeStream()
: AudioSystem.STREAM_DEFAULT);
if (btInfo.mProfile == BluetoothProfile.LE_AUDIO
- || btInfo.mProfile == BluetoothProfile.HEARING_AID) {
- onUpdateCommunicationRouteClient(isBluetoothScoRequested(),
+ || btInfo.mProfile
+ == BluetoothProfile.HEARING_AID) {
+ onUpdateCommunicationRouteClient(
+ isBluetoothScoRequested(),
"setBluetoothActiveDevice");
}
}
}
}
- break;
+ } break;
case MSG_BT_HEADSET_CNCT_FAILED:
synchronized (mSetModeLock) {
synchronized (mDeviceStateLock) {
@@ -1885,11 +1867,11 @@
break;
case MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE: {
final BtDeviceInfo btInfo = (BtDeviceInfo) msg.obj;
+ final Pair<Integer, Boolean> codecAndChanged =
+ mBtHelper.getCodecWithFallback(
+ btInfo.mDevice, btInfo.mProfile, btInfo.mIsLeOutput,
+ "MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE");
synchronized (mDeviceStateLock) {
- final Pair<Integer, Boolean> codecAndChanged =
- mBtHelper.getCodecWithFallback(
- btInfo.mDevice, btInfo.mProfile, btInfo.mIsLeOutput,
- "MSG_L_BLUETOOTH_DEVICE_CONFIG_CHANGE");
mDeviceInventory.onBluetoothDeviceConfigChange(btInfo,
codecAndChanged.first, codecAndChanged.second,
BtHelper.EVENT_DEVICE_CONFIG_CHANGE);
@@ -2101,7 +2083,7 @@
private static final int MSG_L_SET_WIRED_DEVICE_CONNECTION_STATE = 2;
private static final int MSG_I_BROADCAST_BT_CONNECTION_STATE = 3;
private static final int MSG_IIL_SET_FORCE_USE = 4;
- private static final int MSG_IIL_SET_FORCE_BT_A2DP_USE = 5;
+ private static final int MSG_L_SET_FORCE_BT_A2DP_USE = 5;
private static final int MSG_TOGGLE_HDMI = 6;
private static final int MSG_L_SET_BT_ACTIVE_DEVICE = 7;
private static final int MSG_BT_HEADSET_CNCT_FAILED = 9;
@@ -2298,7 +2280,7 @@
MESSAGES_MUTE_MUSIC.add(MSG_L_SET_BT_ACTIVE_DEVICE);
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);
+ MESSAGES_MUTE_MUSIC.add(MSG_L_SET_FORCE_BT_A2DP_USE);
}
private AtomicBoolean mMusicMuted = new AtomicBoolean(false);
diff --git a/services/core/java/com/android/server/audio/BtHelper.java b/services/core/java/com/android/server/audio/BtHelper.java
index 7d6ca93..a649d34 100644
--- a/services/core/java/com/android/server/audio/BtHelper.java
+++ b/services/core/java/com/android/server/audio/BtHelper.java
@@ -242,10 +242,6 @@
mDeviceBroker.setForceUse_Async(AudioSystem.FOR_MEDIA, forMed, "onAudioServerDied()");
}
- /*package*/ synchronized boolean isAvrcpAbsoluteVolumeSupported() {
- return (mA2dp != null && mAvrcpAbsVolSupported);
- }
-
/*package*/ synchronized void setAvrcpAbsoluteVolumeSupported(boolean supported) {
mAvrcpAbsVolSupported = supported;
Log.i(TAG, "setAvrcpAbsoluteVolumeSupported supported=" + supported);
@@ -681,8 +677,6 @@
}
}
- // @GuardedBy("mDeviceBroker.mSetModeLock")
- @GuardedBy("AudioDeviceBroker.this.mDeviceStateLock")
/*package*/ synchronized boolean isProfilePoxyConnected(int profile) {
switch (profile) {
case BluetoothProfile.HEADSET: