Merge "AudioService: make BT A2DP API async" into sc-dev

This commit is contained in:
TreeHugger Robot
2021-04-15 08:11:25 +00:00
committed by Android (Google) Code Review
4 changed files with 58 additions and 26 deletions

View File

@@ -503,7 +503,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
private static final class BtDeviceConnectionInfo {
/*package*/ static final class BtDeviceConnectionInfo {
final @NonNull BluetoothDevice mDevice;
final @AudioService.BtProfileConnectionState int mState;
final int mProfile;
@@ -520,6 +520,14 @@ import java.util.concurrent.atomic.AtomicBoolean;
mVolume = vol;
}
BtDeviceConnectionInfo(@NonNull BtDeviceConnectionInfo info) {
mDevice = info.mDevice;
mState = info.mState;
mProfile = info.mProfile;
mSupprNoisy = info.mSupprNoisy;
mVolume = info.mVolume;
}
// redefine equality op so we can match messages intended for this device
@Override
public boolean equals(Object o) {
@@ -541,18 +549,19 @@ import java.util.concurrent.atomic.AtomicBoolean;
}
}
/*package*/ void postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
@NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state,
int profile, boolean suppressNoisyIntent, int a2dpVolume) {
final BtDeviceConnectionInfo info = new BtDeviceConnectionInfo(device, state, profile,
suppressNoisyIntent, a2dpVolume);
final String name = TextUtils.emptyIfNull(device.getName());
/**
* will block on mDeviceStateLock, which is held during an A2DP (dis) connection
* not just a simple message post
* @param info struct with the (dis)connection information
*/
/*package*/ void queueBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
@NonNull BtDeviceConnectionInfo info) {
final String name = TextUtils.emptyIfNull(info.mDevice.getName());
new MediaMetrics.Item(MediaMetrics.Name.AUDIO_DEVICE + MediaMetrics.SEPARATOR
+ "postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent")
.set(MediaMetrics.Property.STATE, state == BluetoothProfile.STATE_CONNECTED
.set(MediaMetrics.Property.STATE, info.mState == BluetoothProfile.STATE_CONNECTED
? MediaMetrics.Value.CONNECTED : MediaMetrics.Value.DISCONNECTED)
.set(MediaMetrics.Property.INDEX, a2dpVolume)
.set(MediaMetrics.Property.INDEX, info.mVolume)
.set(MediaMetrics.Property.NAME, name)
.record();
@@ -562,10 +571,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
// when receiving a request to change the connection state of a device, this last
// request is the source of truth, so cancel all previous requests that are already in
// the handler
removeScheduledA2dpEvents(device);
removeScheduledA2dpEvents(info.mDevice);
sendLMsgNoDelay(
state == BluetoothProfile.STATE_CONNECTED
info.mState == BluetoothProfile.STATE_CONNECTED
? MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_CONNECTION
: MSG_L_A2DP_DEVICE_CONNECTION_CHANGE_EXT_DISCONNECTION,
SENDMSG_QUEUE, info);

View File

@@ -310,6 +310,8 @@ public class AudioService extends IAudioService.Stub
private static final int MSG_UPDATE_A11Y_SERVICE_UIDS = 35;
private static final int MSG_UPDATE_AUDIO_MODE = 36;
private static final int MSG_RECORDING_CONFIG_CHANGE = 37;
private static final int MSG_SET_A2DP_DEV_CONNECTION_STATE = 38;
private static final int MSG_A2DP_DEV_CONFIG_CHANGE = 39;
// start of messages handled under wakelock
// these messages can only be queued, i.e. sent with queueMsgUnderWakeLock(),
@@ -6114,7 +6116,7 @@ public class AudioService extends IAudioService.Stub
* See AudioManager.setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent()
*/
public void setBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
@NonNull BluetoothDevice device, @AudioService.BtProfileConnectionState int state,
@NonNull BluetoothDevice device, @BtProfileConnectionState int state,
int profile, boolean suppressNoisyIntent, int a2dpVolume) {
if (device == null) {
throw new IllegalArgumentException("Illegal null device");
@@ -6124,8 +6126,13 @@ public class AudioService extends IAudioService.Stub
throw new IllegalArgumentException("Illegal BluetoothProfile state for device "
+ " (dis)connection, got " + state);
}
mDeviceBroker.postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(device, state,
profile, suppressNoisyIntent, a2dpVolume);
AudioDeviceBroker.BtDeviceConnectionInfo info =
new AudioDeviceBroker.BtDeviceConnectionInfo(device, state,
profile, suppressNoisyIntent, a2dpVolume);
sendMsg(mAudioHandler, MSG_SET_A2DP_DEV_CONNECTION_STATE, SENDMSG_QUEUE,
0 /*arg1*/, 0 /*arg2*/,
/*obj*/ info, 0 /*delay*/);
}
/** only public for mocking/spying, do not call outside of AudioService */
@@ -6143,7 +6150,8 @@ public class AudioService extends IAudioService.Stub
if (device == null) {
throw new IllegalArgumentException("Illegal null device");
}
mDeviceBroker.postBluetoothA2dpDeviceConfigChange(device);
sendMsg(mAudioHandler, MSG_A2DP_DEV_CONFIG_CHANGE, SENDMSG_QUEUE, 0, 0,
/*obj*/ device, /*delay*/ 0);
}
private static final Set<Integer> DEVICE_MEDIA_UNMUTED_ON_PLUG_SET;
@@ -7505,6 +7513,15 @@ public class AudioService extends IAudioService.Stub
onUpdateAudioMode(msg.arg1, msg.arg2, (String) msg.obj, false /*force*/);
}
break;
case MSG_SET_A2DP_DEV_CONNECTION_STATE:
mDeviceBroker.queueBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
(AudioDeviceBroker.BtDeviceConnectionInfo) msg.obj);
break;
case MSG_A2DP_DEV_CONFIG_CHANGE:
mDeviceBroker.postBluetoothA2dpDeviceConfigChange((BluetoothDevice) msg.obj);
break;
}
}
}

