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 * <p>Contains the source codec type, the codec priority, the codec sample 33 * rate, the codec bits per sample, and the codec channel mode. 34 * <p>The source codec type values are the same as those supported by the 35 * device hardware. 36 * 37 * {@see BluetoothA2dp} 38 */ 39 public final class BluetoothCodecConfig implements Parcelable { 40 /** @hide */ 41 @IntDef(prefix = "SOURCE_CODEC_TYPE_", 42 value = {SOURCE_CODEC_TYPE_SBC, SOURCE_CODEC_TYPE_AAC, SOURCE_CODEC_TYPE_APTX, 43 SOURCE_CODEC_TYPE_APTX_HD, SOURCE_CODEC_TYPE_LDAC, SOURCE_CODEC_TYPE_LC3, 44 SOURCE_CODEC_TYPE_OPUS, SOURCE_CODEC_TYPE_INVALID}) 45 @Retention(RetentionPolicy.SOURCE) 46 public @interface SourceCodecType {} 47 48 /** 49 * Source codec type SBC. This is the mandatory source codec 50 * type. 51 */ 52 public static final int SOURCE_CODEC_TYPE_SBC = 0; 53 54 /** 55 * Source codec type AAC. 56 */ 57 public static final int SOURCE_CODEC_TYPE_AAC = 1; 58 59 /** 60 * Source codec type APTX. 61 */ 62 public static final int SOURCE_CODEC_TYPE_APTX = 2; 63 64 /** 65 * Source codec type APTX HD. 66 */ 67 public static final int SOURCE_CODEC_TYPE_APTX_HD = 3; 68 69 /** 70 * Source codec type LDAC. 71 */ 72 public static final int SOURCE_CODEC_TYPE_LDAC = 4; 73 74 /** 75 * Source codec type LC3. 76 */ 77 public static final int SOURCE_CODEC_TYPE_LC3 = 5; 78 79 /** 80 * Source codec type Opus. 81 */ 82 public static final int SOURCE_CODEC_TYPE_OPUS = 6; 83 84 /** 85 * Source codec type invalid. This is the default value used for codec 86 * type. 87 */ 88 public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000; 89 90 /** 91 * Represents the count of valid source codec types. 92 */ 93 private static final int SOURCE_CODEC_TYPE_MAX = 7; 94 95 /** @hide */ 96 @IntDef(prefix = "CODEC_PRIORITY_", value = { 97 CODEC_PRIORITY_DISABLED, 98 CODEC_PRIORITY_DEFAULT, 99 CODEC_PRIORITY_HIGHEST 100 }) 101 @Retention(RetentionPolicy.SOURCE) 102 public @interface CodecPriority {} 103 104 /** 105 * Codec priority disabled. 106 * Used to indicate that this codec is disabled and should not be used. 107 */ 108 public static final int CODEC_PRIORITY_DISABLED = -1; 109 110 /** 111 * Codec priority default. 112 * Default value used for codec priority. 113 */ 114 public static final int CODEC_PRIORITY_DEFAULT = 0; 115 116 /** 117 * Codec priority highest. 118 * Used to indicate the highest priority a codec can have. 119 */ 120 public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000; 121 122 /** @hide */ 123 @IntDef(prefix = "SAMPLE_RATE_", value = { 124 SAMPLE_RATE_NONE, 125 SAMPLE_RATE_44100, 126 SAMPLE_RATE_48000, 127 SAMPLE_RATE_88200, 128 SAMPLE_RATE_96000, 129 SAMPLE_RATE_176400, 130 SAMPLE_RATE_192000 131 }) 132 @Retention(RetentionPolicy.SOURCE) 133 public @interface SampleRate {} 134 135 /** 136 * Codec sample rate 0 Hz. Default value used for 137 * codec sample rate. 138 */ 139 public static final int SAMPLE_RATE_NONE = 0; 140 141 /** 142 * Codec sample rate 44100 Hz. 143 */ 144 public static final int SAMPLE_RATE_44100 = 0x1 << 0; 145 146 /** 147 * Codec sample rate 48000 Hz. 148 */ 149 public static final int SAMPLE_RATE_48000 = 0x1 << 1; 150 151 /** 152 * Codec sample rate 88200 Hz. 153 */ 154 public static final int SAMPLE_RATE_88200 = 0x1 << 2; 155 156 /** 157 * Codec sample rate 96000 Hz. 158 */ 159 public static final int SAMPLE_RATE_96000 = 0x1 << 3; 160 161 /** 162 * Codec sample rate 176400 Hz. 163 */ 164 public static final int SAMPLE_RATE_176400 = 0x1 << 4; 165 166 /** 167 * Codec sample rate 192000 Hz. 168 */ 169 public static final int SAMPLE_RATE_192000 = 0x1 << 5; 170 171 /** @hide */ 172 @IntDef(prefix = "BITS_PER_SAMPLE_", value = { 173 BITS_PER_SAMPLE_NONE, 174 BITS_PER_SAMPLE_16, 175 BITS_PER_SAMPLE_24, 176 BITS_PER_SAMPLE_32 177 }) 178 @Retention(RetentionPolicy.SOURCE) 179 public @interface BitsPerSample {} 180 181 /** 182 * Codec bits per sample 0. Default value of the codec 183 * bits per sample. 184 */ 185 public static final int BITS_PER_SAMPLE_NONE = 0; 186 187 /** 188 * Codec bits per sample 16. 189 */ 190 public static final int BITS_PER_SAMPLE_16 = 0x1 << 0; 191 192 /** 193 * Codec bits per sample 24. 194 */ 195 public static final int BITS_PER_SAMPLE_24 = 0x1 << 1; 196 197 /** 198 * Codec bits per sample 32. 199 */ 200 public static final int BITS_PER_SAMPLE_32 = 0x1 << 2; 201 202 /** @hide */ 203 @IntDef(prefix = "CHANNEL_MODE_", value = { 204 CHANNEL_MODE_NONE, 205 CHANNEL_MODE_MONO, 206 CHANNEL_MODE_STEREO 207 }) 208 @Retention(RetentionPolicy.SOURCE) 209 public @interface ChannelMode {} 210 211 /** 212 * Codec channel mode NONE. Default value of the 213 * codec channel mode. 214 */ 215 public static final int CHANNEL_MODE_NONE = 0; 216 217 /** 218 * Codec channel mode MONO. 219 */ 220 public static final int CHANNEL_MODE_MONO = 0x1 << 0; 221 222 /** 223 * Codec channel mode STEREO. 224 */ 225 public static final int CHANNEL_MODE_STEREO = 0x1 << 1; 226 227 private final @SourceCodecType int mCodecType; 228 private @CodecPriority int mCodecPriority; 229 private final @SampleRate int mSampleRate; 230 private final @BitsPerSample int mBitsPerSample; 231 private final @ChannelMode int mChannelMode; 232 private final long mCodecSpecific1; 233 private final long mCodecSpecific2; 234 private final long mCodecSpecific3; 235 private final long mCodecSpecific4; 236 237 /** 238 * Creates a new BluetoothCodecConfig. 239 * 240 * @param codecType the source codec type 241 * @param codecPriority the priority of this codec 242 * @param sampleRate the codec sample rate 243 * @param bitsPerSample the bits per sample of this codec 244 * @param channelMode the channel mode of this codec 245 * @param codecSpecific1 the specific value 1 246 * @param codecSpecific2 the specific value 2 247 * @param codecSpecific3 the specific value 3 248 * @param codecSpecific4 the specific value 4 249 * values to 0. 250 * @hide 251 */ 252 @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)253 public BluetoothCodecConfig(@SourceCodecType int codecType, @CodecPriority int codecPriority, 254 @SampleRate int sampleRate, @BitsPerSample int bitsPerSample, 255 @ChannelMode int channelMode, long codecSpecific1, 256 long codecSpecific2, long codecSpecific3, 257 long codecSpecific4) { 258 mCodecType = codecType; 259 mCodecPriority = codecPriority; 260 mSampleRate = sampleRate; 261 mBitsPerSample = bitsPerSample; 262 mChannelMode = channelMode; 263 mCodecSpecific1 = codecSpecific1; 264 mCodecSpecific2 = codecSpecific2; 265 mCodecSpecific3 = codecSpecific3; 266 mCodecSpecific4 = codecSpecific4; 267 } 268 269 /** 270 * Creates a new BluetoothCodecConfig. 271 * <p> By default, the codec priority will be set 272 * to {@link BluetoothCodecConfig#CODEC_PRIORITY_DEFAULT}, the sample rate to 273 * {@link BluetoothCodecConfig#SAMPLE_RATE_NONE}, the bits per sample to 274 * {@link BluetoothCodecConfig#BITS_PER_SAMPLE_NONE}, the channel mode to 275 * {@link BluetoothCodecConfig#CHANNEL_MODE_NONE}, and all the codec specific 276 * values to 0. 277 * 278 * @param codecType the source codec type 279 * @hide 280 */ BluetoothCodecConfig(@ourceCodecType int codecType)281 public BluetoothCodecConfig(@SourceCodecType int codecType) { 282 this(codecType, BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT, 283 BluetoothCodecConfig.SAMPLE_RATE_NONE, 284 BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, 285 BluetoothCodecConfig.CHANNEL_MODE_NONE, 0, 0, 0, 0); 286 } 287 BluetoothCodecConfig(Parcel in)288 private BluetoothCodecConfig(Parcel in) { 289 mCodecType = in.readInt(); 290 mCodecPriority = in.readInt(); 291 mSampleRate = in.readInt(); 292 mBitsPerSample = in.readInt(); 293 mChannelMode = in.readInt(); 294 mCodecSpecific1 = in.readLong(); 295 mCodecSpecific2 = in.readLong(); 296 mCodecSpecific3 = in.readLong(); 297 mCodecSpecific4 = in.readLong(); 298 } 299 300 @Override equals(@ullable Object o)301 public boolean equals(@Nullable Object o) { 302 if (o instanceof BluetoothCodecConfig) { 303 BluetoothCodecConfig other = (BluetoothCodecConfig) o; 304 return (other.mCodecType == mCodecType 305 && other.mCodecPriority == mCodecPriority 306 && other.mSampleRate == mSampleRate 307 && other.mBitsPerSample == mBitsPerSample 308 && other.mChannelMode == mChannelMode 309 && other.mCodecSpecific1 == mCodecSpecific1 310 && other.mCodecSpecific2 == mCodecSpecific2 311 && other.mCodecSpecific3 == mCodecSpecific3 312 && other.mCodecSpecific4 == mCodecSpecific4); 313 } 314 return false; 315 } 316 317 /** 318 * Returns a hash representation of this BluetoothCodecConfig 319 * based on all the config values. 320 */ 321 @Override hashCode()322 public int hashCode() { 323 return Objects.hash(mCodecType, mCodecPriority, mSampleRate, 324 mBitsPerSample, mChannelMode, mCodecSpecific1, 325 mCodecSpecific2, mCodecSpecific3, mCodecSpecific4); 326 } 327 328 /** 329 * Adds capability string to an existing string. 330 * 331 * @param prevStr the previous string with the capabilities. Can be a {@code null} pointer 332 * @param capStr the capability string to append to prevStr argument 333 * @return the result string in the form "prevStr|capStr" 334 */ appendCapabilityToString(@ullable String prevStr, @NonNull String capStr)335 private static String appendCapabilityToString(@Nullable String prevStr, 336 @NonNull String capStr) { 337 if (prevStr == null) { 338 return capStr; 339 } 340 return prevStr + "|" + capStr; 341 } 342 343 /** 344 * Returns a {@link String} that describes each BluetoothCodecConfig parameter 345 * current value. 346 */ 347 @Override toString()348 public String toString() { 349 String sampleRateStr = null; 350 if (mSampleRate == SAMPLE_RATE_NONE) { 351 sampleRateStr = appendCapabilityToString(sampleRateStr, "NONE"); 352 } 353 if ((mSampleRate & SAMPLE_RATE_44100) != 0) { 354 sampleRateStr = appendCapabilityToString(sampleRateStr, "44100"); 355 } 356 if ((mSampleRate & SAMPLE_RATE_48000) != 0) { 357 sampleRateStr = appendCapabilityToString(sampleRateStr, "48000"); 358 } 359 if ((mSampleRate & SAMPLE_RATE_88200) != 0) { 360 sampleRateStr = appendCapabilityToString(sampleRateStr, "88200"); 361 } 362 if ((mSampleRate & SAMPLE_RATE_96000) != 0) { 363 sampleRateStr = appendCapabilityToString(sampleRateStr, "96000"); 364 } 365 if ((mSampleRate & SAMPLE_RATE_176400) != 0) { 366 sampleRateStr = appendCapabilityToString(sampleRateStr, "176400"); 367 } 368 if ((mSampleRate & SAMPLE_RATE_192000) != 0) { 369 sampleRateStr = appendCapabilityToString(sampleRateStr, "192000"); 370 } 371 372 String bitsPerSampleStr = null; 373 if (mBitsPerSample == BITS_PER_SAMPLE_NONE) { 374 bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "NONE"); 375 } 376 if ((mBitsPerSample & BITS_PER_SAMPLE_16) != 0) { 377 bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "16"); 378 } 379 if ((mBitsPerSample & BITS_PER_SAMPLE_24) != 0) { 380 bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "24"); 381 } 382 if ((mBitsPerSample & BITS_PER_SAMPLE_32) != 0) { 383 bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "32"); 384 } 385 386 String channelModeStr = null; 387 if (mChannelMode == CHANNEL_MODE_NONE) { 388 channelModeStr = appendCapabilityToString(channelModeStr, "NONE"); 389 } 390 if ((mChannelMode & CHANNEL_MODE_MONO) != 0) { 391 channelModeStr = appendCapabilityToString(channelModeStr, "MONO"); 392 } 393 if ((mChannelMode & CHANNEL_MODE_STEREO) != 0) { 394 channelModeStr = appendCapabilityToString(channelModeStr, "STEREO"); 395 } 396 397 return "{codecName:" + getCodecName(mCodecType) 398 + ",mCodecType:" + mCodecType 399 + ",mCodecPriority:" + mCodecPriority 400 + ",mSampleRate:" + String.format("0x%x", mSampleRate) 401 + "(" + sampleRateStr + ")" 402 + ",mBitsPerSample:" + String.format("0x%x", mBitsPerSample) 403 + "(" + bitsPerSampleStr + ")" 404 + ",mChannelMode:" + String.format("0x%x", mChannelMode) 405 + "(" + channelModeStr + ")" 406 + ",mCodecSpecific1:" + mCodecSpecific1 407 + ",mCodecSpecific2:" + mCodecSpecific2 408 + ",mCodecSpecific3:" + mCodecSpecific3 409 + ",mCodecSpecific4:" + mCodecSpecific4 + "}"; 410 } 411 412 /** 413 * @return 0 414 * @hide 415 */ 416 @Override describeContents()417 public int describeContents() { 418 return 0; 419 } 420 421 public static final @NonNull Creator<BluetoothCodecConfig> CREATOR = new Creator<>() { 422 public BluetoothCodecConfig createFromParcel(Parcel in) { 423 return new BluetoothCodecConfig(in); 424 } 425 426 public BluetoothCodecConfig[] newArray(int size) { 427 return new BluetoothCodecConfig[size]; 428 } 429 }; 430 431 /** 432 * Flattens the object to a parcel 433 * 434 * @param out The Parcel in which the object should be written 435 * @param flags Additional flags about how the object should be written 436 * 437 * @hide 438 */ 439 @Override writeToParcel(Parcel out, int flags)440 public void writeToParcel(Parcel out, int flags) { 441 out.writeInt(mCodecType); 442 out.writeInt(mCodecPriority); 443 out.writeInt(mSampleRate); 444 out.writeInt(mBitsPerSample); 445 out.writeInt(mChannelMode); 446 out.writeLong(mCodecSpecific1); 447 out.writeLong(mCodecSpecific2); 448 out.writeLong(mCodecSpecific3); 449 out.writeLong(mCodecSpecific4); 450 } 451 452 /** 453 * Returns the codec name converted to {@link String}. 454 * @hide 455 */ getCodecName(@ourceCodecType int codecType)456 public static @NonNull String getCodecName(@SourceCodecType int codecType) { 457 switch (codecType) { 458 case SOURCE_CODEC_TYPE_SBC: 459 return "SBC"; 460 case SOURCE_CODEC_TYPE_AAC: 461 return "AAC"; 462 case SOURCE_CODEC_TYPE_APTX: 463 return "aptX"; 464 case SOURCE_CODEC_TYPE_APTX_HD: 465 return "aptX HD"; 466 case SOURCE_CODEC_TYPE_LDAC: 467 return "LDAC"; 468 case SOURCE_CODEC_TYPE_LC3: 469 return "LC3"; 470 case SOURCE_CODEC_TYPE_OPUS: 471 return "Opus"; 472 case SOURCE_CODEC_TYPE_INVALID: 473 return "INVALID CODEC"; 474 default: 475 break; 476 } 477 return "UNKNOWN CODEC(" + codecType + ")"; 478 } 479 480 /** 481 * Returns the source codec type of this config. 482 */ getCodecType()483 public @SourceCodecType int getCodecType() { 484 return mCodecType; 485 } 486 487 /** 488 * Checks whether the codec is mandatory. 489 * <p> The actual mandatory codec type for Android Bluetooth audio is SBC. 490 * See {@link #SOURCE_CODEC_TYPE_SBC}. 491 * 492 * @return {@code true} if the codec is mandatory, {@code false} otherwise 493 */ isMandatoryCodec()494 public boolean isMandatoryCodec() { 495 return mCodecType == SOURCE_CODEC_TYPE_SBC; 496 } 497 498 /** 499 * Returns the codec selection priority. 500 * <p>The codec selection priority is relative to other codecs: larger value 501 * means higher priority. 502 */ getCodecPriority()503 public @CodecPriority int getCodecPriority() { 504 return mCodecPriority; 505 } 506 507 /** 508 * Sets the codec selection priority. 509 * <p>The codec selection priority is relative to other codecs: larger value 510 * means higher priority. 511 * 512 * @param codecPriority the priority this codec should have 513 * @hide 514 */ setCodecPriority(@odecPriority int codecPriority)515 public void setCodecPriority(@CodecPriority int codecPriority) { 516 mCodecPriority = codecPriority; 517 } 518 519 /** 520 * Returns the codec sample rate. The value can be a bitmask with all 521 * supported sample rates. 522 */ getSampleRate()523 public @SampleRate int getSampleRate() { 524 return mSampleRate; 525 } 526 527 /** 528 * Returns the codec bits per sample. The value can be a bitmask with all 529 * bits per sample supported. 530 */ getBitsPerSample()531 public @BitsPerSample int getBitsPerSample() { 532 return mBitsPerSample; 533 } 534 535 /** 536 * Returns the codec channel mode. The value can be a bitmask with all 537 * supported channel modes. 538 */ getChannelMode()539 public @ChannelMode int getChannelMode() { 540 return mChannelMode; 541 } 542 543 /** 544 * Returns the codec specific value1. 545 * As the value and usage differ for each codec, please refer to the concerned 546 * codec specification to obtain the codec specific information. 547 * 548 * <p>See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific 549 * information elements. 550 * <p>See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio 551 * codec specific information elements. 552 * <p>See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC 553 * codec specific information elements. 554 * <p>See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family 555 * codec specific information elements. 556 * <p>See section 4.7.2 of the Bluetooth A2dp specification for Vendor Specific A2DP 557 * codec specific information elements. 558 */ getCodecSpecific1()559 public long getCodecSpecific1() { 560 return mCodecSpecific1; 561 } 562 563 /** 564 * Returns the codec specific value2. 565 * As the value and usage differ for each codec, please refer to the concerned 566 * codec specification to obtain the codec specific information. 567 * 568 * <p>See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific 569 * information elements. 570 * <p>See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio 571 * codec specific information elements. 572 * <p>See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC 573 * codec specific information elements. 574 * <p>See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family 575 * codec specific information elements. 576 * <p>See section 4.7.2 of the Bluetooth A2dp specification for Vendor Specific A2DP 577 * codec specific information elements. 578 */ getCodecSpecific2()579 public long getCodecSpecific2() { 580 return mCodecSpecific2; 581 } 582 583 /** 584 * Returns the codec specific value3. 585 * As the value and usage differ for each codec, please refer to the concerned 586 * codec specification to obtain the codec specific information. 587 * 588 * <p>See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific 589 * information elements. 590 * <p>See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio 591 * codec specific information elements. 592 * <p>See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC 593 * codec specific information elements. 594 * <p>See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family 595 * codec specific information elements. 596 * <p>See section 4.7.2 of the Bluetooth A2dp specification for Vendor Specific A2DP 597 * codec specific information elements. 598 */ getCodecSpecific3()599 public long getCodecSpecific3() { 600 return mCodecSpecific3; 601 } 602 603 /** 604 * Returns the codec specific value4. 605 * As the value and usage differ for each codec, please refer to the concerned 606 * codec specification to obtain the codec specific information. 607 * 608 * <p>See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific 609 * information elements. 610 * <p>See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio 611 * codec specific information elements. 612 * <p>See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC 613 * codec specific information elements. 614 * <p>See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family 615 * codec specific information elements. 616 * <p>See section 4.7.2 of the Bluetooth A2dp specification for Vendor Specific A2DP 617 * codec specific information elements. 618 */ getCodecSpecific4()619 public long getCodecSpecific4() { 620 return mCodecSpecific4; 621 } 622 623 /** 624 * Checks whether a value set presented by a bitmask has zero or single bit 625 * 626 * @param valueSet the value set presented by a bitmask 627 * @return {@code true} if the valueSet contains zero or single bit, {@code false} otherwise 628 * @hide 629 */ hasSingleBit(int valueSet)630 private static boolean hasSingleBit(int valueSet) { 631 return (valueSet == 0 || (valueSet & (valueSet - 1)) == 0); 632 } 633 634 /** 635 * Returns whether the object contains none or single sample rate. 636 * @hide 637 */ hasSingleSampleRate()638 public boolean hasSingleSampleRate() { 639 return hasSingleBit(mSampleRate); 640 } 641 642 /** 643 * Returns whether the object contains none or single bits per sample. 644 * @hide 645 */ hasSingleBitsPerSample()646 public boolean hasSingleBitsPerSample() { 647 return hasSingleBit(mBitsPerSample); 648 } 649 650 /** 651 * Returns whether the object contains none or single channel mode. 652 * @hide 653 */ hasSingleChannelMode()654 public boolean hasSingleChannelMode() { 655 return hasSingleBit(mChannelMode); 656 } 657 658 /** 659 * Checks whether the audio feeding parameters are the same. 660 * 661 * @param other the codec config to compare against 662 * @return {@code true} if the audio feeding parameters are same, {@code false} otherwise 663 * @hide 664 */ sameAudioFeedingParameters(BluetoothCodecConfig other)665 public boolean sameAudioFeedingParameters(BluetoothCodecConfig other) { 666 return (other != null && other.mSampleRate == mSampleRate 667 && other.mBitsPerSample == mBitsPerSample 668 && other.mChannelMode == mChannelMode); 669 } 670 671 /** 672 * Checks whether another codec config has the similar feeding parameters. 673 * Any parameters with NONE value will be considered to be a wildcard matching. 674 * 675 * @param other the codec config to compare against 676 * @return {@code true} if the audio feeding parameters are similar, {@code false} otherwise 677 * @hide 678 */ similarCodecFeedingParameters(BluetoothCodecConfig other)679 public boolean similarCodecFeedingParameters(BluetoothCodecConfig other) { 680 if (other == null || mCodecType != other.mCodecType) { 681 return false; 682 } 683 int sampleRate = other.mSampleRate; 684 if (mSampleRate == SAMPLE_RATE_NONE 685 || sampleRate == SAMPLE_RATE_NONE) { 686 sampleRate = mSampleRate; 687 } 688 int bitsPerSample = other.mBitsPerSample; 689 if (mBitsPerSample == BITS_PER_SAMPLE_NONE 690 || bitsPerSample == BITS_PER_SAMPLE_NONE) { 691 bitsPerSample = mBitsPerSample; 692 } 693 int channelMode = other.mChannelMode; 694 if (mChannelMode == CHANNEL_MODE_NONE 695 || channelMode == CHANNEL_MODE_NONE) { 696 channelMode = mChannelMode; 697 } 698 return sameAudioFeedingParameters(new BluetoothCodecConfig( 699 mCodecType, /* priority */ 0, sampleRate, bitsPerSample, channelMode, 700 /* specific1 */ 0, /* specific2 */ 0, /* specific3 */ 0, 701 /* specific4 */ 0)); 702 } 703 704 /** 705 * Checks whether the codec specific parameters are the same. 706 * <p> Currently, only AAC VBR and LDAC Playback Quality on CodecSpecific1 707 * are compared. 708 * 709 * @param other the codec config to compare against 710 * @return {@code true} if the codec specific parameters are the same, {@code false} otherwise 711 * @hide 712 */ sameCodecSpecificParameters(BluetoothCodecConfig other)713 public boolean sameCodecSpecificParameters(BluetoothCodecConfig other) { 714 if (other == null && mCodecType != other.mCodecType) { 715 return false; 716 } 717 switch (mCodecType) { 718 case SOURCE_CODEC_TYPE_AAC: 719 case SOURCE_CODEC_TYPE_LDAC: 720 case SOURCE_CODEC_TYPE_LC3: 721 case SOURCE_CODEC_TYPE_OPUS: 722 if (mCodecSpecific1 != other.mCodecSpecific1) { 723 return false; 724 } 725 // fall through 726 default: 727 return true; 728 } 729 } 730 731 /** 732 * Builder for {@link BluetoothCodecConfig}. 733 * <p> By default, the codec type will be set to 734 * {@link BluetoothCodecConfig#SOURCE_CODEC_TYPE_INVALID}, the codec priority 735 * to {@link BluetoothCodecConfig#CODEC_PRIORITY_DEFAULT}, the sample rate to 736 * {@link BluetoothCodecConfig#SAMPLE_RATE_NONE}, the bits per sample to 737 * {@link BluetoothCodecConfig#BITS_PER_SAMPLE_NONE}, the channel mode to 738 * {@link BluetoothCodecConfig#CHANNEL_MODE_NONE}, and all the codec specific 739 * values to 0. 740 */ 741 public static final class Builder { 742 private int mCodecType = BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID; 743 private int mCodecPriority = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT; 744 private int mSampleRate = BluetoothCodecConfig.SAMPLE_RATE_NONE; 745 private int mBitsPerSample = BluetoothCodecConfig.BITS_PER_SAMPLE_NONE; 746 private int mChannelMode = BluetoothCodecConfig.CHANNEL_MODE_NONE; 747 private long mCodecSpecific1 = 0; 748 private long mCodecSpecific2 = 0; 749 private long mCodecSpecific3 = 0; 750 private long mCodecSpecific4 = 0; 751 752 /** 753 * Set codec type for Bluetooth codec config. 754 * 755 * @param codecType of this codec 756 * @return the same Builder instance 757 */ setCodecType(@ourceCodecType int codecType)758 public @NonNull Builder setCodecType(@SourceCodecType int codecType) { 759 mCodecType = codecType; 760 return this; 761 } 762 763 /** 764 * Set codec priority for Bluetooth codec config. 765 * 766 * @param codecPriority of this codec 767 * @return the same Builder instance 768 */ setCodecPriority(@odecPriority int codecPriority)769 public @NonNull Builder setCodecPriority(@CodecPriority int codecPriority) { 770 mCodecPriority = codecPriority; 771 return this; 772 } 773 774 /** 775 * Set sample rate for Bluetooth codec config. 776 * 777 * @param sampleRate of this codec 778 * @return the same Builder instance 779 */ setSampleRate(@ampleRate int sampleRate)780 public @NonNull Builder setSampleRate(@SampleRate int sampleRate) { 781 mSampleRate = sampleRate; 782 return this; 783 } 784 785 /** 786 * Set the bits per sample for Bluetooth codec config. 787 * 788 * @param bitsPerSample of this codec 789 * @return the same Builder instance 790 */ setBitsPerSample(@itsPerSample int bitsPerSample)791 public @NonNull Builder setBitsPerSample(@BitsPerSample int bitsPerSample) { 792 mBitsPerSample = bitsPerSample; 793 return this; 794 } 795 796 /** 797 * Set the channel mode for Bluetooth codec config. 798 * 799 * @param channelMode of this codec 800 * @return the same Builder instance 801 */ setChannelMode(@hannelMode int channelMode)802 public @NonNull Builder setChannelMode(@ChannelMode int channelMode) { 803 mChannelMode = channelMode; 804 return this; 805 } 806 807 /** 808 * Set the first codec specific values for Bluetooth codec config. 809 * 810 * @param codecSpecific1 codec specific value or 0 if default 811 * @return the same Builder instance 812 */ setCodecSpecific1(long codecSpecific1)813 public @NonNull Builder setCodecSpecific1(long codecSpecific1) { 814 mCodecSpecific1 = codecSpecific1; 815 return this; 816 } 817 818 /** 819 * Set the second codec specific values for Bluetooth codec config. 820 * 821 * @param codecSpecific2 codec specific value or 0 if default 822 * @return the same Builder instance 823 */ setCodecSpecific2(long codecSpecific2)824 public @NonNull Builder setCodecSpecific2(long codecSpecific2) { 825 mCodecSpecific2 = codecSpecific2; 826 return this; 827 } 828 829 /** 830 * Set the third codec specific values for Bluetooth codec config. 831 * 832 * @param codecSpecific3 codec specific value or 0 if default 833 * @return the same Builder instance 834 */ setCodecSpecific3(long codecSpecific3)835 public @NonNull Builder setCodecSpecific3(long codecSpecific3) { 836 mCodecSpecific3 = codecSpecific3; 837 return this; 838 } 839 840 /** 841 * Set the fourth codec specific values for Bluetooth codec config. 842 * 843 * @param codecSpecific4 codec specific value or 0 if default 844 * @return the same Builder instance 845 */ setCodecSpecific4(long codecSpecific4)846 public @NonNull Builder setCodecSpecific4(long codecSpecific4) { 847 mCodecSpecific4 = codecSpecific4; 848 return this; 849 } 850 851 /** 852 * Build {@link BluetoothCodecConfig}. 853 * @return new BluetoothCodecConfig built 854 */ build()855 public @NonNull BluetoothCodecConfig build() { 856 return new BluetoothCodecConfig(mCodecType, mCodecPriority, 857 mSampleRate, mBitsPerSample, 858 mChannelMode, mCodecSpecific1, 859 mCodecSpecific2, mCodecSpecific3, 860 mCodecSpecific4); 861 } 862 } 863 } 864