Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1ea5fd3a authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

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

parents 74515037 9e049008
Loading
Loading
Loading
Loading
+21 −12
Original line number Diff line number Diff line
@@ -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);
+21 −4
Original line number Diff line number Diff line
@@ -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,

        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;
            }
        }
    }
+4 −2
Original line number Diff line number Diff line
@@ -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) {
+12 −8
Original line number Diff line number Diff line
@@ -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,