View File

@@ -454,8 +454,10 @@ public class BtHelper {
}
final BluetoothDevice btDevice = deviceList.get(0);
// the device is guaranteed CONNECTED
mDeviceBroker.postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(btDevice,
BluetoothA2dp.STATE_CONNECTED, BluetoothProfile.A2DP_SINK, true, -1);
mDeviceBroker.queueBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
new AudioDeviceBroker.BtDeviceConnectionInfo(btDevice,
BluetoothA2dp.STATE_CONNECTED, BluetoothProfile.A2DP_SINK,
true, -1));
}
/*package*/ synchronized void onA2dpSinkProfileConnected(BluetoothProfile profile) {

View File

@@ -98,8 +98,9 @@ public class AudioDeviceBrokerTest {
Log.i(TAG, "starting testPostA2dpDeviceConnectionChange");
Assert.assertNotNull("invalid null BT device", mFakeBtDevice);
mAudioDeviceBroker.postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(mFakeBtDevice,
BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP, true, 1);
mAudioDeviceBroker.queueBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
new AudioDeviceBroker.BtDeviceConnectionInfo(mFakeBtDevice,
BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP, true, 1));
Thread.sleep(2 * MAX_MESSAGE_HANDLING_DELAY_MS);
verify(mSpyDevInventory, times(1)).setBluetoothA2dpDeviceConnectionState(
any(BluetoothDevice.class),
@@ -209,20 +210,23 @@ public class AudioDeviceBrokerTest {
((NoOpAudioSystemAdapter) mSpyAudioSystem).configureIsStreamActive(mockMediaPlayback);
// first connection: ensure the device is connected as a starting condition for the test
mAudioDeviceBroker.postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(mFakeBtDevice,
BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP, true, 1);
mAudioDeviceBroker.queueBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
new AudioDeviceBroker.BtDeviceConnectionInfo(mFakeBtDevice,
BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP, true, 1));
Thread.sleep(MAX_MESSAGE_HANDLING_DELAY_MS);
// disconnection
mAudioDeviceBroker.postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(mFakeBtDevice,
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.A2DP, false, -1);
mAudioDeviceBroker.queueBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
new AudioDeviceBroker.BtDeviceConnectionInfo(mFakeBtDevice,
BluetoothProfile.STATE_DISCONNECTED, BluetoothProfile.A2DP, false, -1));
if (delayAfterDisconnection > 0) {
Thread.sleep(delayAfterDisconnection);
}
// reconnection
mAudioDeviceBroker.postBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(mFakeBtDevice,
BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP, true, 2);
mAudioDeviceBroker.queueBluetoothA2dpDeviceConnectionStateSuppressNoisyIntent(
new AudioDeviceBroker.BtDeviceConnectionInfo(mFakeBtDevice,
BluetoothProfile.STATE_CONNECTED, BluetoothProfile.A2DP, true, 2));
Thread.sleep(AudioService.BECOMING_NOISY_DELAY_MS + MAX_MESSAGE_HANDLING_DELAY_MS);
// Verify disconnection has been cancelled and we're seeing two connections attempts,