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