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

Commit 856c8b96 authored by Omer Osman's avatar Omer Osman
Browse files

Add support for Opus in BT Java Service

This CL adds Opus to the BluetoothCodecConfig, and sets the codec as the
default low latency codec.

Bug: 226441860
Test: A2dpCodecConfigTest BluetoothCodecConfigTest A2dpStateMachineTest
Tag: #feature
Ignore-AOSP-First: TM QPR1 Feature

Change-Id: Id94a7f8fab1a7f5e0199d757a70ff19010694fff
parent f9001f6c
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -85,6 +85,7 @@
    <integer name="a2dp_source_codec_priority_aptx_hd">4001</integer>
    <integer name="a2dp_source_codec_priority_ldac">5001</integer>
    <integer name="a2dp_source_codec_priority_lc3">6001</integer>
    <integer name="a2dp_source_codec_priority_opus">7001</integer>

    <!-- For enabling the AVRCP Target Cover Artowrk feature-->
    <bool name="avrcp_target_enable_cover_art">true</bool>
+23 −5
Original line number Diff line number Diff line
@@ -37,6 +37,9 @@ class A2dpCodecConfig {
    private static final boolean DBG = true;
    private static final String TAG = "A2dpCodecConfig";

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

    private Context mContext;
    private A2dpNativeInterface mA2dpNativeInterface;

@@ -53,6 +56,8 @@ class A2dpCodecConfig {
            BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
    private @CodecPriority int mA2dpSourceCodecPriorityLc3 =
            BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
    private @CodecPriority int mA2dpSourceCodecPriorityOpus =
            BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;

    private BluetoothCodecConfig[] mCodecConfigOffloading = new BluetoothCodecConfig[0];

@@ -243,6 +248,16 @@ class A2dpCodecConfig {
            mA2dpSourceCodecPriorityLc3 = value;
        }

        try {
            value = resources.getInteger(R.integer.a2dp_source_codec_priority_opus);
        } catch (NotFoundException e) {
            value = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
        }
        if ((value >= BluetoothCodecConfig.CODEC_PRIORITY_DISABLED) && (value
                < BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST)) {
            mA2dpSourceCodecPriorityOpus = value;
        }

        BluetoothCodecConfig codecConfig;
        BluetoothCodecConfig[] codecConfigArray =
                new BluetoothCodecConfig[6];
@@ -272,8 +287,9 @@ class A2dpCodecConfig {
                .build();
        codecConfigArray[4] = codecConfig;
        codecConfig = new BluetoothCodecConfig.Builder()
                .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3)
                .setCodecPriority(mA2dpSourceCodecPriorityLc3)
                // TODO(b/240635097): update in U
                .setCodecType(SOURCE_CODEC_TYPE_OPUS)
                .setCodecPriority(mA2dpSourceCodecPriorityOpus)
                .build();
        codecConfigArray[5] = codecConfig;

@@ -282,14 +298,16 @@ class A2dpCodecConfig {

    public void switchCodecByBufferSize(
            BluetoothDevice device, boolean isLowLatency, int currentCodecType) {
        if ((isLowLatency && currentCodecType == BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3)
        || (!isLowLatency && currentCodecType != BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3)) {
        // TODO(b/240635097): update in U
        if ((isLowLatency && currentCodecType == SOURCE_CODEC_TYPE_OPUS)
                || (!isLowLatency && currentCodecType != SOURCE_CODEC_TYPE_OPUS)) {
            return;
        }
        BluetoothCodecConfig[] codecConfigArray = assignCodecConfigPriorities();
        for (int i = 0; i < codecConfigArray.length; i++){
            BluetoothCodecConfig codecConfig = codecConfigArray[i];
            if (codecConfig.getCodecType() == BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3) {
            // TODO(b/240635097): update in U
            if (codecConfig.getCodecType() == SOURCE_CODEC_TYPE_OPUS) {
                if (isLowLatency) {
                    codecConfig.setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST);
                } else {
+10 −0
Original line number Diff line number Diff line
@@ -76,6 +76,9 @@ final class A2dpStateMachine extends StateMachine {
    private static final boolean DBG = true;
    private static final String TAG = "A2dpStateMachine";

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

    static final int CONNECT = 1;
    static final int DISCONNECT = 2;
    @VisibleForTesting
@@ -666,6 +669,13 @@ final class A2dpStateMachine extends StateMachine {
                    && (prevCodecConfig.getCodecSpecific1()
                        != newCodecConfig.getCodecSpecific1())) {
                update = true;
            } else if ((newCodecConfig.getCodecType()
                        == SOURCE_CODEC_TYPE_OPUS) // TODO(b/240635097): update in U
                    && (prevCodecConfig != null)
                    // check framesize field
                    && (prevCodecConfig.getCodecSpecific1()
                        != newCodecConfig.getCodecSpecific1())) {
                update = true;
            }
            if (update) {
                mA2dpService.codecConfigUpdated(mDevice, mCodecStatus, false);
+36 −24
Original line number Diff line number Diff line
@@ -44,6 +44,10 @@ import java.util.Arrays;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class A2dpCodecConfigTest {

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

    private Context mTargetContext;
    private BluetoothDevice mTestDevice;
    private A2dpCodecConfig mA2dpCodecConfig;
@@ -57,7 +61,7 @@ public class A2dpCodecConfigTest {
            BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX,
            BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD,
            BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
            BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3
            SOURCE_CODEC_TYPE_OPUS // TODO(b/240635097): update in U
    };

    // Not use the default value to make sure it reads from config
@@ -67,6 +71,7 @@ public class A2dpCodecConfigTest {
    private static final int APTX_HD_PRIORITY_DEFAULT = 7001;
    private static final int LDAC_PRIORITY_DEFAULT = 9001;
    private static final int LC3_PRIORITY_DEFAULT = 11001;
    private static final int OPUS_PRIORITY_DEFAULT = 13001;
    private static final int PRIORITY_HIGH = 1000000;

    private static final BluetoothCodecConfig[] sCodecCapabilities = new BluetoothCodecConfig[] {
@@ -108,13 +113,11 @@ public class A2dpCodecConfigTest {
                                     | BluetoothCodecConfig.BITS_PER_SAMPLE_32,
                                     BluetoothCodecConfig.CHANNEL_MODE_STEREO,
                                     0, 0, 0, 0),       // Codec-specific fields
            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3,
                                     LC3_PRIORITY_DEFAULT,
                                     BluetoothCodecConfig.SAMPLE_RATE_44100
                                     | BluetoothCodecConfig.SAMPLE_RATE_48000,
            buildBluetoothCodecConfig(SOURCE_CODEC_TYPE_OPUS, // TODO(b/240635097): update in U
                                     OPUS_PRIORITY_DEFAULT,
                                     BluetoothCodecConfig.SAMPLE_RATE_48000,
                                     BluetoothCodecConfig.BITS_PER_SAMPLE_16,
                                     BluetoothCodecConfig.CHANNEL_MODE_MONO
                                     | BluetoothCodecConfig.CHANNEL_MODE_STEREO,
                                     BluetoothCodecConfig.CHANNEL_MODE_STEREO,
                                     0, 0, 0, 0)        // Codec-specific fields
    };

@@ -149,8 +152,8 @@ public class A2dpCodecConfigTest {
                                     BluetoothCodecConfig.BITS_PER_SAMPLE_32,
                                     BluetoothCodecConfig.CHANNEL_MODE_STEREO,
                                     0, 0, 0, 0),       // Codec-specific fields
            buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3,
                                     LC3_PRIORITY_DEFAULT,
            buildBluetoothCodecConfig(SOURCE_CODEC_TYPE_OPUS, // TODO(b/240635097): update in U
                                     OPUS_PRIORITY_DEFAULT,
                                     BluetoothCodecConfig.SAMPLE_RATE_48000,
                                     BluetoothCodecConfig.BITS_PER_SAMPLE_16,
                                     BluetoothCodecConfig.CHANNEL_MODE_STEREO,
@@ -174,8 +177,8 @@ public class A2dpCodecConfigTest {
                .thenReturn(APTX_HD_PRIORITY_DEFAULT);
        when(mMockResources.getInteger(R.integer.a2dp_source_codec_priority_ldac))
                .thenReturn(LDAC_PRIORITY_DEFAULT);
        when(mMockResources.getInteger(R.integer.a2dp_source_codec_priority_lc3))
                .thenReturn(LC3_PRIORITY_DEFAULT);
        when(mMockResources.getInteger(R.integer.a2dp_source_codec_priority_opus))
                .thenReturn(OPUS_PRIORITY_DEFAULT);

        mA2dpCodecConfig = new A2dpCodecConfig(mMockContext, mA2dpNativeInterface);
        mTestDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice("00:01:02:03:04:05");
@@ -209,8 +212,8 @@ public class A2dpCodecConfigTest {
                case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
                    Assert.assertEquals(config.getCodecPriority(), LDAC_PRIORITY_DEFAULT);
                    break;
                case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3:
                    Assert.assertEquals(config.getCodecPriority(), LC3_PRIORITY_DEFAULT);
                case SOURCE_CODEC_TYPE_OPUS: // TODO(b/240635097): update in U
                    Assert.assertEquals(config.getCodecPriority(), OPUS_PRIORITY_DEFAULT);
                    break;
            }
        }
@@ -242,8 +245,9 @@ public class A2dpCodecConfigTest {
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, PRIORITY_HIGH,
                true);
        testCodecPriorityChangeHelper(
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3, LC3_PRIORITY_DEFAULT,
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3, PRIORITY_HIGH,
                // TODO(b/240635097): update in U
                SOURCE_CODEC_TYPE_OPUS, OPUS_PRIORITY_DEFAULT,
                SOURCE_CODEC_TYPE_OPUS, PRIORITY_HIGH,
                false);
    }

@@ -255,27 +259,33 @@ public class A2dpCodecConfigTest {
    public void testSetCodecPreference_priorityDefaultToRaiseHigh() {
        testCodecPriorityChangeHelper(
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH,
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3, LC3_PRIORITY_DEFAULT,
                // TODO(b/240635097): update in U
                SOURCE_CODEC_TYPE_OPUS, OPUS_PRIORITY_DEFAULT,
                true);
        testCodecPriorityChangeHelper(
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH,
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3, LC3_PRIORITY_DEFAULT,
                // TODO(b/240635097): update in U
                SOURCE_CODEC_TYPE_OPUS, OPUS_PRIORITY_DEFAULT,
                true);
        testCodecPriorityChangeHelper(
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, PRIORITY_HIGH,
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3, LC3_PRIORITY_DEFAULT,
                // TODO(b/240635097): update in U
                SOURCE_CODEC_TYPE_OPUS, OPUS_PRIORITY_DEFAULT,
                true);
        testCodecPriorityChangeHelper(
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, PRIORITY_HIGH,
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3, LC3_PRIORITY_DEFAULT,
                // TODO(b/240635097): update in U
                SOURCE_CODEC_TYPE_OPUS, OPUS_PRIORITY_DEFAULT,
                true);
        testCodecPriorityChangeHelper(
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, PRIORITY_HIGH,
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3, LC3_PRIORITY_DEFAULT,
                // TODO(b/240635097): update in U
                SOURCE_CODEC_TYPE_OPUS, OPUS_PRIORITY_DEFAULT,
                true);
        testCodecPriorityChangeHelper(
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3, PRIORITY_HIGH,
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3, LC3_PRIORITY_DEFAULT,
                // TODO(b/240635097): update in U
                SOURCE_CODEC_TYPE_OPUS, PRIORITY_HIGH,
                SOURCE_CODEC_TYPE_OPUS, OPUS_PRIORITY_DEFAULT,
                false);
    }

@@ -302,7 +312,8 @@ public class A2dpCodecConfigTest {
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH,
                true);
        testCodecPriorityChangeHelper(
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3, PRIORITY_HIGH,
                // TODO(b/240635097): update in U
                SOURCE_CODEC_TYPE_OPUS, PRIORITY_HIGH,
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH,
                true);
    }
@@ -330,7 +341,8 @@ public class A2dpCodecConfigTest {
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH,
                true);
        testCodecPriorityChangeHelper(
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3, PRIORITY_HIGH,
                // TODO(b/240635097): update in U
                SOURCE_CODEC_TYPE_OPUS, PRIORITY_HIGH,
                BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH,
                true);
    }
+33 −0
Original line number Diff line number Diff line
@@ -53,6 +53,9 @@ import java.util.Arrays;
@MediumTest
@RunWith(AndroidJUnit4.class)
public class A2dpStateMachineTest {
    // TODO(b/240635097): remove in U
    private static final int SOURCE_CODEC_TYPE_OPUS = 6;

    private BluetoothAdapter mAdapter;
    private Context mTargetContext;
    private HandlerThread mHandlerThread;
@@ -62,6 +65,7 @@ public class A2dpStateMachineTest {

    private BluetoothCodecConfig mCodecConfigSbc;
    private BluetoothCodecConfig mCodecConfigAac;
    private BluetoothCodecConfig mCodecConfigOpus;

    @Mock private AdapterService mAdapterService;
    @Mock private A2dpService mA2dpService;
@@ -103,6 +107,18 @@ public class A2dpStateMachineTest {
                    .setCodecSpecific4(0)
                    .build();

        mCodecConfigOpus = new BluetoothCodecConfig.Builder()
                    .setCodecType(SOURCE_CODEC_TYPE_OPUS) // TODO(b/240635097): update in U
                    .setCodecPriority(BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT)
                    .setSampleRate(BluetoothCodecConfig.SAMPLE_RATE_48000)
                    .setBitsPerSample(BluetoothCodecConfig.BITS_PER_SAMPLE_16)
                    .setChannelMode(BluetoothCodecConfig.CHANNEL_MODE_STEREO)
                    .setCodecSpecific1(0)
                    .setCodecSpecific2(0)
                    .setCodecSpecific3(0)
                    .setCodecSpecific4(0)
                    .build();

        // Set up thread and looper
        mHandlerThread = new HandlerThread("A2dpStateMachineTestHandlerThread");
        mHandlerThread.start();
@@ -326,12 +342,21 @@ public class A2dpStateMachineTest {
        codecsSelectableSbcAac[0] = mCodecConfigSbc;
        codecsSelectableSbcAac[1] = mCodecConfigAac;

        BluetoothCodecConfig[] codecsSelectableSbcAacOpus;
        codecsSelectableSbcAacOpus = new BluetoothCodecConfig[3];
        codecsSelectableSbcAacOpus[0] = mCodecConfigSbc;
        codecsSelectableSbcAacOpus[1] = mCodecConfigAac;
        codecsSelectableSbcAacOpus[2] = mCodecConfigOpus;

        BluetoothCodecStatus codecStatusSbcAndSbc = new BluetoothCodecStatus(mCodecConfigSbc,
                Arrays.asList(codecsSelectableSbcAac), Arrays.asList(codecsSelectableSbc));
        BluetoothCodecStatus codecStatusSbcAndSbcAac = new BluetoothCodecStatus(mCodecConfigSbc,
                Arrays.asList(codecsSelectableSbcAac), Arrays.asList(codecsSelectableSbcAac));
        BluetoothCodecStatus codecStatusAacAndSbcAac = new BluetoothCodecStatus(mCodecConfigAac,
                Arrays.asList(codecsSelectableSbcAac), Arrays.asList(codecsSelectableSbcAac));
        BluetoothCodecStatus codecStatusOpusAndSbcAacOpus = new BluetoothCodecStatus(
                mCodecConfigOpus, Arrays.asList(codecsSelectableSbcAacOpus),
                Arrays.asList(codecsSelectableSbcAacOpus));

        // Set default codec status when device disconnected
        // Selected codec = SBC, selectable codec = SBC
@@ -368,5 +393,13 @@ public class A2dpStateMachineTest {
        mA2dpStateMachine.processCodecConfigEvent(codecStatusAacAndSbcAac);
        verify(mA2dpService).codecConfigUpdated(mTestDevice, codecStatusAacAndSbcAac, false);
        verify(mA2dpService, times(2)).updateOptionalCodecsSupport(mTestDevice);

        // Update selected codec
        // Selected codec = OPUS, selectable codec = SBC+AAC+OPUS
        mA2dpStateMachine.processCodecConfigEvent(codecStatusOpusAndSbcAacOpus);
        if (!offloadEnabled) {
            verify(mA2dpService).codecConfigUpdated(mTestDevice, codecStatusOpusAndSbcAacOpus, true);
        }
        verify(mA2dpService, times(3)).updateOptionalCodecsSupport(mTestDevice);
    }
}
Loading