• Home
  • History
  • Annotate
  • 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.UnsupportedAppUsage;
20  import android.os.Parcel;
21  import android.os.Parcelable;
22  
23  import java.util.Objects;
24  
25  /**
26   * Represents the codec configuration for a Bluetooth A2DP source device.
27   *
28   * {@see BluetoothA2dp}
29   *
30   * {@hide}
31   */
32  public final class BluetoothCodecConfig implements Parcelable {
33      // Add an entry for each source codec here.
34      // NOTE: The values should be same as those listed in the following file:
35      //   hardware/libhardware/include/hardware/bt_av.h
36      @UnsupportedAppUsage
37      public static final int SOURCE_CODEC_TYPE_SBC = 0;
38      @UnsupportedAppUsage
39      public static final int SOURCE_CODEC_TYPE_AAC = 1;
40      @UnsupportedAppUsage
41      public static final int SOURCE_CODEC_TYPE_APTX = 2;
42      @UnsupportedAppUsage
43      public static final int SOURCE_CODEC_TYPE_APTX_HD = 3;
44      @UnsupportedAppUsage
45      public static final int SOURCE_CODEC_TYPE_LDAC = 4;
46      @UnsupportedAppUsage
47      public static final int SOURCE_CODEC_TYPE_MAX = 5;
48  
49      @UnsupportedAppUsage
50      public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000;
51  
52      @UnsupportedAppUsage
53      public static final int CODEC_PRIORITY_DISABLED = -1;
54      @UnsupportedAppUsage
55      public static final int CODEC_PRIORITY_DEFAULT = 0;
56      @UnsupportedAppUsage
57      public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000;
58  
59      @UnsupportedAppUsage
60      public static final int SAMPLE_RATE_NONE = 0;
61      @UnsupportedAppUsage
62      public static final int SAMPLE_RATE_44100 = 0x1 << 0;
63      @UnsupportedAppUsage
64      public static final int SAMPLE_RATE_48000 = 0x1 << 1;
65      @UnsupportedAppUsage
66      public static final int SAMPLE_RATE_88200 = 0x1 << 2;
67      @UnsupportedAppUsage
68      public static final int SAMPLE_RATE_96000 = 0x1 << 3;
69      @UnsupportedAppUsage
70      public static final int SAMPLE_RATE_176400 = 0x1 << 4;
71      @UnsupportedAppUsage
72      public static final int SAMPLE_RATE_192000 = 0x1 << 5;
73  
74      @UnsupportedAppUsage
75      public static final int BITS_PER_SAMPLE_NONE = 0;
76      @UnsupportedAppUsage
77      public static final int BITS_PER_SAMPLE_16 = 0x1 << 0;
78      @UnsupportedAppUsage
79      public static final int BITS_PER_SAMPLE_24 = 0x1 << 1;
80      @UnsupportedAppUsage
81      public static final int BITS_PER_SAMPLE_32 = 0x1 << 2;
82  
83      @UnsupportedAppUsage
84      public static final int CHANNEL_MODE_NONE = 0;
85      @UnsupportedAppUsage
86      public static final int CHANNEL_MODE_MONO = 0x1 << 0;
87      @UnsupportedAppUsage
88      public static final int CHANNEL_MODE_STEREO = 0x1 << 1;
89  
90      private final int mCodecType;
91      private int mCodecPriority;
92      private final int mSampleRate;
93      private final int mBitsPerSample;
94      private final int mChannelMode;
95      private final long mCodecSpecific1;
96      private final long mCodecSpecific2;
97      private final long mCodecSpecific3;
98      private final long mCodecSpecific4;
99  
100      @UnsupportedAppUsage
BluetoothCodecConfig(int codecType, int codecPriority, int sampleRate, int bitsPerSample, int channelMode, long codecSpecific1, long codecSpecific2, long codecSpecific3, long codecSpecific4)101      public BluetoothCodecConfig(int codecType, int codecPriority,
102              int sampleRate, int bitsPerSample,
103              int channelMode, long codecSpecific1,
104              long codecSpecific2, long codecSpecific3,
105              long codecSpecific4) {
106          mCodecType = codecType;
107          mCodecPriority = codecPriority;
108          mSampleRate = sampleRate;
109          mBitsPerSample = bitsPerSample;
110          mChannelMode = channelMode;
111          mCodecSpecific1 = codecSpecific1;
112          mCodecSpecific2 = codecSpecific2;
113          mCodecSpecific3 = codecSpecific3;
114          mCodecSpecific4 = codecSpecific4;
115      }
116  
117      @UnsupportedAppUsage
BluetoothCodecConfig(int codecType)118      public BluetoothCodecConfig(int codecType) {
119          mCodecType = codecType;
120          mCodecPriority = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT;
121          mSampleRate = BluetoothCodecConfig.SAMPLE_RATE_NONE;
122          mBitsPerSample = BluetoothCodecConfig.BITS_PER_SAMPLE_NONE;
123          mChannelMode = BluetoothCodecConfig.CHANNEL_MODE_NONE;
124          mCodecSpecific1 = 0;
125          mCodecSpecific2 = 0;
126          mCodecSpecific3 = 0;
127          mCodecSpecific4 = 0;
128      }
129  
130      @Override
equals(Object o)131      public boolean equals(Object o) {
132          if (o instanceof BluetoothCodecConfig) {
133              BluetoothCodecConfig other = (BluetoothCodecConfig) o;
134              return (other.mCodecType == mCodecType
135                      && other.mCodecPriority == mCodecPriority
136                      && other.mSampleRate == mSampleRate
137                      && other.mBitsPerSample == mBitsPerSample
138                      && other.mChannelMode == mChannelMode
139                      && other.mCodecSpecific1 == mCodecSpecific1
140                      && other.mCodecSpecific2 == mCodecSpecific2
141                      && other.mCodecSpecific3 == mCodecSpecific3
142                      && other.mCodecSpecific4 == mCodecSpecific4);
143          }
144          return false;
145      }
146  
147      @Override
hashCode()148      public int hashCode() {
149          return Objects.hash(mCodecType, mCodecPriority, mSampleRate,
150                  mBitsPerSample, mChannelMode, mCodecSpecific1,
151                  mCodecSpecific2, mCodecSpecific3, mCodecSpecific4);
152      }
153  
154      /**
155       * Checks whether the object contains valid codec configuration.
156       *
157       * @return true if the object contains valid codec configuration, otherwise false.
158       */
isValid()159      public boolean isValid() {
160          return (mSampleRate != SAMPLE_RATE_NONE)
161                  && (mBitsPerSample != BITS_PER_SAMPLE_NONE)
162                  && (mChannelMode != CHANNEL_MODE_NONE);
163      }
164  
165      /**
166       * Adds capability string to an existing string.
167       *
168       * @param prevStr the previous string with the capabilities. Can be a null pointer.
169       * @param capStr the capability string to append to prevStr argument.
170       * @return the result string in the form "prevStr|capStr".
171       */
appendCapabilityToString(String prevStr, String capStr)172      private static String appendCapabilityToString(String prevStr,
173              String capStr) {
174          if (prevStr == null) {
175              return capStr;
176          }
177          return prevStr + "|" + capStr;
178      }
179  
180      @Override
toString()181      public String toString() {
182          String sampleRateStr = null;
183          if (mSampleRate == SAMPLE_RATE_NONE) {
184              sampleRateStr = appendCapabilityToString(sampleRateStr, "NONE");
185          }
186          if ((mSampleRate & SAMPLE_RATE_44100) != 0) {
187              sampleRateStr = appendCapabilityToString(sampleRateStr, "44100");
188          }
189          if ((mSampleRate & SAMPLE_RATE_48000) != 0) {
190              sampleRateStr = appendCapabilityToString(sampleRateStr, "48000");
191          }
192          if ((mSampleRate & SAMPLE_RATE_88200) != 0) {
193              sampleRateStr = appendCapabilityToString(sampleRateStr, "88200");
194          }
195          if ((mSampleRate & SAMPLE_RATE_96000) != 0) {
196              sampleRateStr = appendCapabilityToString(sampleRateStr, "96000");
197          }
198          if ((mSampleRate & SAMPLE_RATE_176400) != 0) {
199              sampleRateStr = appendCapabilityToString(sampleRateStr, "176400");
200          }
201          if ((mSampleRate & SAMPLE_RATE_192000) != 0) {
202              sampleRateStr = appendCapabilityToString(sampleRateStr, "192000");
203          }
204  
205          String bitsPerSampleStr = null;
206          if (mBitsPerSample == BITS_PER_SAMPLE_NONE) {
207              bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "NONE");
208          }
209          if ((mBitsPerSample & BITS_PER_SAMPLE_16) != 0) {
210              bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "16");
211          }
212          if ((mBitsPerSample & BITS_PER_SAMPLE_24) != 0) {
213              bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "24");
214          }
215          if ((mBitsPerSample & BITS_PER_SAMPLE_32) != 0) {
216              bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "32");
217          }
218  
219          String channelModeStr = null;
220          if (mChannelMode == CHANNEL_MODE_NONE) {
221              channelModeStr = appendCapabilityToString(channelModeStr, "NONE");
222          }
223          if ((mChannelMode & CHANNEL_MODE_MONO) != 0) {
224              channelModeStr = appendCapabilityToString(channelModeStr, "MONO");
225          }
226          if ((mChannelMode & CHANNEL_MODE_STEREO) != 0) {
227              channelModeStr = appendCapabilityToString(channelModeStr, "STEREO");
228          }
229  
230          return "{codecName:" + getCodecName()
231                  + ",mCodecType:" + mCodecType
232                  + ",mCodecPriority:" + mCodecPriority
233                  + ",mSampleRate:" + String.format("0x%x", mSampleRate)
234                  + "(" + sampleRateStr + ")"
235                  + ",mBitsPerSample:" + String.format("0x%x", mBitsPerSample)
236                  + "(" + bitsPerSampleStr + ")"
237                  + ",mChannelMode:" + String.format("0x%x", mChannelMode)
238                  + "(" + channelModeStr + ")"
239                  + ",mCodecSpecific1:" + mCodecSpecific1
240                  + ",mCodecSpecific2:" + mCodecSpecific2
241                  + ",mCodecSpecific3:" + mCodecSpecific3
242                  + ",mCodecSpecific4:" + mCodecSpecific4 + "}";
243      }
244  
245      @Override
describeContents()246      public int describeContents() {
247          return 0;
248      }
249  
250      public static final @android.annotation.NonNull Parcelable.Creator<BluetoothCodecConfig> CREATOR =
251              new Parcelable.Creator<BluetoothCodecConfig>() {
252                  public BluetoothCodecConfig createFromParcel(Parcel in) {
253                      final int codecType = in.readInt();
254                      final int codecPriority = in.readInt();
255                      final int sampleRate = in.readInt();
256                      final int bitsPerSample = in.readInt();
257                      final int channelMode = in.readInt();
258                      final long codecSpecific1 = in.readLong();
259                      final long codecSpecific2 = in.readLong();
260                      final long codecSpecific3 = in.readLong();
261                      final long codecSpecific4 = in.readLong();
262                      return new BluetoothCodecConfig(codecType, codecPriority,
263                              sampleRate, bitsPerSample,
264                              channelMode, codecSpecific1,
265                              codecSpecific2, codecSpecific3,
266                              codecSpecific4);
267                  }
268  
269                  public BluetoothCodecConfig[] newArray(int size) {
270                      return new BluetoothCodecConfig[size];
271                  }
272              };
273  
274      @Override
writeToParcel(Parcel out, int flags)275      public void writeToParcel(Parcel out, int flags) {
276          out.writeInt(mCodecType);
277          out.writeInt(mCodecPriority);
278          out.writeInt(mSampleRate);
279          out.writeInt(mBitsPerSample);
280          out.writeInt(mChannelMode);
281          out.writeLong(mCodecSpecific1);
282          out.writeLong(mCodecSpecific2);
283          out.writeLong(mCodecSpecific3);
284          out.writeLong(mCodecSpecific4);
285      }
286  
287      /**
288       * Gets the codec name.
289       *
290       * @return the codec name
291       */
getCodecName()292      public String getCodecName() {
293          switch (mCodecType) {
294              case SOURCE_CODEC_TYPE_SBC:
295                  return "SBC";
296              case SOURCE_CODEC_TYPE_AAC:
297                  return "AAC";
298              case SOURCE_CODEC_TYPE_APTX:
299                  return "aptX";
300              case SOURCE_CODEC_TYPE_APTX_HD:
301                  return "aptX HD";
302              case SOURCE_CODEC_TYPE_LDAC:
303                  return "LDAC";
304              case SOURCE_CODEC_TYPE_INVALID:
305                  return "INVALID CODEC";
306              default:
307                  break;
308          }
309          return "UNKNOWN CODEC(" + mCodecType + ")";
310      }
311  
312      /**
313       * Gets the codec type.
314       * See {@link android.bluetooth.BluetoothCodecConfig#SOURCE_CODEC_TYPE_SBC}.
315       *
316       * @return the codec type
317       */
318      @UnsupportedAppUsage
getCodecType()319      public int getCodecType() {
320          return mCodecType;
321      }
322  
323      /**
324       * Checks whether the codec is mandatory.
325       *
326       * @return true if the codec is mandatory, otherwise false.
327       */
isMandatoryCodec()328      public boolean isMandatoryCodec() {
329          return mCodecType == SOURCE_CODEC_TYPE_SBC;
330      }
331  
332      /**
333       * Gets the codec selection priority.
334       * The codec selection priority is relative to other codecs: larger value
335       * means higher priority. If 0, reset to default.
336       *
337       * @return the codec priority
338       */
339      @UnsupportedAppUsage
getCodecPriority()340      public int getCodecPriority() {
341          return mCodecPriority;
342      }
343  
344      /**
345       * Sets the codec selection priority.
346       * The codec selection priority is relative to other codecs: larger value
347       * means higher priority. If 0, reset to default.
348       *
349       * @param codecPriority the codec priority
350       */
351      @UnsupportedAppUsage
setCodecPriority(int codecPriority)352      public void setCodecPriority(int codecPriority) {
353          mCodecPriority = codecPriority;
354      }
355  
356      /**
357       * Gets the codec sample rate. The value can be a bitmask with all
358       * supported sample rates:
359       * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_NONE} or
360       * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_44100} or
361       * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_48000} or
362       * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_88200} or
363       * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_96000} or
364       * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_176400} or
365       * {@link android.bluetooth.BluetoothCodecConfig#SAMPLE_RATE_192000}
366       *
367       * @return the codec sample rate
368       */
369      @UnsupportedAppUsage
getSampleRate()370      public int getSampleRate() {
371          return mSampleRate;
372      }
373  
374      /**
375       * Gets the codec bits per sample. The value can be a bitmask with all
376       * bits per sample supported:
377       * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_NONE} or
378       * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_16} or
379       * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_24} or
380       * {@link android.bluetooth.BluetoothCodecConfig#BITS_PER_SAMPLE_32}
381       *
382       * @return the codec bits per sample
383       */
384      @UnsupportedAppUsage
getBitsPerSample()385      public int getBitsPerSample() {
386          return mBitsPerSample;
387      }
388  
389      /**
390       * Gets the codec channel mode. The value can be a bitmask with all
391       * supported channel modes:
392       * {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_NONE} or
393       * {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_MONO} or
394       * {@link android.bluetooth.BluetoothCodecConfig#CHANNEL_MODE_STEREO}
395       *
396       * @return the codec channel mode
397       */
398      @UnsupportedAppUsage
getChannelMode()399      public int getChannelMode() {
400          return mChannelMode;
401      }
402  
403      /**
404       * Gets a codec specific value1.
405       *
406       * @return a codec specific value1.
407       */
408      @UnsupportedAppUsage
getCodecSpecific1()409      public long getCodecSpecific1() {
410          return mCodecSpecific1;
411      }
412  
413      /**
414       * Gets a codec specific value2.
415       *
416       * @return a codec specific value2
417       */
418      @UnsupportedAppUsage
getCodecSpecific2()419      public long getCodecSpecific2() {
420          return mCodecSpecific2;
421      }
422  
423      /**
424       * Gets a codec specific value3.
425       *
426       * @return a codec specific value3
427       */
428      @UnsupportedAppUsage
getCodecSpecific3()429      public long getCodecSpecific3() {
430          return mCodecSpecific3;
431      }
432  
433      /**
434       * Gets a codec specific value4.
435       *
436       * @return a codec specific value4
437       */
438      @UnsupportedAppUsage
getCodecSpecific4()439      public long getCodecSpecific4() {
440          return mCodecSpecific4;
441      }
442  
443      /**
444       * Checks whether the audio feeding parameters are same.
445       *
446       * @param other the codec config to compare against
447       * @return true if the audio feeding parameters are same, otherwise false
448       */
sameAudioFeedingParameters(BluetoothCodecConfig other)449      public boolean sameAudioFeedingParameters(BluetoothCodecConfig other) {
450          return (other != null && other.mSampleRate == mSampleRate
451                  && other.mBitsPerSample == mBitsPerSample
452                  && other.mChannelMode == mChannelMode);
453      }
454  }
455