1 /* 2 * Copyright (C) 2016 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 android.bluetooth; 18 19 import android.annotation.IntDef; 20 import android.annotation.NonNull; 21 import android.annotation.Nullable; 22 import android.compat.annotation.UnsupportedAppUsage; 23 import android.os.Parcel; 24 import android.os.Parcelable; 25 26 import java.lang.annotation.Retention; 27 import java.lang.annotation.RetentionPolicy; 28 import java.util.Objects; 29 30 /** 31 * Represents the codec configuration for a Bluetooth A2DP source device. 32 * 33 * {@see BluetoothA2dp} 34 * 35 * {@hide} 36 */ 37 public final class BluetoothCodecConfig implements Parcelable { 38 // Add an entry for each source codec here. 39 // NOTE: The values should be same as those listed in the following file: 40 // hardware/libhardware/include/hardware/bt_av.h 41 42 /** @hide */ 43 @IntDef(prefix = "SOURCE_CODEC_TYPE_", value = { 44 SOURCE_CODEC_TYPE_SBC, 45 SOURCE_CODEC_TYPE_AAC, 46 SOURCE_CODEC_TYPE_APTX, 47 SOURCE_CODEC_TYPE_APTX_HD, 48 SOURCE_CODEC_TYPE_LDAC, 49 SOURCE_CODEC_TYPE_MAX, 50 SOURCE_CODEC_TYPE_INVALID 51 }) 52 @Retention(RetentionPolicy.SOURCE) 53 public @interface SourceCodecType {} 54 55 @UnsupportedAppUsage 56 public static final int SOURCE_CODEC_TYPE_SBC = 0; 57 58 @UnsupportedAppUsage 59 public static final int SOURCE_CODEC_TYPE_AAC = 1; 60 61 @UnsupportedAppUsage 62 public static final int SOURCE_CODEC_TYPE_APTX = 2; 63 64 @UnsupportedAppUsage 65 public static final int SOURCE_CODEC_TYPE_APTX_HD = 3; 66 67 @UnsupportedAppUsage 68 public static final int SOURCE_CODEC_TYPE_LDAC = 4; 69 70 @UnsupportedAppUsage 71 public static final int SOURCE_CODEC_TYPE_MAX = 5; 72 73 @UnsupportedAppUsage 74 public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000; 75 76 /** @hide */ 77 @IntDef(prefix = "CODEC_PRIORITY_", value = { 78 CODEC_PRIORITY_DISABLED, 79 CODEC_PRIORITY_DEFAULT, 80 CODEC_PRIORITY_HIGHEST 81 }) 82 @Retention(RetentionPolicy.SOURCE) 83 public @interface CodecPriority {} 84 85 @UnsupportedAppUsage 86 public static final int CODEC_PRIORITY_DISABLED = -1; 87 88 @UnsupportedAppUsage 89 public static final int CODEC_PRIORITY_DEFAULT = 0; 90 91 @UnsupportedAppUsage 92 public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000; 93 94 95 /** @hide */ 96 @IntDef(prefix = "SAMPLE_RATE_", value = { 97 SAMPLE_RATE_NONE, 98 SAMPLE_RATE_44100, 99 SAMPLE_RATE_48000, 100 SAMPLE_RATE_88200, 101 SAMPLE_RATE_96000, 102 SAMPLE_RATE_176400, 103 SAMPLE_RATE_192000 104 }) 105 @Retention(RetentionPolicy.SOURCE) 106 public @interface SampleRate {} 107 108 @UnsupportedAppUsage 109 public static final int SAMPLE_RATE_NONE = 0; 110 111 @UnsupportedAppUsage 112 public static final int SAMPLE_RATE_44100 = 0x1 << 0; 113 114 @UnsupportedAppUsage 115 public static final int SAMPLE_RATE_48000 = 0x1 << 1; 116 117 @UnsupportedAppUsage 118 public static final int SAMPLE_RATE_88200 = 0x1 << 2; 119 120 @UnsupportedAppUsage 121 public static final int SAMPLE_RATE_96000 = 0x1 << 3; 122 123 @UnsupportedAppUsage 124 public static final int SAMPLE_RATE_176400 = 0x1 << 4; 125 126 @UnsupportedAppUsage 127 public static final int SAMPLE_RATE_192000 = 0x1 << 5; 128 129 130 /** @hide */ 131 @IntDef(prefix = "BITS_PER_SAMPLE_", value = { 132 BITS_PER_SAMPLE_NONE, 133 BITS_PER_SAMPLE_16, 134 BITS_PER_SAMPLE_24, 135 BITS_PER_SAMPLE_32 136 }) 137 @Retention(RetentionPolicy.SOURCE) 138 public @interface BitsPerSample {} 139 140 @UnsupportedAppUsage 141 public static final int BITS_PER_SAMPLE_NONE = 0; 142 143 @UnsupportedAppUsage 144 public static final int BITS_PER_SAMPLE_16 = 0x1 << 0; 145 146 @UnsupportedAppUsage 147 public static final int BITS_PER_SAMPLE_24 = 0x1 << 1; 148 149 @UnsupportedAppUsage 150 public static final int BITS_PER_SAMPLE_32 = 0x1 << 2; 151 152 153 /** @hide */ 154 @IntDef(prefix = "CHANNEL_MODE_", value = { 155 CHANNEL_MODE_NONE, 156 CHANNEL_MODE_MONO, 157 CHANNEL_MODE_STEREO 158 }) 159 @Retention(RetentionPolicy.SOURCE) 160 public @interface ChannelMode {} 161 162 @UnsupportedAppUsage 163 public static final int CHANNEL_MODE_NONE = 0; 164 165 @UnsupportedAppUsage 166 public static final int CHANNEL_MODE_MONO = 0x1 << 0; 167 168 @UnsupportedAppUsage 169 public static final int CHANNEL_MODE_STEREO = 0x1 << 1; 170 171 private final @SourceCodecType int mCodecType; 172 private @CodecPriority int mCodecPriority; 173 private final @SampleRate int mSampleRate; 174 private final @BitsPerSample int mBitsPerSample; 175 private final @ChannelMode int mChannelMode; 176 private final long mCodecSpecific1; 177 private final long mCodecSpecific2; 178 private final long mCodecSpecific3; 179 private final long mCodecSpecific4; 180 181 @UnsupportedAppUsage BluetoothCodecConfig(@ourceCodecType int codecType, @CodecPriority int codecPriority, @SampleRate int sampleRate, @BitsPerSample int bitsPerSample, @ChannelMode int channelMode, long codecSpecific1, long codecSpecific2, long codecSpecific3, long codecSpecific4)182 public BluetoothCodecConfig(@SourceCodecType int codecType, @CodecPriority int codecPriority, 183 @SampleRate int sampleRate, @BitsPerSample int bitsPerSample, 184 @ChannelMode int channelMode, long codecSpecific1, 185 long codecSpecific2, long codecSpecific3, 186 long codecSpecific4) { 187 mCodecType = codecType; 188 mCodecPriority = codecPriority; 189 mSampleRate = sampleRate; 190 mBitsPerSample = bitsPerSample; 191 mChannelMode = channelMode; 192 mCodecSpecific1 = codecSpecific1; 193 mCodecSpecific2 = codecSpecific2; 194 mCodecSpecific3 = codecSpecific3; 195 mCodecSpecific4 = codecSpecific4; 196 } 197 198 @UnsupportedAppUsage BluetoothCodecConfig(@ourceCodecType int codecType)199 public BluetoothCodecConfig(@SourceCodecType int codecType) { 200 mCodecType = codecType; 201 mCodecPriority = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT; 202 mSampleRate = BluetoothCodecConfig.SAMPLE_RATE_NONE; 203 mBitsPerSample = BluetoothCodecConfig.BITS_PER_SAMPLE_NONE; 204 mChannelMode = BluetoothCodecConfig.CHANNEL_MODE_NONE; 205 mCodecSpecific1 = 0; 206 mCodecSpecific2 = 0; 207 mCodecSpecific3 = 0; 208 mCodecSpecific4 = 0; 209 } 210 211 @Override equals(@ullable Object o)212 public boolean equals(@Nullable Object o) { 213 if (o instanceof BluetoothCodecConfig) { 214 BluetoothCodecConfig other = (BluetoothCodecConfig) o; 215 return (other.mCodecType == mCodecType 216 && other.mCodecPriority == mCodecPriority 217 && other.mSampleRate == mSampleRate 218 && other.mBitsPerSample == mBitsPerSample 219 && other.mChannelMode == mChannelMode 220 && other.mCodecSpecific1 == mCodecSpecific1 221 && other.mCodecSpecific2 == mCodecSpecific2 222 && other.mCodecSpecific3 == mCodecSpecific3 223 && other.mCodecSpecific4 == mCodecSpecific4); 224 } 225 return false; 226 } 227 228 /** 229 * Returns a hash based on the config values 230 * 231 * @return a hash based on the config values 232 * @hide 233 */ 234 @Override hashCode()235 public int hashCode() { 236 return Objects.hash(mCodecType, mCodecPriority, mSampleRate, 237 mBitsPerSample, mChannelMode, mCodecSpecific1, 238 mCodecSpecific2, mCodecSpecific3, mCodecSpecific4); 239 } 240 241 /** 242 * Checks whether the object contains valid codec configuration. 243 * 244 * @return true if the object contains valid codec configuration, otherwise false. 245 * @hide 246 */ isValid()247 public boolean isValid() { 248 return (mSampleRate != SAMPLE_RATE_NONE) 249 && (mBitsPerSample != BITS_PER_SAMPLE_NONE) 250 && (mChannelMode != CHANNEL_MODE_NONE); 251 } 252 253 /** 254 * Adds capability string to an existing string. 255 * 256 * @param prevStr the previous string with the capabilities. Can be a null pointer. 257 * @param capStr the capability string to append to prevStr argument. 258 * @return the result string in the form "prevStr|capStr". 259 */ appendCapabilityToString(String prevStr, String capStr)260 private static String appendCapabilityToString(String prevStr, 261 String capStr) { 262 if (prevStr == null) { 263 return capStr; 264 } 265 return prevStr + "|" + capStr; 266 } 267 268 @Override toString()269 public String toString() { 270 String sampleRateStr = null; 271 if (mSampleRate == SAMPLE_RATE_NONE) { 272 sampleRateStr = appendCapabilityToString(sampleRateStr, "NONE"); 273 } 274 if ((mSampleRate & SAMPLE_RATE_44100) != 0) { 275 sampleRateStr = appendCapabilityToString(sampleRateStr, "44100"); 276 } 277 if ((mSampleRate & SAMPLE_RATE_48000) != 0) { 278 sampleRateStr = appendCapabilityToString(sampleRateStr, "48000"); 279 } 280 if ((mSampleRate & SAMPLE_RATE_88200) != 0) { 281 sampleRateStr = appendCapabilityToString(sampleRateStr, "88200"); 282 } 283 if ((mSampleRate & SAMPLE_RATE_96000) != 0) { 284 sampleRateStr = appendCapabilityToString(sampleRateStr, "96000"); 285 } 286 if ((mSampleRate & SAMPLE_RATE_176400) != 0) { 287 sampleRateStr = appendCapabilityToString(sampleRateStr, "176400"); 288 } 289 if ((mSampleRate & SAMPLE_RATE_192000) != 0) { 290 sampleRateStr = appendCapabilityToString(sampleRateStr, "192000"); 291 } 292 293 String bitsPerSampleStr = null; 294 if (mBitsPerSample == BITS_PER_SAMPLE_NONE) { 295 bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "NONE"); 296 } 297 if ((mBitsPerSample & BITS_PER_SAMPLE_16) != 0) { 298 bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "16"); 299 } 300 if ((mBitsPerSample & BITS_PER_SAMPLE_24) != 0) { 301 bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "24"); 302 } 303 if ((mBitsPerSample & BITS_PER_SAMPLE_32) != 0) { 304 bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "32"); 305 } 306 307 String channelModeStr = null; 308 if (mChannelMode == CHANNEL_MODE_NONE) { 309 channelModeStr = appendCapabilityToString(channelModeStr, "NONE"); 310 } 311 if ((mChannelMode & CHANNEL_MODE_MONO) != 0) { 312 channelModeStr = appendCapabilityToString(channelModeStr, "MONO"); 313 } 314 if ((mChannelMode & CHANNEL_MODE_STEREO) != 0) { 315 channelModeStr = appendCapabilityToString(channelModeStr, "STEREO"); 316 } 317 318 return "{codecName:" + getCodecName() 319 + ",mCodecType:" + mCodecType 320 + ",mCodecPriority:" + mCodecPriority 321 + ",mSampleRate:" + String.format("0x%x", mSampleRate) 322 + "(" + sampleRateStr + ")" 323 + ",mBitsPerSample:" + String.format("0x%x", mBitsPerSample) 324 + "(" + bitsPerSampleStr + ")" 325 + ",mChannelMode:" + String.format("0x%x", mChannelMode) 326 + "(" + channelModeStr + ")" 327 + ",mCodecSpecific1:" + mCodecSpecific1 328 + ",mCodecSpecific2:" + mCodecSpecific2 329 + ",mCodecSpecific3:" + mCodecSpecific3 330 + ",mCodecSpecific4:" + mCodecSpecific4 + "}"; 331 } 332 333 /** 334 * Always returns 0 335 * 336 * @return 0 337 * @hide 338 */ 339 @Override describeContents()340 public int describeContents() { 341 return 0; 342 } 343 344 public static final @android.annotation.NonNull Parcelable.Creator<BluetoothCodecConfig> CREATOR = 345 new Parcelable.Creator<BluetoothCodecConfig>() { 346 public BluetoothCodecConfig createFromParcel(Parcel in) { 347 final int codecType = in.readInt(); 348 final int codecPriority = in.readInt(); 349 final int sampleRate = in.readInt(); 350 final int bitsPerSample = in.readInt(); 351 final int channelMode = in.readInt(); 352 final long codecSpecific1 = in.readLong(); 353 final long codecSpecific2 = in.readLong(); 354 final long codecSpecific3 = in.readLong(); 355 final long codecSpecific4 = in.readLong(); 356 return new BluetoothCodecConfig(codecType, codecPriority, 357 sampleRate, bitsPerSample, 358 channelMode, codecSpecific1, 359 codecSpecific2, codecSpecific3, 360 codecSpecific4); 361 } 362 363 public BluetoothCodecConfig[] newArray(int size) { 364 return new BluetoothCodecConfig[size]; 365 } 366 }; 367 368 /** 369 * Flattens the object to a parcel 370 * 371 * @param out The Parcel in which the object should be written. 372 * @param flags Additional flags about how the object should be written. 373 * 374 * @hide 375 */ 376 @Override writeToParcel(Parcel out, int flags)377 public void writeToParcel(Parcel out, int flags) { 378 out.writeInt(mCodecType); 379 out.writeInt(mCodecPriority); 380 out.writeInt(mSampleRate); 381 out.writeInt(mBitsPerSample); 382 out.writeInt(mChannelMode); 383 out.writeLong(mCodecSpecific1); 384 out.writeLong(mCodecSpecific2); 385 out.writeLong(mCodecSpecific3); 386 out.writeLong(mCodecSpecific4); 387 } 388 389 /** 390 * Gets the codec name. 391 * 392 * @return the codec name 393 */ getCodecName()394 public @NonNull String getCodecName() { 395 switch (mCodecType) { 396 case SOURCE_CODEC_TYPE_SBC: 397 return "SBC"; 398 case SOURCE_CODEC_TYPE_AAC: 399 return "AAC"; 400 case SOURCE_CODEC_TYPE_APTX: 401 return "aptX"; 402 case SOURCE_CODEC_TYPE_APTX_HD: 403 return "aptX HD"; 404 case SOURCE_CODEC_TYPE_LDAC: 405 return "LDAC"; 406 case SOURCE_CODEC_TYPE_INVALID: 407 return "INVALID CODEC"; 408 default: 409 break; 410 } 411 return "UNKNOWN CODEC(" + mCodecType + ")"; 412 } 413 414 /** 415 * Gets the codec type. 416 * See {@link android.bluetooth.BluetoothCodecConfig#SOURCE_CODEC_TYPE_SBC}. 417 * 418 * @return the codec type 419 */ 420 @UnsupportedAppUsage getCodecType()421 public @SourceCodecType int getCodecType() { 422 return mCodecType; 423 } 424 425 /** 426 * Checks whether the codec is mandatory. 427 * 428 * @return true if the codec is mandatory, otherwise false. 429 */ isMandatoryCodec()430 public boolean isMandatoryCodec() { 431 return mCodecType == SOURCE_CODEC_TYPE_SBC; 432 } 433 434 /** 435 * Gets the codec selection priority. 436 * The codec selection priority is relative to other codecs: larger value 437 * means higher priority. If 0, reset to default. 438 * 439 * @return the codec priority 440 */ 441 @UnsupportedAppUsage getCodecPriority()442 public @CodecPriority int getCodecPriority() { 443 return mCodecPriority; 444 } 445 446 /** 447 * Sets the codec selection priority. 448 * The codec selection priority is relative to other codecs: larger value 449 * means higher priority. If 0, reset to default. 450 * 451 * @param codecPriority the codec priority 452 * @hide 453 */ 454 @UnsupportedAppUsage setCodecPriority(@odecPriority int codecPriority)455 public void setCodecPriority(@CodecPriority int codecPriority) { 456 mCodecPriority = codecPriority; 457 } 458 459 /** 460 * Gets the codec sample rate. The value can be a bitmask with all 461 * supported sample rates: 462 * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_NONE} or 463 * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_44100} or 464 * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_48000} or 465 * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_88200} or 466 * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_96000} or 467 * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_176400} or 468 * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_192000} 469 * 470 * @return the codec sample rate 471 */ 472 @UnsupportedAppUsage getSampleRate()473 public @SampleRate int getSampleRate() { 474 return mSampleRate; 475 } 476 477 /** 478 * Gets the codec bits per sample. The value can be a bitmask with all 479 * bits per sample supported: 480 * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_NONE} or 481 * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_16} or 482 * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_24} or 483 * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_32} 484 * 485 * @return the codec bits per sample 486 */ 487 @UnsupportedAppUsage getBitsPerSample()488 public @BitsPerSample int getBitsPerSample() { 489 return mBitsPerSample; 490 } 491 492 /** 493 * Gets the codec channel mode. The value can be a bitmask with all 494 * supported channel modes: 495 * {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_NONE} or 496 * {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_MONO} or 497 * {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_STEREO} 498 * 499 * @return the codec channel mode 500 * @hide 501 */ 502 @UnsupportedAppUsage getChannelMode()503 public @ChannelMode int getChannelMode() { 504 return mChannelMode; 505 } 506 507 /** 508 * Gets a codec specific value1. 509 * 510 * @return a codec specific value1. 511 */ 512 @UnsupportedAppUsage getCodecSpecific1()513 public long getCodecSpecific1() { 514 return mCodecSpecific1; 515 } 516 517 /** 518 * Gets a codec specific value2. 519 * 520 * @return a codec specific value2 521 * @hide 522 */ 523 @UnsupportedAppUsage getCodecSpecific2()524 public long getCodecSpecific2() { 525 return mCodecSpecific2; 526 } 527 528 /** 529 * Gets a codec specific value3. 530 * 531 * @return a codec specific value3 532 * @hide 533 */ 534 @UnsupportedAppUsage getCodecSpecific3()535 public long getCodecSpecific3() { 536 return mCodecSpecific3; 537 } 538 539 /** 540 * Gets a codec specific value4. 541 * 542 * @return a codec specific value4 543 * @hide 544 */ 545 @UnsupportedAppUsage getCodecSpecific4()546 public long getCodecSpecific4() { 547 return mCodecSpecific4; 548 } 549 550 /** 551 * Checks whether a value set presented by a bitmask has zero or single bit 552 * 553 * @param valueSet the value set presented by a bitmask 554 * @return true if the valueSet contains zero or single bit, otherwise false. 555 * @hide 556 */ hasSingleBit(int valueSet)557 private static boolean hasSingleBit(int valueSet) { 558 return (valueSet == 0 || (valueSet & (valueSet - 1)) == 0); 559 } 560 561 /** 562 * Checks whether the object contains none or single sample rate. 563 * 564 * @return true if the object contains none or single sample rate, otherwise false. 565 * @hide 566 */ hasSingleSampleRate()567 public boolean hasSingleSampleRate() { 568 return hasSingleBit(mSampleRate); 569 } 570 571 /** 572 * Checks whether the object contains none or single bits per sample. 573 * 574 * @return true if the object contains none or single bits per sample, otherwise false. 575 * @hide 576 */ hasSingleBitsPerSample()577 public boolean hasSingleBitsPerSample() { 578 return hasSingleBit(mBitsPerSample); 579 } 580 581 /** 582 * Checks whether the object contains none or single channel mode. 583 * 584 * @return true if the object contains none or single channel mode, otherwise false. 585 * @hide 586 */ hasSingleChannelMode()587 public boolean hasSingleChannelMode() { 588 return hasSingleBit(mChannelMode); 589 } 590 591 /** 592 * Checks whether the audio feeding parameters are same. 593 * 594 * @param other the codec config to compare against 595 * @return true if the audio feeding parameters are same, otherwise false 596 * @hide 597 */ sameAudioFeedingParameters(BluetoothCodecConfig other)598 public boolean sameAudioFeedingParameters(BluetoothCodecConfig other) { 599 return (other != null && other.mSampleRate == mSampleRate 600 && other.mBitsPerSample == mBitsPerSample 601 && other.mChannelMode == mChannelMode); 602 } 603 604 /** 605 * Checks whether another codec config has the similar feeding parameters. 606 * Any parameters with NONE value will be considered to be a wildcard matching. 607 * 608 * @param other the codec config to compare against 609 * @return true if the audio feeding parameters are similar, otherwise false. 610 * @hide 611 */ similarCodecFeedingParameters(BluetoothCodecConfig other)612 public boolean similarCodecFeedingParameters(BluetoothCodecConfig other) { 613 if (other == null || mCodecType != other.mCodecType) { 614 return false; 615 } 616 int sampleRate = other.mSampleRate; 617 if (mSampleRate == BluetoothCodecConfig.SAMPLE_RATE_NONE 618 || sampleRate == BluetoothCodecConfig.SAMPLE_RATE_NONE) { 619 sampleRate = mSampleRate; 620 } 621 int bitsPerSample = other.mBitsPerSample; 622 if (mBitsPerSample == BluetoothCodecConfig.BITS_PER_SAMPLE_NONE 623 || bitsPerSample == BluetoothCodecConfig.BITS_PER_SAMPLE_NONE) { 624 bitsPerSample = mBitsPerSample; 625 } 626 int channelMode = other.mChannelMode; 627 if (mChannelMode == BluetoothCodecConfig.CHANNEL_MODE_NONE 628 || channelMode == BluetoothCodecConfig.CHANNEL_MODE_NONE) { 629 channelMode = mChannelMode; 630 } 631 return sameAudioFeedingParameters(new BluetoothCodecConfig( 632 mCodecType, /* priority */ 0, sampleRate, bitsPerSample, channelMode, 633 /* specific1 */ 0, /* specific2 */ 0, /* specific3 */ 0, 634 /* specific4 */ 0)); 635 } 636 637 /** 638 * Checks whether the codec specific parameters are the same. 639 * 640 * @param other the codec config to compare against 641 * @return true if the codec specific parameters are the same, otherwise false. 642 * @hide 643 */ sameCodecSpecificParameters(BluetoothCodecConfig other)644 public boolean sameCodecSpecificParameters(BluetoothCodecConfig other) { 645 if (other == null && mCodecType != other.mCodecType) { 646 return false; 647 } 648 // Currently we only care about the AAC VBR and LDAC Playback Quality at CodecSpecific1 649 switch (mCodecType) { 650 case SOURCE_CODEC_TYPE_AAC: 651 case SOURCE_CODEC_TYPE_LDAC: 652 if (mCodecSpecific1 != other.mCodecSpecific1) { 653 return false; 654 } 655 // fall through 656 default: 657 return true; 658 } 659 } 660 } 661