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