• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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