/* * 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 android.annotation.FlaggedApi; 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 com.android.bluetooth.flags.Flags; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** * Represents the codec configuration for a Bluetooth A2DP source device. * *

Contains the source codec type, the codec priority, the codec sample rate, the codec bits per * sample, and the codec channel mode. * *

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. * *

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:" + String.format("0x%x", mSampleRate) + "(" + sampleRateStr + ")") + (",mBitsPerSample:" + String.format("0x%x", mBitsPerSample) + "(" + bitsPerSampleStr + ")") + (",mChannelMode:" + String.format("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 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. */ @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY) public @Nullable BluetoothCodecType getExtendedCodecType() { return mCodecType; } /** * Checks whether the codec is mandatory. * *

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. * *

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. * *

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. * *

See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific information * elements. * *

See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio codec specific * information elements. * *

See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC codec specific * information elements. * *

See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family codec specific * information elements. * *

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. * *

See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific information * elements. * *

See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio codec specific * information elements. * *

See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC codec specific * information elements. * *

See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family codec specific * information elements. * *

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. * *

See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific information * elements. * *

See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio codec specific * information elements. * *

See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC codec specific * information elements. * *

See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family codec specific * information elements. * *

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. * *

See section 4.3.2 of the Bluetooth A2dp specification for SBC codec specific information * elements. * *

See section 4.4.2 of the Bluetooth A2dp specification for MPEG-1,2 Audio codec specific * information elements. * *

See section 4.5.2 of the Bluetooth A2dp specification for MPEG-2, 4 AAC codec specific * information elements. * *

See section 4.6.2 of the Bluetooth A2dp specification for ATRAC family codec specific * information elements. * *

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 */ 0, sampleRate, bitsPerSample, channelMode, /* specific1 */ 0, /* specific2 */ 0, /* specific3 */ 0, /* specific4 */ 0)); } /** * Checks whether the codec specific parameters are the same. * *

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}. * *

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 */ @FlaggedApi(Flags.FLAG_A2DP_OFFLOAD_CODEC_EXTENSIBILITY) 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); } } }