| /* | |
| * Copyright (C) 2016 The Android Open Source Project | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| package android.bluetooth; | |
| import static android.bluetooth.BluetoothUtils.formatSimple; | |
| import android.annotation.IntDef; | |
| import android.annotation.NonNull; | |
| import android.annotation.Nullable; | |
| import android.annotation.SuppressLint; | |
| import android.compat.annotation.UnsupportedAppUsage; | |
| import android.os.Parcel; | |
| import android.os.Parcelable; | |
| import java.lang.annotation.Retention; | |
| import java.lang.annotation.RetentionPolicy; | |
| import java.util.Objects; | |
| /** | |
| * Represents the codec configuration for a Bluetooth A2DP source device. | |
| * | |
| * <p>Contains the source codec type, the codec priority, the codec sample rate, the codec bits per | |
| * sample, and the codec channel mode. | |
| * | |
| * <p>The source codec type values are the same as those supported by the device hardware. | |
| * | |
| * @see BluetoothA2dp | |
| */ | |
| public final class BluetoothCodecConfig implements Parcelable { | |
| /** @hide */ | |
| @IntDef( | |
| prefix = "SOURCE_CODEC_TYPE_", | |
| value = { | |
| SOURCE_CODEC_TYPE_SBC, | |
| SOURCE_CODEC_TYPE_AAC, | |
| SOURCE_CODEC_TYPE_APTX, | |
| SOURCE_CODEC_TYPE_APTX_HD, | |
| SOURCE_CODEC_TYPE_LDAC, | |
| SOURCE_CODEC_TYPE_LC3, | |
| SOURCE_CODEC_TYPE_OPUS, | |
| SOURCE_CODEC_TYPE_INVALID | |
| }) | |
| @Retention(RetentionPolicy.SOURCE) | |
| public @interface SourceCodecType {} | |
| /** | |
| * Source codec type SBC. This is the mandatory source codec type. | |
| * | |
| * @deprecated Use the {@link BluetoothCodecType} values returned by {@link | |
| * BluetoothA2dp#getSupportedCodecTypes} instead. | |
| */ | |
| @Deprecated public static final int SOURCE_CODEC_TYPE_SBC = 0; | |
| /** | |
| * Source codec type AAC. | |
| * | |
| * @deprecated Use the {@link BluetoothCodecType} values returned by {@link | |
| * BluetoothA2dp#getSupportedCodecTypes} instead. | |
| */ | |
| @Deprecated public static final int SOURCE_CODEC_TYPE_AAC = 1; | |
| /** | |
| * Source codec type APTX. | |
| * | |
| * @deprecated Use the {@link BluetoothCodecType} values returned by {@link | |
| * BluetoothA2dp#getSupportedCodecTypes} instead. | |
| */ | |
| @Deprecated public static final int SOURCE_CODEC_TYPE_APTX = 2; | |
| /** | |
| * Source codec type APTX HD. | |
| * | |
| * @deprecated Use the {@link BluetoothCodecType} values returned by {@link | |
| * BluetoothA2dp#getSupportedCodecTypes} instead. | |
| */ | |
| @Deprecated public static final int SOURCE_CODEC_TYPE_APTX_HD = 3; | |
| /** | |
| * Source codec type LDAC. | |
| * | |
| * @deprecated Use the {@link BluetoothCodecType} values returned by {@link | |
| * BluetoothA2dp#getSupportedCodecTypes} instead. | |
| */ | |
| @Deprecated public static final int SOURCE_CODEC_TYPE_LDAC = 4; | |
| /** | |
| * Source codec type LC3. | |
| * | |
| * @deprecated Use the {@link BluetoothCodecType} values returned by {@link | |
| * BluetoothA2dp#getSupportedCodecTypes} instead. | |
| */ | |
| @Deprecated public static final int SOURCE_CODEC_TYPE_LC3 = 5; | |
| /** | |
| * Source codec type Opus. | |
| * | |
| * @deprecated Use the {@link BluetoothCodecType} values returned by {@link | |
| * BluetoothA2dp#getSupportedCodecTypes} instead. | |
| */ | |
| @Deprecated public static final int SOURCE_CODEC_TYPE_OPUS = 6; | |
| /** | |
| * Source codec type invalid. This is the default value used for codec type. | |
| * | |
| * @deprecated Use the {@link BluetoothCodecType} values returned by {@link | |
| * BluetoothA2dp#getSupportedCodecTypes} instead. | |
| */ | |
| @Deprecated public static final int SOURCE_CODEC_TYPE_INVALID = 1000 * 1000; | |
| /** Represents the count of valid source codec types. */ | |
| static final int SOURCE_CODEC_TYPE_MAX = 7; | |
| /** @hide */ | |
| @IntDef( | |
| prefix = "CODEC_PRIORITY_", | |
| value = {CODEC_PRIORITY_DISABLED, CODEC_PRIORITY_DEFAULT, CODEC_PRIORITY_HIGHEST}) | |
| @Retention(RetentionPolicy.SOURCE) | |
| public @interface CodecPriority {} | |
| /** | |
| * Codec priority disabled. Used to indicate that this codec is disabled and should not be used. | |
| */ | |
| public static final int CODEC_PRIORITY_DISABLED = -1; | |
| /** Codec priority default. Default value used for codec priority. */ | |
| public static final int CODEC_PRIORITY_DEFAULT = 0; | |
| /** Codec priority highest. Used to indicate the highest priority a codec can have. */ | |
| public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000; | |
| /** @hide */ | |
| @IntDef( | |
| prefix = "SAMPLE_RATE_", | |
| value = { | |
| SAMPLE_RATE_NONE, | |
| SAMPLE_RATE_44100, | |
| SAMPLE_RATE_48000, | |
| SAMPLE_RATE_88200, | |
| SAMPLE_RATE_96000, | |
| SAMPLE_RATE_176400, | |
| SAMPLE_RATE_192000 | |
| }) | |
| @Retention(RetentionPolicy.SOURCE) | |
| public @interface SampleRate {} | |
| /** Codec sample rate 0 Hz. Default value used for codec sample rate. */ | |
| public static final int SAMPLE_RATE_NONE = 0; | |
| /** Codec sample rate 44100 Hz. */ | |
| public static final int SAMPLE_RATE_44100 = 0x1 << 0; | |
| /** Codec sample rate 48000 Hz. */ | |
| public static final int SAMPLE_RATE_48000 = 0x1 << 1; | |
| /** Codec sample rate 88200 Hz. */ | |
| public static final int SAMPLE_RATE_88200 = 0x1 << 2; | |
| /** Codec sample rate 96000 Hz. */ | |
| public static final int SAMPLE_RATE_96000 = 0x1 << 3; | |
| /** Codec sample rate 176400 Hz. */ | |
| public static final int SAMPLE_RATE_176400 = 0x1 << 4; | |
| /** Codec sample rate 192000 Hz. */ | |
| public static final int SAMPLE_RATE_192000 = 0x1 << 5; | |
| /** @hide */ | |
| @IntDef( | |
| prefix = "BITS_PER_SAMPLE_", | |
| value = { | |
| BITS_PER_SAMPLE_NONE, | |
| BITS_PER_SAMPLE_16, | |
| BITS_PER_SAMPLE_24, | |
| BITS_PER_SAMPLE_32 | |
| }) | |
| @Retention(RetentionPolicy.SOURCE) | |
| public @interface BitsPerSample {} | |
| /** Codec bits per sample 0. Default value of the codec bits per sample. */ | |
| public static final int BITS_PER_SAMPLE_NONE = 0; | |
| /** Codec bits per sample 16. */ | |
| public static final int BITS_PER_SAMPLE_16 = 0x1 << 0; | |
| /** Codec bits per sample 24. */ | |
| public static final int BITS_PER_SAMPLE_24 = 0x1 << 1; | |
| /** Codec bits per sample 32. */ | |
| public static final int BITS_PER_SAMPLE_32 = 0x1 << 2; | |
| /** @hide */ | |
| @IntDef( | |
| prefix = "CHANNEL_MODE_", | |
| value = {CHANNEL_MODE_NONE, CHANNEL_MODE_MONO, CHANNEL_MODE_STEREO}) | |
| @Retention(RetentionPolicy.SOURCE) | |
| public @interface ChannelMode {} | |
| /** Codec channel mode NONE. Default value of the codec channel mode. */ | |
| public static final int CHANNEL_MODE_NONE = 0; | |
| /** Codec channel mode MONO. */ | |
| public static final int CHANNEL_MODE_MONO = 0x1 << 0; | |
| /** Codec channel mode STEREO. */ | |
| public static final int CHANNEL_MODE_STEREO = 0x1 << 1; | |
| private final @Nullable BluetoothCodecType mCodecType; | |
| private @CodecPriority int mCodecPriority; | |
| private final @SampleRate int mSampleRate; | |
| private final @BitsPerSample int mBitsPerSample; | |
| private final @ChannelMode int mChannelMode; | |
| private final long mCodecSpecific1; | |
| private final long mCodecSpecific2; | |
| private final long mCodecSpecific3; | |
| private final long mCodecSpecific4; | |
| /** | |
| * Creates a new BluetoothCodecConfig. | |
| * | |
| * @param codecType the source codec type | |
| * @param codecPriority the priority of this codec | |
| * @param sampleRate the codec sample rate | |
| * @param bitsPerSample the bits per sample of this codec | |
| * @param channelMode the channel mode of this codec | |
| * @param codecSpecific1 the specific value 1 | |
| * @param codecSpecific2 the specific value 2 | |
| * @param codecSpecific3 the specific value 3 | |
| * @param codecSpecific4 the specific value 4 values to 0. | |
| * @hide | |
| */ | |
| @UnsupportedAppUsage | |
| public BluetoothCodecConfig( | |
| @SourceCodecType int codecType, | |
| @CodecPriority int codecPriority, | |
| @SampleRate int sampleRate, | |
| @BitsPerSample int bitsPerSample, | |
| @ChannelMode int channelMode, | |
| long codecSpecific1, | |
| long codecSpecific2, | |
| long codecSpecific3, | |
| long codecSpecific4) { | |
| this( | |
| BluetoothCodecType.createFromType(codecType), | |
| codecPriority, | |
| sampleRate, | |
| bitsPerSample, | |
| channelMode, | |
| codecSpecific1, | |
| codecSpecific2, | |
| codecSpecific3, | |
| codecSpecific4); | |
| } | |
| /** | |
| * Creates a new BluetoothCodecConfig. | |
| * | |
| * @param codecType the source codec type | |
| * @param codecPriority the priority of this codec | |
| * @param sampleRate the codec sample rate | |
| * @param bitsPerSample the bits per sample of this codec | |
| * @param channelMode the channel mode of this codec | |
| * @param codecSpecific1 the specific value 1 | |
| * @param codecSpecific2 the specific value 2 | |
| * @param codecSpecific3 the specific value 3 | |
| * @param codecSpecific4 the specific value 4 values to 0. | |
| * @hide | |
| */ | |
| public BluetoothCodecConfig( | |
| @Nullable BluetoothCodecType codecType, | |
| @CodecPriority int codecPriority, | |
| @SampleRate int sampleRate, | |
| @BitsPerSample int bitsPerSample, | |
| @ChannelMode int channelMode, | |
| long codecSpecific1, | |
| long codecSpecific2, | |
| long codecSpecific3, | |
| long codecSpecific4) { | |
| mCodecType = codecType; | |
| mCodecPriority = codecPriority; | |
| mSampleRate = sampleRate; | |
| mBitsPerSample = bitsPerSample; | |
| mChannelMode = channelMode; | |
| mCodecSpecific1 = codecSpecific1; | |
| mCodecSpecific2 = codecSpecific2; | |
| mCodecSpecific3 = codecSpecific3; | |
| mCodecSpecific4 = codecSpecific4; | |
| } | |
| /** | |
| * Creates a new BluetoothCodecConfig. | |
| * | |
| * <p>By default, the codec priority will be set to {@link | |
| * BluetoothCodecConfig#CODEC_PRIORITY_DEFAULT}, the sample rate to {@link | |
| * BluetoothCodecConfig#SAMPLE_RATE_NONE}, the bits per sample to {@link | |
| * BluetoothCodecConfig#BITS_PER_SAMPLE_NONE}, the channel mode to {@link | |
| * BluetoothCodecConfig#CHANNEL_MODE_NONE}, and all the codec specific values to 0. | |
| * | |
| * @param codecType the source codec type | |
| * @hide | |
| */ | |
| public BluetoothCodecConfig(@SourceCodecType int codecType) { | |
| this( | |
| BluetoothCodecType.createFromType(codecType), | |
| BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT, | |
| BluetoothCodecConfig.SAMPLE_RATE_NONE, | |
| BluetoothCodecConfig.BITS_PER_SAMPLE_NONE, | |
| BluetoothCodecConfig.CHANNEL_MODE_NONE, | |
| 0, | |
| 0, | |
| 0, | |
| 0); | |
| } | |
| private BluetoothCodecConfig(Parcel in) { | |
| mCodecType = BluetoothCodecType.createFromType(in.readInt()); | |
| mCodecPriority = in.readInt(); | |
| mSampleRate = in.readInt(); | |
| mBitsPerSample = in.readInt(); | |
| mChannelMode = in.readInt(); | |
| mCodecSpecific1 = in.readLong(); | |
| mCodecSpecific2 = in.readLong(); | |
| mCodecSpecific3 = in.readLong(); | |
| mCodecSpecific4 = in.readLong(); | |
| } | |
| @Override | |
| public boolean equals(@Nullable Object o) { | |
| if (o instanceof BluetoothCodecConfig) { | |
| BluetoothCodecConfig other = (BluetoothCodecConfig) o; | |
| return (Objects.equals(other.mCodecType, mCodecType) | |
| && other.mCodecPriority == mCodecPriority | |
| && other.mSampleRate == mSampleRate | |
| && other.mBitsPerSample == mBitsPerSample | |
| && other.mChannelMode == mChannelMode | |
| && other.mCodecSpecific1 == mCodecSpecific1 | |
| && other.mCodecSpecific2 == mCodecSpecific2 | |
| && other.mCodecSpecific3 == mCodecSpecific3 | |
| && other.mCodecSpecific4 == mCodecSpecific4); | |
| } | |
| return false; | |
| } | |
| /** | |
| * Returns a hash representation of this BluetoothCodecConfig based on all the config values. | |
| */ | |
| @Override | |
| public int hashCode() { | |
| return Objects.hash( | |
| mCodecType, | |
| mCodecPriority, | |
| mSampleRate, | |
| mBitsPerSample, | |
| mChannelMode, | |
| mCodecSpecific1, | |
| mCodecSpecific2, | |
| mCodecSpecific3, | |
| mCodecSpecific4); | |
| } | |
| /** | |
| * Adds capability string to an existing string. | |
| * | |
| * @param prevStr the previous string with the capabilities. Can be a {@code null} pointer | |
| * @param capStr the capability string to append to prevStr argument | |
| * @return the result string in the form "prevStr|capStr" | |
| */ | |
| private static String appendCapabilityToString( | |
| @Nullable String prevStr, @NonNull String capStr) { | |
| if (prevStr == null) { | |
| return capStr; | |
| } | |
| return prevStr + "|" + capStr; | |
| } | |
| /** | |
| * Returns a {@link String} that describes each BluetoothCodecConfig parameter current value. | |
| */ | |
| @Override | |
| public String toString() { | |
| String codecName = null; | |
| int codecType = SOURCE_CODEC_TYPE_INVALID; | |
| if (mCodecType != null) { | |
| codecName = mCodecType.getCodecName(); | |
| codecType = mCodecType.getNativeCodecType(); | |
| } | |
| String sampleRateStr = null; | |
| if (mSampleRate == SAMPLE_RATE_NONE) { | |
| sampleRateStr = appendCapabilityToString(sampleRateStr, "NONE"); | |
| } | |
| if ((mSampleRate & SAMPLE_RATE_44100) != 0) { | |
| sampleRateStr = appendCapabilityToString(sampleRateStr, "44100"); | |
| } | |
| if ((mSampleRate & SAMPLE_RATE_48000) != 0) { | |
| sampleRateStr = appendCapabilityToString(sampleRateStr, "48000"); | |
| } | |
| if ((mSampleRate & SAMPLE_RATE_88200) != 0) { | |
| sampleRateStr = appendCapabilityToString(sampleRateStr, "88200"); | |
| } | |
| if ((mSampleRate & SAMPLE_RATE_96000) != 0) { | |
| sampleRateStr = appendCapabilityToString(sampleRateStr, "96000"); | |
| } | |
| if ((mSampleRate & SAMPLE_RATE_176400) != 0) { | |
| sampleRateStr = appendCapabilityToString(sampleRateStr, "176400"); | |
| } | |
| if ((mSampleRate & SAMPLE_RATE_192000) != 0) { | |
| sampleRateStr = appendCapabilityToString(sampleRateStr, "192000"); | |
| } | |
| String bitsPerSampleStr = null; | |
| if (mBitsPerSample == BITS_PER_SAMPLE_NONE) { | |
| bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "NONE"); | |
| } | |
| if ((mBitsPerSample & BITS_PER_SAMPLE_16) != 0) { | |
| bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "16"); | |
| } | |
| if ((mBitsPerSample & BITS_PER_SAMPLE_24) != 0) { | |
| bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "24"); | |
| } | |
| if ((mBitsPerSample & BITS_PER_SAMPLE_32) != 0) { | |
| bitsPerSampleStr = appendCapabilityToString(bitsPerSampleStr, "32"); | |
| } | |
| String channelModeStr = null; | |
| if (mChannelMode == CHANNEL_MODE_NONE) { | |
| channelModeStr = appendCapabilityToString(channelModeStr, "NONE"); | |
| } | |
| if ((mChannelMode & CHANNEL_MODE_MONO) != 0) { | |
| channelModeStr = appendCapabilityToString(channelModeStr, "MONO"); | |
| } | |
| if ((mChannelMode & CHANNEL_MODE_STEREO) != 0) { | |
| channelModeStr = appendCapabilityToString(channelModeStr, "STEREO"); | |
| } | |
| return ("{codecName:" + codecName) | |
| + (",mCodecType:" + codecType) | |
| + (",mCodecPriority:" + mCodecPriority) | |
| + (",mSampleRate:" + formatSimple("0x%x", mSampleRate) + "(" + sampleRateStr + ")") | |
| + (",mBitsPerSample:" | |
| + formatSimple("0x%x", mBitsPerSample) | |
| + "(" | |
| + bitsPerSampleStr | |
| + ")") | |
| + (",mChannelMode:" | |
| + formatSimple("0x%x", mChannelMode) | |
| + "(" | |
| + channelModeStr | |
| + ")") | |
| + (",mCodecSpecific1:" + mCodecSpecific1) | |
| + (",mCodecSpecific2:" + mCodecSpecific2) | |
| + (",mCodecSpecific3:" + mCodecSpecific3) | |
| + (",mCodecSpecific4:" + mCodecSpecific4) | |
| + "}"; | |
| } | |
| /** | |
| * @return 0 | |
| * @hide | |
| */ | |
| @Override | |
| public int describeContents() { | |
| return 0; | |
| } | |
| public static final @NonNull Creator<BluetoothCodecConfig> CREATOR = | |
| new Creator<>() { | |
| public BluetoothCodecConfig createFromParcel(Parcel in) { | |
| return new BluetoothCodecConfig(in); | |
| } | |
| public BluetoothCodecConfig[] newArray(int size) { | |
| return new BluetoothCodecConfig[size]; | |
| } | |
| }; | |
| /** | |
| * Flattens the object to a parcel | |
| * | |
| * @param out The Parcel in which the object should be written | |
| * @param flags Additional flags about how the object should be written | |
| * @hide | |
| */ | |
| @Override | |
| public void writeToParcel(Parcel out, int flags) { | |
| out.writeInt(getCodecType()); | |
| out.writeInt(mCodecPriority); | |
| out.writeInt(mSampleRate); | |
| out.writeInt(mBitsPerSample); | |
| out.writeInt(mChannelMode); | |
| out.writeLong(mCodecSpecific1); | |
| out.writeLong(mCodecSpecific2); | |
| out.writeLong(mCodecSpecific3); | |
| out.writeLong(mCodecSpecific4); | |
| } | |
| /** | |
| * Returns the codec name converted to {@link String}. | |
| * | |
| * @hide | |
| */ | |
| public static @NonNull String getCodecName(@SourceCodecType int codecType) { | |
| switch (codecType) { | |
| case SOURCE_CODEC_TYPE_SBC: | |
| return "SBC"; | |
| case SOURCE_CODEC_TYPE_AAC: | |
| return "AAC"; | |
| case SOURCE_CODEC_TYPE_APTX: | |
| return "aptX"; | |
| case SOURCE_CODEC_TYPE_APTX_HD: | |
| return "aptX HD"; | |
| case SOURCE_CODEC_TYPE_LDAC: | |
| return "LDAC"; | |
| case SOURCE_CODEC_TYPE_LC3: | |
| return "LC3"; | |
| case SOURCE_CODEC_TYPE_OPUS: | |
| return "Opus"; | |
| case SOURCE_CODEC_TYPE_INVALID: | |
| return "INVALID CODEC"; | |
| default: | |
| break; | |
| } | |
| return "UNKNOWN CODEC(" + codecType + ")"; | |
| } | |
| /** | |
| * Returns the source codec type of this config. | |
| * | |
| * @deprecated use {@link BluetoothCodecConfig#getExtendedCodecType} instead. | |
| */ | |
| @Deprecated | |
| @SuppressLint("WrongConstant") | |
| public @SourceCodecType int getCodecType() { | |
| return mCodecType == null ? SOURCE_CODEC_TYPE_INVALID : mCodecType.getNativeCodecType(); | |
| } | |
| /** Returns the source codec type of this config. */ | |
| public @Nullable BluetoothCodecType getExtendedCodecType() { | |
| return mCodecType; | |
| } | |
| /** | |
| * Checks whether the codec is mandatory. | |
| * | |
| * <p>The actual mandatory codec type for Android Bluetooth audio is SBC. See {@link | |
| * #SOURCE_CODEC_TYPE_SBC}. | |
| * | |
| * @return {@code true} if the codec is mandatory, {@code false} otherwise | |
| */ | |
| public boolean isMandatoryCodec() { | |
| return mCodecType == null ? false : mCodecType.isMandatoryCodec(); | |
| } | |
| /** | |
| * Returns the codec selection priority. | |
| * | |
| * <p>The codec selection priority is relative to other codecs: larger value means higher | |
| * priority. | |
| */ | |
| public @CodecPriority int getCodecPriority() { | |
| return mCodecPriority; | |
| } | |
| /** | |
| * Sets the codec selection priority. | |
| * | |
| * <p>The codec selection priority is relative to other codecs: larger value means higher | |
| * priority. | |
| * | |
| * @param codecPriority the priority this codec should have | |
| * @hide | |
| */ | |
| public void setCodecPriority(@CodecPriority int codecPriority) { | |
| mCodecPriority = codecPriority; | |
| } | |
| /** | |
| * Returns the codec sample rate. The value can be a bitmask with all supported sample rates. | |
| */ | |
| public @SampleRate int getSampleRate() { | |
| return mSampleRate; | |
| } | |
| /** | |
| * Returns the codec bits per sample. The value can be a bitmask with all bits per sample | |
| * supported. | |
| */ | |
| public @BitsPerSample int getBitsPerSample() { | |
| return mBitsPerSample; | |
| } | |
| /** | |
| * Returns the codec channel mode. The value can be a bitmask with all supported channel modes. | |
| */ | |
| public @ChannelMode int getChannelMode() { | |
| return mChannelMode; | |
| } | |
| /** | |
| * Returns the codec specific value1. As the value and usage differ for each codec, please refer | |
| * to the concerned codec specification to obtain the codec specific information. | |
| * | |
| * <p>See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific information | |
| * elements. | |
| * | |
| * <p>See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio codec specific | |
| * information elements. | |
| * | |
| * <p>See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC codec specific | |
| * information elements. | |
| * | |
| * <p>See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family codec specific | |
| * information elements. | |
| * | |
| * <p>See section 4.7.2 of the Bluetooth A2dp specification for Vendor Specific A2DP codec | |
| * specific information elements. | |
| */ | |
| public long getCodecSpecific1() { | |
| return mCodecSpecific1; | |
| } | |
| /** | |
| * Returns the codec specific value2. As the value and usage differ for each codec, please refer | |
| * to the concerned codec specification to obtain the codec specific information. | |
| * | |
| * <p>See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific information | |
| * elements. | |
| * | |
| * <p>See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio codec specific | |
| * information elements. | |
| * | |
| * <p>See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC codec specific | |
| * information elements. | |
| * | |
| * <p>See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family codec specific | |
| * information elements. | |
| * | |
| * <p>See section 4.7.2 of the Bluetooth A2dp specification for Vendor Specific A2DP codec | |
| * specific information elements. | |
| */ | |
| public long getCodecSpecific2() { | |
| return mCodecSpecific2; | |
| } | |
| /** | |
| * Returns the codec specific value3. As the value and usage differ for each codec, please refer | |
| * to the concerned codec specification to obtain the codec specific information. | |
| * | |
| * <p>See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific information | |
| * elements. | |
| * | |
| * <p>See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio codec specific | |
| * information elements. | |
| * | |
| * <p>See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC codec specific | |
| * information elements. | |
| * | |
| * <p>See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family codec specific | |
| * information elements. | |
| * | |
| * <p>See section 4.7.2 of the Bluetooth A2dp specification for Vendor Specific A2DP codec | |
| * specific information elements. | |
| */ | |
| public long getCodecSpecific3() { | |
| return mCodecSpecific3; | |
| } | |
| /** | |
| * Returns the codec specific value4. As the value and usage differ for each codec, please refer | |
| * to the concerned codec specification to obtain the codec specific information. | |
| * | |
| * <p>See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific information | |
| * elements. | |
| * | |
| * <p>See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio codec specific | |
| * information elements. | |
| * | |
| * <p>See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC codec specific | |
| * information elements. | |
| * | |
| * <p>See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family codec specific | |
| * information elements. | |
| * | |
| * <p>See section 4.7.2 of the Bluetooth A2dp specification for Vendor Specific A2DP codec | |
| * specific information elements. | |
| */ | |
| public long getCodecSpecific4() { | |
| return mCodecSpecific4; | |
| } | |
| /** | |
| * Checks whether a value set presented by a bitmask has zero or single bit | |
| * | |
| * @param valueSet the value set presented by a bitmask | |
| * @return {@code true} if the valueSet contains zero or single bit, {@code false} otherwise | |
| * @hide | |
| */ | |
| private static boolean hasSingleBit(int valueSet) { | |
| return (valueSet == 0 || (valueSet & (valueSet - 1)) == 0); | |
| } | |
| /** | |
| * Returns whether the object contains none or single sample rate. | |
| * | |
| * @hide | |
| */ | |
| public boolean hasSingleSampleRate() { | |
| return hasSingleBit(mSampleRate); | |
| } | |
| /** | |
| * Returns whether the object contains none or single bits per sample. | |
| * | |
| * @hide | |
| */ | |
| public boolean hasSingleBitsPerSample() { | |
| return hasSingleBit(mBitsPerSample); | |
| } | |
| /** | |
| * Returns whether the object contains none or single channel mode. | |
| * | |
| * @hide | |
| */ | |
| public boolean hasSingleChannelMode() { | |
| return hasSingleBit(mChannelMode); | |
| } | |
| /** | |
| * Checks whether the audio feeding parameters are the same. | |
| * | |
| * @param other the codec config to compare against | |
| * @return {@code true} if the audio feeding parameters are same, {@code false} otherwise | |
| * @hide | |
| */ | |
| public boolean sameAudioFeedingParameters(BluetoothCodecConfig other) { | |
| return (other != null | |
| && other.mSampleRate == mSampleRate | |
| && other.mBitsPerSample == mBitsPerSample | |
| && other.mChannelMode == mChannelMode); | |
| } | |
| /** | |
| * Checks whether another codec config has the similar feeding parameters. Any parameters with | |
| * NONE value will be considered to be a wildcard matching. | |
| * | |
| * @param other the codec config to compare against | |
| * @return {@code true} if the audio feeding parameters are similar, {@code false} otherwise | |
| * @hide | |
| */ | |
| public boolean similarCodecFeedingParameters(BluetoothCodecConfig other) { | |
| if (other == null || !Objects.equals(mCodecType, other.mCodecType)) { | |
| return false; | |
| } | |
| int sampleRate = other.mSampleRate; | |
| if (mSampleRate == SAMPLE_RATE_NONE || sampleRate == SAMPLE_RATE_NONE) { | |
| sampleRate = mSampleRate; | |
| } | |
| int bitsPerSample = other.mBitsPerSample; | |
| if (mBitsPerSample == BITS_PER_SAMPLE_NONE || bitsPerSample == BITS_PER_SAMPLE_NONE) { | |
| bitsPerSample = mBitsPerSample; | |
| } | |
| int channelMode = other.mChannelMode; | |
| if (mChannelMode == CHANNEL_MODE_NONE || channelMode == CHANNEL_MODE_NONE) { | |
| channelMode = mChannelMode; | |
| } | |
| return sameAudioFeedingParameters( | |
| new BluetoothCodecConfig( | |
| mCodecType, /* priority */ | |
| CODEC_PRIORITY_DEFAULT, | |
| sampleRate, | |
| bitsPerSample, | |
| channelMode, | |
| /* specific1 */ 0, /* specific2 */ | |
| 0, /* specific3 */ | |
| 0, | |
| /* specific4 */ 0)); | |
| } | |
| /** | |
| * Checks whether the codec specific parameters are the same. | |
| * | |
| * <p>Currently, only AAC VBR and LDAC Playback Quality on CodecSpecific1 are compared. | |
| * | |
| * @param other the codec config to compare against | |
| * @return {@code true} if the codec specific parameters are the same, {@code false} otherwise | |
| * @hide | |
| */ | |
| public boolean sameCodecSpecificParameters(BluetoothCodecConfig other) { | |
| if (other == null && !Objects.equals(mCodecType, other.mCodecType)) { | |
| return false; | |
| } | |
| switch (getCodecType()) { | |
| case SOURCE_CODEC_TYPE_AAC: | |
| case SOURCE_CODEC_TYPE_LDAC: | |
| case SOURCE_CODEC_TYPE_LC3: | |
| case SOURCE_CODEC_TYPE_OPUS: | |
| if (mCodecSpecific1 != other.mCodecSpecific1) { | |
| return false; | |
| } | |
| // fall through | |
| default: | |
| return true; | |
| } | |
| } | |
| /** | |
| * Builder for {@link BluetoothCodecConfig}. | |
| * | |
| * <p>By default, the codec type will be set to {@link | |
| * BluetoothCodecConfig#SOURCE_CODEC_TYPE_INVALID}, the codec priority to {@link | |
| * BluetoothCodecConfig#CODEC_PRIORITY_DEFAULT}, the sample rate to {@link | |
| * BluetoothCodecConfig#SAMPLE_RATE_NONE}, the bits per sample to {@link | |
| * BluetoothCodecConfig#BITS_PER_SAMPLE_NONE}, the channel mode to {@link | |
| * BluetoothCodecConfig#CHANNEL_MODE_NONE}, and all the codec specific values to 0. | |
| */ | |
| public static final class Builder { | |
| private @Nullable BluetoothCodecType mCodecType = null; | |
| private int mCodecPriority = BluetoothCodecConfig.CODEC_PRIORITY_DEFAULT; | |
| private int mSampleRate = BluetoothCodecConfig.SAMPLE_RATE_NONE; | |
| private int mBitsPerSample = BluetoothCodecConfig.BITS_PER_SAMPLE_NONE; | |
| private int mChannelMode = BluetoothCodecConfig.CHANNEL_MODE_NONE; | |
| private long mCodecSpecific1 = 0; | |
| private long mCodecSpecific2 = 0; | |
| private long mCodecSpecific3 = 0; | |
| private long mCodecSpecific4 = 0; | |
| /** | |
| * Set codec type for Bluetooth codec config. | |
| * | |
| * @param codecType of this codec | |
| * @return the same Builder instance | |
| * @deprecated use {@link BluetoothCodecType} instead | |
| */ | |
| @Deprecated | |
| public @NonNull Builder setCodecType(@SourceCodecType int codecType) { | |
| mCodecType = BluetoothCodecType.createFromType(codecType); | |
| return this; | |
| } | |
| /** | |
| * Set codec type for Bluetooth codec config. | |
| * | |
| * @param codecType of this codec | |
| * @return the same Builder instance | |
| */ | |
| public @NonNull Builder setExtendedCodecType(@Nullable BluetoothCodecType codecType) { | |
| mCodecType = codecType; | |
| return this; | |
| } | |
| /** | |
| * Set codec priority for Bluetooth codec config. | |
| * | |
| * @param codecPriority of this codec | |
| * @return the same Builder instance | |
| */ | |
| public @NonNull Builder setCodecPriority(@CodecPriority int codecPriority) { | |
| mCodecPriority = codecPriority; | |
| return this; | |
| } | |
| /** | |
| * Set sample rate for Bluetooth codec config. | |
| * | |
| * @param sampleRate of this codec | |
| * @return the same Builder instance | |
| */ | |
| public @NonNull Builder setSampleRate(@SampleRate int sampleRate) { | |
| mSampleRate = sampleRate; | |
| return this; | |
| } | |
| /** | |
| * Set the bits per sample for Bluetooth codec config. | |
| * | |
| * @param bitsPerSample of this codec | |
| * @return the same Builder instance | |
| */ | |
| public @NonNull Builder setBitsPerSample(@BitsPerSample int bitsPerSample) { | |
| mBitsPerSample = bitsPerSample; | |
| return this; | |
| } | |
| /** | |
| * Set the channel mode for Bluetooth codec config. | |
| * | |
| * @param channelMode of this codec | |
| * @return the same Builder instance | |
| */ | |
| public @NonNull Builder setChannelMode(@ChannelMode int channelMode) { | |
| mChannelMode = channelMode; | |
| return this; | |
| } | |
| /** | |
| * Set the first codec specific values for Bluetooth codec config. | |
| * | |
| * @param codecSpecific1 codec specific value or 0 if default | |
| * @return the same Builder instance | |
| */ | |
| public @NonNull Builder setCodecSpecific1(long codecSpecific1) { | |
| mCodecSpecific1 = codecSpecific1; | |
| return this; | |
| } | |
| /** | |
| * Set the second codec specific values for Bluetooth codec config. | |
| * | |
| * @param codecSpecific2 codec specific value or 0 if default | |
| * @return the same Builder instance | |
| */ | |
| public @NonNull Builder setCodecSpecific2(long codecSpecific2) { | |
| mCodecSpecific2 = codecSpecific2; | |
| return this; | |
| } | |
| /** | |
| * Set the third codec specific values for Bluetooth codec config. | |
| * | |
| * @param codecSpecific3 codec specific value or 0 if default | |
| * @return the same Builder instance | |
| */ | |
| public @NonNull Builder setCodecSpecific3(long codecSpecific3) { | |
| mCodecSpecific3 = codecSpecific3; | |
| return this; | |
| } | |
| /** | |
| * Set the fourth codec specific values for Bluetooth codec config. | |
| * | |
| * @param codecSpecific4 codec specific value or 0 if default | |
| * @return the same Builder instance | |
| */ | |
| public @NonNull Builder setCodecSpecific4(long codecSpecific4) { | |
| mCodecSpecific4 = codecSpecific4; | |
| return this; | |
| } | |
| /** | |
| * Build {@link BluetoothCodecConfig}. | |
| * | |
| * @return new BluetoothCodecConfig built | |
| */ | |
| public @NonNull BluetoothCodecConfig build() { | |
| return new BluetoothCodecConfig( | |
| mCodecType, | |
| mCodecPriority, | |
| mSampleRate, | |
| mBitsPerSample, | |
| mChannelMode, | |
| mCodecSpecific1, | |
| mCodecSpecific2, | |
| mCodecSpecific3, | |
| mCodecSpecific4); | |
| } | |
| } | |
| } |