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