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