• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.bluetooth.a2dp;
18 
19 import static org.mockito.Mockito.*;
20 
21 import android.bluetooth.BluetoothAdapter;
22 import android.bluetooth.BluetoothCodecConfig;
23 import android.bluetooth.BluetoothCodecStatus;
24 import android.bluetooth.BluetoothDevice;
25 import android.content.Context;
26 import android.content.res.Resources;
27 
28 import androidx.test.InstrumentationRegistry;
29 import androidx.test.filters.MediumTest;
30 import androidx.test.runner.AndroidJUnit4;
31 
32 import com.android.bluetooth.R;
33 
34 import org.junit.After;
35 import org.junit.Assert;
36 import org.junit.Before;
37 import org.junit.Test;
38 import org.junit.runner.RunWith;
39 import org.mockito.Mock;
40 import org.mockito.MockitoAnnotations;
41 
42 @MediumTest
43 @RunWith(AndroidJUnit4.class)
44 public class A2dpCodecConfigTest {
45     private Context mTargetContext;
46     private BluetoothDevice mTestDevice;
47     private A2dpCodecConfig mA2dpCodecConfig;
48 
49     @Mock private Context mMockContext;
50     @Mock private Resources mMockResources;
51     @Mock private A2dpNativeInterface mA2dpNativeInterface;
52 
53     private static final int[] sOptionalCodecTypes = new int[] {
54             BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
55             BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX,
56             BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD,
57             BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC
58     };
59 
60     // Not use the default value to make sure it reads from config
61     private static final int SBC_PRIORITY_DEFAULT = 1001;
62     private static final int AAC_PRIORITY_DEFAULT = 3001;
63     private static final int APTX_PRIORITY_DEFAULT = 5001;
64     private static final int APTX_HD_PRIORITY_DEFAULT = 7001;
65     private static final int LDAC_PRIORITY_DEFAULT = 9001;
66     private static final int PRIORITY_HIGH = 1000000;
67 
68     private static final BluetoothCodecConfig[] sCodecCapabilities = new BluetoothCodecConfig[] {
69             new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
70                                      SBC_PRIORITY_DEFAULT,
71                                      BluetoothCodecConfig.SAMPLE_RATE_44100,
72                                      BluetoothCodecConfig.BITS_PER_SAMPLE_16,
73                                      BluetoothCodecConfig.CHANNEL_MODE_MONO
74                                      | BluetoothCodecConfig.CHANNEL_MODE_STEREO,
75                                      0, 0, 0, 0),       // Codec-specific fields
76             new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
77                                      AAC_PRIORITY_DEFAULT,
78                                      BluetoothCodecConfig.SAMPLE_RATE_44100,
79                                      BluetoothCodecConfig.BITS_PER_SAMPLE_16,
80                                      BluetoothCodecConfig.CHANNEL_MODE_STEREO,
81                                      0, 0, 0, 0),       // Codec-specific fields
82             new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX,
83                                      APTX_PRIORITY_DEFAULT,
84                                      BluetoothCodecConfig.SAMPLE_RATE_44100
85                                      | BluetoothCodecConfig.SAMPLE_RATE_48000,
86                                      BluetoothCodecConfig.BITS_PER_SAMPLE_16,
87                                      BluetoothCodecConfig.CHANNEL_MODE_STEREO,
88                                      0, 0, 0, 0),       // Codec-specific fields
89             new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD,
90                                      APTX_HD_PRIORITY_DEFAULT,
91                                      BluetoothCodecConfig.SAMPLE_RATE_44100
92                                      | BluetoothCodecConfig.SAMPLE_RATE_48000,
93                                      BluetoothCodecConfig.BITS_PER_SAMPLE_24,
94                                      BluetoothCodecConfig.CHANNEL_MODE_STEREO,
95                                      0, 0, 0, 0),       // Codec-specific fields
96             new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
97                                      LDAC_PRIORITY_DEFAULT,
98                                      BluetoothCodecConfig.SAMPLE_RATE_44100
99                                      | BluetoothCodecConfig.SAMPLE_RATE_48000
100                                      | BluetoothCodecConfig.SAMPLE_RATE_88200
101                                      | BluetoothCodecConfig.SAMPLE_RATE_96000,
102                                      BluetoothCodecConfig.BITS_PER_SAMPLE_16
103                                      | BluetoothCodecConfig.BITS_PER_SAMPLE_24
104                                      | BluetoothCodecConfig.BITS_PER_SAMPLE_32,
105                                      BluetoothCodecConfig.CHANNEL_MODE_STEREO,
106                                      0, 0, 0, 0)        // Codec-specific fields
107     };
108 
109     private static final BluetoothCodecConfig[] sDefaultCodecConfigs = new BluetoothCodecConfig[] {
110             new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
111                                      SBC_PRIORITY_DEFAULT,
112                                      BluetoothCodecConfig.SAMPLE_RATE_44100,
113                                      BluetoothCodecConfig.BITS_PER_SAMPLE_16,
114                                      BluetoothCodecConfig.CHANNEL_MODE_STEREO,
115                                      0, 0, 0, 0),       // Codec-specific fields
116             new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
117                                      AAC_PRIORITY_DEFAULT,
118                                      BluetoothCodecConfig.SAMPLE_RATE_44100,
119                                      BluetoothCodecConfig.BITS_PER_SAMPLE_16,
120                                      BluetoothCodecConfig.CHANNEL_MODE_STEREO,
121                                      0, 0, 0, 0),       // Codec-specific fields
122             new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX,
123                                      APTX_PRIORITY_DEFAULT,
124                                      BluetoothCodecConfig.SAMPLE_RATE_48000,
125                                      BluetoothCodecConfig.BITS_PER_SAMPLE_16,
126                                      BluetoothCodecConfig.CHANNEL_MODE_STEREO,
127                                      0, 0, 0, 0),       // Codec-specific fields
128             new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD,
129                                      APTX_HD_PRIORITY_DEFAULT,
130                                      BluetoothCodecConfig.SAMPLE_RATE_48000,
131                                      BluetoothCodecConfig.BITS_PER_SAMPLE_24,
132                                      BluetoothCodecConfig.CHANNEL_MODE_STEREO,
133                                      0, 0, 0, 0),       // Codec-specific fields
134             new BluetoothCodecConfig(BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
135                                      LDAC_PRIORITY_DEFAULT,
136                                      BluetoothCodecConfig.SAMPLE_RATE_96000,
137                                      BluetoothCodecConfig.BITS_PER_SAMPLE_32,
138                                      BluetoothCodecConfig.CHANNEL_MODE_STEREO,
139                                      0, 0, 0, 0)        // Codec-specific fields
140     };
141 
142     @Before
setUp()143     public void setUp() throws Exception {
144         // Set up mocks and test assets
145         MockitoAnnotations.initMocks(this);
146         mTargetContext = InstrumentationRegistry.getTargetContext();
147 
148         when(mMockContext.getResources()).thenReturn(mMockResources);
149         when(mMockResources.getInteger(R.integer.a2dp_source_codec_priority_sbc))
150                 .thenReturn(SBC_PRIORITY_DEFAULT);
151         when(mMockResources.getInteger(R.integer.a2dp_source_codec_priority_aac))
152                 .thenReturn(AAC_PRIORITY_DEFAULT);
153         when(mMockResources.getInteger(R.integer.a2dp_source_codec_priority_aptx))
154                 .thenReturn(APTX_PRIORITY_DEFAULT);
155         when(mMockResources.getInteger(R.integer.a2dp_source_codec_priority_aptx_hd))
156                 .thenReturn(APTX_HD_PRIORITY_DEFAULT);
157         when(mMockResources.getInteger(R.integer.a2dp_source_codec_priority_ldac))
158                 .thenReturn(LDAC_PRIORITY_DEFAULT);
159 
160         mA2dpCodecConfig = new A2dpCodecConfig(mMockContext, mA2dpNativeInterface);
161         mTestDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice("00:01:02:03:04:05");
162 
163         doReturn(true).when(mA2dpNativeInterface).setCodecConfigPreference(
164                 any(BluetoothDevice.class),
165                 any(BluetoothCodecConfig[].class));
166     }
167 
168     @After
tearDown()169     public void tearDown() throws Exception {
170     }
171 
172     @Test
testAssignCodecConfigPriorities()173     public void testAssignCodecConfigPriorities() {
174         BluetoothCodecConfig[] codecConfigs = mA2dpCodecConfig.codecConfigPriorities();
175         for (BluetoothCodecConfig config : codecConfigs) {
176             switch(config.getCodecType()) {
177                 case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC:
178                     Assert.assertEquals(config.getCodecPriority(), SBC_PRIORITY_DEFAULT);
179                     break;
180                 case BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC:
181                     Assert.assertEquals(config.getCodecPriority(), AAC_PRIORITY_DEFAULT);
182                     break;
183                 case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX:
184                     Assert.assertEquals(config.getCodecPriority(), APTX_PRIORITY_DEFAULT);
185                     break;
186                 case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD:
187                     Assert.assertEquals(config.getCodecPriority(), APTX_HD_PRIORITY_DEFAULT);
188                     break;
189                 case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC:
190                     Assert.assertEquals(config.getCodecPriority(), LDAC_PRIORITY_DEFAULT);
191                     break;
192             }
193         }
194     }
195 
196     /**
197      * Test that we can fallback to default codec by lower the codec priority we changed before.
198      */
199     @Test
testSetCodecPreference_priorityHighToDefault()200     public void testSetCodecPreference_priorityHighToDefault() {
201         testCodecPriorityChangeHelper(
202                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, SBC_PRIORITY_DEFAULT,
203                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH,
204                 true);
205         testCodecPriorityChangeHelper(
206                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, AAC_PRIORITY_DEFAULT,
207                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH,
208                 true);
209         testCodecPriorityChangeHelper(
210                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, APTX_PRIORITY_DEFAULT,
211                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, PRIORITY_HIGH,
212                 true);
213         testCodecPriorityChangeHelper(
214                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, APTX_HD_PRIORITY_DEFAULT,
215                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, PRIORITY_HIGH,
216                 true);
217         testCodecPriorityChangeHelper(
218                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, LDAC_PRIORITY_DEFAULT,
219                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, PRIORITY_HIGH,
220                 false);
221     }
222 
223     /**
224      * Test that we can change the default codec to another by raising the codec priority.
225      * LDAC is the default highest codec, so no need to test others.
226      */
227     @Test
testSetCodecPreference_priorityDefaultToRaiseHigh()228     public void testSetCodecPreference_priorityDefaultToRaiseHigh() {
229         testCodecPriorityChangeHelper(
230                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH,
231                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, LDAC_PRIORITY_DEFAULT,
232                 true);
233         testCodecPriorityChangeHelper(
234                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH,
235                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, LDAC_PRIORITY_DEFAULT,
236                 true);
237         testCodecPriorityChangeHelper(
238                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, PRIORITY_HIGH,
239                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, LDAC_PRIORITY_DEFAULT,
240                 true);
241         testCodecPriorityChangeHelper(
242                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, PRIORITY_HIGH,
243                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, LDAC_PRIORITY_DEFAULT,
244                 true);
245         testCodecPriorityChangeHelper(
246                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, PRIORITY_HIGH,
247                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, LDAC_PRIORITY_DEFAULT,
248                 false);
249     }
250 
251     @Test
testSetCodecPreference_prioritySbcHighToOthersHigh()252     public void testSetCodecPreference_prioritySbcHighToOthersHigh() {
253         testCodecPriorityChangeHelper(
254                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH,
255                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH,
256                 false);
257         testCodecPriorityChangeHelper(
258                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH,
259                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH,
260                 true);
261         testCodecPriorityChangeHelper(
262                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, PRIORITY_HIGH,
263                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH,
264                 true);
265         testCodecPriorityChangeHelper(
266                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, PRIORITY_HIGH,
267                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH,
268                 true);
269         testCodecPriorityChangeHelper(
270                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, PRIORITY_HIGH,
271                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH,
272                 true);
273     }
274 
275     @Test
testSetCodecPreference_priorityAacHighToOthersHigh()276     public void testSetCodecPreference_priorityAacHighToOthersHigh() {
277         testCodecPriorityChangeHelper(
278                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC, PRIORITY_HIGH,
279                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH,
280                 true);
281         testCodecPriorityChangeHelper(
282                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH,
283                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH,
284                 false);
285         testCodecPriorityChangeHelper(
286                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX, PRIORITY_HIGH,
287                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH,
288                 true);
289         testCodecPriorityChangeHelper(
290                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD, PRIORITY_HIGH,
291                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH,
292                 true);
293         testCodecPriorityChangeHelper(
294                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC, PRIORITY_HIGH,
295                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC, PRIORITY_HIGH,
296                 true);
297     }
298 
299     @Test
testSetCodecPreference_parametersChangedInSameCodec()300     public void testSetCodecPreference_parametersChangedInSameCodec() {
301         // The SBC default / preferred config is Stereo
302         testCodecParametersChangeHelper(
303                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
304                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
305                 BluetoothCodecConfig.SAMPLE_RATE_44100,
306                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
307                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
308                 false);
309         // SBC Mono is mandatory
310         testCodecParametersChangeHelper(
311                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
312                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
313                 BluetoothCodecConfig.SAMPLE_RATE_44100,
314                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
315                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
316                 true);
317 
318         // The LDAC default / preferred config within mDefaultCodecConfigs
319         testCodecParametersChangeHelper(
320                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
321                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
322                 BluetoothCodecConfig.SAMPLE_RATE_96000,
323                 BluetoothCodecConfig.BITS_PER_SAMPLE_32,
324                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
325                 false);
326 
327         testCodecParametersChangeHelper(
328                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
329                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
330                 BluetoothCodecConfig.SAMPLE_RATE_44100,
331                 BluetoothCodecConfig.BITS_PER_SAMPLE_32,
332                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
333                 true);
334         testCodecParametersChangeHelper(
335                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
336                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
337                 BluetoothCodecConfig.SAMPLE_RATE_96000,
338                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
339                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
340                 true);
341         testCodecParametersChangeHelper(
342                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
343                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
344                 BluetoothCodecConfig.SAMPLE_RATE_44100,
345                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
346                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
347                 true);
348 
349         // None for system default (Developer options)
350         testCodecParametersChangeHelper(
351                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
352                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
353                 BluetoothCodecConfig.SAMPLE_RATE_NONE,
354                 BluetoothCodecConfig.BITS_PER_SAMPLE_32,
355                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
356                 false);
357         testCodecParametersChangeHelper(
358                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
359                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
360                 BluetoothCodecConfig.SAMPLE_RATE_96000,
361                 BluetoothCodecConfig.BITS_PER_SAMPLE_NONE,
362                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
363                 false);
364         testCodecParametersChangeHelper(
365                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
366                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
367                 BluetoothCodecConfig.SAMPLE_RATE_96000,
368                 BluetoothCodecConfig.BITS_PER_SAMPLE_32,
369                 BluetoothCodecConfig.CHANNEL_MODE_NONE,
370                 false);
371 
372         int unsupportedParameter = 0xc0;
373         testCodecParametersChangeHelper(
374                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
375                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
376                 unsupportedParameter,
377                 BluetoothCodecConfig.BITS_PER_SAMPLE_32,
378                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
379                 false);
380         testCodecParametersChangeHelper(
381                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
382                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
383                 BluetoothCodecConfig.SAMPLE_RATE_96000,
384                 unsupportedParameter,
385                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
386                 false);
387         testCodecParametersChangeHelper(
388                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
389                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
390                 BluetoothCodecConfig.SAMPLE_RATE_96000,
391                 BluetoothCodecConfig.BITS_PER_SAMPLE_32,
392                 unsupportedParameter,
393                 false);
394 
395         int multipleSupportedParameters = 0x03;
396         testCodecParametersChangeHelper(
397                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
398                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
399                 multipleSupportedParameters,
400                 BluetoothCodecConfig.BITS_PER_SAMPLE_32,
401                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
402                 false);
403         testCodecParametersChangeHelper(
404                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
405                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
406                 BluetoothCodecConfig.SAMPLE_RATE_96000,
407                 multipleSupportedParameters,
408                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
409                 false);
410         testCodecParametersChangeHelper(
411                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
412                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
413                 BluetoothCodecConfig.SAMPLE_RATE_96000,
414                 BluetoothCodecConfig.BITS_PER_SAMPLE_32,
415                 multipleSupportedParameters,
416                 false);
417     }
418 
419     @Test
testSetCodecPreference_parametersChangedToAnotherCodec()420     public void testSetCodecPreference_parametersChangedToAnotherCodec() {
421         // different sample rate (44.1 kHz -> 96 kHz)
422         testCodecParametersChangeHelper(
423                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
424                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
425                 BluetoothCodecConfig.SAMPLE_RATE_96000,
426                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
427                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
428                 true);
429         // different bits per channel (16 bits -> 32 bits)
430         testCodecParametersChangeHelper(
431                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
432                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
433                 BluetoothCodecConfig.SAMPLE_RATE_44100,
434                 BluetoothCodecConfig.BITS_PER_SAMPLE_32,
435                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
436                 true);
437         // change all PCM parameters
438         testCodecParametersChangeHelper(
439                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
440                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
441                 BluetoothCodecConfig.SAMPLE_RATE_44100,
442                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
443                 BluetoothCodecConfig.CHANNEL_MODE_MONO,
444                 true);
445 
446         // None for system default (Developer options)
447         testCodecParametersChangeHelper(
448                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
449                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
450                 BluetoothCodecConfig.SAMPLE_RATE_NONE,
451                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
452                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
453                 true);
454         testCodecParametersChangeHelper(
455                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
456                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
457                 BluetoothCodecConfig.SAMPLE_RATE_44100,
458                 BluetoothCodecConfig.BITS_PER_SAMPLE_NONE,
459                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
460                 true);
461         testCodecParametersChangeHelper(
462                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
463                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
464                 BluetoothCodecConfig.SAMPLE_RATE_44100,
465                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
466                 BluetoothCodecConfig.CHANNEL_MODE_NONE,
467                 true);
468         testCodecParametersChangeHelper(
469                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
470                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
471                 BluetoothCodecConfig.SAMPLE_RATE_NONE,
472                 BluetoothCodecConfig.BITS_PER_SAMPLE_NONE,
473                 BluetoothCodecConfig.CHANNEL_MODE_NONE,
474                 true);
475 
476         int unsupportedParameter = 0xc0;
477         testCodecParametersChangeHelper(
478                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
479                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
480                 unsupportedParameter,
481                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
482                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
483                 false);
484         testCodecParametersChangeHelper(
485                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
486                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
487                 BluetoothCodecConfig.SAMPLE_RATE_44100,
488                 unsupportedParameter,
489                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
490                 false);
491         testCodecParametersChangeHelper(
492                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
493                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
494                 BluetoothCodecConfig.SAMPLE_RATE_44100,
495                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
496                 unsupportedParameter,
497                 false);
498 
499         int multipleSupportedParameters = 0x03;
500         testCodecParametersChangeHelper(
501                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
502                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
503                 multipleSupportedParameters,
504                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
505                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
506                 false);
507         testCodecParametersChangeHelper(
508                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
509                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
510                 BluetoothCodecConfig.SAMPLE_RATE_44100,
511                 multipleSupportedParameters,
512                 BluetoothCodecConfig.CHANNEL_MODE_STEREO,
513                 false);
514         testCodecParametersChangeHelper(
515                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
516                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC,
517                 BluetoothCodecConfig.SAMPLE_RATE_44100,
518                 BluetoothCodecConfig.BITS_PER_SAMPLE_16,
519                 multipleSupportedParameters,
520                 false);
521     }
522 
523     @Test
testSetCodecPreference_ldacCodecSpecificFieldChanged()524     public void testSetCodecPreference_ldacCodecSpecificFieldChanged() {
525         int ldacAudioQualityHigh = 1000;
526         int ldacAudioQualityABR = 1003;
527         int sbcCodecSpecificParameter = 0;
528         testCodecSpecificParametersChangeHelper(
529                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
530                 ldacAudioQualityABR,
531                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
532                 ldacAudioQualityABR,
533                 false);
534         testCodecSpecificParametersChangeHelper(
535                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
536                 ldacAudioQualityHigh,
537                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
538                 ldacAudioQualityABR,
539                 true);
540         testCodecSpecificParametersChangeHelper(
541                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
542                 ldacAudioQualityABR,
543                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
544                 sbcCodecSpecificParameter,
545                 true);
546 
547         // Only LDAC will check the codec specific1 field, but not SBC
548         testCodecSpecificParametersChangeHelper(
549                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
550                 sbcCodecSpecificParameter,
551                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
552                 ldacAudioQualityABR,
553                 true);
554         testCodecSpecificParametersChangeHelper(
555                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
556                 ldacAudioQualityABR,
557                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC,
558                 ldacAudioQualityABR,
559                 true);
560         testCodecSpecificParametersChangeHelper(
561                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
562                 ldacAudioQualityHigh,
563                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
564                 sbcCodecSpecificParameter,
565                 false);
566     }
567 
568     @Test
testDisableOptionalCodecs()569     public void testDisableOptionalCodecs() {
570         BluetoothCodecConfig[] codecConfigsArray =
571                 new BluetoothCodecConfig[BluetoothCodecConfig.SOURCE_CODEC_TYPE_MAX];
572         codecConfigsArray[0] = new BluetoothCodecConfig(
573                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
574                 BluetoothCodecConfig.CODEC_PRIORITY_HIGHEST,
575                 BluetoothCodecConfig.SAMPLE_RATE_NONE,
576                 BluetoothCodecConfig.BITS_PER_SAMPLE_NONE,
577                 BluetoothCodecConfig.CHANNEL_MODE_NONE,
578                 0, 0, 0, 0);       // Codec-specific fields
579 
580         // shouldn't invoke to native when current codec is SBC
581         mA2dpCodecConfig.disableOptionalCodecs(
582                 mTestDevice,
583                 getDefaultCodecConfigByType(
584                         BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
585                         BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT));
586         verify(mA2dpNativeInterface, times(0)).setCodecConfigPreference(mTestDevice,
587                                                                         codecConfigsArray);
588 
589         // should invoke to native when current codec is an optional codec
590         int invokedCounter = 0;
591         for (int codecType : sOptionalCodecTypes) {
592             mA2dpCodecConfig.disableOptionalCodecs(
593                     mTestDevice,
594                     getDefaultCodecConfigByType(codecType,
595                                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT));
596             verify(mA2dpNativeInterface, times(++invokedCounter))
597                     .setCodecConfigPreference(mTestDevice, codecConfigsArray);
598         }
599     }
600 
601     @Test
testEnableOptionalCodecs()602     public void testEnableOptionalCodecs() {
603         BluetoothCodecConfig[] codecConfigsArray =
604                 new BluetoothCodecConfig[BluetoothCodecConfig.SOURCE_CODEC_TYPE_MAX];
605         codecConfigsArray[0] = new BluetoothCodecConfig(
606                 BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
607                 SBC_PRIORITY_DEFAULT,
608                 BluetoothCodecConfig.SAMPLE_RATE_NONE,
609                 BluetoothCodecConfig.BITS_PER_SAMPLE_NONE,
610                 BluetoothCodecConfig.CHANNEL_MODE_NONE,
611                 0, 0, 0, 0);       // Codec-specific fields
612 
613         // should invoke to native when current codec is SBC
614         mA2dpCodecConfig.enableOptionalCodecs(
615                 mTestDevice,
616                 getDefaultCodecConfigByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC,
617                                             BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT));
618         verify(mA2dpNativeInterface, times(1))
619                 .setCodecConfigPreference(mTestDevice, codecConfigsArray);
620 
621         // shouldn't invoke to native when current codec is already an optional
622         for (int codecType : sOptionalCodecTypes) {
623             mA2dpCodecConfig.enableOptionalCodecs(
624                     mTestDevice,
625                     getDefaultCodecConfigByType(codecType,
626                                                 BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT));
627             verify(mA2dpNativeInterface, times(1))
628                     .setCodecConfigPreference(mTestDevice, codecConfigsArray);
629         }
630     }
631 
getDefaultCodecConfigByType(int codecType, int codecPriority)632     private BluetoothCodecConfig getDefaultCodecConfigByType(int codecType, int codecPriority) {
633         for (BluetoothCodecConfig codecConfig : sDefaultCodecConfigs) {
634             if (codecConfig.getCodecType() != codecType) {
635                 continue;
636             }
637             return new BluetoothCodecConfig(
638                     codecConfig.getCodecType(),
639                     (codecPriority != BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT
640                      ? codecPriority : codecConfig.getCodecPriority()),
641                     codecConfig.getSampleRate(), codecConfig.getBitsPerSample(),
642                     codecConfig.getChannelMode(), codecConfig.getCodecSpecific1(),
643                     codecConfig.getCodecSpecific2(), codecConfig.getCodecSpecific3(),
644                     codecConfig.getCodecSpecific4());
645         }
646         Assert.fail("getDefaultCodecConfigByType: No such codecType=" + codecType
647                 + " in sDefaultCodecConfigs");
648         return null;
649     }
650 
getCodecCapabilitiesByType(int codecType)651     private BluetoothCodecConfig getCodecCapabilitiesByType(int codecType) {
652         for (BluetoothCodecConfig codecCapabilities : sCodecCapabilities) {
653             if (codecCapabilities.getCodecType() != codecType) {
654                 continue;
655             }
656             return new BluetoothCodecConfig(
657                     codecCapabilities.getCodecType(), codecCapabilities.getCodecPriority(),
658                     codecCapabilities.getSampleRate(), codecCapabilities.getBitsPerSample(),
659                     codecCapabilities.getChannelMode(), codecCapabilities.getCodecSpecific1(),
660                     codecCapabilities.getCodecSpecific2(), codecCapabilities.getCodecSpecific3(),
661                     codecCapabilities.getCodecSpecific4());
662         }
663         Assert.fail("getCodecCapabilitiesByType: No such codecType=" + codecType
664                 + " in sCodecCapabilities");
665         return null;
666     }
667 
testCodecParametersChangeHelper(int newCodecType, int oldCodecType, int sampleRate, int bitsPerSample, int channelMode, boolean invokeNative)668     private void testCodecParametersChangeHelper(int newCodecType, int oldCodecType,
669             int sampleRate, int bitsPerSample, int channelMode, boolean invokeNative) {
670         BluetoothCodecConfig oldCodecConfig =
671                 getDefaultCodecConfigByType(oldCodecType, PRIORITY_HIGH);
672         BluetoothCodecConfig[] newCodecConfigsArray = new BluetoothCodecConfig[] {
673                 new BluetoothCodecConfig(newCodecType,
674                                          PRIORITY_HIGH,
675                                          sampleRate, bitsPerSample, channelMode,
676                                          0, 0, 0, 0)       // Codec-specific fields
677         };
678 
679         // Test cases: 1. no mandatory; 2. mandatory + old + new; 3. all codecs
680         BluetoothCodecConfig[] minimumCodecsArray;
681         if (!oldCodecConfig.isMandatoryCodec() && !newCodecConfigsArray[0].isMandatoryCodec()) {
682             BluetoothCodecConfig[] optionalCodecsArray;
683             if (oldCodecType != newCodecType) {
684                 optionalCodecsArray = new BluetoothCodecConfig[] {
685                         getCodecCapabilitiesByType(oldCodecType),
686                         getCodecCapabilitiesByType(newCodecType)
687                 };
688                 minimumCodecsArray = new BluetoothCodecConfig[] {
689                         getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC),
690                         getCodecCapabilitiesByType(oldCodecType),
691                         getCodecCapabilitiesByType(newCodecType)
692                 };
693             } else {
694                 optionalCodecsArray = new BluetoothCodecConfig[]
695                         {getCodecCapabilitiesByType(oldCodecType)};
696                 minimumCodecsArray = new BluetoothCodecConfig[] {
697                         getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC),
698                         getCodecCapabilitiesByType(oldCodecType)
699                 };
700             }
701             BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig,
702                                                                         sCodecCapabilities,
703                                                                         optionalCodecsArray);
704             mA2dpCodecConfig.setCodecConfigPreference(mTestDevice,
705                                                       codecStatus,
706                                                       newCodecConfigsArray[0]);
707             // no mandatory codec in selectable, and should not apply
708             verify(mA2dpNativeInterface, times(0)).setCodecConfigPreference(mTestDevice,
709                                                                             newCodecConfigsArray);
710 
711 
712         } else {
713             if (oldCodecType != newCodecType) {
714                 minimumCodecsArray = new BluetoothCodecConfig[] {
715                         getCodecCapabilitiesByType(oldCodecType),
716                         getCodecCapabilitiesByType(newCodecType)
717                 };
718             } else {
719                 minimumCodecsArray = new BluetoothCodecConfig[] {
720                         getCodecCapabilitiesByType(oldCodecType),
721                 };
722             }
723         }
724 
725         // 2. mandatory + old + new codecs only
726         BluetoothCodecStatus codecStatus =
727                 new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, minimumCodecsArray);
728         mA2dpCodecConfig.setCodecConfigPreference(mTestDevice,
729                                                   codecStatus,
730                                                   newCodecConfigsArray[0]);
731         verify(mA2dpNativeInterface, times(invokeNative ? 1 : 0))
732                 .setCodecConfigPreference(mTestDevice, newCodecConfigsArray);
733 
734         // 3. all codecs were selectable
735         codecStatus = new BluetoothCodecStatus(oldCodecConfig,
736                                                sCodecCapabilities,
737                                                sCodecCapabilities);
738         mA2dpCodecConfig.setCodecConfigPreference(mTestDevice,
739                                                   codecStatus,
740                                                   newCodecConfigsArray[0]);
741         verify(mA2dpNativeInterface, times(invokeNative ? 2 : 0))
742                 .setCodecConfigPreference(mTestDevice, newCodecConfigsArray);
743     }
744 
testCodecSpecificParametersChangeHelper(int newCodecType, int newCodecSpecific, int oldCodecType, int oldCodecSpecific, boolean invokeNative)745     private void testCodecSpecificParametersChangeHelper(int newCodecType, int newCodecSpecific,
746             int oldCodecType, int oldCodecSpecific, boolean invokeNative) {
747         BluetoothCodecConfig codecDefaultTemp =
748                 getDefaultCodecConfigByType(oldCodecType, PRIORITY_HIGH);
749         BluetoothCodecConfig oldCodecConfig =
750                 new BluetoothCodecConfig(codecDefaultTemp.getCodecType(),
751                                          codecDefaultTemp.getCodecPriority(),
752                                          codecDefaultTemp.getSampleRate(),
753                                          codecDefaultTemp.getBitsPerSample(),
754                                          codecDefaultTemp.getChannelMode(),
755                                          oldCodecSpecific, 0, 0, 0);       // Codec-specific fields
756         codecDefaultTemp = getDefaultCodecConfigByType(newCodecType, PRIORITY_HIGH);
757         BluetoothCodecConfig[] newCodecConfigsArray = new BluetoothCodecConfig[] {
758                 new BluetoothCodecConfig(codecDefaultTemp.getCodecType(),
759                                          codecDefaultTemp.getCodecPriority(),
760                                          codecDefaultTemp.getSampleRate(),
761                                          codecDefaultTemp.getBitsPerSample(),
762                                          codecDefaultTemp.getChannelMode(),
763                                          newCodecSpecific, 0, 0, 0)       // Codec-specific fields
764         };
765         BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig,
766                                                                     sCodecCapabilities,
767                                                                     sCodecCapabilities);
768         mA2dpCodecConfig.setCodecConfigPreference(mTestDevice,
769                                                   codecStatus,
770                                                   newCodecConfigsArray[0]);
771         verify(mA2dpNativeInterface, times(invokeNative ? 1 : 0))
772                 .setCodecConfigPreference(mTestDevice, newCodecConfigsArray);
773     }
774 
testCodecPriorityChangeHelper(int newCodecType, int newCodecPriority, int oldCodecType, int oldCodecPriority, boolean shouldApplyWhenAllSelectable)775     private void testCodecPriorityChangeHelper(int newCodecType, int newCodecPriority,
776             int oldCodecType, int oldCodecPriority, boolean shouldApplyWhenAllSelectable) {
777 
778         BluetoothCodecConfig[] newCodecConfigsArray =
779                 new BluetoothCodecConfig[] {
780                         getDefaultCodecConfigByType(newCodecType, newCodecPriority)
781                 };
782         BluetoothCodecConfig oldCodecConfig = getDefaultCodecConfigByType(oldCodecType,
783                                                                           oldCodecPriority);
784 
785         // Test cases: 1. no mandatory; 2. no new codec; 3. mandatory + old + new; 4. all codecs
786         BluetoothCodecConfig[] minimumCodecsArray;
787         boolean isMinimumCodecsArraySelectable;
788         if (!oldCodecConfig.isMandatoryCodec()) {
789             if (oldCodecType == newCodecType || newCodecConfigsArray[0].isMandatoryCodec()) {
790                 // selectable: {-mandatory, +oldCodec = newCodec}, or
791                 // selectable: {-mandatory = newCodec, +oldCodec}. Not applied
792                 BluetoothCodecConfig[] poorCodecsArray = new BluetoothCodecConfig[]
793                         {getCodecCapabilitiesByType(oldCodecType)};
794                 BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig,
795                                                                             sCodecCapabilities,
796                                                                             poorCodecsArray);
797                 mA2dpCodecConfig.setCodecConfigPreference(mTestDevice,
798                                                           codecStatus,
799                                                           newCodecConfigsArray[0]);
800                 verify(mA2dpNativeInterface, times(0))
801                         .setCodecConfigPreference(mTestDevice, newCodecConfigsArray);
802 
803                 // selectable: {+mandatory, +oldCodec = newCodec}, or
804                 // selectable: {+mandatory = newCodec, +oldCodec}.
805                 minimumCodecsArray = new BluetoothCodecConfig[] {
806                         getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC),
807                         getCodecCapabilitiesByType(oldCodecType)
808                 };
809             } else {
810                 // selectable: {-mandatory, +oldCodec, +newCodec}. Not applied
811                 BluetoothCodecConfig[] poorCodecsArray = new BluetoothCodecConfig[] {
812                         getCodecCapabilitiesByType(oldCodecType),
813                         getCodecCapabilitiesByType(newCodecType)
814                 };
815                 BluetoothCodecStatus codecStatus = new BluetoothCodecStatus(oldCodecConfig,
816                                                                             sCodecCapabilities,
817                                                                             poorCodecsArray);
818                 mA2dpCodecConfig.setCodecConfigPreference(
819                         mTestDevice, codecStatus, newCodecConfigsArray[0]);
820                 verify(mA2dpNativeInterface, times(0))
821                         .setCodecConfigPreference(mTestDevice, newCodecConfigsArray);
822 
823                 // selectable: {+mandatory, +oldCodec, -newCodec}. Not applied
824                 poorCodecsArray = new BluetoothCodecConfig[] {
825                         getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC),
826                         getCodecCapabilitiesByType(oldCodecType)
827                 };
828                 codecStatus = new BluetoothCodecStatus(oldCodecConfig,
829                                                        sCodecCapabilities,
830                                                        poorCodecsArray);
831                 mA2dpCodecConfig.setCodecConfigPreference(mTestDevice,
832                                                           codecStatus,
833                                                           newCodecConfigsArray[0]);
834                 verify(mA2dpNativeInterface, times(0))
835                         .setCodecConfigPreference(mTestDevice, newCodecConfigsArray);
836 
837                 // selectable: {+mandatory, +oldCodec, +newCodec}.
838                 minimumCodecsArray = new BluetoothCodecConfig[] {
839                       getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC),
840                       getCodecCapabilitiesByType(oldCodecType),
841                       getCodecCapabilitiesByType(newCodecType)
842                 };
843             }
844             // oldCodec priority should be reset to default, so compare with the default
845             if (newCodecConfigsArray[0].getCodecPriority()
846                     > getDefaultCodecConfigByType(
847                             oldCodecType,
848                             BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT).getCodecPriority()
849                     && oldCodecType != newCodecType) {
850                 isMinimumCodecsArraySelectable = true;
851             } else {
852                 // the old codec was still the highest priority after reset to default
853                 isMinimumCodecsArraySelectable = false;
854             }
855         } else if (oldCodecType != newCodecType) {
856             // selectable: {+mandatory = oldCodec, -newCodec}. Not applied
857             BluetoothCodecConfig[] poorCodecsArray = new BluetoothCodecConfig[]
858                     {getCodecCapabilitiesByType(oldCodecType)};
859             BluetoothCodecStatus codecStatus =
860                     new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, poorCodecsArray);
861             mA2dpCodecConfig.setCodecConfigPreference(mTestDevice,
862                                                       codecStatus,
863                                                       newCodecConfigsArray[0]);
864             verify(mA2dpNativeInterface, times(0))
865                     .setCodecConfigPreference(mTestDevice, newCodecConfigsArray);
866 
867             // selectable: {+mandatory = oldCodec, +newCodec}.
868             minimumCodecsArray = new BluetoothCodecConfig[] {
869                     getCodecCapabilitiesByType(oldCodecType),
870                     getCodecCapabilitiesByType(newCodecType)
871             };
872             isMinimumCodecsArraySelectable = true;
873         } else {
874             // selectable: {mandatory = oldCodec = newCodec}.
875             minimumCodecsArray = new BluetoothCodecConfig[]
876                     {getCodecCapabilitiesByType(BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC)};
877             isMinimumCodecsArraySelectable = false;
878         }
879 
880         // 3. mandatory + old + new codecs only
881         int invokedCounter = (isMinimumCodecsArraySelectable ? 1 : 0);
882         BluetoothCodecStatus codecStatus =
883                 new BluetoothCodecStatus(oldCodecConfig, sCodecCapabilities, minimumCodecsArray);
884         mA2dpCodecConfig.setCodecConfigPreference(mTestDevice,
885                                                   codecStatus,
886                                                   newCodecConfigsArray[0]);
887         verify(mA2dpNativeInterface, times(invokedCounter))
888                 .setCodecConfigPreference(mTestDevice, newCodecConfigsArray);
889 
890         // 4. all codecs were selectable
891         invokedCounter += (shouldApplyWhenAllSelectable ? 1 : 0);
892         codecStatus = new BluetoothCodecStatus(oldCodecConfig,
893                                                sCodecCapabilities,
894                                                sCodecCapabilities);
895         mA2dpCodecConfig.setCodecConfigPreference(mTestDevice,
896                                                   codecStatus,
897                                                   newCodecConfigsArray[0]);
898         verify(mA2dpNativeInterface, times(invokedCounter))
899                 .setCodecConfigPreference(mTestDevice, newCodecConfigsArray);
900     }
901 }
902