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

Commit 55f4be4d authored by Ugo Yu's avatar Ugo Yu
Browse files

Enable optional codec by default

* Set option codec support/enable status to unknown as their
  default value.
* When a remote Bluetooth device is connected A2DP with optional
  codec selection supported, we should default enable, we should
  enable this feature if the current enable state is unknown.
* Add unit test for this case.

Test: runtest bluetooth
Bug: 124254557
Change-Id: Idc682cd197295c792a45dd0ab2f286d89093e09c
parent d24fd2d4
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -1013,10 +1013,17 @@ public class A2dpService extends ProfileService {
        }
        if (supportsOptional) {
            int enabled = getOptionalCodecsEnabled(device);
            if (enabled == BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED) {
            switch (enabled) {
                case BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN:
                    // Enable optional codec by default.
                    setOptionalCodecsEnabled(device, BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED);
                    // Fall through intended
                case BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED:
                    enableOptionalCodecs(device);
            } else if (enabled == BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED) {
                    break;
                case BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED:
                    disableOptionalCodecs(device);
                    break;
            }
        }
    }
+4 −4
Original line number Diff line number Diff line
@@ -411,14 +411,14 @@ public class DatabaseManager {
        synchronized (mMetadataCache) {
            if (device == null) {
                Log.e(TAG, "setA2dpOptionalCodec: device is null");
                return BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED;
                return BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN;
            }

            String address = device.getAddress();

            if (!mMetadataCache.containsKey(address)) {
                Log.e(TAG, "getA2dpOptionalCodec: device " + address + " is not in cache");
                return BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED;
                return BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN;
            }

            Metadata data = mMetadataCache.get(address);
@@ -479,14 +479,14 @@ public class DatabaseManager {
        synchronized (mMetadataCache) {
            if (device == null) {
                Log.e(TAG, "getA2dpOptionalCodecEnabled: device is null");
                return BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED;
                return BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN;
            }

            String address = device.getAddress();

            if (!mMetadataCache.containsKey(address)) {
                Log.e(TAG, "getA2dpOptionalCodecEnabled: device " + address + " is not in cache");
                return BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED;
                return BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN;
            }

            Metadata data = mMetadataCache.get(address);
+2 −2
Original line number Diff line number Diff line
@@ -51,8 +51,8 @@ class Metadata {
        migrated = false;
        profilePriorites = new ProfilePrioritiesEntity();
        publicMetadata = new CustomizedMetadataEntity();
        a2dpSupportsOptionalCodecs = BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED;
        a2dpOptionalCodecsEnabled = BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED;
        a2dpSupportsOptionalCodecs = BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN;
        a2dpOptionalCodecsEnabled = BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN;
    }

    String getAddress() {
+167 −0
Original line number Diff line number Diff line
@@ -807,7 +807,98 @@ public class A2dpServiceTest {
        Assert.assertEquals(mTestDevice, mA2dpService.getActiveDevice());
    }

    /**
     * Test that whether updateOptionalCodecsSupport() method is working as intended
     * when a Bluetooth device is connected with A2DP.
     */
    @Test
    public void testUpdateOptionalCodecsSupport() {
        int verifySupportTime = 0;
        int verifyNotSupportTime = 0;
        int verifyEnabledTime = 0;
        // Test for device supports optional codec
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, true,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN,
                ++verifySupportTime, verifyNotSupportTime, ++verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, true,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED,
                ++verifySupportTime, verifyNotSupportTime, verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, true,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED,
                ++verifySupportTime, verifyNotSupportTime, verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, true,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN,
                verifySupportTime, verifyNotSupportTime, ++verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, true,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED,
                verifySupportTime, verifyNotSupportTime, verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, true,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED,
                verifySupportTime, verifyNotSupportTime, verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, true,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN,
                ++verifySupportTime, verifyNotSupportTime, ++verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, true,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED,
                ++verifySupportTime, verifyNotSupportTime, verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, true,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED,
                ++verifySupportTime, verifyNotSupportTime, verifyEnabledTime);

        // Test for device not supports optional codec
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, false,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN,
                verifySupportTime, ++verifyNotSupportTime, verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, false,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED,
                verifySupportTime, ++verifyNotSupportTime, verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN, false,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED,
                verifySupportTime, ++verifyNotSupportTime, verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, false,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN,
                verifySupportTime, ++verifyNotSupportTime, verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, false,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED,
                verifySupportTime, ++verifyNotSupportTime, verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED, false,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED,
                verifySupportTime, ++verifyNotSupportTime, verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, false,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN,
                verifySupportTime, verifyNotSupportTime, verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, false,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED,
                verifySupportTime, verifyNotSupportTime, verifyEnabledTime);
        testUpdateOptionalCodecsSupportCase(
                BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED, false,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED,
                verifySupportTime, verifyNotSupportTime, verifyEnabledTime);
    }

    private void connectDevice(BluetoothDevice device) {
        connectDeviceWithCodecStatus(device, null);
    }

    private void connectDeviceWithCodecStatus(BluetoothDevice device,
            BluetoothCodecStatus codecStatus) {
        A2dpStackEvent connCompletedEvent;

        List<BluetoothDevice> prevConnectedDevices = mA2dpService.getConnectedDevices();
@@ -818,6 +909,8 @@ public class A2dpServiceTest {
                .thenReturn(BluetoothProfile.PRIORITY_ON);
        doReturn(true).when(mA2dpNativeInterface).connectA2dp(device);
        doReturn(true).when(mA2dpNativeInterface).disconnectA2dp(device);
        doReturn(true).when(mA2dpNativeInterface).setCodecConfigPreference(
                any(BluetoothDevice.class), any(BluetoothCodecConfig[].class));

        // Send a connect request
        Assert.assertTrue("Connect failed", mA2dpService.connect(device));
@@ -828,6 +921,10 @@ public class A2dpServiceTest {
        Assert.assertEquals(BluetoothProfile.STATE_CONNECTING,
                            mA2dpService.getConnectionState(device));

        if (codecStatus != null) {
            generateCodecMessageFromNative(device, codecStatus);
        }

        // Send a message to trigger connection completed
        connCompletedEvent = new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CONNECTION_STATE_CHANGED);
        connCompletedEvent.device = device;
@@ -943,4 +1040,74 @@ public class A2dpServiceTest {
        Assert.assertEquals(expected, mA2dpService.okToConnect(device, true));  // Outgoing
        Assert.assertEquals(false, mA2dpService.okToConnect(device, false)); // Incoming
    }

    /**
     * Helper function to test updateOptionalCodecsSupport() method
     *
     * @param previousSupport previous optional codec support status
     * @param support new optional codec support status
     * @param previousEnabled previous optional codec enable status
     * @param verifySupportTime verify times of optional codec set to support
     * @param verifyNotSupportTime verify times of optional codec set to not support
     * @param verifyEnabledTime verify times of optional codec set to enabled
     */
    private void testUpdateOptionalCodecsSupportCase(int previousSupport, boolean support,
            int previousEnabled, int verifySupportTime, int verifyNotSupportTime,
            int verifyEnabledTime) {
        when(mAdapterService.getDatabase()).thenReturn(mDatabaseManager);
        doReturn(true).when(mA2dpNativeInterface).setActiveDevice(any(BluetoothDevice.class));

        BluetoothCodecConfig codecConfigSbc =
                new BluetoothCodecConfig(
                        BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
                        BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
                        BluetoothCodecConfig.SAMPLE_RATE_44100,
                        BluetoothCodecConfig.BITS_PER_SAMPLE_16,
                        BluetoothCodecConfig.CHANNEL_MODE_STEREO,
                        0, 0, 0, 0);       // Codec-specific fields
        BluetoothCodecConfig codecConfigAac =
                new BluetoothCodecConfig(
                        BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
                        BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT,
                        BluetoothCodecConfig.SAMPLE_RATE_44100,
                        BluetoothCodecConfig.BITS_PER_SAMPLE_16,
                        BluetoothCodecConfig.CHANNEL_MODE_STEREO,
                        0, 0, 0, 0);       // Codec-specific fields
        BluetoothCodecConfig codecConfig = codecConfigSbc;

        BluetoothCodecConfig[] codecsLocalCapabilities;
        BluetoothCodecConfig[] codecsSelectableCapabilities;
        if (support) {
            codecsLocalCapabilities = new BluetoothCodecConfig[2];
            codecsSelectableCapabilities = new BluetoothCodecConfig[2];
            codecsLocalCapabilities[0] = codecConfigSbc;
            codecsLocalCapabilities[1] = codecConfigAac;
            codecsSelectableCapabilities[0] = codecConfigSbc;
            codecsSelectableCapabilities[1] = codecConfigAac;
        } else {
            codecsLocalCapabilities = new BluetoothCodecConfig[1];
            codecsSelectableCapabilities = new BluetoothCodecConfig[1];
            codecsLocalCapabilities[0] = codecConfigSbc;
            codecsSelectableCapabilities[0] = codecConfigSbc;
        }
        BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(codecConfig,
                                                                    codecsLocalCapabilities,
                                                                    codecsSelectableCapabilities);

        when(mDatabaseManager.getA2dpSupportsOptionalCodecs(mTestDevice))
                .thenReturn(previousSupport);
        when(mDatabaseManager.getA2dpOptionalCodecsEnabled(mTestDevice))
                .thenReturn(previousEnabled);
        connectDeviceWithCodecStatus(mTestDevice, codecStatus);

        verify(mDatabaseManager, times(verifyNotSupportTime)).setA2dpSupportsOptionalCodecs(
                mTestDevice, BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
        verify(mDatabaseManager, times(verifySupportTime)).setA2dpSupportsOptionalCodecs(
                mTestDevice, BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
        verify(mDatabaseManager, times(verifyEnabledTime)).setA2dpOptionalCodecsEnabled(
                mTestDevice, BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED);

        generateConnectionMessageFromNative(mTestDevice, BluetoothProfile.STATE_DISCONNECTED,
                                            BluetoothProfile.STATE_CONNECTED);
    }
}
+12 −12
Original line number Diff line number Diff line
@@ -98,10 +98,10 @@ public final class DatabaseManagerTest {
                    mDatabaseManager.getProfilePriority(mTestDevice, id));
        }

        Assert.assertEquals(BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED,
        Assert.assertEquals(BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN,
                mDatabaseManager.getA2dpSupportsOptionalCodecs(mTestDevice));

        Assert.assertEquals(BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED,
        Assert.assertEquals(BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN,
                    mDatabaseManager.getA2dpOptionalCodecsEnabled(mTestDevice));

        for (int id = 0; id < MAX_META_ID; id++) {
@@ -145,15 +145,15 @@ public final class DatabaseManagerTest {
        // Cases of device not in database
        testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, false,
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN,
                BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN);
        testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, false,
                BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED,
                BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN);
        testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, false,
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED,
                BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN);
        testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, false,
                badValue, BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
                badValue, BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN);

        // Cases of device already in database
        testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, true,
@@ -166,7 +166,7 @@ public final class DatabaseManagerTest {
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED,
                BluetoothA2dp.OPTIONAL_CODECS_SUPPORTED);
        testSetGetA2dpOptionalCodecsCase(A2DP_SUPPORT_OP_CODEC_TEST, true,
                badValue, BluetoothA2dp.OPTIONAL_CODECS_NOT_SUPPORTED);
                badValue, BluetoothA2dp.OPTIONAL_CODECS_SUPPORT_UNKNOWN);
    }

    @Test
@@ -176,15 +176,15 @@ public final class DatabaseManagerTest {
        // Cases of device not in database
        testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, false,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED);
                BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN);
        testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, false,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED);
                BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN);
        testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, false,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED);
                BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN);
        testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, false,
                badValue, BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED);
                badValue, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN);

        // Cases of device already in database
        testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, true,
@@ -197,7 +197,7 @@ public final class DatabaseManagerTest {
                BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED,
                BluetoothA2dp.OPTIONAL_CODECS_PREF_ENABLED);
        testSetGetA2dpOptionalCodecsCase(A2DP_ENALBED_OP_CODEC_TEST, true,
                badValue, BluetoothA2dp.OPTIONAL_CODECS_PREF_DISABLED);
                badValue, BluetoothA2dp.OPTIONAL_CODECS_PREF_UNKNOWN);
    }

    @Test