1 /*
2  * Copyright (C) 2023 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.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SystemApi;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 
26 import com.android.bluetooth.flags.Flags;
27 
28 /**
29  * Represents a supported source codec type for a Bluetooth A2DP device. See {@link
30  * BluetoothA2dp#getSupportedCodecTypes}. The codec type is uniquely identified by its name and
31  * codec identifier.
32  */
33 @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY)
34 public final class BluetoothCodecType implements Parcelable {
35     private final int mNativeCodecType;
36     private final long mCodecId;
37     private final @NonNull String mCodecName;
38 
BluetoothCodecType(Parcel in)39     private BluetoothCodecType(Parcel in) {
40         mNativeCodecType = in.readInt();
41         mCodecId = in.readLong();
42         mCodecName = in.readString();
43     }
44 
45     /** SBC codec identifier. See {@link BluetoothCodecType#getCodecId}. */
46     public static final long CODEC_ID_SBC = 0x0000000000;
47 
48     /** AAC codec identifier. See {@link BluetoothCodecType#getCodecId}. */
49     public static final long CODEC_ID_AAC = 0x0000000002;
50 
51     /** AptX codec identifier. See {@link BluetoothCodecType#getCodecId}. */
52     public static final long CODEC_ID_APTX = 0x0001004fff;
53 
54     /** Aptx HD codec identifier. See {@link BluetoothCodecType#getCodecId}. */
55     public static final long CODEC_ID_APTX_HD = 0x002400d7ff;
56 
57     /** LDAC codec identifier. See {@link BluetoothCodecType#getCodecId}. */
58     public static final long CODEC_ID_LDAC = 0x00aa012dff;
59 
60     /** Opus codec identifier. See {@link BluetoothCodecType#getCodecId}. */
61     public static final long CODEC_ID_OPUS = 0x000100e0ff;
62 
63     /**
64      * Create the bluetooth codec type from the static codec type index.
65      *
66      * @param codecType the static codec type
67      * @param codecId the unique codec id
68      */
BluetoothCodecType(@luetoothCodecConfig.SourceCodecType int codecType, long codecId)69     private BluetoothCodecType(@BluetoothCodecConfig.SourceCodecType int codecType, long codecId) {
70         mNativeCodecType = codecType;
71         mCodecId = codecId;
72         mCodecName = BluetoothCodecConfig.getCodecName(codecType);
73     }
74 
75     /**
76      * Create the bluetooth codec type from the static codec type index.
77      *
78      * @param codecType the static codec type
79      * @param codecId the unique codec id
80      * @param codecName the codec name
81      * @hide
82      */
83     @SystemApi
BluetoothCodecType(int codecType, long codecId, @NonNull String codecName)84     public BluetoothCodecType(int codecType, long codecId, @NonNull String codecName) {
85         mNativeCodecType = codecType;
86         mCodecId = codecId;
87         mCodecName = codecName;
88     }
89 
90     /** Returns if the codec type is mandatory in the Bluetooth specification. */
91     @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY)
isMandatoryCodec()92     public boolean isMandatoryCodec() {
93         return mNativeCodecType == BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC;
94     }
95 
96     /**
97      * Returns the codec unique identifier. The codec identifier is 40 bits, - Bits 0-7: Audio Codec
98      * ID, as defined by [ID 6.5.1] 0x00: SBC 0x02: AAC 0xFF: Vendor - Bits 8-23: Company ID, set to
99      * 0, if octet 0 is not 0xFF. - Bits 24-39: Vendor-defined codec ID, set to 0, if octet 0 is not
100      * 0xFF.
101      */
102     @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY)
getCodecId()103     public long getCodecId() {
104         return mCodecId;
105     }
106 
107     /** Returns the codec name. */
108     @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY)
getCodecName()109     public @NonNull String getCodecName() {
110         return mCodecName;
111     }
112 
113     /**
114      * Returns the native codec type. The native codec type is arbitrarily assigned to the codec.
115      * Prefer {@link BluetoothCodecType#getCodecId}.
116      *
117      * @hide
118      */
getNativeCodecType()119     public int getNativeCodecType() {
120         return mNativeCodecType;
121     }
122 
123     @Override
toString()124     public String toString() {
125         return mCodecName;
126     }
127 
128     @Override
hashCode()129     public int hashCode() {
130         return Long.hashCode(mCodecId);
131     }
132 
133     @Override
equals(@ullable Object o)134     public boolean equals(@Nullable Object o) {
135         if (o instanceof BluetoothCodecType) {
136             BluetoothCodecType other = (BluetoothCodecType) o;
137             return other.mCodecId == mCodecId;
138         }
139         return false;
140     }
141 
142     /** @hide */
createFromParcel(Parcel in)143     public static @NonNull BluetoothCodecType createFromParcel(Parcel in) {
144         return new BluetoothCodecType(in);
145     }
146 
147     /** @hide */
148     @Override
149     @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY)
writeToParcel(@onNull Parcel dest, int flags)150     public void writeToParcel(@NonNull Parcel dest, int flags) {
151         dest.writeInt(mNativeCodecType);
152         dest.writeLong(mCodecId);
153         dest.writeString(mCodecName);
154     }
155 
156     /**
157      * Create the bluetooth codec type from the static codec type index.
158      *
159      * @param codecType the static codec type
160      * @return the codec type if valid
161      * @hide
162      */
163     @SystemApi
164     @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY)
createFromType( @luetoothCodecConfig.SourceCodecType int codecType)165     public static @Nullable BluetoothCodecType createFromType(
166             @BluetoothCodecConfig.SourceCodecType int codecType) {
167         long codecId =
168                 switch (codecType) {
169                     case BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC -> CODEC_ID_SBC;
170                     case BluetoothCodecConfig.SOURCE_CODEC_TYPE_AAC -> CODEC_ID_AAC;
171                     case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX -> CODEC_ID_APTX;
172                     case BluetoothCodecConfig.SOURCE_CODEC_TYPE_APTX_HD -> CODEC_ID_APTX_HD;
173                     case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LDAC -> CODEC_ID_LDAC;
174                     case BluetoothCodecConfig.SOURCE_CODEC_TYPE_OPUS -> CODEC_ID_OPUS;
175                     case BluetoothCodecConfig.SOURCE_CODEC_TYPE_LC3,
176                                     BluetoothCodecConfig.SOURCE_CODEC_TYPE_INVALID ->
177                             -1;
178                     default -> -1;
179                 };
180         if (codecId == -1) {
181             return null;
182         }
183         return new BluetoothCodecType(codecType, codecId);
184     }
185 
186     /**
187      * @return 0
188      * @hide
189      */
190     @Override
191     @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY)
describeContents()192     public int describeContents() {
193         return 0;
194     }
195 
196     @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY)
197     public static final @NonNull Creator<BluetoothCodecType> CREATOR =
198             new Creator<>() {
199                 public BluetoothCodecType createFromParcel(Parcel in) {
200                     return new BluetoothCodecType(in);
201                 }
202 
203                 public BluetoothCodecType[] newArray(int size) {
204                     return new BluetoothCodecType[size];
205                 }
206             };
207 }
208