AudioDeviceBroker: fix communication route for idle apps

AudioDeviceBroker.onUpdateCommunicationRouteClient() was just evaluating
if SCO audio should be used by the audio policy for calls (which includes when SCO audio
is already active from an external  request - e.g. by Telecom) but not if no more active
request to use SCO exists. Thus it was failing to stop internal SCO audio requests when
no more communication route client was active.

Also fix a spurious CONNECTING intent broadcast in
BtHelper.requestScoState()

Bug: 294167472
Test: repro steps in bug
Change-Id: Ib94dc3aa8cfe7120a87661b6403ee4060a295f8c
This commit is contained in:
Eric Laurent
2023-08-11 19:14:56 +02:00
parent b20dbb5003
commit a0245642ce
2 changed files with 30 additions and 18 deletions

View File

@@ -391,7 +391,6 @@ public class AudioDeviceBroker {
final boolean wasBtScoRequested = isBluetoothScoRequested();
CommunicationRouteClient client;
// Save previous client route in case of failure to start BT SCO audio
AudioDeviceAttributes prevClientDevice = null;
boolean prevPrivileged = false;
@@ -1043,7 +1042,7 @@ public class AudioDeviceBroker {
synchronized (mBluetoothAudioStateLock) {
mBluetoothScoOn = on;
updateAudioHalBluetoothState();
postUpdateCommunicationRouteClient(eventSource);
postUpdateCommunicationRouteClient(isBluetoothScoRequested(), eventSource);
}
}
@@ -1395,8 +1394,10 @@ public class AudioDeviceBroker {
MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET, SENDMSG_QUEUE, capturePreset);
}
/*package*/ void postUpdateCommunicationRouteClient(String eventSource) {
sendLMsgNoDelay(MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT, SENDMSG_QUEUE, eventSource);
/*package*/ void postUpdateCommunicationRouteClient(
boolean wasBtScoRequested, String eventSource) {
sendILMsgNoDelay(MSG_IL_UPDATE_COMMUNICATION_ROUTE_CLIENT, SENDMSG_QUEUE,
wasBtScoRequested ? 1 : 0, eventSource);
}
/*package*/ void postSetCommunicationDeviceForClient(CommunicationDeviceInfo info) {
@@ -1708,7 +1709,8 @@ public class AudioDeviceBroker {
: AudioSystem.STREAM_DEFAULT);
if (btInfo.mProfile == BluetoothProfile.LE_AUDIO
|| btInfo.mProfile == BluetoothProfile.HEARING_AID) {
onUpdateCommunicationRouteClient("setBluetoothActiveDevice");
onUpdateCommunicationRouteClient(isBluetoothScoRequested(),
"setBluetoothActiveDevice");
}
}
}
@@ -1762,9 +1764,11 @@ public class AudioDeviceBroker {
case MSG_I_SET_MODE_OWNER:
synchronized (mSetModeLock) {
synchronized (mDeviceStateLock) {
boolean wasBtScoRequested = isBluetoothScoRequested();
mAudioModeOwner = (AudioModeInfo) msg.obj;
if (mAudioModeOwner.mMode != AudioSystem.MODE_RINGTONE) {
onUpdateCommunicationRouteClient("setNewModeOwner");
onUpdateCommunicationRouteClient(
wasBtScoRequested, "setNewModeOwner");
}
}
}
@@ -1787,10 +1791,10 @@ public class AudioDeviceBroker {
}
break;
case MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT:
case MSG_IL_UPDATE_COMMUNICATION_ROUTE_CLIENT:
synchronized (mSetModeLock) {
synchronized (mDeviceStateLock) {
onUpdateCommunicationRouteClient((String) msg.obj);
onUpdateCommunicationRouteClient(msg.arg1 == 1, (String) msg.obj);
}
}
break;
@@ -1973,7 +1977,7 @@ public class AudioDeviceBroker {
private static final int MSG_I_SAVE_CLEAR_PREF_DEVICES_FOR_CAPTURE_PRESET = 38;
private static final int MSG_L_SET_COMMUNICATION_DEVICE_FOR_CLIENT = 42;
private static final int MSG_L_UPDATE_COMMUNICATION_ROUTE_CLIENT = 43;
private static final int MSG_IL_UPDATE_COMMUNICATION_ROUTE_CLIENT = 43;
private static final int MSG_I_SCO_AUDIO_STATE_CHANGED = 44;
private static final int MSG_L_BT_ACTIVE_DEVICE_CHANGE_EXT = 45;
@@ -2330,16 +2334,20 @@ public class AudioDeviceBroker {
*/
// @GuardedBy("mSetModeLock")
@GuardedBy("mDeviceStateLock")
private void onUpdateCommunicationRouteClient(String eventSource) {
updateCommunicationRoute(eventSource);
private void onUpdateCommunicationRouteClient(boolean wasBtScoRequested, String eventSource) {
CommunicationRouteClient crc = topCommunicationRouteClient();
if (AudioService.DEBUG_COMM_RTE) {
Log.v(TAG, "onUpdateCommunicationRouteClient, crc: "
+ crc + " eventSource: " + eventSource);
Log.v(TAG, "onUpdateCommunicationRouteClient, crc: " + crc
+ " wasBtScoRequested: " + wasBtScoRequested + " eventSource: " + eventSource);
}
if (crc != null) {
setCommunicationRouteForClient(crc.getBinder(), crc.getUid(), crc.getDevice(),
BtHelper.SCO_MODE_UNDEFINED, crc.isPrivileged(), eventSource);
} else {
if (!isBluetoothScoRequested() && wasBtScoRequested) {
mBtHelper.stopBluetoothSco(eventSource);
}
updateCommunicationRoute(eventSource);
}
}
@@ -2433,6 +2441,7 @@ public class AudioDeviceBroker {
List<AudioRecordingConfiguration> recordConfigs) {
synchronized (mSetModeLock) {
synchronized (mDeviceStateLock) {
final boolean wasBtScoRequested = isBluetoothScoRequested();
boolean updateCommunicationRoute = false;
for (CommunicationRouteClient crc : mCommunicationRouteClients) {
boolean wasActive = crc.isActive();
@@ -2461,7 +2470,8 @@ public class AudioDeviceBroker {
}
}
if (updateCommunicationRoute) {
postUpdateCommunicationRouteClient("updateCommunicationRouteClientsActivity");
postUpdateCommunicationRouteClient(
wasBtScoRequested, "updateCommunicationRouteClientsActivity");
}
}
}

View File

@@ -329,7 +329,7 @@ public class BtHelper {
default:
break;
}
if(broadcast) {
if (broadcast) {
broadcastScoConnectionState(scoAudioState);
//FIXME: this is to maintain compatibility with deprecated intent
// AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED. Remove when appropriate.
@@ -718,8 +718,10 @@ public class BtHelper {
checkScoAudioState();
if (state == BluetoothHeadset.STATE_AUDIO_CONNECTED) {
// Make sure that the state transitions to CONNECTING even if we cannot initiate
// the connection.
broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTING);
// the connection except if already connected internally
if (mScoAudioState != SCO_STATE_ACTIVE_INTERNAL) {
broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTING);
}
switch (mScoAudioState) {
case SCO_STATE_INACTIVE:
mScoAudioMode = scoAudioMode;
@@ -775,7 +777,7 @@ public class BtHelper {
broadcastScoConnectionState(AudioManager.SCO_AUDIO_STATE_CONNECTED);
break;
case SCO_STATE_ACTIVE_INTERNAL:
Log.w(TAG, "requestScoState: already in ACTIVE mode, simply return");
// Already in ACTIVE mode, simply return
break;
case SCO_STATE_ACTIVE_EXTERNAL:
/* Confirm SCO Audio connection to requesting app as it is already connected