summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--android/app/src/com/android/bluetooth/le_audio/LeAudioService.java76
-rw-r--r--framework/java/android/bluetooth/BluetoothLeAudio.java29
-rw-r--r--framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java18
-rw-r--r--system/binder/android/bluetooth/BluetoothLeAudioCodecConfig.aidl19
-rw-r--r--system/binder/android/bluetooth/IBluetoothLeAudio.aidl5
5 files changed, 142 insertions, 5 deletions
diff --git a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
index 121dc49320..7df5de50bc 100644
--- a/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
+++ b/android/app/src/com/android/bluetooth/le_audio/LeAudioService.java
@@ -26,6 +26,8 @@ import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothLeAudio;
+import android.bluetooth.BluetoothLeAudioCodecConfig;
+import android.bluetooth.BluetoothLeAudioCodecStatus;
import android.bluetooth.BluetoothLeAudioContentMetadata;
import android.bluetooth.BluetoothLeBroadcastMetadata;
import android.bluetooth.BluetoothProfile;
@@ -1695,6 +1697,52 @@ public class LeAudioService extends ProfileService {
}
/**
+ * Gets the current codec status (configuration and capability).
+ *
+ * @param device the remote Bluetooth device.
+ * @return the current codec status
+ * @hide
+ */
+ public BluetoothLeAudioCodecStatus getCodecStatus(BluetoothDevice device) {
+ if (DBG) {
+ Log.d(TAG, "getCodecStatus(" + device + ")");
+ }
+
+ return null;
+ }
+
+ /**
+ * Sets the codec configuration preference.
+ *
+ * @param device the remote Bluetooth device.
+ * @param codecConfig the codec configuration preference
+ * @hide
+ */
+ public void setCodecConfigPreference(BluetoothDevice device,
+ BluetoothLeAudioCodecConfig codecConfig) {
+ if (DBG) {
+ Log.d(TAG, "setCodecConfigPreference(" + device + "): "
+ + Objects.toString(codecConfig));
+ }
+ if (device == null) {
+ Log.e(TAG, "setCodecConfigPreference: Invalid device");
+ return;
+ }
+ if (codecConfig == null) {
+ Log.e(TAG, "setCodecConfigPreference: Codec config can't be null");
+ return;
+ }
+ BluetoothLeAudioCodecStatus codecStatus = getCodecStatus(device);
+ if (codecStatus == null) {
+ Log.e(TAG, "setCodecConfigPreference: Codec status is null");
+ return;
+ }
+
+ // TODO: pass the information to bt stack
+ }
+
+
+ /**
* Binder object: must be a static class or memory leak may occur
*/
@VisibleForTesting
@@ -2057,6 +2105,34 @@ public class LeAudioService extends ProfileService {
receiver.propagateException(e);
}
}
+
+ @Override
+ public void getCodecStatus(BluetoothDevice device,
+ AttributionSource source, SynchronousResultReceiver receiver) {
+ try {
+ LeAudioService service = getService(source);
+ BluetoothLeAudioCodecStatus codecStatus = null;
+ if (service != null) {
+ enforceBluetoothPrivilegedPermission(service);
+ codecStatus = service.getCodecStatus(device);
+ }
+ receiver.send(codecStatus);
+ } catch (RuntimeException e) {
+ receiver.propagateException(e);
+ }
+ }
+
+ @Override
+ public void setCodecConfigPreference(BluetoothDevice device,
+ BluetoothLeAudioCodecConfig codecConfig, AttributionSource source) {
+ LeAudioService service = getService(source);
+ if (service == null) {
+ return;
+ }
+
+ enforceBluetoothPrivilegedPermission(service);
+ service.setCodecConfigPreference(device, codecConfig);
+ }
}
@Override
diff --git a/framework/java/android/bluetooth/BluetoothLeAudio.java b/framework/java/android/bluetooth/BluetoothLeAudio.java
index 2db1d1afe5..23e9a039f4 100644
--- a/framework/java/android/bluetooth/BluetoothLeAudio.java
+++ b/framework/java/android/bluetooth/BluetoothLeAudio.java
@@ -966,9 +966,22 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
Log.d(TAG, "getCodecStatus(" + device + ")");
}
+ final IBluetoothLeAudio service = getService();
final BluetoothLeAudioCodecStatus defaultValue = null;
- // TODO: Add the implementation to get codec status
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mAdapter.isEnabled() && isValidDevice(device)) {
+ try {
+ final SynchronousResultReceiver<BluetoothLeAudioCodecStatus> recv =
+ new SynchronousResultReceiver();
+ service.getCodecStatus(device, mAttributionSource, recv);
+ return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
+ } catch (RemoteException | TimeoutException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
return defaultValue;
}
@@ -994,8 +1007,18 @@ public final class BluetoothLeAudio implements BluetoothProfile, AutoCloseable {
throw new IllegalArgumentException("codecConfig cannot be null");
}
- // TODO: Add the implementation to set config preference
- return;
+ final IBluetoothLeAudio service = getService();
+
+ if (service == null) {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else if (mAdapter.isEnabled() && isValidDevice(device)) {
+ try {
+ service.setCodecConfigPreference(device, codecConfig, mAttributionSource);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
}
}
diff --git a/framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java b/framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java
index dea0642041..399ffa743c 100644
--- a/framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java
+++ b/framework/java/android/bluetooth/BluetoothLeAudioCodecStatus.java
@@ -109,8 +109,15 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
* @return {@code true} if the codec config matches, {@code false} otherwise
*/
public boolean isCodecConfigSelectable(@Nullable BluetoothLeAudioCodecConfig codecConfig) {
- // TODO: Add the implementation to check the config is selectable
- return true;
+ if (codecConfig == null) {
+ return false;
+ }
+ for (BluetoothLeAudioCodecConfig selectableConfig : mCodecsSelectableCapabilities) {
+ if (codecConfig.equals(selectableConfig)) {
+ return true;
+ }
+ }
+ return false;
}
/**
@@ -171,6 +178,8 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
/**
* Returns the current codec configuration.
+ *
+ * @return The current codec config.
*/
public @Nullable BluetoothLeAudioCodecConfig getCodecConfig() {
return mCodecConfig;
@@ -178,6 +187,8 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
/**
* Returns the codecs local capabilities.
+ *
+ * @return The list of codec config that supported by the local system.
*/
public @NonNull List<BluetoothLeAudioCodecConfig> getCodecLocalCapabilities() {
return (mCodecsLocalCapabilities == null)
@@ -186,6 +197,9 @@ public final class BluetoothLeAudioCodecStatus implements Parcelable {
/**
* Returns the 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)
diff --git a/system/binder/android/bluetooth/BluetoothLeAudioCodecConfig.aidl b/system/binder/android/bluetooth/BluetoothLeAudioCodecConfig.aidl
new file mode 100644
index 0000000000..e32217eff7
--- /dev/null
+++ b/system/binder/android/bluetooth/BluetoothLeAudioCodecConfig.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2022 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;
+
+parcelable BluetoothLeAudioCodecConfig;
diff --git a/system/binder/android/bluetooth/IBluetoothLeAudio.aidl b/system/binder/android/bluetooth/IBluetoothLeAudio.aidl
index 22a90a0758..c588802fee 100644
--- a/system/binder/android/bluetooth/IBluetoothLeAudio.aidl
+++ b/system/binder/android/bluetooth/IBluetoothLeAudio.aidl
@@ -18,6 +18,7 @@
package android.bluetooth;
import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothLeAudioCodecConfig;
import android.bluetooth.BluetoothLeAudioContentMetadata;
import android.bluetooth.IBluetoothLeBroadcastCallback;
import android.content.AttributionSource;
@@ -51,6 +52,10 @@ oneway interface IBluetoothLeAudio {
void getConnectionPolicy(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
void getConnectedGroupLeadDevice(int groupId, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
+ void getCodecStatus(in BluetoothDevice device, in AttributionSource source, in SynchronousResultReceiver receiver);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)")
+ void setCodecConfigPreference(in BluetoothDevice device, in BluetoothLeAudioCodecConfig codecConfig, in AttributionSource source);
/* Same value as bluetooth::groups::kGroupUnknown */
const int LE_AUDIO_GROUP_ID_INVALID = -1;