summaryrefslogtreecommitdiff
path: root/framework/java
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-03-18 01:09:07 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2022-03-18 01:09:07 +0000
commit9b52556d5cd7842ebfb13f13f3dc9ca68ae018c3 (patch)
tree72f48848f750d5fff52fee563cad8e952abcfd43 /framework/java
parentad221bf0c86a98f68d69e06ad79e025a38563881 (diff)
parent1d06e1a4e899e5a0d22905241ea5cf935224ef81 (diff)
Snap for 8317698 from 1d06e1a4e899e5a0d22905241ea5cf935224ef81 to tm-release
Change-Id: I50c536ec3728a64771a134f3c4eba5c68465e640
Diffstat (limited to 'framework/java')
-rw-r--r--framework/java/android/bluetooth/BluetoothA2dp.java56
-rw-r--r--framework/java/android/bluetooth/BluetoothAdapter.java81
-rw-r--r--framework/java/android/bluetooth/BluetoothCodecConfig.java8
-rw-r--r--framework/java/android/bluetooth/BluetoothDevice.java38
-rw-r--r--framework/java/android/bluetooth/BluetoothDevicePicker.java22
-rw-r--r--framework/java/android/bluetooth/BluetoothLeAudio.java49
-rw-r--r--framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java161
-rw-r--r--framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java194
8 files changed, 463 insertions, 146 deletions
diff --git a/framework/java/android/bluetooth/BluetoothA2dp.java b/framework/java/android/bluetooth/BluetoothA2dp.java
index 8b27e7faef..6c15925d53 100644
--- a/framework/java/android/bluetooth/BluetoothA2dp.java
+++ b/framework/java/android/bluetooth/BluetoothA2dp.java
@@ -835,9 +835,14 @@ public final class BluetoothA2dp implements BluetoothProfile {
}
/**
- * Enables the optional codecs.
+ * Enables the optional codecs for the given device for this connection.
*
- * @param device the remote Bluetooth device.
+ * If the given device supports another codec type than
+ * {@link BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC}, this will switch to it.
+ * See {@link #setOptionalCodecsEnabled} to enable optional codecs by default
+ * when the given device is connected.
+ *
+ * @param device the remote Bluetooth device
* @hide
*/
@SystemApi
@@ -851,9 +856,15 @@ public final class BluetoothA2dp implements BluetoothProfile {
}
/**
- * Disables the optional codecs.
+ * Disables the optional codecs for the given device.
*
- * @param device the remote Bluetooth device.
+ * When optional codecs are disabled, the device will use the default
+ * Bluetooth audio codec type.
+ * See {@link BluetoothCodecConfig.SOURCE_CODEC_TYPE_SBC}.
+ * See {@link #setOptionalCodecsEnabled} to disable optional codecs by default
+ * when the given device is connected.
+ *
+ * @param device the remote Bluetooth device
* @hide
*/
@SystemApi
@@ -870,7 +881,7 @@ public final class BluetoothA2dp implements BluetoothProfile {
* Enables or disables the optional codecs.
*
* @param device the remote Bluetooth device.
- * @param enable if true, enable the optional codecs, other disable them
+ * @param enable if true, enable the optional codecs, otherwise disable them
*/
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
private void enableDisableOptionalCodecs(BluetoothDevice device, boolean enable) {
@@ -894,17 +905,18 @@ public final class BluetoothA2dp implements BluetoothProfile {
/**
* Returns whether this device supports optional codecs.
*
- * @param device The device to check
- * @return one of OPTIONAL_CODECS_SUPPORT_UNKNOWN, OPTIONAL_CODECS_NOT_SUPPORTED, or
- * OPTIONAL_CODECS_SUPPORTED.
+ * @param device the remote Bluetooth device
+ * @return whether the optional codecs are supported or not, or
+ * {@link #OPTIONAL_CODECS_SUPPORT_UNKNOWN} if the state
+ * can't be retrieved.
* @hide
*/
@SystemApi
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
- @OptionalCodecsSupportStatus
- public int isOptionalCodecsSupported(@NonNull BluetoothDevice device) {
+ public @OptionalCodecsSupportStatus int isOptionalCodecsSupported(
+ @NonNull BluetoothDevice device) {
if (DBG) log("isOptionalCodecsSupported(" + device + ")");
verifyDeviceNotNull(device, "isOptionalCodecsSupported");
final IBluetoothA2dp service = getService();
@@ -925,19 +937,20 @@ public final class BluetoothA2dp implements BluetoothProfile {
}
/**
- * Returns whether this device should have optional codecs enabled.
+ * Returns whether this device has its optional codecs enabled.
*
- * @param device The device in question.
- * @return one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
- * OPTIONAL_CODECS_PREF_DISABLED.
+ * @param device the remote Bluetooth device
+ * @return whether the optional codecs are enabled or not, or
+ * {@link #OPTIONAL_CODECS_PREF_UNKNOWN} if the state
+ * can't be retrieved.
* @hide
*/
@SystemApi
@RequiresLegacyBluetoothAdminPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
- @OptionalCodecsPreferenceStatus
- public int isOptionalCodecsEnabled(@NonNull BluetoothDevice device) {
+ public @OptionalCodecsPreferenceStatus int isOptionalCodecsEnabled(
+ @NonNull BluetoothDevice device) {
if (DBG) log("isOptionalCodecsEnabled(" + device + ")");
verifyDeviceNotNull(device, "isOptionalCodecsEnabled");
final IBluetoothA2dp service = getService();
@@ -958,12 +971,13 @@ public final class BluetoothA2dp implements BluetoothProfile {
}
/**
- * Sets a persistent preference for whether a given device should have optional codecs enabled.
+ * Sets the default state of optional codecs for the given device.
+ *
+ * Automatically enables or disables the optional codecs for the given device when
+ * connected.
*
- * @param device The device to set this preference for.
- * @param value Whether the optional codecs should be enabled for this device. This should be
- * one of OPTIONAL_CODECS_PREF_UNKNOWN, OPTIONAL_CODECS_PREF_ENABLED, or
- * OPTIONAL_CODECS_PREF_DISABLED.
+ * @param device the remote Bluetooth device
+ * @param value whether the optional codecs should be enabled for this device
* @hide
*/
@SystemApi
diff --git a/framework/java/android/bluetooth/BluetoothAdapter.java b/framework/java/android/bluetooth/BluetoothAdapter.java
index de3f570d96..58ab06dffb 100644
--- a/framework/java/android/bluetooth/BluetoothAdapter.java
+++ b/framework/java/android/bluetooth/BluetoothAdapter.java
@@ -59,7 +59,6 @@ import android.os.IBinder;
import android.os.IpcDataCache;
import android.os.ParcelUuid;
import android.os.RemoteException;
-import android.os.ResultReceiver;
import android.sysprop.BluetoothProperties;
import android.util.Log;
import android.util.Pair;
@@ -832,6 +831,55 @@ public final class BluetoothAdapter {
};
/**
+ * Interface for Bluetooth activity energy info listener. Should be implemented by applications
+ * and set when calling {@link BluetoothAdapter#requestControllerActivityEnergyInfo}.
+ *
+ * @hide
+ */
+ @SystemApi
+ public interface OnBluetoothActivityEnergyInfoListener {
+ /**
+ * Called when Bluetooth activity energy info is available.
+ * Note: this listener is triggered at most once for each call to
+ * {@link #requestControllerActivityEnergyInfo}.
+ *
+ * @param info the latest {@link BluetoothActivityEnergyInfo}, or null if unavailable.
+ */
+ void onBluetoothActivityEnergyInfo(@Nullable BluetoothActivityEnergyInfo info);
+ }
+
+ private static class OnBluetoothActivityEnergyInfoProxy
+ extends IBluetoothActivityEnergyInfoListener.Stub {
+ private final Object mLock = new Object();
+ @Nullable @GuardedBy("mLock") private Executor mExecutor;
+ @Nullable @GuardedBy("mLock") private OnBluetoothActivityEnergyInfoListener mListener;
+
+ OnBluetoothActivityEnergyInfoProxy(Executor executor,
+ OnBluetoothActivityEnergyInfoListener listener) {
+ mExecutor = executor;
+ mListener = listener;
+ }
+
+ @Override
+ public void onBluetoothActivityEnergyInfo(BluetoothActivityEnergyInfo info) {
+ Executor executor;
+ OnBluetoothActivityEnergyInfoListener listener;
+ synchronized (mLock) {
+ if (mExecutor == null || mListener == null) {
+ return;
+ }
+ executor = mExecutor;
+ listener = mListener;
+ // null out to allow garbage collection, prevent triggering listener more than once
+ mExecutor = null;
+ mListener = null;
+ }
+ Binder.clearCallingIdentity();
+ executor.execute(() -> listener.onBluetoothActivityEnergyInfo(info));
+ }
+ }
+
+ /**
* Get a handle to the default local Bluetooth adapter.
* <p>
* Currently Android only supports one Bluetooth adapter, but the API could
@@ -1488,11 +1536,10 @@ public final class BluetoothAdapter {
* @return the UUIDs supported by the local Bluetooth Adapter.
* @hide
*/
- @SystemApi
+ @UnsupportedAppUsage
@RequiresLegacyBluetoothPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
- @SuppressLint(value = {"ArrayReturn", "NullableCollection"})
public @NonNull ParcelUuid[] getUuids() {
if (getState() != STATE_ON) {
return new ParcelUuid[0];
@@ -1516,6 +1563,18 @@ public final class BluetoothAdapter {
}
/**
+ * Get the UUIDs supported by the local Bluetooth adapter.
+ *
+ * @return a list of the UUIDs supported by the local Bluetooth Adapter.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public @NonNull List<ParcelUuid> getUuidsList() {
+ return Arrays.asList(getUuids());
+ }
+
+ /**
* Set the friendly Bluetooth name of the local Bluetooth adapter.
* <p>This name is visible to remote Bluetooth devices.
* <p>Valid Bluetooth names are a maximum of 248 bytes using UTF-8
@@ -2675,22 +2734,22 @@ public final class BluetoothAdapter {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED,
})
- public void requestControllerActivityEnergyInfo(@NonNull ResultReceiver result) {
- requireNonNull(result, "ResultReceiver cannot be null");
+ public void requestControllerActivityEnergyInfo(
+ @NonNull @CallbackExecutor Executor executor,
+ @NonNull OnBluetoothActivityEnergyInfoListener listener) {
+ requireNonNull(executor, "executor cannot be null");
+ requireNonNull(listener, "listener cannot be null");
try {
mServiceLock.readLock().lock();
if (mService != null) {
- mService.requestActivityInfo(result, mAttributionSource);
- result = null;
+ mService.requestActivityInfo(
+ new OnBluetoothActivityEnergyInfoProxy(executor, listener),
+ mAttributionSource);
}
} catch (RemoteException e) {
Log.e(TAG, "getControllerActivityEnergyInfoCallback: " + e);
} finally {
mServiceLock.readLock().unlock();
- if (result != null) {
- // Only send an immediate result if we failed.
- result.send(0, null);
- }
}
}
diff --git a/framework/java/android/bluetooth/BluetoothCodecConfig.java b/framework/java/android/bluetooth/BluetoothCodecConfig.java
index d0e426853c..16b787db8e 100644
--- a/framework/java/android/bluetooth/BluetoothCodecConfig.java
+++ b/framework/java/android/bluetooth/BluetoothCodecConfig.java
@@ -536,6 +536,8 @@ public final class BluetoothCodecConfig implements Parcelable {
/**
* 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.
*/
public long getCodecSpecific1() {
return mCodecSpecific1;
@@ -543,6 +545,8 @@ public final class BluetoothCodecConfig implements Parcelable {
/**
* 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.
*/
public long getCodecSpecific2() {
return mCodecSpecific2;
@@ -550,6 +554,8 @@ public final class BluetoothCodecConfig implements Parcelable {
/**
* 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.
*/
public long getCodecSpecific3() {
return mCodecSpecific3;
@@ -557,6 +563,8 @@ public final class BluetoothCodecConfig implements Parcelable {
/**
* 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.
*/
public long getCodecSpecific4() {
return mCodecSpecific4;
diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java
index 978c8ed4ac..698e409723 100644
--- a/framework/java/android/bluetooth/BluetoothDevice.java
+++ b/framework/java/android/bluetooth/BluetoothDevice.java
@@ -19,6 +19,7 @@ package android.bluetooth;
import static android.bluetooth.BluetoothUtils.getSyncTimeout;
import android.annotation.IntDef;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -794,6 +795,15 @@ public final class BluetoothDevice implements Parcelable, Attributable {
/**
* Broadcast Action: This intent is used to broadcast CONNECTION ACCESS REQUEST
*
+ * This action will trigger a prompt for the user to accept or deny giving the
+ * permission for this device. Permissions can be specified with
+ * {@link #EXTRA_ACCESS_REQUEST_TYPE}.
+ *
+ * The reply will be an {@link #ACTION_CONNECTION_ACCESS_REPLY} sent to the specified
+ * {@link #EXTRA_PACKAGE_NAME} and {@link #EXTRA_CLASS_NAME}.
+ *
+ * This action can be cancelled with {@link #ACTION_CONNECTION_ACCESS_CANCEL}.
+ *
* @hide
*/
@SystemApi
@@ -807,6 +817,13 @@ public final class BluetoothDevice implements Parcelable, Attributable {
/**
* Broadcast Action: This intent is used to broadcast CONNECTION ACCESS REPLY
*
+ * This action is the reply from {@link #ACTION_CONNECTION_ACCESS_REQUEST}
+ * that is sent to the specified {@link #EXTRA_PACKAGE_NAME}
+ * and {@link #EXTRA_CLASS_NAME}.
+ *
+ * See the extra fields {@link #EXTRA_CONNECTION_ACCESS_RESULT} and
+ * {@link #EXTRA_ALWAYS_ALLOWED} for possible results.
+ *
* @hide
*/
@SystemApi
@@ -844,7 +861,11 @@ public final class BluetoothDevice implements Parcelable, Attributable {
"android.bluetooth.device.action.SILENCE_MODE_CHANGED";
/**
- * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST} intent.
+ * Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REQUEST}.
+ *
+ * Possible values are {@link #REQUEST_TYPE_PROFILE_CONNECTION},
+ * {@link #REQUEST_TYPE_PHONEBOOK_ACCESS}, {@link #REQUEST_TYPE_MESSAGE_ACCESS}
+ * and {@link #REQUEST_TYPE_SIM_ACCESS}
*
* @hide
*/
@@ -888,6 +909,8 @@ public final class BluetoothDevice implements Parcelable, Attributable {
/**
* Used as an extra field in {@link #ACTION_CONNECTION_ACCESS_REPLY} intent.
*
+ * Possible values are {@link #CONNECTION_ACCESS_YES} and {@link #CONNECTION_ACCESS_NO}.
+ *
* @hide
*/
@SystemApi
@@ -1044,7 +1067,8 @@ public final class BluetoothDevice implements Parcelable, Attributable {
public static final int PAIRING_VARIANT_DISPLAY_PIN = 5;
/**
- * The user will be prompted to accept or deny the OOB pairing request
+ * The user will be prompted to accept or deny the OOB pairing request.
+ * This is used for Bluetooth 2.1 secure simple pairing.
*
* @hide
*/
@@ -1624,7 +1648,7 @@ public final class BluetoothDevice implements Parcelable, Attributable {
@RequiresLegacyBluetoothPermission
@RequiresBluetoothConnectPermission
@RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
- public int getBatteryLevel() {
+ public @IntRange(from = -100, to = 100) int getBatteryLevel() {
if (DBG) log("getBatteryLevel()");
final IBluetooth service = sService;
final int defaultValue = BATTERY_LEVEL_BLUETOOTH_OFF;
@@ -2009,10 +2033,14 @@ public final class BluetoothDevice implements Parcelable, Attributable {
/**
* Disconnects all connected bluetooth profiles between the local and remote device.
- * Disconnection is asynchronous and you should listen to each profile's broadcast intent
+ * Disconnection is asynchronous, so you should listen to each profile's broadcast intent
* ACTION_CONNECTION_STATE_CHANGED to verify whether disconnection was successful. For example,
* to verify a2dp is disconnected, you would listen for
- * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}
+ * {@link BluetoothA2dp#ACTION_CONNECTION_STATE_CHANGED}. Once all profiles have disconnected,
+ * the ACL link should come down and {@link #ACTION_ACL_DISCONNECTED} should be broadcast.
+ * <p>
+ * In the rare event that one or more profiles fail to disconnect, call this method again to
+ * send another request to disconnect each connected profile.
*
* @return whether the messages were successfully sent to try to disconnect all profiles
* @throws IllegalArgumentException if the device address is invalid
diff --git a/framework/java/android/bluetooth/BluetoothDevicePicker.java b/framework/java/android/bluetooth/BluetoothDevicePicker.java
index d17ab8d72a..d1fc0622e4 100644
--- a/framework/java/android/bluetooth/BluetoothDevicePicker.java
+++ b/framework/java/android/bluetooth/BluetoothDevicePicker.java
@@ -30,15 +30,37 @@ import android.bluetooth.annotations.RequiresBluetoothConnectPermission;
*/
@SystemApi
public interface BluetoothDevicePicker {
+
+ /**
+ * Extra for filter type used with {@link #ACTION_LAUNCH}.
+ * The value must be a boolean indicating whether the device should need authentication or not.
+ */
@SuppressLint("ActionValue")
public static final String EXTRA_NEED_AUTH =
"android.bluetooth.devicepicker.extra.NEED_AUTH";
+
+ /**
+ * Extra for filter type used with {@link #ACTION_LAUNCH}.
+ * This extra must contain the filter type that will be applied to the device list.
+ * Possible values are {@link #FILTER_TYPE_ALL}, {@link #FILTER_TYPE_AUDIO},
+ * {@link #FILTER_TYPE_TRANSFER}, {@link #FILTER_TYPE_PANU}, and {@link #FILTER_TYPE_NAP}.
+ */
@SuppressLint("ActionValue")
public static final String EXTRA_FILTER_TYPE =
"android.bluetooth.devicepicker.extra.FILTER_TYPE";
+
+ /**
+ * Extra for filter type used with {@link #ACTION_LAUNCH}.
+ * This extra must contain the package name that called {@link #ACTION_LAUNCH}.
+ */
@SuppressLint("ActionValue")
public static final String EXTRA_LAUNCH_PACKAGE =
"android.bluetooth.devicepicker.extra.LAUNCH_PACKAGE";
+
+ /**
+ * Extra for filter type used with {@link #ACTION_LAUNCH}.
+ * This extra must contain the class name that called {@link #ACTION_LAUNCH}.
+ */
@SuppressLint("ActionValue")
public static final String EXTRA_LAUNCH_CLASS =
"android.bluetooth.devicepicker.extra.DEVICE_PICKER_LAUNCH_CLASS";
diff --git a/framework/java/android/bluetooth/BluetoothLeAudio.java b/framework/java/android/bluetooth/BluetoothLeAudio.java
index b81a8a43a0..91b7d499bb 100644
--- a/framework/java/android/bluetooth/BluetoothLeAudio.java
+++ b/framework/java/android/bluetooth/BluetoothLeAudio.java
@@ -22,6 +22,7 @@ import static android.bluetooth.BluetoothUtils.getSyncTimeout;
import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
@@ -152,7 +153,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
/**
* Intent used to broadcast group node status information.
*
- * <p>This intent will have 3 extra:
+ * <p>This intent will have 3 extras:
* <ul>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
* be null if no device is active. </li>
@@ -174,7 +175,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
/**
* Intent used to broadcast group status information.
*
- * <p>This intent will have 4 extra:
+ * <p>This intent will have 3 extras:
* <ul>
* <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. It can
* be null if no device is active. </li>
@@ -827,13 +828,13 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
}
/**
- * Get lead device for a group.
+ * Get Lead device for the group.
*
* Lead device is the device that can be used as an active device in the system.
* Active devices points to the Audio Device for the Le Audio group.
- * This method returns a list of Lead devices for all the connected LE Audio
- * groups and those devices should be used in the setActiveDevice() method by other parts
- * of the system, which wants to setActive a particular Le Audio Group.
+ * This method returns the Lead devices for the connected LE Audio
+ * group and this device should be used in the setActiveDevice() method by other parts
+ * of the system, which wants to set to active a particular Le Audio group.
*
* Note: getActiveDevice() returns the Lead device for the currently active LE Audio group.
* Note: When lead device gets disconnected, there will be new lead device for the group.
@@ -1161,7 +1162,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED
})
- public void setVolume(int volume) {
+ public void setVolume(@IntRange(from = 0, to = 255) int volume) {
if (VDBG) log("setVolume(vol: " + volume + " )");
final IBluetoothLeAudio service = getService();
if (service == null) {
@@ -1392,7 +1393,7 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
/**
* Gets the current codec status (configuration and capability).
*
- * @param device the remote Bluetooth device.
+ * @param groupId The group id
* @return the current codec status
* @hide
*/
@@ -1403,9 +1404,9 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED
})
- public BluetoothLeAudioCodecStatus getCodecStatus(@NonNull BluetoothDevice device) {
+ public BluetoothLeAudioCodecStatus getCodecStatus(int groupId) {
if (DBG) {
- Log.d(TAG, "getCodecStatus(" + device + ")");
+ Log.d(TAG, "getCodecStatus(" + groupId + ")");
}
final IBluetoothLeAudio service = getService();
@@ -1414,11 +1415,11 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
if (service == null) {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
- } else if (mAdapter.isEnabled() && isValidDevice(device)) {
+ } else if (mAdapter.isEnabled()) {
try {
final SynchronousResultReceiver<BluetoothLeAudioCodecStatus> recv =
new SynchronousResultReceiver();
- service.getCodecStatus(device, mAttributionSource, recv);
+ service.getCodecStatus(groupId, mAttributionSource, recv);
return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
} catch (TimeoutException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
@@ -1433,9 +1434,11 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
/**
* Sets the codec configuration preference.
*
- * @param device the remote Bluetooth device.
- * @param codecConfig the codec configuration preference
+ * @param groupId the groupId
+ * @param inputCodecConfig the input codec configuration preference
+ * @param outputCodecConfig the output codec configuration preference
* @throws IllegalStateException if LE Audio Service is null
+ * @throws NullPointerException if any of the configs is null
* @hide
*/
@SystemApi
@@ -1444,14 +1447,13 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
android.Manifest.permission.BLUETOOTH_CONNECT,
android.Manifest.permission.BLUETOOTH_PRIVILEGED
})
- public void setCodecConfigPreference(@NonNull BluetoothDevice device,
- @NonNull BluetoothLeAudioCodecConfig codecConfig) {
- if (DBG) Log.d(TAG, "setCodecConfigPreference(" + device + ")");
+ public void setCodecConfigPreference(int groupId,
+ @NonNull BluetoothLeAudioCodecConfig inputCodecConfig,
+ @NonNull BluetoothLeAudioCodecConfig outputCodecConfig) {
+ if (DBG) Log.d(TAG, "setCodecConfigPreference(" + groupId + ")");
- if (codecConfig == null) {
- Log.e(TAG, "setCodecConfigPreference: Codec config can't be null");
- throw new IllegalArgumentException("codecConfig cannot be null");
- }
+ Objects.requireNonNull(inputCodecConfig, " inputCodecConfig shall not be null");
+ Objects.requireNonNull(outputCodecConfig, " outputCodecConfig shall not be null");
final IBluetoothLeAudio service = getService();
@@ -1459,9 +1461,10 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
Log.w(TAG, "Proxy not attached to service");
if (DBG) log(Log.getStackTraceString(new Throwable()));
throw new IllegalStateException("Service is unavailable");
- } else if (mAdapter.isEnabled() && isValidDevice(device)) {
+ } else if (mAdapter.isEnabled()) {
try {
- service.setCodecConfigPreference(device, codecConfig, mAttributionSource);
+ service.setCodecConfigPreference(groupId, inputCodecConfig, outputCodecConfig,
+ mAttributionSource);
} catch (RemoteException e) {
Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
e.rethrowFromSystemServer();
diff --git a/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java b/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java
index 004bf6b84f..c91d13ffe0 100644
--- a/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java
+++ b/framework/java/android/bluetooth/BluetoothLeAudioCodecConfig.java
@@ -72,7 +72,7 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
public static final int CODEC_PRIORITY_HIGHEST = 1000 * 1000;
/** @hide */
- @IntDef(prefix = "SAMPLE_RATE_",
+ @IntDef(flag = true, prefix = "SAMPLE_RATE_",
value = {SAMPLE_RATE_NONE, SAMPLE_RATE_8000, SAMPLE_RATE_16000, SAMPLE_RATE_24000,
SAMPLE_RATE_32000, SAMPLE_RATE_44100, SAMPLE_RATE_48000})
@Retention(RetentionPolicy.SOURCE)
@@ -81,41 +81,45 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
/**
* Codec sample rate 0 Hz. Default value used for
* codec sample rate.
+ * Values are the bit mask as defined in the
+ * Bluetooth Assigned Numbers, Generic Audio,
+ * Supported_Sampling_Frequencies table
+ * Note: We use only part of it.
*/
public static final int SAMPLE_RATE_NONE = 0;
/**
* Codec sample rate 8000 Hz.
*/
- public static final int SAMPLE_RATE_8000 = 1;
+ public static final int SAMPLE_RATE_8000 = 0x01 << 0;
/**
* Codec sample rate 16000 Hz.
*/
- public static final int SAMPLE_RATE_16000 = 2;
+ public static final int SAMPLE_RATE_16000 = 0x01 << 2;
/**
* Codec sample rate 24000 Hz.
*/
- public static final int SAMPLE_RATE_24000 = 3;
+ public static final int SAMPLE_RATE_24000 = 0x01 << 4;
/**
* Codec sample rate 32000 Hz.
*/
- public static final int SAMPLE_RATE_32000 = 4;
+ public static final int SAMPLE_RATE_32000 = 0x01 << 5;
/**
* Codec sample rate 44100 Hz.
*/
- public static final int SAMPLE_RATE_44100 = 5;
+ public static final int SAMPLE_RATE_44100 = 0x01 << 6;
/**
* Codec sample rate 48000 Hz.
*/
- public static final int SAMPLE_RATE_48000 = 6;
+ public static final int SAMPLE_RATE_48000 = 0x01 << 7;
/** @hide */
- @IntDef(prefix = "BITS_PER_SAMPLE_",
+ @IntDef(flag = true, prefix = "BITS_PER_SAMPLE_",
value = {BITS_PER_SAMPLE_NONE, BITS_PER_SAMPLE_16, BITS_PER_SAMPLE_24,
BITS_PER_SAMPLE_32})
@Retention(RetentionPolicy.SOURCE)
@@ -130,42 +134,52 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
/**
* Codec bits per sample 16.
*/
- public static final int BITS_PER_SAMPLE_16 = 1;
+ public static final int BITS_PER_SAMPLE_16 = 0x01 << 0;
/**
* Codec bits per sample 24.
*/
- public static final int BITS_PER_SAMPLE_24 = 2;
+ public static final int BITS_PER_SAMPLE_24 = 0x01 << 1;
/**
* Codec bits per sample 32.
*/
- public static final int BITS_PER_SAMPLE_32 = 3;
+ public static final int BITS_PER_SAMPLE_32 = 0x01 << 3;
- /** @hide */
- @IntDef(prefix = "CHANNEL_MODE_",
- value = {CHANNEL_MODE_NONE, CHANNEL_MODE_MONO, CHANNEL_MODE_STEREO})
+ /**
+ * Values are the bit mask as defined in the
+ * Bluetooth Assigned Numbers, Generic Audio,
+ * Supported_Audio_Channel_Counts table
+ * Note: We use only part of it.
+ * @hide */
+ @IntDef(flag = true, prefix = "CHANNEL_COUNT_",
+ value = {CHANNEL_COUNT_NONE, CHANNEL_COUNT_1, CHANNEL_COUNT_2})
@Retention(RetentionPolicy.SOURCE)
- public @interface ChannelMode {}
+ public @interface ChannelCount {}
/**
* Codec channel mode NONE. Default value of the
* codec channel mode.
*/
- public static final int CHANNEL_MODE_NONE = 0;
+ public static final int CHANNEL_COUNT_NONE = 0;
/**
* Codec channel mode MONO.
*/
- public static final int CHANNEL_MODE_MONO = 1;
+ public static final int CHANNEL_COUNT_1 = 0x01 << 0;
/**
* Codec channel mode STEREO.
*/
- public static final int CHANNEL_MODE_STEREO = 2;
+ public static final int CHANNEL_COUNT_2 = 0x01 << 1;
- /** @hide */
- @IntDef(prefix = "FRAME_DURATION_",
+ /**
+ * Values are the bit mask as defined in the
+ * Bluetooth Assigned Numbers, Generic Audio,
+ * Supported_Frame_Durations table
+ *
+ * @hide */
+ @IntDef(flag = true, prefix = "FRAME_DURATION_",
value = {FRAME_DURATION_NONE, FRAME_DURATION_7500, FRAME_DURATION_10000})
@Retention(RetentionPolicy.SOURCE)
public @interface FrameDuration {}
@@ -178,20 +192,23 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
/**
* Frame duration 7500 us.
*/
- public static final int FRAME_DURATION_7500 = 1;
+ public static final int FRAME_DURATION_7500 = 0x01 << 0;
/**
* Frame duration 10000 us.
*/
- public static final int FRAME_DURATION_10000 = 2;
+ public static final int FRAME_DURATION_10000 = 0x01 << 1;
private final @SourceCodecType int mCodecType;
private final @CodecPriority int mCodecPriority;
private final @SampleRate int mSampleRate;
private final @BitsPerSample int mBitsPerSample;
- private final @ChannelMode int mChannelMode;
+ private final @ChannelCount int mChannelCount;
private final @FrameDuration int mFrameDuration;
private final int mOctetsPerFrame;
+ private final int mMinOctetsPerFrame;
+ private final int mMaxOctetsPerFrame;
+
/**
* Creates a new BluetoothLeAudioCodecConfig.
@@ -200,21 +217,26 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
* @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 channelCount the channel count of this codec
* @param frameDuration the frame duration of this codec
* @param octetsPerFrame the octets per frame of this codec
+ * @param minOctetsPerFrame the minimum octets per frame of this codec
+ * @param maxOctetsPerFrame the maximum octets per frame of this codec
*/
private BluetoothLeAudioCodecConfig(@SourceCodecType int codecType,
@CodecPriority int codecPriority, @SampleRate int sampleRate,
- @BitsPerSample int bitsPerSample, @ChannelMode int channelMode,
- @FrameDuration int frameDuration, int octetsPerFrame) {
+ @BitsPerSample int bitsPerSample, @ChannelCount int channelCount,
+ @FrameDuration int frameDuration, int octetsPerFrame,
+ int minOctetsPerFrame, int maxOctetsPerFrame) {
mCodecType = codecType;
mCodecPriority = codecPriority;
mSampleRate = sampleRate;
mBitsPerSample = bitsPerSample;
- mChannelMode = channelMode;
+ mChannelCount = channelCount;
mFrameDuration = frameDuration;
mOctetsPerFrame = octetsPerFrame;
+ mMinOctetsPerFrame = minOctetsPerFrame;
+ mMaxOctetsPerFrame = maxOctetsPerFrame;
}
@Override
@@ -233,11 +255,14 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
int codecPriority = in.readInt();
int sampleRate = in.readInt();
int bitsPerSample = in.readInt();
- int channelMode = in.readInt();
+ int channelCount = in.readInt();
int frameDuration = in.readInt();
int octetsPerFrame = in.readInt();
+ int minOctetsPerFrame = in.readInt();
+ int maxOctetsPerFrame = in.readInt();
return new BluetoothLeAudioCodecConfig(codecType, codecPriority, sampleRate,
- bitsPerSample, channelMode, frameDuration, octetsPerFrame);
+ bitsPerSample, channelCount, frameDuration, octetsPerFrame,
+ minOctetsPerFrame, maxOctetsPerFrame);
}
public BluetoothLeAudioCodecConfig[] newArray(int size) {
@@ -251,17 +276,21 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
out.writeInt(mCodecPriority);
out.writeInt(mSampleRate);
out.writeInt(mBitsPerSample);
- out.writeInt(mChannelMode);
+ out.writeInt(mChannelCount);
out.writeInt(mFrameDuration);
out.writeInt(mOctetsPerFrame);
+ out.writeInt(mMinOctetsPerFrame);
+ out.writeInt(mMaxOctetsPerFrame);
}
@Override
public String toString() {
return "{codecName:" + getCodecName() + ",mCodecType:" + mCodecType
+ ",mCodecPriority:" + mCodecPriority + ",mSampleRate:" + mSampleRate
- + ",mBitsPerSample:" + mBitsPerSample + ",mChannelMode:" + mChannelMode
- + ",mFrameDuration:" + mFrameDuration + ",mOctetsPerFrame:" + mOctetsPerFrame + "}";
+ + ",mBitsPerSample:" + mBitsPerSample + ",mChannelCount:" + mChannelCount
+ + ",mFrameDuration:" + mFrameDuration + ",mOctetsPerFrame:" + mOctetsPerFrame
+ + ",mMinOctetsPerFrame:" + mMinOctetsPerFrame
+ + ",mMaxOctetsPerFrame:" + mMaxOctetsPerFrame + "}";
}
/**
@@ -316,8 +345,8 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
/**
* Returns the codec channel mode.
*/
- public @ChannelMode int getChannelMode() {
- return mChannelMode;
+ public @ChannelCount int getChannelCount() {
+ return mChannelCount;
}
/**
@@ -334,6 +363,20 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
return mOctetsPerFrame;
}
+ /**
+ * Returns the minimum octets per frame
+ */
+ public int getMinOctetsPerFrame() {
+ return mMinOctetsPerFrame;
+ }
+
+ /**
+ * Returns the maximum octets per frame
+ */
+ public int getMaxOctetsPerFrame() {
+ return mMaxOctetsPerFrame;
+ }
+
@Override
public boolean equals(@NonNull Object o) {
if (o instanceof BluetoothLeAudioCodecConfig) {
@@ -342,9 +385,11 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
&& other.getCodecPriority() == mCodecPriority
&& other.getSampleRate() == mSampleRate
&& other.getBitsPerSample() == mBitsPerSample
- && other.getChannelMode() == mChannelMode
+ && other.getChannelCount() == mChannelCount
&& other.getFrameDuration() == mFrameDuration
- && other.getOctetsPerFrame() == mOctetsPerFrame);
+ && other.getOctetsPerFrame() == mOctetsPerFrame
+ && other.getMinOctetsPerFrame() == mMinOctetsPerFrame
+ && other.getMaxOctetsPerFrame() == mMaxOctetsPerFrame);
}
return false;
}
@@ -356,7 +401,8 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
@Override
public int hashCode() {
return Objects.hash(mCodecType, mCodecPriority, mSampleRate,
- mBitsPerSample, mChannelMode, mFrameDuration, mOctetsPerFrame);
+ mBitsPerSample, mChannelCount, mFrameDuration, mOctetsPerFrame,
+ mMinOctetsPerFrame, mMaxOctetsPerFrame);
}
/**
@@ -369,9 +415,11 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
private int mCodecPriority = BluetoothLeAudioCodecConfig.CODEC_PRIORITY_DEFAULT;
private int mSampleRate = BluetoothLeAudioCodecConfig.SAMPLE_RATE_NONE;
private int mBitsPerSample = BluetoothLeAudioCodecConfig.BITS_PER_SAMPLE_NONE;
- private int mChannelMode = BluetoothLeAudioCodecConfig.CHANNEL_MODE_NONE;
+ private int mChannelCount = BluetoothLeAudioCodecConfig.CHANNEL_COUNT_NONE;
private int mFrameDuration = BluetoothLeAudioCodecConfig.FRAME_DURATION_NONE;
private int mOctetsPerFrame = 0;
+ private int mMinOctetsPerFrame = 0;
+ private int mMaxOctetsPerFrame = 0;
public Builder() {}
@@ -380,9 +428,11 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
mCodecPriority = config.getCodecPriority();
mSampleRate = config.getSampleRate();
mBitsPerSample = config.getBitsPerSample();
- mChannelMode = config.getChannelMode();
+ mChannelCount = config.getChannelCount();
mFrameDuration = config.getFrameDuration();
mOctetsPerFrame = config.getOctetsPerFrame();
+ mMinOctetsPerFrame = config.getMinOctetsPerFrame();
+ mMaxOctetsPerFrame = config.getMaxOctetsPerFrame();
}
/**
@@ -430,13 +480,13 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
}
/**
- * Set the channel mode for Bluetooth LE audio codec config.
+ * Set the channel count for Bluetooth LE audio codec config.
*
- * @param channelMode of this codec
+ * @param channelCount of this codec
* @return the same Builder instance
*/
- public @NonNull Builder setChannelMode(@ChannelMode int channelMode) {
- mChannelMode = channelMode;
+ public @NonNull Builder setChannelCount(@ChannelCount int channelCount) {
+ mChannelCount = channelCount;
return this;
}
@@ -463,12 +513,35 @@ public final class BluetoothLeAudioCodecConfig implements Parcelable {
}
/**
+ * Set the minimum octets per frame for Bluetooth LE audio codec config.
+ *
+ * @param minOctetsPerFrame of this codec
+ * @return the same Builder instance
+ */
+ public @NonNull Builder setMinOctetsPerFrame(int minOctetsPerFrame) {
+ mMinOctetsPerFrame = minOctetsPerFrame;
+ return this;
+ }
+
+ /**
+ * Set the maximum octets per frame for Bluetooth LE audio codec config.
+ *
+ * @param maxOctetsPerFrame of this codec
+ * @return the same Builder instance
+ */
+ public @NonNull Builder setMaxOctetsPerFrame(int maxOctetsPerFrame) {
+ mMaxOctetsPerFrame = maxOctetsPerFrame;
+ return this;
+ }
+
+ /**
* Build {@link BluetoothLeAudioCodecConfig}.
* @return new BluetoothLeAudioCodecConfig built
*/
public @NonNull BluetoothLeAudioCodecConfig build() {
return new BluetoothLeAudioCodecConfig(mCodecType, mCodecPriority, mSampleRate,
- mBitsPerSample, mChannelMode, mFrameDuration, mOctetsPerFrame);
+ mBitsPerSample, mChannelCount, mFrameDuration, mOctetsPerFrame,
+ mMinOctetsPerFrame, mMaxOctetsPerFrame);
}
}
}
diff --git a/framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java b/framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java
index 399ffa743c..bdb9d5d5c6 100644
--- a/framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java
+++ b/framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java
@@ -41,29 +41,47 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
public static final String EXTRA_LE_AUDIO_CODEC_STATUS =
"android.bluetooth.extra.LE_AUDIO_CODEC_STATUS";
- private final @Nullable BluetoothLeAudioCodecConfig mCodecConfig;
- private final @Nullable List<BluetoothLeAudioCodecConfig> mCodecsLocalCapabilities;
- private final @Nullable List<BluetoothLeAudioCodecConfig> mCodecsSelectableCapabilities;
+ private final @Nullable BluetoothLeAudioCodecConfig mInputCodecConfig;
+ private final @Nullable BluetoothLeAudioCodecConfig mOutputCodecConfig;
+ private final @Nullable List<BluetoothLeAudioCodecConfig> mInputCodecsLocalCapabilities;
+ private final @Nullable List<BluetoothLeAudioCodecConfig> mOutputCodecsLocalCapabilities;
+ private final @Nullable List<BluetoothLeAudioCodecConfig> mInputCodecsSelectableCapabilities;
+ private final @Nullable List<BluetoothLeAudioCodecConfig> mOutputCodecsSelectableCapabilities;
/**
* Represents the codec status for a Bluetooth LE Audio source device.
*
- * @param codecConfig the current code configutration.
- * @param codecsLocalCapabilities the local codecs capabilities.
- * @param codecsSelectableCapabilities the selectable codecs capabilities.
+ * @param inputCodecConfig the current input code configutration.
+ * @param outputCodecConfig the current output code configutration.
+ * @param inputCodecsLocalCapabilities the local input codecs capabilities.
+ * @param outputCodecsLocalCapabilities the local output codecs capabilities.
+ * @param inputCodecsSelectableCapabilities the selectable input codecs capabilities.
+ * @param outputCodecsSelectableCapabilities the selectable output codecs capabilities.
*/
- public BluetoothLeAudioCodecStatus(@Nullable BluetoothLeAudioCodecConfig codecConfig,
- @NonNull List<BluetoothLeAudioCodecConfig> codecsLocalCapabilities,
- @NonNull List<BluetoothLeAudioCodecConfig> codecsSelectableCapabilities) {
- mCodecConfig = codecConfig;
- mCodecsLocalCapabilities = codecsLocalCapabilities;
- mCodecsSelectableCapabilities = codecsSelectableCapabilities;
+ public BluetoothLeAudioCodecStatus(@Nullable BluetoothLeAudioCodecConfig inputCodecConfig,
+ @Nullable BluetoothLeAudioCodecConfig outputCodecConfig,
+ @NonNull List<BluetoothLeAudioCodecConfig> inputCodecsLocalCapabilities,
+ @NonNull List<BluetoothLeAudioCodecConfig> outputCodecsLocalCapabilities,
+ @NonNull List<BluetoothLeAudioCodecConfig> inputCodecsSelectableCapabilities,
+ @NonNull List<BluetoothLeAudioCodecConfig> outputCodecsSelectableCapabilities) {
+ mInputCodecConfig = inputCodecConfig;
+ mOutputCodecConfig = outputCodecConfig;
+ mInputCodecsLocalCapabilities = inputCodecsLocalCapabilities;
+ mOutputCodecsLocalCapabilities = outputCodecsLocalCapabilities;
+ mInputCodecsSelectableCapabilities = inputCodecsSelectableCapabilities;
+ mOutputCodecsSelectableCapabilities = outputCodecsSelectableCapabilities;
}
private BluetoothLeAudioCodecStatus(Parcel in) {
- mCodecConfig = in.readTypedObject(BluetoothLeAudioCodecConfig.CREATOR);
- mCodecsLocalCapabilities = in.createTypedArrayList(BluetoothLeAudioCodecConfig.CREATOR);
- mCodecsSelectableCapabilities =
+ mInputCodecConfig = in.readTypedObject(BluetoothLeAudioCodecConfig.CREATOR);
+ mOutputCodecConfig = in.readTypedObject(BluetoothLeAudioCodecConfig.CREATOR);
+ mInputCodecsLocalCapabilities =
+ in.createTypedArrayList(BluetoothLeAudioCodecConfig.CREATOR);
+ mOutputCodecsLocalCapabilities =
+ in.createTypedArrayList(BluetoothLeAudioCodecConfig.CREATOR);
+ mInputCodecsSelectableCapabilities =
+ in.createTypedArrayList(BluetoothLeAudioCodecConfig.CREATOR);
+ mOutputCodecsSelectableCapabilities =
in.createTypedArrayList(BluetoothLeAudioCodecConfig.CREATOR);
}
@@ -71,10 +89,16 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
public boolean equals(@Nullable Object o) {
if (o instanceof BluetoothLeAudioCodecStatus) {
BluetoothLeAudioCodecStatus other = (BluetoothLeAudioCodecStatus) o;
- return (Objects.equals(other.mCodecConfig, mCodecConfig)
- && sameCapabilities(other.mCodecsLocalCapabilities, mCodecsLocalCapabilities)
- && sameCapabilities(other.mCodecsSelectableCapabilities,
- mCodecsSelectableCapabilities));
+ return (Objects.equals(other.mInputCodecConfig, mInputCodecConfig)
+ && Objects.equals(other.mOutputCodecConfig, mOutputCodecConfig)
+ && sameCapabilities(other.mInputCodecsLocalCapabilities,
+ mInputCodecsLocalCapabilities)
+ && sameCapabilities(other.mOutputCodecsLocalCapabilities,
+ mOutputCodecsLocalCapabilities)
+ && sameCapabilities(other.mInputCodecsSelectableCapabilities,
+ mInputCodecsSelectableCapabilities)
+ && sameCapabilities(other.mOutputCodecsSelectableCapabilities,
+ mOutputCodecsSelectableCapabilities));
}
return false;
}
@@ -101,19 +125,67 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
return c1.containsAll(c2);
}
+ private boolean isCodecConfigSelectable(BluetoothLeAudioCodecConfig codecConfig,
+ BluetoothLeAudioCodecConfig selectableConfig) {
+ if (codecConfig.getCodecType() != selectableConfig.getCodecType()) {
+ return false;
+ }
+ if ((codecConfig.getFrameDuration() != BluetoothLeAudioCodecConfig.FRAME_DURATION_NONE)
+ && ((codecConfig.getFrameDuration() & selectableConfig.getFrameDuration()) == 0)) {
+ return false;
+ }
+ if ((codecConfig.getChannelCount() != BluetoothLeAudioCodecConfig.CHANNEL_COUNT_NONE)
+ && ((codecConfig.getChannelCount() & selectableConfig.getChannelCount()) == 0)) {
+ return false;
+ }
+ if ((codecConfig.getSampleRate() != BluetoothLeAudioCodecConfig.SAMPLE_RATE_NONE)
+ && ((codecConfig.getSampleRate() & selectableConfig.getSampleRate()) == 0)) {
+ return false;
+ }
+ if ((codecConfig.getBitsPerSample() != BluetoothLeAudioCodecConfig.BITS_PER_SAMPLE_NONE)
+ && ((codecConfig.getBitsPerSample() & selectableConfig.getBitsPerSample()) == 0)) {
+ return false;
+ }
+ if ((codecConfig.getOctetsPerFrame() != 0)
+ && ((codecConfig.getOctetsPerFrame() < selectableConfig.getMinOctetsPerFrame())
+ || (codecConfig.getOctetsPerFrame() > selectableConfig.getMaxOctetsPerFrame()))) {
+ return false;
+ }
+ return true;
+ }
/**
- * Checks whether the codec config matches the selectable capabilities.
+ * Checks whether the Input 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 {@code true} if the codec config matches, {@code false} otherwise
*/
- public boolean isCodecConfigSelectable(@Nullable BluetoothLeAudioCodecConfig codecConfig) {
+ public boolean isInputCodecConfigSelectable(@Nullable BluetoothLeAudioCodecConfig codecConfig) {
if (codecConfig == null) {
return false;
}
- for (BluetoothLeAudioCodecConfig selectableConfig : mCodecsSelectableCapabilities) {
- if (codecConfig.equals(selectableConfig)) {
+ for (BluetoothLeAudioCodecConfig selectableConfig : mInputCodecsSelectableCapabilities) {
+ if (isCodecConfigSelectable(codecConfig, selectableConfig)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Checks whether the Output 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 {@code true} if the codec config matches, {@code false} otherwise
+ */
+ public boolean isOutputCodecConfigSelectable(
+ @Nullable BluetoothLeAudioCodecConfig codecConfig) {
+ if (codecConfig == null) {
+ return false;
+ }
+ for (BluetoothLeAudioCodecConfig selectableConfig : mOutputCodecsSelectableCapabilities) {
+ if (isCodecConfigSelectable(codecConfig, selectableConfig)) {
return true;
}
}
@@ -125,7 +197,9 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
*/
@Override
public int hashCode() {
- return Objects.hash(mCodecConfig, mCodecsLocalCapabilities, mCodecsLocalCapabilities);
+ return Objects.hash(mInputCodecConfig, mOutputCodecConfig,
+ mInputCodecsLocalCapabilities, mOutputCodecsLocalCapabilities,
+ mInputCodecsSelectableCapabilities, mOutputCodecsSelectableCapabilities);
}
/**
@@ -134,9 +208,12 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
*/
@Override
public String toString() {
- return "{mCodecConfig:" + mCodecConfig
- + ",mCodecsLocalCapabilities:" + mCodecsLocalCapabilities
- + ",mCodecsSelectableCapabilities:" + mCodecsSelectableCapabilities
+ return "{mInputCodecConfig:" + mInputCodecConfig
+ + ",mOutputCodecConfig:" + mOutputCodecConfig
+ + ",mInputCodecsLocalCapabilities:" + mInputCodecsLocalCapabilities
+ + ",mOutputCodecsLocalCapabilities:" + mOutputCodecsLocalCapabilities
+ + ",mInputCodecsSelectableCapabilities:" + mInputCodecsSelectableCapabilities
+ + ",mOutputCodecsSelectableCapabilities:" + mOutputCodecsSelectableCapabilities
+ "}";
}
@@ -171,38 +248,71 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
*/
@Override
public void writeToParcel(@NonNull Parcel out, int flags) {
- out.writeTypedObject(mCodecConfig, flags);
- out.writeTypedList(mCodecsLocalCapabilities);
- out.writeTypedList(mCodecsSelectableCapabilities);
+ out.writeTypedObject(mInputCodecConfig, flags);
+ out.writeTypedObject(mOutputCodecConfig, flags);
+ out.writeTypedList(mInputCodecsLocalCapabilities);
+ out.writeTypedList(mOutputCodecsLocalCapabilities);
+ out.writeTypedList(mInputCodecsSelectableCapabilities);
+ out.writeTypedList(mOutputCodecsSelectableCapabilities);
+ }
+
+ /**
+ * Returns the current Input codec configuration.
+ *
+ * @return The current input codec config.
+ */
+ public @Nullable BluetoothLeAudioCodecConfig getInputCodecConfig() {
+ return mInputCodecConfig;
}
/**
- * Returns the current codec configuration.
+ * Returns the current Output codec configuration.
*
- * @return The current codec config.
+ * @return The current output codec config.
*/
- public @Nullable BluetoothLeAudioCodecConfig getCodecConfig() {
- return mCodecConfig;
+ public @Nullable BluetoothLeAudioCodecConfig getOutputCodecConfig() {
+ return mOutputCodecConfig;
}
/**
- * Returns the codecs local capabilities.
+ * Returns the input codecs local capabilities.
*
* @return The list of codec config that supported by the local system.
*/
- public @NonNull List<BluetoothLeAudioCodecConfig> getCodecLocalCapabilities() {
- return (mCodecsLocalCapabilities == null)
- ? Collections.emptyList() : mCodecsLocalCapabilities;
+ public @NonNull List<BluetoothLeAudioCodecConfig> getInputCodecLocalCapabilities() {
+ return (mInputCodecsLocalCapabilities == null)
+ ? Collections.emptyList() : mInputCodecsLocalCapabilities;
+ }
+
+ /**
+ * Returns the output codecs local capabilities.
+ *
+ * @return The list of codec config that supported by the local system.
+ */
+ public @NonNull List<BluetoothLeAudioCodecConfig> getOutputCodecLocalCapabilities() {
+ return (mOutputCodecsLocalCapabilities == null)
+ ? Collections.emptyList() : mOutputCodecsLocalCapabilities;
+ }
+
+ /**
+ * Returns the Input codecs selectable capabilities.
+ *
+ * @return The list of codec config that supported by both of the local system and
+ * remote devices.
+ */
+ public @NonNull List<BluetoothLeAudioCodecConfig> getInputCodecSelectableCapabilities() {
+ return (mInputCodecsSelectableCapabilities == null)
+ ? Collections.emptyList() : mInputCodecsSelectableCapabilities;
}
/**
- * Returns the codecs selectable capabilities.
+ * Returns the Output codecs selectable capabilities.
*
* @return The list of codec config that supported by both of the local system and
* remote devices.
*/
- public @NonNull List<BluetoothLeAudioCodecConfig> getCodecSelectableCapabilities() {
- return (mCodecsSelectableCapabilities == null)
- ? Collections.emptyList() : mCodecsSelectableCapabilities;
+ public @NonNull List<BluetoothLeAudioCodecConfig> getOutputCodecSelectableCapabilities() {
+ return (mOutputCodecsSelectableCapabilities == null)
+ ? Collections.emptyList() : mOutputCodecsSelectableCapabilities;
}
}