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