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_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 private 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 @android.annotation.NonNull Parcelable.Creator<BluetoothCodecConfig> CREATOR = 422 new Parcelable.Creator<BluetoothCodecConfig>() { 423 public BluetoothCodecConfig createFromParcel(Parcel in) { 424 return new BluetoothCodecConfig(in); 425 } 426 427 public BluetoothCodecConfig[] newArray(int size) { 428 return new BluetoothCodecConfig[size]; 429 } 430 }; 431 432 /** 433 * Flattens the object to a parcel 434 * 435 * @param out The Parcel in which the object should be written 436 * @param flags Additional flags about how the object should be written 437 * 438 * @hide 439 */ 440 @Override writeToParcel(Parcel out, int flags)441 public void writeToParcel(Parcel out, int flags) { 442 out.writeInt(mCodecType); 443 out.writeInt(mCodecPriority); 444 out.writeInt(mSampleRate); 445 out.writeInt(mBitsPerSample); 446 out.writeInt(mChannelMode); 447 out.writeLong(mCodecSpecific1); 448 out.writeLong(mCodecSpecific2); 449 out.writeLong(mCodecSpecific3); 450 out.writeLong(mCodecSpecific4); 451 } 452 453 /** 454 * Returns the codec name converted to {@link String}. 455 * @hide 456 */ getCodecName(@ourceCodecType int codecType)457 public static @NonNull String getCodecName(@SourceCodecType int codecType) { 458 switch (codecType) { 459 case SOURCE_CODEC_TYPE_SBC: 460 return "SBC"; 461 case SOURCE_CODEC_TYPE_AAC: 462 return "AAC"; 463 case SOURCE_CODEC_TYPE_APTX: 464 return "aptX"; 465 case SOURCE_CODEC_TYPE_APTX_HD: 466 return "aptX HD"; 467 case SOURCE_CODEC_TYPE_LDAC: 468 return "LDAC"; 469 case SOURCE_CODEC_TYPE_LC3: 470 return "LC3"; 471 case SOURCE_CODEC_TYPE_OPUS: 472 return "Opus"; 473 case SOURCE_CODEC_TYPE_INVALID: 474 return "INVALID CODEC"; 475 default: 476 break; 477 } 478 return "UNKNOWN CODEC(" + codecType + ")"; 479 } 480 481 /** 482 * Returns the source codec type of this config. 483 */ getCodecType()484 public @SourceCodecType int getCodecType() { 485 return mCodecType; 486 } 487 488 /** 489 * Checks whether the codec is mandatory. 490 * <p> The actual mandatory codec type for Android Bluetooth audio is SBC. 491 * See {@link #SOURCE_CODEC_TYPE_SBC}. 492 * 493 * @return {@code true} if the codec is mandatory, {@code false} otherwise 494 */ isMandatoryCodec()495 public boolean isMandatoryCodec() { 496 return mCodecType == SOURCE_CODEC_TYPE_SBC; 497 } 498 499 /** 500 * Returns the codec selection priority. 501 * <p>The codec selection priority is relative to other codecs: larger value 502 * means higher priority. 503 */ getCodecPriority()504 public @CodecPriority int getCodecPriority() { 505 return mCodecPriority; 506 } 507 508 /** 509 * Sets the codec selection priority. 510 * <p>The codec selection priority is relative to other codecs: larger value 511 * means higher priority. 512 * 513 * @param codecPriority the priority this codec should have 514 * @hide 515 */ setCodecPriority(@odecPriority int codecPriority)516 public void setCodecPriority(@CodecPriority int codecPriority) { 517 mCodecPriority = codecPriority; 518 } 519 520 /** 521 * Returns the codec sample rate. The value can be a bitmask with all 522 * supported sample rates. 523 */ getSampleRate()524 public @SampleRate int getSampleRate() { 525 return mSampleRate; 526 } 527 528 /** 529 * Returns the codec bits per sample. The value can be a bitmask with all 530 * bits per sample supported. 531 */ getBitsPerSample()532 public @BitsPerSample int getBitsPerSample() { 533 return mBitsPerSample; 534 } 535 536 /** 537 * Returns the codec channel mode. The value can be a bitmask with all 538 * supported channel modes. 539 */ getChannelMode()540 public @ChannelMode int getChannelMode() { 541 return mChannelMode; 542 } 543 544 /** 545 * Returns the codec specific value1. 546 * As the value and usage differ for each codec, please refer to the concerned 547 * codec specification to obtain the codec specific information. 548 * 549 * <p>See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific 550 * information elements. 551 * <p>See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio 552 * codec specific information elements. 553 * <p>See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC 554 * codec specific information elements. 555 * <p>See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family 556 * codec specific information elements. 557 * <p>See section 4.7.2 of the Bluetooth A2dp specification for Vendor Specific A2DP 558 * codec specific information elements. 559 */ getCodecSpecific1()560 public long getCodecSpecific1() { 561 return mCodecSpecific1; 562 } 563 564 /** 565 * Returns the codec specific value2. 566 * As the value and usage differ for each codec, please refer to the concerned 567 * codec specification to obtain the codec specific information. 568 * 569 * <p>See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific 570 * information elements. 571 * <p>See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio 572 * codec specific information elements. 573 * <p>See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC 574 * codec specific information elements. 575 * <p>See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family 576 * codec specific information elements. 577 * <p>See section 4.7.2 of the Bluetooth A2dp specification for Vendor Specific A2DP 578 * codec specific information elements. 579 */ getCodecSpecific2()580 public long getCodecSpecific2() { 581 return mCodecSpecific2; 582 } 583 584 /** 585 * Returns the codec specific value3. 586 * As the value and usage differ for each codec, please refer to the concerned 587 * codec specification to obtain the codec specific information. 588 * 589 * <p>See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific 590 * information elements. 591 * <p>See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio 592 * codec specific information elements. 593 * <p>See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC 594 * codec specific information elements. 595 * <p>See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family 596 * codec specific information elements. 597 * <p>See section 4.7.2 of the Bluetooth A2dp specification for Vendor Specific A2DP 598 * codec specific information elements. 599 */ getCodecSpecific3()600 public long getCodecSpecific3() { 601 return mCodecSpecific3; 602 } 603 604 /** 605 * Returns the codec specific value4. 606 * As the value and usage differ for each codec, please refer to the concerned 607 * codec specification to obtain the codec specific information. 608 * 609 * <p>See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific 610 * information elements. 611 * <p>See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio 612 * codec specific information elements. 613 * <p>See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC 614 * codec specific information elements. 615 * <p>See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family 616 * codec specific information elements. 617 * <p>See section 4.7.2 of the Bluetooth A2dp specification for Vendor Specific A2DP 618 * codec specific information elements. 619 */ getCodecSpecific4()620 public long getCodecSpecific4() { 621 return mCodecSpecific4; 622 } 623 624 /** 625 * Checks whether a value set presented by a bitmask has zero or single bit 626 * 627 * @param valueSet the value set presented by a bitmask 628 * @return {@code true} if the valueSet contains zero or single bit, {@code false} otherwise 629 * @hide 630 */ hasSingleBit(int valueSet)631 private static boolean hasSingleBit(int valueSet) { 632 return (valueSet == 0 || (valueSet & (valueSet - 1)) == 0); 633 } 634 635 /** 636 * Returns whether the object contains none or single sample rate. 637 * @hide 638 */ hasSingleSampleRate()639 public boolean hasSingleSampleRate() { 640 return hasSingleBit(mSampleRate); 641 } 642 643 /** 644 * Returns whether the object contains none or single bits per sample. 645 * @hide 646 */ hasSingleBitsPerSample()647 public boolean hasSingleBitsPerSample() { 648 return hasSingleBit(mBitsPerSample); 649 } 650 651 /** 652 * Returns whether the object contains none or single channel mode. 653 * @hide 654 */ hasSingleChannelMode()655 public boolean hasSingleChannelMode() { 656 return hasSingleBit(mChannelMode); 657 } 658 659 /** 660 * Checks whether the audio feeding parameters are the same. 661 * 662 * @param other the codec config to compare against 663 * @return {@code true} if the audio feeding parameters are same, {@code false} otherwise 664 * @hide 665 */ sameAudioFeedingParameters(BluetoothCodecConfig other)666 public boolean sameAudioFeedingParameters(BluetoothCodecConfig other) { 667 return (other != null && other.mSampleRate == mSampleRate 668 && other.mBitsPerSample == mBitsPerSample 669 && other.mChannelMode == mChannelMode); 670 } 671 672 /** 673 * Checks whether another codec config has the similar feeding parameters. 674 * Any parameters with NONE value will be considered to be a wildcard matching. 675 * 676 * @param other the codec config to compare against 677 * @return {@code true} if the audio feeding parameters are similar, {@code false} otherwise 678 * @hide 679 */ similarCodecFeedingParameters(BluetoothCodecConfig other)680 public boolean similarCodecFeedingParameters(BluetoothCodecConfig other) { 681 if (other == null || mCodecType != other.mCodecType) { 682 return false; 683 } 684 int sampleRate = other.mSampleRate; 685 if (mSampleRate == SAMPLE_RATE_NONE 686 || sampleRate == SAMPLE_RATE_NONE) { 687 sampleRate = mSampleRate; 688 } 689 int bitsPerSample = other.mBitsPerSample; 690 if (mBitsPerSample == BITS_PER_SAMPLE_NONE 691 || bitsPerSample == BITS_PER_SAMPLE_NONE) { 692 bitsPerSample = mBitsPerSample; 693 } 694 int channelMode = other.mChannelMode; 695 if (mChannelMode == CHANNEL_MODE_NONE 696 || channelMode == CHANNEL_MODE_NONE) { 697 channelMode = mChannelMode; 698 } 699 return sameAudioFeedingParameters(new BluetoothCodecConfig( 700 mCodecType, /* priority */ 0, sampleRate, bitsPerSample, channelMode, 701 /* specific1 */ 0, /* specific2 */ 0, /* specific3 */ 0, 702 /* specific4 */ 0)); 703 } 704 705 /** 706 * Checks whether the codec specific parameters are the same. 707 * <p> Currently, only AAC VBR and LDAC Playback Quality on CodecSpecific1 708 * are compared. 709 * 710 * @param other the codec config to compare against 711 * @return {@code true} if the codec specific parameters are the same, {@code false} otherwise 712 * @hide 713 */ sameCodecSpecificParameters(BluetoothCodecConfig other)714 public boolean sameCodecSpecificParameters(BluetoothCodecConfig other) { 715 if (other == null && mCodecType != other.mCodecType) { 716 return false; 717 } 718 switch (mCodecType) { 719 case SOURCE_CODEC_TYPE_AAC: 720 case SOURCE_CODEC_TYPE_LDAC: 721 case SOURCE_CODEC_TYPE_LC3: 722 case SOURCE_CODEC_TYPE_OPUS: 723 if (mCodecSpecific1 != other.mCodecSpecific1) { 724 return false; 725 } 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