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

Commit 23266c65 authored by Carter Hsu's avatar Carter Hsu Committed by Android (Google) Code Review
Browse files

Merge "Add Low Latency Audio Control" into tm-qpr-dev

parents 0c1d39b8 4dba532e
Loading
Loading
Loading
Loading
+34 −0
Original line number Diff line number Diff line
@@ -71,6 +71,9 @@ public class A2dpService extends ProfileService {
    private static final boolean DBG = true;
    private static final String TAG = "A2dpService";

    // TODO(b/240635097): remove in U
    private static final int SOURCE_CODEC_TYPE_OPUS = 6;

    private static A2dpService sA2dpService;

    private AdapterService mAdapterService;
@@ -600,6 +603,7 @@ public class A2dpService extends ProfileService {
            // This needs to happen before we inform the audio manager that the device
            // disconnected. Please see comment in updateAndBroadcastActiveDevice() for why.
            updateAndBroadcastActiveDevice(device);
            updateLowLatencyAudioSupport(device);

            BluetoothDevice newActiveDevice = null;
            synchronized (mStateMachines) {
@@ -819,6 +823,7 @@ public class A2dpService extends ProfileService {
            Log.e(TAG, "enableOptionalCodecs: Codec status is null");
            return;
        }
        updateLowLatencyAudioSupport(device);
        mA2dpCodecConfig.enableOptionalCodecs(device, codecStatus.getCodecConfig());
    }

@@ -849,6 +854,7 @@ public class A2dpService extends ProfileService {
            Log.e(TAG, "disableOptionalCodecs: Codec status is null");
            return;
        }
        updateLowLatencyAudioSupport(device);
        mA2dpCodecConfig.disableOptionalCodecs(device, codecStatus.getCodecConfig());
    }

@@ -1208,6 +1214,34 @@ public class A2dpService extends ProfileService {
        }
    }

    /**
     *  Check for low-latency codec support and inform AdapterService
     *
     *  @param device device whose audio low latency will be allowed or disallowed
     */
    @VisibleForTesting
    public void updateLowLatencyAudioSupport(BluetoothDevice device) {
        synchronized (mStateMachines) {
            A2dpStateMachine sm = mStateMachines.get(device);
            if (sm == null) {
                return;
            }
            BluetoothCodecStatus codecStatus = sm.getCodecStatus();
            boolean lowLatencyAudioAllow = false;
            BluetoothCodecConfig lowLatencyCodec = new BluetoothCodecConfig.Builder()
                    .setCodecType(SOURCE_CODEC_TYPE_OPUS) // remove in U
                    .build();

            if (codecStatus != null
                    && codecStatus.isCodecConfigSelectable(lowLatencyCodec)
                    && getOptionalCodecsEnabled(device)
                            == BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
                lowLatencyAudioAllow = true;
            }
            mAdapterService.allowLowLatencyAudio(lowLatencyAudioAllow, device);
        }
    }

    private void connectionStateChanged(BluetoothDevice device, int fromState, int toState) {
        if ((device == null) || (fromState == toState)) {
            return;
+2 −0
Original line number Diff line number Diff line
@@ -483,6 +483,7 @@ final class A2dpStateMachine extends StateMachine {
            // codecs (perhaps it's had a firmware update, etc.) and save that state if
            // it differs from what we had saved before.
            mA2dpService.updateOptionalCodecsSupport(mDevice);
            mA2dpService.updateLowLatencyAudioSupport(mDevice);
            broadcastConnectionState(mConnectionState, mLastConnectionState);
            // Upon connected, the audio starts out as stopped
            broadcastAudioState(BluetoothA2dp.STATE_NOT_PLAYING,
@@ -655,6 +656,7 @@ final class A2dpStateMachine extends StateMachine {
            // for this codec change event.
            mA2dpService.updateOptionalCodecsSupport(mDevice);
        }
        mA2dpService.updateLowLatencyAudioSupport(mDevice);
        if (mA2dpOffloadEnabled) {
            boolean update = false;
            BluetoothCodecConfig newCodecConfig = mCodecStatus.getCodecConfig();
+15 −0
Original line number Diff line number Diff line
@@ -362,6 +362,7 @@ public class A2dpStateMachineTest {
        // Selected codec = SBC, selectable codec = SBC
        mA2dpStateMachine.processCodecConfigEvent(codecStatusSbcAndSbc);
        verify(mA2dpService).codecConfigUpdated(mTestDevice, codecStatusSbcAndSbc, false);
        verify(mA2dpService, times(1)).updateLowLatencyAudioSupport(mTestDevice);

        // Inject an event to change state machine to connected state
        A2dpStackEvent connStCh =
@@ -379,6 +380,7 @@ public class A2dpStateMachineTest {

        // Verify that state machine update optional codec when enter connected state
        verify(mA2dpService, times(1)).updateOptionalCodecsSupport(mTestDevice);
        verify(mA2dpService, times(2)).updateLowLatencyAudioSupport(mTestDevice);

        // Change codec status when device connected.
        // Selected codec = SBC, selectable codec = SBC+AAC
@@ -387,12 +389,14 @@ public class A2dpStateMachineTest {
            verify(mA2dpService).codecConfigUpdated(mTestDevice, codecStatusSbcAndSbcAac, true);
        }
        verify(mA2dpService, times(2)).updateOptionalCodecsSupport(mTestDevice);
        verify(mA2dpService, times(3)).updateLowLatencyAudioSupport(mTestDevice);

        // Update selected codec with selectable codec unchanged.
        // Selected codec = AAC, selectable codec = SBC+AAC
        mA2dpStateMachine.processCodecConfigEvent(codecStatusAacAndSbcAac);
        verify(mA2dpService).codecConfigUpdated(mTestDevice, codecStatusAacAndSbcAac, false);
        verify(mA2dpService, times(2)).updateOptionalCodecsSupport(mTestDevice);
        verify(mA2dpService, times(4)).updateLowLatencyAudioSupport(mTestDevice);

        // Update selected codec
        // Selected codec = OPUS, selectable codec = SBC+AAC+OPUS
@@ -401,5 +405,16 @@ public class A2dpStateMachineTest {
            verify(mA2dpService).codecConfigUpdated(mTestDevice, codecStatusOpusAndSbcAacOpus, true);
        }
        verify(mA2dpService, times(3)).updateOptionalCodecsSupport(mTestDevice);
        // Check if low latency audio been updated.
        verify(mA2dpService, times(5)).updateLowLatencyAudioSupport(mTestDevice);

        // Update selected codec with selectable codec changed.
        // Selected codec = SBC, selectable codec = SBC+AAC
        mA2dpStateMachine.processCodecConfigEvent(codecStatusSbcAndSbcAac);
        if (!offloadEnabled) {
            verify(mA2dpService).codecConfigUpdated(mTestDevice, codecStatusSbcAndSbcAac, true);
        }
        // Check if low latency audio been update.
        verify(mA2dpService, times(6)).updateLowLatencyAudioSupport(mTestDevice);
    }
}