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