Loading android/app/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java +25 −30 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ import android.util.Log; import com.android.bluetooth.R; import java.util.Arrays; import java.util.List; import java.util.Objects; /* * A2DP Codec Configuration setup. Loading Loading @@ -82,8 +82,8 @@ class A2dpCodecConfig { Objects.requireNonNull(codecStatus); // Check whether the codecConfig is selectable for this Bluetooth device. BluetoothCodecConfig[] selectableCodecs = codecStatus.getCodecsSelectableCapabilities(); if (!Arrays.asList(selectableCodecs).stream().anyMatch(codec -> List<BluetoothCodecConfig> selectableCodecs = codecStatus.getCodecsSelectableCapabilities(); if (!selectableCodecs.stream().anyMatch(codec -> codec.isMandatoryCodec())) { // Do not set codec preference to native if the selectableCodecs not contain mandatory // codec. The reason could be remote codec negotiation is not completed yet. Loading Loading @@ -160,7 +160,7 @@ class A2dpCodecConfig { // Get the codec type of the highest priority of selectableCodecs and codecConfig. private int getPrioitizedCodecType(BluetoothCodecConfig codecConfig, BluetoothCodecConfig[] selectableCodecs) { List<BluetoothCodecConfig> selectableCodecs) { BluetoothCodecConfig prioritizedCodecConfig = codecConfig; for (BluetoothCodecConfig config : selectableCodecs) { if (prioritizedCodecConfig == null) { Loading Loading @@ -233,36 +233,31 @@ class A2dpCodecConfig { BluetoothCodecConfig codecConfig; BluetoothCodecConfig[] codecConfigArray = new BluetoothCodecConfig[BluetoothCodecConfig.SOURCE_CODEC_TYPE_MAX]; codecConfig = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, mA2dpSourceCodecPrioritySbc, BluetoothCodecConfig.SAMPLE_RATE_NONE, BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, BluetoothCodecConfig .CHANNEL_MODE_NONE, 0 /* codecSpecific1 */, 0 /* codecSpecific2 */, 0 /* codecSpecific3 */, 0 /* codecSpecific4 */); new BluetoothCodecConfig[BluetoothCodecConfig.getMaxCodecType()]; codecConfig = new BluetoothCodecConfig.Builder() .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC) .setCodecPriority(mA2dpSourceCodecPrioritySbc) .build(); codecConfigArray[0] = codecConfig; codecConfig = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, mA2dpSourceCodecPriorityAac, BluetoothCodecConfig.SAMPLE_RATE_NONE, BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, BluetoothCodecConfig .CHANNEL_MODE_NONE, 0 /* codecSpecific1 */, 0 /* codecSpecific2 */, 0 /* codecSpecific3 */, 0 /* codecSpecific4 */); codecConfig = new BluetoothCodecConfig.Builder() .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC) .setCodecPriority(mA2dpSourceCodecPriorityAac) .build(); codecConfigArray[1] = codecConfig; codecConfig = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, mA2dpSourceCodecPriorityAptx, BluetoothCodecConfig.SAMPLE_RATE_NONE, BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, BluetoothCodecConfig .CHANNEL_MODE_NONE, 0 /* codecSpecific1 */, 0 /* codecSpecific2 */, 0 /* codecSpecific3 */, 0 /* codecSpecific4 */); codecConfig = new BluetoothCodecConfig.Builder() .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX) .setCodecPriority(mA2dpSourceCodecPriorityAptx) .build(); codecConfigArray[2] = codecConfig; codecConfig = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, mA2dpSourceCodecPriorityAptxHd, BluetoothCodecConfig.SAMPLE_RATE_NONE, BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, BluetoothCodecConfig .CHANNEL_MODE_NONE, 0 /* codecSpecific1 */, 0 /* codecSpecific2 */, 0 /* codecSpecific3 */, 0 /* codecSpecific4 */); codecConfig = new BluetoothCodecConfig.Builder() .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD) .setCodecPriority(mA2dpSourceCodecPriorityAptxHd) .build(); codecConfigArray[3] = codecConfig; codecConfig = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, mA2dpSourceCodecPriorityLdac, BluetoothCodecConfig.SAMPLE_RATE_NONE, BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, BluetoothCodecConfig .CHANNEL_MODE_NONE, 0 /* codecSpecific1 */, 0 /* codecSpecific2 */, 0 /* codecSpecific3 */, 0 /* codecSpecific4 */); codecConfig = new BluetoothCodecConfig.Builder() .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC) .setCodecPriority(mA2dpSourceCodecPriorityLdac) .build(); codecConfigArray[4] = codecConfig; return codecConfigArray; Loading android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java +4 −3 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ */ package com.android.bluetooth.a2dp; import android.annotation.RequiresPermission; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothCodecConfig; Loading @@ -33,6 +32,8 @@ import com.android.bluetooth.Utils; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import java.util.Arrays; /** * A2DP Native Interface to/from JNI. */ Loading Loading @@ -197,8 +198,8 @@ public class A2dpNativeInterface { A2dpStackEvent event = new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CODEC_CONFIG_CHANGED); event.device = getDevice(address); event.codecStatus = new BluetoothCodecStatus(newCodecConfig, codecsLocalCapabilities, codecsSelectableCapabilities); Arrays.asList(codecsLocalCapabilities), Arrays.asList(codecsSelectableCapabilities)); if (DBG) { Log.d(TAG, "onCodecConfigChanged: " + event); } Loading android/app/src/com/android/bluetooth/a2dp/A2dpService.java +2 −1 Original line number Diff line number Diff line Loading @@ -948,7 +948,8 @@ public class A2dpService extends ProfileService { codecConfig.getBitsPerSample(), codecConfig.getChannelMode(), codecConfig.getCodecSpecific1(), codecConfig.getCodecSpecific2(), codecConfig.getCodecSpecific3(), codecConfig.getCodecSpecific4(), metricId); BluetoothCodecConfig[] codecCapabilities = codecStatus.getCodecsSelectableCapabilities(); List<BluetoothCodecConfig> codecCapabilities = codecStatus.getCodecsSelectableCapabilities(); for (BluetoothCodecConfig codecCapability : codecCapabilities) { BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED, mAdapterService.obfuscateAddress(device), codecCapability.getCodecType(), Loading android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java +14 −4 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ import com.android.internal.util.StateMachine; import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; import java.util.Objects; import java.util.Scanner; Loading Loading @@ -716,12 +717,21 @@ final class A2dpStateMachine extends StateMachine { private static boolean sameSelectableCodec(BluetoothCodecStatus prevCodecStatus, BluetoothCodecStatus newCodecStatus) { if (prevCodecStatus == null) { if (prevCodecStatus == null || newCodecStatus == null) { return false; } return BluetoothCodecStatus.sameCapabilities( prevCodecStatus.getCodecsSelectableCapabilities(), newCodecStatus.getCodecsSelectableCapabilities()); List<BluetoothCodecConfig> c1 = prevCodecStatus.getCodecsSelectableCapabilities(); List<BluetoothCodecConfig> c2 = newCodecStatus.getCodecsSelectableCapabilities(); if (c1 == null) { return (c2 == null); } if (c2 == null) { return false; } if (c1.size() != c2.size()) { return false; } return c1.containsAll(c2); } private static String messageWhatToString(int what) { Loading android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpCodecConfigTest.java +60 −36 Original line number Diff line number Diff line Loading @@ -39,6 +39,8 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.Arrays; @MediumTest @RunWith(AndroidJUnit4.class) public class A2dpCodecConfigTest { Loading Loading @@ -66,34 +68,34 @@ public class A2dpCodecConfigTest { private static final int PRIORITY_HIGH = 1000000; private static final BluetoothCodecConfig[] sCodecCapabilities = new BluetoothCodecConfig[] { new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, SBC_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_44100, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_MONO | BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, AAC_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_44100, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, APTX_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_44100 | BluetoothCodecConfig.SAMPLE_RATE_48000, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, APTX_HD_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_44100 | BluetoothCodecConfig.SAMPLE_RATE_48000, BluetoothCodecConfig.BITS_PER_SAMPLE_24, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, LDAC_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_44100 | BluetoothCodecConfig.SAMPLE_RATE_48000 Loading @@ -107,31 +109,31 @@ public class A2dpCodecConfigTest { }; private static final BluetoothCodecConfig[] sDefaultCodecConfigs = new BluetoothCodecConfig[] { new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, SBC_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_44100, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, AAC_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_44100, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, APTX_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_48000, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, APTX_HD_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_48000, BluetoothCodecConfig.BITS_PER_SAMPLE_24, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, LDAC_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_96000, BluetoothCodecConfig.BITS_PER_SAMPLE_32, Loading Loading @@ -568,8 +570,8 @@ public class A2dpCodecConfigTest { @Test public void testDisableOptionalCodecs() { BluetoothCodecConfig[] codecConfigsArray = new BluetoothCodecConfig[BluetoothCodecConfig.SOURCE_CODEC_TYPE_MAX]; codecConfigsArray[0] = new BluetoothCodecConfig( new BluetoothCodecConfig[BluetoothCodecConfig.getMaxCodecType()]; codecConfigsArray[0] = buildBluetoothCodecConfig( BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST, BluetoothCodecConfig.SAMPLE_RATE_NONE, Loading Loading @@ -601,8 +603,8 @@ public class A2dpCodecConfigTest { @Test public void testEnableOptionalCodecs() { BluetoothCodecConfig[] codecConfigsArray = new BluetoothCodecConfig[BluetoothCodecConfig.SOURCE_CODEC_TYPE_MAX]; codecConfigsArray[0] = new BluetoothCodecConfig( new BluetoothCodecConfig[BluetoothCodecConfig.getMaxCodecType()]; codecConfigsArray[0] = buildBluetoothCodecConfig( BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, SBC_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_NONE, Loading Loading @@ -634,7 +636,7 @@ public class A2dpCodecConfigTest { if (codecConfig.getCodecType() != codecType) { continue; } return new BluetoothCodecConfig( return buildBluetoothCodecConfig( codecConfig.getCodecType(), (codecPriority != BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT ? codecPriority : codecConfig.getCodecPriority()), Loading @@ -653,7 +655,7 @@ public class A2dpCodecConfigTest { if (codecCapabilities.getCodecType() != codecType) { continue; } return new BluetoothCodecConfig( return buildBluetoothCodecConfig( codecCapabilities.getCodecType(), codecCapabilities.getCodecPriority(), codecCapabilities.getSampleRate(), codecCapabilities.getBitsPerSample(), codecCapabilities.getChannelMode(), codecCapabilities.getCodecSpecific1(), Loading @@ -670,7 +672,7 @@ public class A2dpCodecConfigTest { BluetoothCodecConfig oldCodecConfig = getDefaultCodecConfigByType(oldCodecType, PRIORITY_HIGH); BluetoothCodecConfig[] newCodecConfigsArray = new BluetoothCodecConfig[] { new BluetoothCodecConfig(newCodecType, buildBluetoothCodecConfig(newCodecType, PRIORITY_HIGH, sampleRate, bitsPerSample, channelMode, 0, 0, 0, 0) // Codec-specific fields Loading Loading @@ -699,8 +701,8 @@ public class A2dpCodecConfigTest { }; } BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, optionalCodecsArray); Arrays.asList(sCodecCapabilities), Arrays.asList(optionalCodecsArray)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading @@ -724,7 +726,9 @@ public class A2dpCodecConfigTest { // 2. mandatory + old + new codecs only BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, minimumCodecsArray); new BluetoothCodecStatus(oldCodecConfig, Arrays.asList(sCodecCapabilities), Arrays.asList(minimumCodecsArray)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading @@ -733,8 +737,8 @@ public class A2dpCodecConfigTest { // 3. all codecs were selectable codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, sCodecCapabilities); Arrays.asList(sCodecCapabilities), Arrays.asList(sCodecCapabilities)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading @@ -747,7 +751,7 @@ public class A2dpCodecConfigTest { BluetoothCodecConfig codecDefaultTemp = getDefaultCodecConfigByType(oldCodecType, PRIORITY_HIGH); BluetoothCodecConfig oldCodecConfig = new BluetoothCodecConfig(codecDefaultTemp.getCodecType(), buildBluetoothCodecConfig(codecDefaultTemp.getCodecType(), codecDefaultTemp.getCodecPriority(), codecDefaultTemp.getSampleRate(), codecDefaultTemp.getBitsPerSample(), Loading @@ -755,7 +759,7 @@ public class A2dpCodecConfigTest { oldCodecSpecific, 0, 0, 0); // Codec-specific fields codecDefaultTemp = getDefaultCodecConfigByType(newCodecType, PRIORITY_HIGH); BluetoothCodecConfig[] newCodecConfigsArray = new BluetoothCodecConfig[] { new BluetoothCodecConfig(codecDefaultTemp.getCodecType(), buildBluetoothCodecConfig(codecDefaultTemp.getCodecType(), codecDefaultTemp.getCodecPriority(), codecDefaultTemp.getSampleRate(), codecDefaultTemp.getBitsPerSample(), Loading @@ -763,8 +767,8 @@ public class A2dpCodecConfigTest { newCodecSpecific, 0, 0, 0) // Codec-specific fields }; BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, sCodecCapabilities); Arrays.asList(sCodecCapabilities), Arrays.asList(sCodecCapabilities)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading Loading @@ -792,8 +796,8 @@ public class A2dpCodecConfigTest { BluetoothCodecConfig[] poorCodecsArray = new BluetoothCodecConfig[] {getCodecCapabilitiesByType(oldCodecType)}; BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, poorCodecsArray); Arrays.asList(sCodecCapabilities), Arrays.asList(poorCodecsArray)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading @@ -813,8 +817,8 @@ public class A2dpCodecConfigTest { getCodecCapabilitiesByType(newCodecType) }; BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, poorCodecsArray); Arrays.asList(sCodecCapabilities), Arrays.asList(poorCodecsArray)); mA2dpCodecConfig.setCodecConfigPreference( mTestDevice, codecStatus, newCodecConfigsArray[0]); verify(mA2dpNativeInterface, times(0)) Loading @@ -826,8 +830,8 @@ public class A2dpCodecConfigTest { getCodecCapabilitiesByType(oldCodecType) }; codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, poorCodecsArray); Arrays.asList(sCodecCapabilities), Arrays.asList(poorCodecsArray)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading Loading @@ -857,7 +861,9 @@ public class A2dpCodecConfigTest { BluetoothCodecConfig[] poorCodecsArray = new BluetoothCodecConfig[] {getCodecCapabilitiesByType(oldCodecType)}; BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, poorCodecsArray); new BluetoothCodecStatus(oldCodecConfig, Arrays.asList(sCodecCapabilities), Arrays.asList(poorCodecsArray)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading @@ -880,7 +886,9 @@ public class A2dpCodecConfigTest { // 3. mandatory + old + new codecs only int invokedCounter = (isMinimumCodecsArraySelectable ? 1 : 0); BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, minimumCodecsArray); new BluetoothCodecStatus(oldCodecConfig, Arrays.asList(sCodecCapabilities), Arrays.asList(minimumCodecsArray)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading @@ -890,12 +898,28 @@ public class A2dpCodecConfigTest { // 4. all codecs were selectable invokedCounter += (shouldApplyWhenAllSelectable ? 1 : 0); codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, sCodecCapabilities); Arrays.asList(sCodecCapabilities), Arrays.asList(sCodecCapabilities)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); verify(mA2dpNativeInterface, times(invokedCounter)) .setCodecConfigPreference(mTestDevice, newCodecConfigsArray); } private static BluetoothCodecConfig buildBluetoothCodecConfig(int sourceCodecType, int codecPriority, int sampleRate, int bitsPerSample, int channelMode, long codecSpecific1, long codecSpecific2, long codecSpecific3, long codecSpecific4) { return new BluetoothCodecConfig.Builder() .setCodecType(sourceCodecType) .setCodecPriority(codecPriority) .setSampleRate(sampleRate) .setBitsPerSample(bitsPerSample) .setChannelMode(channelMode) .setCodecSpecific1(codecSpecific1) .setCodecSpecific2(codecSpecific2) .setCodecSpecific3(codecSpecific3) .setCodecSpecific4(codecSpecific4) .build(); } } Loading
android/app/src/com/android/bluetooth/a2dp/A2dpCodecConfig.java +25 −30 Original line number Diff line number Diff line Loading @@ -28,7 +28,7 @@ import android.util.Log; import com.android.bluetooth.R; import java.util.Arrays; import java.util.List; import java.util.Objects; /* * A2DP Codec Configuration setup. Loading Loading @@ -82,8 +82,8 @@ class A2dpCodecConfig { Objects.requireNonNull(codecStatus); // Check whether the codecConfig is selectable for this Bluetooth device. BluetoothCodecConfig[] selectableCodecs = codecStatus.getCodecsSelectableCapabilities(); if (!Arrays.asList(selectableCodecs).stream().anyMatch(codec -> List<BluetoothCodecConfig> selectableCodecs = codecStatus.getCodecsSelectableCapabilities(); if (!selectableCodecs.stream().anyMatch(codec -> codec.isMandatoryCodec())) { // Do not set codec preference to native if the selectableCodecs not contain mandatory // codec. The reason could be remote codec negotiation is not completed yet. Loading Loading @@ -160,7 +160,7 @@ class A2dpCodecConfig { // Get the codec type of the highest priority of selectableCodecs and codecConfig. private int getPrioitizedCodecType(BluetoothCodecConfig codecConfig, BluetoothCodecConfig[] selectableCodecs) { List<BluetoothCodecConfig> selectableCodecs) { BluetoothCodecConfig prioritizedCodecConfig = codecConfig; for (BluetoothCodecConfig config : selectableCodecs) { if (prioritizedCodecConfig == null) { Loading Loading @@ -233,36 +233,31 @@ class A2dpCodecConfig { BluetoothCodecConfig codecConfig; BluetoothCodecConfig[] codecConfigArray = new BluetoothCodecConfig[BluetoothCodecConfig.SOURCE_CODEC_TYPE_MAX]; codecConfig = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, mA2dpSourceCodecPrioritySbc, BluetoothCodecConfig.SAMPLE_RATE_NONE, BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, BluetoothCodecConfig .CHANNEL_MODE_NONE, 0 /* codecSpecific1 */, 0 /* codecSpecific2 */, 0 /* codecSpecific3 */, 0 /* codecSpecific4 */); new BluetoothCodecConfig[BluetoothCodecConfig.getMaxCodecType()]; codecConfig = new BluetoothCodecConfig.Builder() .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC) .setCodecPriority(mA2dpSourceCodecPrioritySbc) .build(); codecConfigArray[0] = codecConfig; codecConfig = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, mA2dpSourceCodecPriorityAac, BluetoothCodecConfig.SAMPLE_RATE_NONE, BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, BluetoothCodecConfig .CHANNEL_MODE_NONE, 0 /* codecSpecific1 */, 0 /* codecSpecific2 */, 0 /* codecSpecific3 */, 0 /* codecSpecific4 */); codecConfig = new BluetoothCodecConfig.Builder() .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC) .setCodecPriority(mA2dpSourceCodecPriorityAac) .build(); codecConfigArray[1] = codecConfig; codecConfig = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, mA2dpSourceCodecPriorityAptx, BluetoothCodecConfig.SAMPLE_RATE_NONE, BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, BluetoothCodecConfig .CHANNEL_MODE_NONE, 0 /* codecSpecific1 */, 0 /* codecSpecific2 */, 0 /* codecSpecific3 */, 0 /* codecSpecific4 */); codecConfig = new BluetoothCodecConfig.Builder() .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX) .setCodecPriority(mA2dpSourceCodecPriorityAptx) .build(); codecConfigArray[2] = codecConfig; codecConfig = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, mA2dpSourceCodecPriorityAptxHd, BluetoothCodecConfig.SAMPLE_RATE_NONE, BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, BluetoothCodecConfig .CHANNEL_MODE_NONE, 0 /* codecSpecific1 */, 0 /* codecSpecific2 */, 0 /* codecSpecific3 */, 0 /* codecSpecific4 */); codecConfig = new BluetoothCodecConfig.Builder() .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD) .setCodecPriority(mA2dpSourceCodecPriorityAptxHd) .build(); codecConfigArray[3] = codecConfig; codecConfig = new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, mA2dpSourceCodecPriorityLdac, BluetoothCodecConfig.SAMPLE_RATE_NONE, BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, BluetoothCodecConfig .CHANNEL_MODE_NONE, 0 /* codecSpecific1 */, 0 /* codecSpecific2 */, 0 /* codecSpecific3 */, 0 /* codecSpecific4 */); codecConfig = new BluetoothCodecConfig.Builder() .setCodecType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC) .setCodecPriority(mA2dpSourceCodecPriorityLdac) .build(); codecConfigArray[4] = codecConfig; return codecConfigArray; Loading
android/app/src/com/android/bluetooth/a2dp/A2dpNativeInterface.java +4 −3 Original line number Diff line number Diff line Loading @@ -21,7 +21,6 @@ */ package com.android.bluetooth.a2dp; import android.annotation.RequiresPermission; import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothCodecConfig; Loading @@ -33,6 +32,8 @@ import com.android.bluetooth.Utils; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import java.util.Arrays; /** * A2DP Native Interface to/from JNI. */ Loading Loading @@ -197,8 +198,8 @@ public class A2dpNativeInterface { A2dpStackEvent event = new A2dpStackEvent(A2dpStackEvent.EVENT_TYPE_CODEC_CONFIG_CHANGED); event.device = getDevice(address); event.codecStatus = new BluetoothCodecStatus(newCodecConfig, codecsLocalCapabilities, codecsSelectableCapabilities); Arrays.asList(codecsLocalCapabilities), Arrays.asList(codecsSelectableCapabilities)); if (DBG) { Log.d(TAG, "onCodecConfigChanged: " + event); } Loading
android/app/src/com/android/bluetooth/a2dp/A2dpService.java +2 −1 Original line number Diff line number Diff line Loading @@ -948,7 +948,8 @@ public class A2dpService extends ProfileService { codecConfig.getBitsPerSample(), codecConfig.getChannelMode(), codecConfig.getCodecSpecific1(), codecConfig.getCodecSpecific2(), codecConfig.getCodecSpecific3(), codecConfig.getCodecSpecific4(), metricId); BluetoothCodecConfig[] codecCapabilities = codecStatus.getCodecsSelectableCapabilities(); List<BluetoothCodecConfig> codecCapabilities = codecStatus.getCodecsSelectableCapabilities(); for (BluetoothCodecConfig codecCapability : codecCapabilities) { BluetoothStatsLog.write(BluetoothStatsLog.BLUETOOTH_A2DP_CODEC_CAPABILITY_CHANGED, mAdapterService.obfuscateAddress(device), codecCapability.getCodecType(), Loading
android/app/src/com/android/bluetooth/a2dp/A2dpStateMachine.java +14 −4 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ import com.android.internal.util.StateMachine; import java.io.FileDescriptor; import java.io.PrintWriter; import java.io.StringWriter; import java.util.List; import java.util.Objects; import java.util.Scanner; Loading Loading @@ -716,12 +717,21 @@ final class A2dpStateMachine extends StateMachine { private static boolean sameSelectableCodec(BluetoothCodecStatus prevCodecStatus, BluetoothCodecStatus newCodecStatus) { if (prevCodecStatus == null) { if (prevCodecStatus == null || newCodecStatus == null) { return false; } return BluetoothCodecStatus.sameCapabilities( prevCodecStatus.getCodecsSelectableCapabilities(), newCodecStatus.getCodecsSelectableCapabilities()); List<BluetoothCodecConfig> c1 = prevCodecStatus.getCodecsSelectableCapabilities(); List<BluetoothCodecConfig> c2 = newCodecStatus.getCodecsSelectableCapabilities(); if (c1 == null) { return (c2 == null); } if (c2 == null) { return false; } if (c1.size() != c2.size()) { return false; } return c1.containsAll(c2); } private static String messageWhatToString(int what) { Loading
android/app/tests/unit/src/com/android/bluetooth/a2dp/A2dpCodecConfigTest.java +60 −36 Original line number Diff line number Diff line Loading @@ -39,6 +39,8 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import java.util.Arrays; @MediumTest @RunWith(AndroidJUnit4.class) public class A2dpCodecConfigTest { Loading Loading @@ -66,34 +68,34 @@ public class A2dpCodecConfigTest { private static final int PRIORITY_HIGH = 1000000; private static final BluetoothCodecConfig[] sCodecCapabilities = new BluetoothCodecConfig[] { new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, SBC_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_44100, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_MONO | BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, AAC_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_44100, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, APTX_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_44100 | BluetoothCodecConfig.SAMPLE_RATE_48000, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, APTX_HD_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_44100 | BluetoothCodecConfig.SAMPLE_RATE_48000, BluetoothCodecConfig.BITS_PER_SAMPLE_24, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, LDAC_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_44100 | BluetoothCodecConfig.SAMPLE_RATE_48000 Loading @@ -107,31 +109,31 @@ public class A2dpCodecConfigTest { }; private static final BluetoothCodecConfig[] sDefaultCodecConfigs = new BluetoothCodecConfig[] { new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, SBC_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_44100, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, AAC_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_44100, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, APTX_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_48000, BluetoothCodecConfig.BITS_PER_SAMPLE_16, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, APTX_HD_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_48000, BluetoothCodecConfig.BITS_PER_SAMPLE_24, BluetoothCodecConfig.CHANNEL_MODE_STEREO, 0, 0, 0, 0), // Codec-specific fields new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, buildBluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, LDAC_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_96000, BluetoothCodecConfig.BITS_PER_SAMPLE_32, Loading Loading @@ -568,8 +570,8 @@ public class A2dpCodecConfigTest { @Test public void testDisableOptionalCodecs() { BluetoothCodecConfig[] codecConfigsArray = new BluetoothCodecConfig[BluetoothCodecConfig.SOURCE_CODEC_TYPE_MAX]; codecConfigsArray[0] = new BluetoothCodecConfig( new BluetoothCodecConfig[BluetoothCodecConfig.getMaxCodecType()]; codecConfigsArray[0] = buildBluetoothCodecConfig( BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST, BluetoothCodecConfig.SAMPLE_RATE_NONE, Loading Loading @@ -601,8 +603,8 @@ public class A2dpCodecConfigTest { @Test public void testEnableOptionalCodecs() { BluetoothCodecConfig[] codecConfigsArray = new BluetoothCodecConfig[BluetoothCodecConfig.SOURCE_CODEC_TYPE_MAX]; codecConfigsArray[0] = new BluetoothCodecConfig( new BluetoothCodecConfig[BluetoothCodecConfig.getMaxCodecType()]; codecConfigsArray[0] = buildBluetoothCodecConfig( BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, SBC_PRIORITY_DEFAULT, BluetoothCodecConfig.SAMPLE_RATE_NONE, Loading Loading @@ -634,7 +636,7 @@ public class A2dpCodecConfigTest { if (codecConfig.getCodecType() != codecType) { continue; } return new BluetoothCodecConfig( return buildBluetoothCodecConfig( codecConfig.getCodecType(), (codecPriority != BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT ? codecPriority : codecConfig.getCodecPriority()), Loading @@ -653,7 +655,7 @@ public class A2dpCodecConfigTest { if (codecCapabilities.getCodecType() != codecType) { continue; } return new BluetoothCodecConfig( return buildBluetoothCodecConfig( codecCapabilities.getCodecType(), codecCapabilities.getCodecPriority(), codecCapabilities.getSampleRate(), codecCapabilities.getBitsPerSample(), codecCapabilities.getChannelMode(), codecCapabilities.getCodecSpecific1(), Loading @@ -670,7 +672,7 @@ public class A2dpCodecConfigTest { BluetoothCodecConfig oldCodecConfig = getDefaultCodecConfigByType(oldCodecType, PRIORITY_HIGH); BluetoothCodecConfig[] newCodecConfigsArray = new BluetoothCodecConfig[] { new BluetoothCodecConfig(newCodecType, buildBluetoothCodecConfig(newCodecType, PRIORITY_HIGH, sampleRate, bitsPerSample, channelMode, 0, 0, 0, 0) // Codec-specific fields Loading Loading @@ -699,8 +701,8 @@ public class A2dpCodecConfigTest { }; } BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, optionalCodecsArray); Arrays.asList(sCodecCapabilities), Arrays.asList(optionalCodecsArray)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading @@ -724,7 +726,9 @@ public class A2dpCodecConfigTest { // 2. mandatory + old + new codecs only BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, minimumCodecsArray); new BluetoothCodecStatus(oldCodecConfig, Arrays.asList(sCodecCapabilities), Arrays.asList(minimumCodecsArray)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading @@ -733,8 +737,8 @@ public class A2dpCodecConfigTest { // 3. all codecs were selectable codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, sCodecCapabilities); Arrays.asList(sCodecCapabilities), Arrays.asList(sCodecCapabilities)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading @@ -747,7 +751,7 @@ public class A2dpCodecConfigTest { BluetoothCodecConfig codecDefaultTemp = getDefaultCodecConfigByType(oldCodecType, PRIORITY_HIGH); BluetoothCodecConfig oldCodecConfig = new BluetoothCodecConfig(codecDefaultTemp.getCodecType(), buildBluetoothCodecConfig(codecDefaultTemp.getCodecType(), codecDefaultTemp.getCodecPriority(), codecDefaultTemp.getSampleRate(), codecDefaultTemp.getBitsPerSample(), Loading @@ -755,7 +759,7 @@ public class A2dpCodecConfigTest { oldCodecSpecific, 0, 0, 0); // Codec-specific fields codecDefaultTemp = getDefaultCodecConfigByType(newCodecType, PRIORITY_HIGH); BluetoothCodecConfig[] newCodecConfigsArray = new BluetoothCodecConfig[] { new BluetoothCodecConfig(codecDefaultTemp.getCodecType(), buildBluetoothCodecConfig(codecDefaultTemp.getCodecType(), codecDefaultTemp.getCodecPriority(), codecDefaultTemp.getSampleRate(), codecDefaultTemp.getBitsPerSample(), Loading @@ -763,8 +767,8 @@ public class A2dpCodecConfigTest { newCodecSpecific, 0, 0, 0) // Codec-specific fields }; BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, sCodecCapabilities); Arrays.asList(sCodecCapabilities), Arrays.asList(sCodecCapabilities)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading Loading @@ -792,8 +796,8 @@ public class A2dpCodecConfigTest { BluetoothCodecConfig[] poorCodecsArray = new BluetoothCodecConfig[] {getCodecCapabilitiesByType(oldCodecType)}; BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, poorCodecsArray); Arrays.asList(sCodecCapabilities), Arrays.asList(poorCodecsArray)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading @@ -813,8 +817,8 @@ public class A2dpCodecConfigTest { getCodecCapabilitiesByType(newCodecType) }; BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, poorCodecsArray); Arrays.asList(sCodecCapabilities), Arrays.asList(poorCodecsArray)); mA2dpCodecConfig.setCodecConfigPreference( mTestDevice, codecStatus, newCodecConfigsArray[0]); verify(mA2dpNativeInterface, times(0)) Loading @@ -826,8 +830,8 @@ public class A2dpCodecConfigTest { getCodecCapabilitiesByType(oldCodecType) }; codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, poorCodecsArray); Arrays.asList(sCodecCapabilities), Arrays.asList(poorCodecsArray)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading Loading @@ -857,7 +861,9 @@ public class A2dpCodecConfigTest { BluetoothCodecConfig[] poorCodecsArray = new BluetoothCodecConfig[] {getCodecCapabilitiesByType(oldCodecType)}; BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, poorCodecsArray); new BluetoothCodecStatus(oldCodecConfig, Arrays.asList(sCodecCapabilities), Arrays.asList(poorCodecsArray)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading @@ -880,7 +886,9 @@ public class A2dpCodecConfigTest { // 3. mandatory + old + new codecs only int invokedCounter = (isMinimumCodecsArraySelectable ? 1 : 0); BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, minimumCodecsArray); new BluetoothCodecStatus(oldCodecConfig, Arrays.asList(sCodecCapabilities), Arrays.asList(minimumCodecsArray)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); Loading @@ -890,12 +898,28 @@ public class A2dpCodecConfigTest { // 4. all codecs were selectable invokedCounter += (shouldApplyWhenAllSelectable ? 1 : 0); codecStatus = new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, sCodecCapabilities); Arrays.asList(sCodecCapabilities), Arrays.asList(sCodecCapabilities)); mA2dpCodecConfig.setCodecConfigPreference(mTestDevice, codecStatus, newCodecConfigsArray[0]); verify(mA2dpNativeInterface, times(invokedCounter)) .setCodecConfigPreference(mTestDevice, newCodecConfigsArray); } private static BluetoothCodecConfig buildBluetoothCodecConfig(int sourceCodecType, int codecPriority, int sampleRate, int bitsPerSample, int channelMode, long codecSpecific1, long codecSpecific2, long codecSpecific3, long codecSpecific4) { return new BluetoothCodecConfig.Builder() .setCodecType(sourceCodecType) .setCodecPriority(codecPriority) .setSampleRate(sampleRate) .setBitsPerSample(bitsPerSample) .setChannelMode(channelMode) .setCodecSpecific1(codecSpecific1) .setCodecSpecific2(codecSpecific2) .setCodecSpecific3(codecSpecific3) .setCodecSpecific4(codecSpecific4) .build(); } }