Merge "Add helpers to check whether the BluetoothCodecConfig instance is selectable" am: 8052fac1b1 am: af3615e586 am: 8cdf1fb47f am: 9b1e5c4614
am: 8ca85b5b2f
Change-Id: I7ae6d9ceaafa45e247c128910e2959a9f7a0ba27
diff --git a/core/java/android/bluetooth/BluetoothCodecConfig.java b/core/java/android/bluetooth/BluetoothCodecConfig.java
index 591c418..36f3a1e 100644
--- a/core/java/android/bluetooth/BluetoothCodecConfig.java
+++ b/core/java/android/bluetooth/BluetoothCodecConfig.java
@@ -441,6 +441,43 @@
}
/**
+ * Checks whether a value set presented by a bitmask has zero or single bit
+ *
+ * @param valueSet the value set presented by a bitmask
+ * @return true if the valueSet contains zero or single bit, otherwise false.
+ */
+ private static boolean hasSingleBit(int valueSet) {
+ return (valueSet == 0 || (valueSet & (valueSet - 1)) == 0);
+ }
+
+ /**
+ * Checks whether the object contains none or single sample rate.
+ *
+ * @return true if the object contains none or single sample rate, otherwise false.
+ */
+ public boolean hasSingleSampleRate() {
+ return hasSingleBit(mSampleRate);
+ }
+
+ /**
+ * Checks whether the object contains none or single bits per sample.
+ *
+ * @return true if the object contains none or single bits per sample, otherwise false.
+ */
+ public boolean hasSingleBitsPerSample() {
+ return hasSingleBit(mBitsPerSample);
+ }
+
+ /**
+ * Checks whether the object contains none or single channel mode.
+ *
+ * @return true if the object contains none or single channel mode, otherwise false.
+ */
+ public boolean hasSingleChannelMode() {
+ return hasSingleBit(mChannelMode);
+ }
+
+ /**
* Checks whether the audio feeding parameters are same.
*
* @param other the codec config to compare against
@@ -451,4 +488,58 @@
&& 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 true if the audio feeding parameters are similar, otherwise false.
+ */
+ public boolean similarCodecFeedingParameters(BluetoothCodecConfig other) {
+ if (other == null || mCodecType != other.mCodecType) {
+ return false;
+ }
+ int sampleRate = other.mSampleRate;
+ if (mSampleRate == BluetoothCodecConfig.SAMPLE_RATE_NONE
+ || sampleRate == BluetoothCodecConfig.SAMPLE_RATE_NONE) {
+ sampleRate = mSampleRate;
+ }
+ int bitsPerSample = other.mBitsPerSample;
+ if (mBitsPerSample == BluetoothCodecConfig.BITS_PER_SAMPLE_NONE
+ || bitsPerSample == BluetoothCodecConfig.BITS_PER_SAMPLE_NONE) {
+ bitsPerSample = mBitsPerSample;
+ }
+ int channelMode = other.mChannelMode;
+ if (mChannelMode == BluetoothCodecConfig.CHANNEL_MODE_NONE
+ || channelMode == BluetoothCodecConfig.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.
+ *
+ * @param other the codec config to compare against
+ * @return true if the codec specific parameters are the same, otherwise false.
+ */
+ public boolean sameCodecSpecificParameters(BluetoothCodecConfig other) {
+ if (other == null && mCodecType != other.mCodecType) {
+ return false;
+ }
+ // Currently we only care about the LDAC Playback Quality at CodecSpecific1
+ switch (mCodecType) {
+ case SOURCE_CODEC_TYPE_LDAC:
+ if (mCodecSpecific1 != other.mCodecSpecific1) {
+ return false;
+ }
+ // fall through
+ default:
+ return true;
+ }
+ }
}
diff --git a/core/java/android/bluetooth/BluetoothCodecStatus.java b/core/java/android/bluetooth/BluetoothCodecStatus.java
index 58b6aea..58a764a 100644
--- a/core/java/android/bluetooth/BluetoothCodecStatus.java
+++ b/core/java/android/bluetooth/BluetoothCodecStatus.java
@@ -89,6 +89,43 @@
return Arrays.asList(c1).containsAll(Arrays.asList(c2));
}
+ /**
+ * Checks whether the codec config matches the selectable capabilities.
+ * Any parameters of the codec config with NONE value will be considered a wildcard matching.
+ *
+ * @param codecConfig the codec config to compare against
+ * @return true if the codec config matches, otherwise false
+ */
+ public boolean isCodecConfigSelectable(BluetoothCodecConfig codecConfig) {
+ if (codecConfig == null || !codecConfig.hasSingleSampleRate()
+ || !codecConfig.hasSingleBitsPerSample() || !codecConfig.hasSingleChannelMode()) {
+ return false;
+ }
+ for (BluetoothCodecConfig selectableConfig : mCodecsSelectableCapabilities) {
+ if (codecConfig.getCodecType() != selectableConfig.getCodecType()) {
+ continue;
+ }
+ int sampleRate = codecConfig.getSampleRate();
+ if ((sampleRate & selectableConfig.getSampleRate()) == 0
+ && sampleRate != BluetoothCodecConfig.SAMPLE_RATE_NONE) {
+ continue;
+ }
+ int bitsPerSample = codecConfig.getBitsPerSample();
+ if ((bitsPerSample & selectableConfig.getBitsPerSample()) == 0
+ && bitsPerSample != BluetoothCodecConfig.BITS_PER_SAMPLE_NONE) {
+ continue;
+ }
+ int channelMode = codecConfig.getChannelMode();
+ if ((channelMode & selectableConfig.getChannelMode()) == 0
+ && channelMode != BluetoothCodecConfig.CHANNEL_MODE_NONE) {
+ continue;
+ }
+ return true;
+ }
+ return false;
+ }
+
+
@Override
public int hashCode() {
return Objects.hash(mCodecConfig, mCodecsLocalCapabilities,