AudioDeviceBroker: fix deadlock with setA2dpSuspended

There is a potential deadlock between AudioDeviceBroker and
HFP HeadsetService when AudioManager.setA2dpSuspended (or
setLeAudioSuspended) is called.

To avoid it, process the suspend requests in the message handler
instead of synchronously.

Bug: 278668288
Fixes: 279558132
Test: repro steps in bug
Change-Id: I83e3a5e918224f63f39438e30221db06f1dc2ad0
This commit is contained in:
Eric Laurent
2023-04-26 16:07:01 +02:00
parent f6adbe0d1f
commit 2bd07ff1da
2 changed files with 19 additions and 2 deletions

View File

@@ -957,6 +957,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
/*package*/ void postSetA2dpSuspended(boolean enable, String eventSource) {
sendILMsgNoDelay(MSG_IL_SET_A2DP_SUSPENDED, SENDMSG_QUEUE, (enable ? 1 : 0), eventSource);
}
/*package*/ void setA2dpSuspended(boolean enable, boolean internal, String eventSource) {
if (AudioService.DEBUG_COMM_RTE) {
Log.v(TAG, "setA2dpSuspended source: " + eventSource + ", enable: "
@@ -985,6 +989,11 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
/*package*/ void postSetLeAudioSuspended(boolean enable, String eventSource) {
sendILMsgNoDelay(
MSG_IL_SET_LEAUDIO_SUSPENDED, SENDMSG_QUEUE, (enable ? 1 : 0), eventSource);
}
/*package*/ void setLeAudioSuspended(boolean enable, boolean internal, String eventSource) {
if (AudioService.DEBUG_COMM_RTE) {
Log.v(TAG, "setLeAudioSuspended source: " + eventSource + ", enable: "
@@ -1795,6 +1804,12 @@ import java.util.concurrent.atomic.AtomicBoolean;
final int capturePreset = msg.arg1;
mDeviceInventory.onSaveClearPreferredDevicesForCapturePreset(capturePreset);
} break;
case MSG_IL_SET_A2DP_SUSPENDED: {
setA2dpSuspended((msg.arg1 == 1), false /*internal*/, (String) msg.obj);
} break;
case MSG_IL_SET_LEAUDIO_SUSPENDED: {
setLeAudioSuspended((msg.arg1 == 1), false /*internal*/, (String) msg.obj);
} break;
default:
Log.wtf(TAG, "Invalid message " + msg.what);
}
@@ -1869,6 +1884,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
private static final int MSG_IL_SAVE_NDEF_DEVICE_FOR_STRATEGY = 47;
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_IL_SET_A2DP_SUSPENDED = 50;
private static final int MSG_IL_SET_LEAUDIO_SUSPENDED = 51;
private static boolean isMessageHandledUnderWakelock(int msgId) {
switch(msgId) {

View File

@@ -6412,7 +6412,7 @@ public class AudioService extends IAudioService.Stub
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);
mDeviceBroker.postSetA2dpSuspended(enable, eventSource);
}
/** @see AudioManager#setA2dpSuspended(boolean) */
@@ -6422,7 +6422,7 @@ public class AudioService extends IAudioService.Stub
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);
mDeviceBroker.postSetLeAudioSuspended(enable, eventSource);
}
/** @see AudioManager#isBluetoothScoOn()