blob: 1e463f7baf67d58a98795a13dec24cf946af4c1a [file] [log] [blame]
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -08001/*
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
17package android.bluetooth;
18
19import android.os.Parcel;
20import android.os.Parcelable;
21
22import java.util.Objects;
23
24/**
25 * Represents the codec configuration for a Bluetooth A2DP source device.
26 *
27 * {@see BluetoothA2dp}
28 *
29 * {@hide}
30 */
31public final class BluetoothCodecConfig implements Parcelable {
Pavlin Radoslavov7ad3acb2017-01-04 16:10:09 -080032 // Add an entry for each source codec here.
33 // NOTE: The values should be same as those listed in the following file:
34 // hardware/libhardware/include/hardware/bt_av.h
Jack He910201b2017-08-22 16:06:54 -070035 public static final int SOURCE_CODEC_TYPE_SBC = 0;
36 public static final int SOURCE_CODEC_TYPE_AAC = 1;
37 public static final int SOURCE_CODEC_TYPE_APTX = 2;
Pavlin Radoslavovba5e2992017-01-14 00:41:05 -080038 public static final int SOURCE_CODEC_TYPE_APTX_HD = 3;
Jack He910201b2017-08-22 16:06:54 -070039 public static final int SOURCE_CODEC_TYPE_LDAC = 4;
40 public static final int SOURCE_CODEC_TYPE_MAX = 5;
Pavlin Radoslavov7ad3acb2017-01-04 16:10:09 -080041
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -080042 public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;
43
Pavlin Radoslavov23f591d82017-02-05 15:45:06 -080044 public static final int CODEC_PRIORITY_DISABLED = -1;
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -080045 public static final int CODEC_PRIORITY_DEFAULT = 0;
46 public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000;
47
Jack He910201b2017-08-22 16:06:54 -070048 public static final int SAMPLE_RATE_NONE = 0;
49 public static final int SAMPLE_RATE_44100 = 0x1 << 0;
50 public static final int SAMPLE_RATE_48000 = 0x1 << 1;
51 public static final int SAMPLE_RATE_88200 = 0x1 << 2;
52 public static final int SAMPLE_RATE_96000 = 0x1 << 3;
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -080053 public static final int SAMPLE_RATE_176400 = 0x1 << 4;
54 public static final int SAMPLE_RATE_192000 = 0x1 << 5;
55
56 public static final int BITS_PER_SAMPLE_NONE = 0;
Jack He910201b2017-08-22 16:06:54 -070057 public static final int BITS_PER_SAMPLE_16 = 0x1 << 0;
58 public static final int BITS_PER_SAMPLE_24 = 0x1 << 1;
59 public static final int BITS_PER_SAMPLE_32 = 0x1 << 2;
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -080060
Jack He910201b2017-08-22 16:06:54 -070061 public static final int CHANNEL_MODE_NONE = 0;
62 public static final int CHANNEL_MODE_MONO = 0x1 << 0;
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -080063 public static final int CHANNEL_MODE_STEREO = 0x1 << 1;
64
65 private final int mCodecType;
Pavlin Radoslavov6319d472017-02-24 10:19:14 -080066 private int mCodecPriority;
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -080067 private final int mSampleRate;
68 private final int mBitsPerSample;
69 private final int mChannelMode;
70 private final long mCodecSpecific1;
71 private final long mCodecSpecific2;
72 private final long mCodecSpecific3;
73 private final long mCodecSpecific4;
74
75 public BluetoothCodecConfig(int codecType, int codecPriority,
Jack He910201b2017-08-22 16:06:54 -070076 int sampleRate, int bitsPerSample,
77 int channelMode, long codecSpecific1,
78 long codecSpecific2, long codecSpecific3,
79 long codecSpecific4) {
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -080080 mCodecType = codecType;
81 mCodecPriority = codecPriority;
82 mSampleRate = sampleRate;
83 mBitsPerSample = bitsPerSample;
84 mChannelMode = channelMode;
85 mCodecSpecific1 = codecSpecific1;
86 mCodecSpecific2 = codecSpecific2;
87 mCodecSpecific3 = codecSpecific3;
88 mCodecSpecific4 = codecSpecific4;
89 }
90
91 @Override
92 public boolean equals(Object o) {
93 if (o instanceof BluetoothCodecConfig) {
Jack He910201b2017-08-22 16:06:54 -070094 BluetoothCodecConfig other = (BluetoothCodecConfig) o;
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -080095 return (other.mCodecType == mCodecType &&
96 other.mCodecPriority == mCodecPriority &&
97 other.mSampleRate == mSampleRate &&
98 other.mBitsPerSample == mBitsPerSample &&
99 other.mChannelMode == mChannelMode &&
100 other.mCodecSpecific1 == mCodecSpecific1 &&
101 other.mCodecSpecific2 == mCodecSpecific2 &&
102 other.mCodecSpecific3 == mCodecSpecific3 &&
103 other.mCodecSpecific4 == mCodecSpecific4);
104 }
105 return false;
106 }
107
108 @Override
109 public int hashCode() {
110 return Objects.hash(mCodecType, mCodecPriority, mSampleRate,
Jack He910201b2017-08-22 16:06:54 -0700111 mBitsPerSample, mChannelMode, mCodecSpecific1,
112 mCodecSpecific2, mCodecSpecific3, mCodecSpecific4);
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -0800113 }
114
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800115 /**
116 * Checks whether the object contains valid codec configuration.
117 *
Jack He910201b2017-08-22 16:06:54 -0700118 * @return true if the object contains valid codec configuration, otherwise false.
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800119 */
120 public boolean isValid() {
121 return (mSampleRate != SAMPLE_RATE_NONE) &&
Jack He910201b2017-08-22 16:06:54 -0700122 (mBitsPerSample != BITS_PER_SAMPLE_NONE) &&
123 (mChannelMode != CHANNEL_MODE_NONE);
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800124 }
125
126 /**
127 * Adds capability string to an existing string.
128 *
Jack He910201b2017-08-22 16:06:54 -0700129 * @param prevStr the previous string with the capabilities. Can be a null pointer.
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800130 * @param capStr the capability string to append to prevStr argument.
131 * @return the result string in the form "prevStr|capStr".
132 */
133 private static String appendCapabilityToString(String prevStr,
Jack He910201b2017-08-22 16:06:54 -0700134 String capStr) {
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800135 if (prevStr == null) {
136 return capStr;
137 }
138 return prevStr + "|" + capStr;
139 }
140
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -0800141 @Override
142 public String toString() {
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800143 String sampleRateStr = null;
144 if (mSampleRate == SAMPLE_RATE_NONE) {
145 sampleRateStr = appendCapabilityToString(sampleRateStr, "NONE");
146 }
147 if ((mSampleRate & SAMPLE_RATE_44100) != 0) {
148 sampleRateStr = appendCapabilityToString(sampleRateStr, "44100");
149 }
150 if ((mSampleRate & SAMPLE_RATE_48000) != 0) {
151 sampleRateStr = appendCapabilityToString(sampleRateStr, "48000");
152 }
153 if ((mSampleRate & SAMPLE_RATE_88200) != 0) {
154 sampleRateStr = appendCapabilityToString(sampleRateStr, "88200");
155 }
156 if ((mSampleRate & SAMPLE_RATE_96000) != 0) {
157 sampleRateStr = appendCapabilityToString(sampleRateStr, "96000");
158 }
159 if ((mSampleRate & SAMPLE_RATE_176400) != 0) {
160 sampleRateStr = appendCapabilityToString(sampleRateStr, "176400");
161 }
162 if ((mSampleRate & SAMPLE_RATE_192000) != 0) {
163 sampleRateStr = appendCapabilityToString(sampleRateStr, "192000");
164 }
165
166 String bitsPerSampleStr = null;
167 if (mBitsPerSample == BITS_PER_SAMPLE_NONE) {
168 bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "NONE");
169 }
170 if ((mBitsPerSample & BITS_PER_SAMPLE_16) != 0) {
171 bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "16");
172 }
173 if ((mBitsPerSample & BITS_PER_SAMPLE_24) != 0) {
174 bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "24");
175 }
176 if ((mBitsPerSample & BITS_PER_SAMPLE_32) != 0) {
177 bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "32");
178 }
179
180 String channelModeStr = null;
181 if (mChannelMode == CHANNEL_MODE_NONE) {
182 channelModeStr = appendCapabilityToString(channelModeStr, "NONE");
183 }
184 if ((mChannelMode & CHANNEL_MODE_MONO) != 0) {
185 channelModeStr = appendCapabilityToString(channelModeStr, "MONO");
186 }
187 if ((mChannelMode & CHANNEL_MODE_STEREO) != 0) {
188 channelModeStr = appendCapabilityToString(channelModeStr, "STEREO");
189 }
190
191 return "{codecName:" + getCodecName() +
Jack He910201b2017-08-22 16:06:54 -0700192 ",mCodecType:" + mCodecType +
193 ",mCodecPriority:" + mCodecPriority +
194 ",mSampleRate:" + String.format("0x%x", mSampleRate) +
195 "(" + sampleRateStr + ")" +
196 ",mBitsPerSample:" + String.format("0x%x", mBitsPerSample) +
197 "(" + bitsPerSampleStr + ")" +
198 ",mChannelMode:" + String.format("0x%x", mChannelMode) +
199 "(" + channelModeStr + ")" +
200 ",mCodecSpecific1:" + mCodecSpecific1 +
201 ",mCodecSpecific2:" + mCodecSpecific2 +
202 ",mCodecSpecific3:" + mCodecSpecific3 +
203 ",mCodecSpecific4:" + mCodecSpecific4 + "}";
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -0800204 }
205
206 public int describeContents() {
207 return 0;
208 }
209
210 public static final Parcelable.Creator<BluetoothCodecConfig> CREATOR =
211 new Parcelable.Creator<BluetoothCodecConfig>() {
Jack He910201b2017-08-22 16:06:54 -0700212 public BluetoothCodecConfig createFromParcel(Parcel in) {
213 final int codecType = in.readInt();
214 final int codecPriority = in.readInt();
215 final int sampleRate = in.readInt();
216 final int bitsPerSample = in.readInt();
217 final int channelMode = in.readInt();
218 final long codecSpecific1 = in.readLong();
219 final long codecSpecific2 = in.readLong();
220 final long codecSpecific3 = in.readLong();
221 final long codecSpecific4 = in.readLong();
222 return new BluetoothCodecConfig(codecType, codecPriority,
223 sampleRate, bitsPerSample,
224 channelMode, codecSpecific1,
225 codecSpecific2, codecSpecific3,
226 codecSpecific4);
227 }
228
229 public BluetoothCodecConfig[] newArray(int size) {
230 return new BluetoothCodecConfig[size];
231 }
232 };
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -0800233
234 public void writeToParcel(Parcel out, int flags) {
235 out.writeInt(mCodecType);
236 out.writeInt(mCodecPriority);
237 out.writeInt(mSampleRate);
238 out.writeInt(mBitsPerSample);
239 out.writeInt(mChannelMode);
240 out.writeLong(mCodecSpecific1);
241 out.writeLong(mCodecSpecific2);
242 out.writeLong(mCodecSpecific3);
243 out.writeLong(mCodecSpecific4);
244 }
245
246 /**
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800247 * Gets the codec name.
248 *
249 * @return the codec name
250 */
251 public String getCodecName() {
252 switch (mCodecType) {
Jack He910201b2017-08-22 16:06:54 -0700253 case SOURCE_CODEC_TYPE_SBC:
254 return "SBC";
255 case SOURCE_CODEC_TYPE_AAC:
256 return "AAC";
257 case SOURCE_CODEC_TYPE_APTX:
258 return "aptX";
259 case SOURCE_CODEC_TYPE_APTX_HD:
260 return "aptX HD";
261 case SOURCE_CODEC_TYPE_LDAC:
262 return "LDAC";
263 case SOURCE_CODEC_TYPE_INVALID:
264 return "INVALID CODEC";
265 default:
266 break;
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800267 }
268 return "UNKNOWN CODEC(" + mCodecType + ")";
269 }
270
271 /**
272 * Gets the codec type.
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -0800273 * See {@link android.bluetooth.BluetoothCodecConfig#SOURCE_CODEC_TYPE_SBC}.
274 *
275 * @return the codec type
276 */
277 public int getCodecType() {
278 return mCodecType;
279 }
280
281 /**
Pavlin Radoslavov6319d472017-02-24 10:19:14 -0800282 * Checks whether the codec is mandatory.
283 *
284 * @return true if the codec is mandatory, otherwise false.
285 */
286 public boolean isMandatoryCodec() {
287 return mCodecType == SOURCE_CODEC_TYPE_SBC;
288 }
289
290 /**
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800291 * Gets the codec selection priority.
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -0800292 * The codec selection priority is relative to other codecs: larger value
293 * means higher priority. If 0, reset to default.
294 *
295 * @return the codec priority
296 */
297 public int getCodecPriority() {
298 return mCodecPriority;
299 }
300
301 /**
Pavlin Radoslavov6319d472017-02-24 10:19:14 -0800302 * Sets the codec selection priority.
303 * The codec selection priority is relative to other codecs: larger value
304 * means higher priority. If 0, reset to default.
305 *
306 * @param codecPriority the codec priority
307 */
308 public void setCodecPriority(int codecPriority) {
309 mCodecPriority = codecPriority;
310 }
311
312 /**
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800313 * Gets the codec sample rate. The value can be a bitmask with all
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -0800314 * supported sample rates:
315 * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_NONE} or
316 * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_44100} or
317 * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_48000} or
318 * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_88200} or
319 * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_96000} or
320 * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_176400} or
321 * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_192000}
322 *
323 * @return the codec sample rate
324 */
325 public int getSampleRate() {
326 return mSampleRate;
327 }
328
329 /**
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800330 * Gets the codec bits per sample. The value can be a bitmask with all
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -0800331 * bits per sample supported:
332 * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_NONE} or
333 * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_16} or
334 * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_24} or
335 * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_32}
336 *
337 * @return the codec bits per sample
338 */
339 public int getBitsPerSample() {
340 return mBitsPerSample;
341 }
342
343 /**
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800344 * Gets the codec channel mode. The value can be a bitmask with all
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -0800345 * supported channel modes:
346 * {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_NONE} or
347 * {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_MONO} or
348 * {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_STEREO}
349 *
350 * @return the codec channel mode
351 */
352 public int getChannelMode() {
353 return mChannelMode;
354 }
355
356 /**
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800357 * Gets a codec specific value1.
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -0800358 *
359 * @return a codec specific value1.
360 */
361 public long getCodecSpecific1() {
362 return mCodecSpecific1;
363 }
364
365 /**
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800366 * Gets a codec specific value2.
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -0800367 *
368 * @return a codec specific value2
369 */
370 public long getCodecSpecific2() {
371 return mCodecSpecific2;
372 }
373
374 /**
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800375 * Gets a codec specific value3.
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -0800376 *
377 * @return a codec specific value3
378 */
379 public long getCodecSpecific3() {
380 return mCodecSpecific3;
381 }
382
383 /**
Pavlin Radoslavovf6d543a2017-01-25 16:54:07 -0800384 * Gets a codec specific value4.
Pavlin Radoslavov178a3d22016-12-21 12:05:51 -0800385 *
386 * @return a codec specific value4
387 */
388 public long getCodecSpecific4() {
389 return mCodecSpecific4;
390 }
391
392 /**
393 * Checks whether the audio feeding parameters are same.
394 *
395 * @param other the codec config to compare against
396 * @return true if the audio feeding parameters are same, otherwise false
397 */
398 public boolean sameAudioFeedingParameters(BluetoothCodecConfig other) {
399 return (other != null && other.mSampleRate == mSampleRate &&
400 other.mBitsPerSample == mBitsPerSample &&
401 other.mChannelMode == mChannelMode);
402 }
403}