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

Commit 7c58336d authored by Łukasz Rymanowski's avatar Łukasz Rymanowski
Browse files

LeAudioService: Fix behaviour of getCodecStatus

With this patch we make sure that if INVALID_CODEC codec is provided by
native it is not on the SelectableCodecConfig list and also not used as
and mInputCodecConfig and mOutputCodecConfig.

With this patch if e.g. for current configuration does not support
input, then getCodecStatus.getInputCodecConfig() will return null.

If user wants to know if given direction is supported by the remote
device, he can use getInputCodecSelectableCapabilities() and
getOutputCodecSelectableCapabilities(), and if it is non empty, it means
direction is supported

Bug: 314094343
Test: atest LeAudioServiceTest
Flag: Exempt, regressions test with unit tests, new test added
Change-Id: Iee754b51779d778d1b8e557e0698ea8d385f1372
parent cebb0e7a
Loading
Loading
Loading
Loading
+16 −4
Original line number Diff line number Diff line
@@ -2807,8 +2807,14 @@ public class LeAudioService extends ProfileService {
                return;
            }

            descriptor.mInputSelectableConfig = stackEvent.valueCodecList1;
            descriptor.mOutputSelectableConfig = stackEvent.valueCodecList2;
            descriptor.mInputSelectableConfig = new ArrayList<>(stackEvent.valueCodecList1);
            descriptor.mOutputSelectableConfig = new ArrayList<>(stackEvent.valueCodecList2);

            BluetoothLeAudioCodecConfig emptyConfig =
                    new BluetoothLeAudioCodecConfig.Builder().build();

            descriptor.mInputSelectableConfig.removeIf(n -> n.equals(emptyConfig));
            descriptor.mOutputSelectableConfig.removeIf(n -> n.equals(emptyConfig));

        } else if (stackEvent.type
                == LeAudioStackEvent.EVENT_TYPE_AUDIO_GROUP_CURRENT_CODEC_CONFIG_CHANGED) {
@@ -2818,11 +2824,17 @@ public class LeAudioService extends ProfileService {
                Log.e(TAG, " Group not found " + groupId);
                return;
            }
            BluetoothLeAudioCodecConfig emptyConfig =
                    new BluetoothLeAudioCodecConfig.Builder().build();

            BluetoothLeAudioCodecStatus status =
                    new BluetoothLeAudioCodecStatus(
                            stackEvent.valueCodec1,
                            stackEvent.valueCodec2,
                            (stackEvent.valueCodec1.equals(emptyConfig)
                                    ? null
                                    : stackEvent.valueCodec1),
                            (stackEvent.valueCodec2.equals(emptyConfig)
                                    ? null
                                    : stackEvent.valueCodec2),
                            mInputLocalCodecCapabilities,
                            mOutputLocalCodecCapabilities,
                            descriptor.mInputSelectableConfig,
+63 −0
Original line number Diff line number Diff line
@@ -138,6 +138,9 @@ public class LeAudioServiceTest {
    @Spy private LeAudioObjectsFactory mObjectsFactory = LeAudioObjectsFactory.getInstance();
    @Spy private ServiceFactory mServiceFactory = new ServiceFactory();

    private static final BluetoothLeAudioCodecConfig EMPTY_CONFIG =
            new BluetoothLeAudioCodecConfig.Builder().build();

    private static final BluetoothLeAudioCodecConfig LC3_16KHZ_CONFIG =
            new BluetoothLeAudioCodecConfig.Builder()
                .setCodecType(BluetoothLeAudioCodecConfig.SOURCE_CODEC_TYPE_LC3)
@@ -165,6 +168,9 @@ public class LeAudioServiceTest {
    private static final List<BluetoothLeAudioCodecConfig> INPUT_SELECTABLE_CONFIG = List.of(
            LC3_16KHZ_CONFIG);

    private static final List<BluetoothLeAudioCodecConfig> INPUT_EMPTY_CONFIG =
            List.of(EMPTY_CONFIG);

    private static final List<BluetoothLeAudioCodecConfig> OUTPUT_SELECTABLE_CONFIG = List.of(
            LC3_48KHZ_16KHZ_CONFIG);

@@ -2046,6 +2052,63 @@ public class LeAudioServiceTest {
        mService.mLeAudioCallbacks.unregister(leAudioCallbacks);
    }

    /** Test native interface group status message handling */
    @Test
    public void testMessageFromNativeGroupCodecConfigChanged_OneDirectionOnly() {
        onGroupCodecConfChangedCallbackCalled = false;

        injectLocalCodecConfigCapaChanged(INPUT_CAPABILITIES_CONFIG, OUTPUT_CAPABILITIES_CONFIG);

        doReturn(true).when(mNativeInterface).connectLeAudio(any(BluetoothDevice.class));
        connectTestDevice(mSingleDevice, testGroupId);

        testCodecStatus =
                new BluetoothLeAudioCodecStatus(
                        null,
                        LC3_48KHZ_CONFIG,
                        INPUT_CAPABILITIES_CONFIG,
                        OUTPUT_CAPABILITIES_CONFIG,
                        new ArrayList<>(),
                        OUTPUT_SELECTABLE_CONFIG);

        IBluetoothLeAudioCallback leAudioCallbacks =
                new IBluetoothLeAudioCallback.Stub() {
                    @Override
                    public void onCodecConfigChanged(int gid, BluetoothLeAudioCodecStatus status) {
                        onGroupCodecConfChangedCallbackCalled = true;
                        assertThat(status.equals(testCodecStatus)).isTrue();
                    }

                    @Override
                    public void onGroupStatusChanged(int gid, int gStatus) {}

                    @Override
                    public void onGroupNodeAdded(BluetoothDevice device, int gid) {}

                    @Override
                    public void onGroupNodeRemoved(BluetoothDevice device, int gid) {}

                    @Override
                    public void onGroupStreamStatusChanged(int groupId, int groupStreamStatus) {}
                };

        mService.mLeAudioCallbacks.register(leAudioCallbacks);

        injectGroupSelectableCodecConfigChanged(
                testGroupId, INPUT_EMPTY_CONFIG, OUTPUT_SELECTABLE_CONFIG);
        injectGroupCurrentCodecConfigChanged(testGroupId, EMPTY_CONFIG, LC3_48KHZ_CONFIG);

        TestUtils.waitForLooperToFinishScheduledTask(mService.getMainLooper());
        assertThat(onGroupCodecConfChangedCallbackCalled).isTrue();

        onGroupCodecConfChangedCallbackCalled = false;
        mService.mLeAudioCallbacks.unregister(leAudioCallbacks);

        BluetoothLeAudioCodecStatus codecStatus = mService.getCodecStatus(testGroupId);
        assertThat(codecStatus.getInputCodecConfig()).isNull();
        assertThat(codecStatus.getOutputCodecConfig()).isNotNull();
    }

    private void verifyActiveDeviceStateIntent(int timeoutMs, BluetoothDevice device) {
        Intent intent = TestUtils.waitForIntent(timeoutMs, mDeviceQueueMap.get(device));
        assertThat(intent).isNotNull();