AudioDeviceBroker: clean communication route clients upon device disconnection
When a device is disconnected and is a valid communication device, go over the communication route clients stack and cancel all route requests to this device. Bug: 286545833 Test: atest AudioCommunicationDeviceTest (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:df5f3fb6a5309b8bc6892e49490bc2e887b24a14) Merged-In: Ie6b8514fe61d3efce6c65af5bc8e5fa2562db4ca Change-Id: Ie6b8514fe61d3efce6c65af5bc8e5fa2562db4ca
This commit is contained in:
committed by
Cherrypicker Worker
parent
43e951b21d
commit
9a703c8092
@@ -375,7 +375,8 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
int scoAudioMode, boolean isPrivileged, String eventSource) {
|
||||
|
||||
if (AudioService.DEBUG_COMM_RTE) {
|
||||
Log.v(TAG, "setCommunicationRouteForClient: device: " + device);
|
||||
Log.v(TAG, "setCommunicationRouteForClient: device: " + device
|
||||
+ ", eventSource: " + eventSource);
|
||||
}
|
||||
AudioService.sDeviceLogger.enqueue((new EventLogger.StringEvent(
|
||||
"setCommunicationRouteForClient for uid: " + uid
|
||||
@@ -497,14 +498,48 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
};
|
||||
|
||||
/*package */ static boolean isValidCommunicationDevice(AudioDeviceInfo device) {
|
||||
return isValidCommunicationDeviceType(device.getType());
|
||||
}
|
||||
|
||||
private static boolean isValidCommunicationDeviceType(int deviceType) {
|
||||
for (int type : VALID_COMMUNICATION_DEVICE_TYPES) {
|
||||
if (device.getType() == type) {
|
||||
if (deviceType == type) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*package */
|
||||
void postCheckCommunicationDeviceRemoval(@NonNull AudioDeviceAttributes device) {
|
||||
if (!isValidCommunicationDeviceType(
|
||||
AudioDeviceInfo.convertInternalDeviceToDeviceType(device.getInternalType()))) {
|
||||
return;
|
||||
}
|
||||
sendLMsgNoDelay(MSG_L_CHECK_COMMUNICATION_DEVICE_REMOVAL, SENDMSG_QUEUE, device);
|
||||
}
|
||||
|
||||
@GuardedBy("mDeviceStateLock")
|
||||
void onCheckCommunicationDeviceRemoval(@NonNull AudioDeviceAttributes device) {
|
||||
if (AudioService.DEBUG_COMM_RTE) {
|
||||
Log.v(TAG, "onCheckCommunicationDeviceRemoval device: " + device.toString());
|
||||
}
|
||||
for (CommunicationRouteClient crc : mCommunicationRouteClients) {
|
||||
if (device.equals(crc.getDevice())) {
|
||||
if (AudioService.DEBUG_COMM_RTE) {
|
||||
Log.v(TAG, "onCheckCommunicationDeviceRemoval removing client: "
|
||||
+ crc.toString());
|
||||
}
|
||||
// Cancelling the route for this client will remove it from the stack and update
|
||||
// the communication route.
|
||||
CommunicationDeviceInfo deviceInfo = new CommunicationDeviceInfo(
|
||||
crc.getBinder(), crc.getUid(), device, false,
|
||||
BtHelper.SCO_MODE_UNDEFINED, "onCheckCommunicationDeviceRemoval",
|
||||
false, crc.isPrivileged());
|
||||
postSetCommunicationDeviceForClient(deviceInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* package */ static List<AudioDeviceInfo> getAvailableCommunicationDevices() {
|
||||
ArrayList<AudioDeviceInfo> commDevices = new ArrayList<>();
|
||||
AudioDeviceInfo[] allDevices =
|
||||
@@ -1449,7 +1484,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ boolean handleDeviceConnection(AudioDeviceAttributes attributes,
|
||||
/*package*/ boolean handleDeviceConnection(@NonNull AudioDeviceAttributes attributes,
|
||||
boolean connect, @Nullable BluetoothDevice btDevice) {
|
||||
synchronized (mDeviceStateLock) {
|
||||
return mDeviceInventory.handleDeviceConnection(
|
||||
@@ -1858,6 +1893,15 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
final BluetoothDevice btDevice = (BluetoothDevice) msg.obj;
|
||||
BtHelper.onNotifyPreferredAudioProfileApplied(btDevice);
|
||||
} break;
|
||||
|
||||
case MSG_L_CHECK_COMMUNICATION_DEVICE_REMOVAL: {
|
||||
synchronized (mSetModeLock) {
|
||||
synchronized (mDeviceStateLock) {
|
||||
onCheckCommunicationDeviceRemoval((AudioDeviceAttributes) msg.obj);
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
Log.wtf(TAG, "Invalid message " + msg.what);
|
||||
}
|
||||
@@ -1934,6 +1978,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
private static final int MSG_IL_BTLEAUDIO_TIMEOUT = 49;
|
||||
|
||||
private static final int MSG_L_NOTIFY_PREFERRED_AUDIOPROFILE_APPLIED = 52;
|
||||
private static final int MSG_L_CHECK_COMMUNICATION_DEVICE_REMOVAL = 53;
|
||||
|
||||
private static boolean isMessageHandledUnderWakelock(int msgId) {
|
||||
switch(msgId) {
|
||||
@@ -2308,6 +2353,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
dispatchCommunicationDevice();
|
||||
}
|
||||
|
||||
@GuardedBy("mDeviceStateLock")
|
||||
private CommunicationRouteClient removeCommunicationRouteClient(
|
||||
IBinder cb, boolean unregister) {
|
||||
for (CommunicationRouteClient cl : mCommunicationRouteClients) {
|
||||
|
||||
@@ -1245,8 +1245,9 @@ public class AudioDeviceInventory {
|
||||
* @param btDevice the corresponding Bluetooth device when relevant.
|
||||
* @return false if an error was reported by AudioSystem
|
||||
*/
|
||||
/*package*/ boolean handleDeviceConnection(AudioDeviceAttributes attributes, boolean connect,
|
||||
boolean isForTesting, @Nullable BluetoothDevice btDevice) {
|
||||
/*package*/ boolean handleDeviceConnection(@NonNull AudioDeviceAttributes attributes,
|
||||
boolean connect, boolean isForTesting,
|
||||
@Nullable BluetoothDevice btDevice) {
|
||||
int device = attributes.getInternalType();
|
||||
String address = attributes.getAddress();
|
||||
String deviceName = attributes.getName();
|
||||
@@ -1297,6 +1298,7 @@ public class AudioDeviceInventory {
|
||||
AudioSystem.DEVICE_STATE_UNAVAILABLE, AudioSystem.AUDIO_FORMAT_DEFAULT);
|
||||
// always remove even if disconnection failed
|
||||
mConnectedDevices.remove(deviceKey);
|
||||
mDeviceBroker.postCheckCommunicationDeviceRemoval(attributes);
|
||||
status = true;
|
||||
}
|
||||
if (status) {
|
||||
@@ -1801,8 +1803,9 @@ public class AudioDeviceInventory {
|
||||
|
||||
// device to remove was visible by APM, update APM
|
||||
mDeviceBroker.clearAvrcpAbsoluteVolumeSupported();
|
||||
final int res = mAudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
|
||||
AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address),
|
||||
AudioDeviceAttributes ada = new AudioDeviceAttributes(
|
||||
AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, address);
|
||||
final int res = mAudioSystem.setDeviceConnectionState(ada,
|
||||
AudioSystem.DEVICE_STATE_UNAVAILABLE, a2dpCodec);
|
||||
|
||||
if (res != AudioSystem.AUDIO_STATUS_OK) {
|
||||
@@ -1816,11 +1819,13 @@ public class AudioDeviceInventory {
|
||||
"A2DP device addr=" + address + " made unavailable")).printLog(TAG));
|
||||
}
|
||||
mApmConnectedDevices.remove(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
|
||||
|
||||
// Remove A2DP routes as well
|
||||
setCurrentAudioRouteNameIfPossible(null, true /*fromA2dp*/);
|
||||
mmi.record();
|
||||
updateBluetoothPreferredModes_l(null /*connectedDevice*/);
|
||||
purgeDevicesRoles_l();
|
||||
mDeviceBroker.postCheckCommunicationDeviceRemoval(ada);
|
||||
}
|
||||
|
||||
@GuardedBy("mDevicesLock")
|
||||
@@ -1855,12 +1860,14 @@ public class AudioDeviceInventory {
|
||||
|
||||
@GuardedBy("mDevicesLock")
|
||||
private void makeA2dpSrcUnavailable(String address) {
|
||||
mAudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
|
||||
AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address),
|
||||
AudioDeviceAttributes ada = new AudioDeviceAttributes(
|
||||
AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address);
|
||||
mAudioSystem.setDeviceConnectionState(ada,
|
||||
AudioSystem.DEVICE_STATE_UNAVAILABLE,
|
||||
AudioSystem.AUDIO_FORMAT_DEFAULT);
|
||||
mConnectedDevices.remove(
|
||||
DeviceInfo.makeDeviceListKey(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, address));
|
||||
mDeviceBroker.postCheckCommunicationDeviceRemoval(ada);
|
||||
}
|
||||
|
||||
@GuardedBy("mDevicesLock")
|
||||
@@ -1893,8 +1900,9 @@ public class AudioDeviceInventory {
|
||||
|
||||
@GuardedBy("mDevicesLock")
|
||||
private void makeHearingAidDeviceUnavailable(String address) {
|
||||
mAudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
|
||||
AudioSystem.DEVICE_OUT_HEARING_AID, address),
|
||||
AudioDeviceAttributes ada = new AudioDeviceAttributes(
|
||||
AudioSystem.DEVICE_OUT_HEARING_AID, address);
|
||||
mAudioSystem.setDeviceConnectionState(ada,
|
||||
AudioSystem.DEVICE_STATE_UNAVAILABLE,
|
||||
AudioSystem.AUDIO_FORMAT_DEFAULT);
|
||||
mConnectedDevices.remove(
|
||||
@@ -1906,6 +1914,7 @@ public class AudioDeviceInventory {
|
||||
.set(MediaMetrics.Property.DEVICE,
|
||||
AudioSystem.getDeviceName(AudioSystem.DEVICE_OUT_HEARING_AID))
|
||||
.record();
|
||||
mDeviceBroker.postCheckCommunicationDeviceRemoval(ada);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2002,9 +2011,10 @@ public class AudioDeviceInventory {
|
||||
|
||||
@GuardedBy("mDevicesLock")
|
||||
private void makeLeAudioDeviceUnavailableNow(String address, int device) {
|
||||
AudioDeviceAttributes ada = null;
|
||||
if (device != AudioSystem.DEVICE_NONE) {
|
||||
final int res = AudioSystem.setDeviceConnectionState(new AudioDeviceAttributes(
|
||||
device, address),
|
||||
ada = new AudioDeviceAttributes(device, address);
|
||||
final int res = AudioSystem.setDeviceConnectionState(ada,
|
||||
AudioSystem.DEVICE_STATE_UNAVAILABLE,
|
||||
AudioSystem.AUDIO_FORMAT_DEFAULT);
|
||||
|
||||
@@ -2024,6 +2034,9 @@ public class AudioDeviceInventory {
|
||||
setCurrentAudioRouteNameIfPossible(null, false /*fromA2dp*/);
|
||||
updateBluetoothPreferredModes_l(null /*connectedDevice*/);
|
||||
purgeDevicesRoles_l();
|
||||
if (ada != null) {
|
||||
mDeviceBroker.postCheckCommunicationDeviceRemoval(ada);
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mDevicesLock")
|
||||
|
||||
Reference in New Issue
Block a user