aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChen Chen <cncn@google.com>2022-01-13 17:57:01 -0800
committerChen Chen <cncn@google.com>2022-01-20 17:59:59 -0800
commit31348f23ddc47bf1d54309d6f0ea0cd41c00e1be (patch)
treeb6d2518d74c36523be54cc009bde0dc05a0b1746
parente08c6a59957172be671dc3b499e601e38ce64c17 (diff)
SpatialAudio: Provide API to allow/disallow low latency audio
Bug: 214615268 Test: Manually test signal passing from framework to bluetooth/system Tag: #feature Change-Id: If7e1706c54bc6652698b0f5d5570de13ae54b519
-rw-r--r--android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp20
-rw-r--r--android/app/src/com/android/bluetooth/btservice/AdapterService.java23
-rw-r--r--framework/java/android/bluetooth/BluetoothDevice.java30
-rw-r--r--system/binder/android/bluetooth/IBluetooth.aidl3
-rw-r--r--system/btif/src/bluetooth.cc9
-rw-r--r--system/include/hardware/bluetooth.h9
-rw-r--r--system/service/bluetooth_interface.cc9
-rw-r--r--system/service/hal/fake_bluetooth_interface.cc1
-rw-r--r--system/test/mock/mock_bluetooth_interface.cc7
9 files changed, 107 insertions, 4 deletions
diff --git a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
index bbf46bb7df..5e3a2971a0 100644
--- a/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
+++ b/android/app/jni/com_android_bluetooth_btservice_AdapterService.cpp
@@ -1714,6 +1714,22 @@ static int getMetricIdNative(JNIEnv* env, jobject obj, jbyteArray address) {
return sBluetoothInterface->get_metric_id(addr_obj);
}
+static jboolean allowLowLatencyAudioNative(JNIEnv* env, jobject obj,
+ jboolean allowed,
+ jbyteArray address) {
+ ALOGV("%s", __func__);
+ if (!sBluetoothInterface) return false;
+ jbyte* addr = env->GetByteArrayElements(address, nullptr);
+ if (addr == nullptr) {
+ jniThrowIOException(env, EINVAL);
+ return false;
+ }
+ RawAddress addr_obj = {};
+ addr_obj.FromOctets((uint8_t*)addr);
+ sBluetoothInterface->allow_low_latency_audio(allowed, addr_obj);
+ return true;
+}
+
static JNINativeMethod sMethods[] = {
/* name, signature, funcPtr */
{"classInitNative", "()V", (void*)classInitNative},
@@ -1753,7 +1769,9 @@ static JNINativeMethod sMethods[] = {
{"createSocketChannelNative", "(ILjava/lang/String;[BIII)I",
(void*)createSocketChannelNative},
{"requestMaximumTxDataLengthNative", "([B)V",
- (void*)requestMaximumTxDataLengthNative}};
+ (void*)requestMaximumTxDataLengthNative},
+ {"allowLowLatencyAudioNative", "(Z[B)Z", (void*)allowLowLatencyAudioNative},
+};
int register_com_android_bluetooth_btservice_AdapterService(JNIEnv* env) {
return jniRegisterNativeMethods(
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
index af56c3dac6..028808f257 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
@@ -2633,6 +2633,16 @@ public class AdapterService extends Service {
service.dump(fd, writer, args);
writer.close();
}
+
+ @Override
+ public boolean allowLowLatencyAudio(boolean allowed, BluetoothDevice device) {
+ AdapterService service = getService();
+ if (service == null) {
+ return false;
+ }
+ enforceBluetoothPrivilegedPermission(service);
+ return service.allowLowLatencyAudio(allowed, device);
+ }
}
// ----API Methods--------
@@ -4116,6 +4126,17 @@ public class AdapterService extends Service {
return getMetricIdNative(Utils.getByteAddress(device));
}
+ /**
+ * Allow audio low latency
+ *
+ * @param allowed true if audio low latency is being allowed
+ * @param device device whose audio low latency will be allowed or disallowed
+ * @return boolean true if audio low latency is successfully allowed or disallowed
+ */
+ public boolean allowLowLatencyAudio(boolean allowed, BluetoothDevice device) {
+ return allowLowLatencyAudioNative(allowed, Utils.getByteAddress(device));
+ }
+
static native void classInitNative();
native boolean initNative(boolean startRestricted, boolean isCommonCriteriaMode,
@@ -4208,6 +4229,8 @@ public class AdapterService extends Service {
/*package*/ native void requestMaximumTxDataLengthNative(byte[] address);
+ private native boolean allowLowLatencyAudioNative(boolean allowed, byte[] address);
+
// Returns if this is a mock object. This is currently used in testing so that we may not call
// System.exit() while finalizing the object. Otherwise GC of mock objects unfortunately ends up
// calling finalize() which in turn calls System.exit() and the process crashes.
diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java
index 1edf5cc96b..70971a0c22 100644
--- a/framework/java/android/bluetooth/BluetoothDevice.java
+++ b/framework/java/android/bluetooth/BluetoothDevice.java
@@ -2828,4 +2828,34 @@ public final class BluetoothDevice implements Parcelable, Attributable {
public static @MetadataKey int getMaxMetadataKey() {
return METADATA_UNTETHERED_CASE_LOW_BATTERY_THRESHOLD;
}
+
+ /**
+ * Enable or disable audio low latency for this {@link BluetoothDevice}.
+ *
+ * @param allowed true if low latency is allowed, false if low latency is disallowed.
+ * @return true if the value is successfully set,
+ * false if there is a error when setting the value.
+ * @hide
+ */
+ @SystemApi
+ @RequiresBluetoothConnectPermission
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
+ public boolean setLowLatencyAudioAllowed(boolean allowed) {
+ final IBluetooth service = sService;
+ Log.i(TAG, "Allowing bluetooth audio low latency: " + allowed);
+ if (service == null) {
+ Log.e(TAG, "Bluetooth is not enabled. Cannot allow low latency");
+ return false;
+ }
+ try {
+ service.allowLowLatencyAudio(allowed, this);
+ } catch (RemoteException e) {
+ Log.e(TAG, "allowLowLatencyAudio fail ", e);
+ e.rethrowFromSystemServer();
+ }
+ return true;
+ }
}
diff --git a/system/binder/android/bluetooth/IBluetooth.aidl b/system/binder/android/bluetooth/IBluetooth.aidl
index b93cd623a0..956159e8bb 100644
--- a/system/binder/android/bluetooth/IBluetooth.aidl
+++ b/system/binder/android/bluetooth/IBluetooth.aidl
@@ -253,4 +253,7 @@ interface IBluetooth
boolean canBondWithoutDialog(in BluetoothDevice device, in AttributionSource attributionSource);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
void generateLocalOobData(in int transport, IBluetoothOobDataCallback callback, in AttributionSource attributionSource);
+
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
+ boolean allowLowLatencyAudio(in boolean allowed, in BluetoothDevice device);
}
diff --git a/system/btif/src/bluetooth.cc b/system/btif/src/bluetooth.cc
index 7427eb4fa6..2d6bedb384 100644
--- a/system/btif/src/bluetooth.cc
+++ b/system/btif/src/bluetooth.cc
@@ -591,6 +591,12 @@ static int set_dynamic_audio_buffer_size(int codec, int size) {
return btif_set_dynamic_audio_buffer_size(codec, size);
}
+static bool allow_low_latency_audio(bool allowed, const RawAddress& address) {
+ LOG_INFO("%s %s", __func__, allowed ? "true" : "false");
+ // Call HAL here
+ return true;
+}
+
EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
sizeof(bluetoothInterface),
init,
@@ -629,7 +635,8 @@ EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
obfuscate_address,
get_metric_id,
set_dynamic_audio_buffer_size,
- generate_local_oob_data};
+ generate_local_oob_data,
+ allow_low_latency_audio};
// callback reporting helpers
diff --git a/system/include/hardware/bluetooth.h b/system/include/hardware/bluetooth.h
index a1d16cebbe..45321db5c3 100644
--- a/system/include/hardware/bluetooth.h
+++ b/system/include/hardware/bluetooth.h
@@ -754,6 +754,15 @@ typedef struct {
* Fetches the local Out of Band data.
*/
int (*generate_local_oob_data)(tBT_TRANSPORT transport);
+
+ /**
+ * Allow or disallow audio low latency
+ *
+ * @param allowed true if allowing audio low latency
+ * @param address Bluetooth MAC address of Bluetooth device
+ * @return true if audio low latency is successfully allowed or disallowed
+ */
+ bool (*allow_low_latency_audio)(bool allowed, const RawAddress& address);
} bt_interface_t;
#define BLUETOOTH_INTERFACE_STRING "bluetoothInterface"
diff --git a/system/service/bluetooth_interface.cc b/system/service/bluetooth_interface.cc
index ee58ef3103..155b13dc3d 100644
--- a/system/service/bluetooth_interface.cc
+++ b/system/service/bluetooth_interface.cc
@@ -584,6 +584,12 @@ static int set_dynamic_audio_buffer_size(int codec, int size) {
return btif_set_dynamic_audio_buffer_size(codec, size);
}
+static bool allow_low_latency_audio(bool allowed, const RawAddress& address) {
+ LOG_INFO("%s %s", __func__, allowed ? "true" : "false");
+ // Call HAL here
+ return true;
+}
+
EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
sizeof(bluetoothInterface),
init,
@@ -622,7 +628,8 @@ EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
obfuscate_address,
get_metric_id,
set_dynamic_audio_buffer_size,
- generate_local_oob_data};
+ generate_local_oob_data,
+ allow_low_latency_audio};
// callback reporting helpers
diff --git a/system/service/hal/fake_bluetooth_interface.cc b/system/service/hal/fake_bluetooth_interface.cc
index e32c380e10..729778d4cd 100644
--- a/system/service/hal/fake_bluetooth_interface.cc
+++ b/system/service/hal/fake_bluetooth_interface.cc
@@ -80,6 +80,7 @@ bt_interface_t fake_bt_iface = {
nullptr, /* get_metric_id */
nullptr, /* set_dynamic_audio_buffer_size */
nullptr, /* generate_local_oob_data */
+ nullptr, /* allow_low_latency_audio */
};
} // namespace
diff --git a/system/test/mock/mock_bluetooth_interface.cc b/system/test/mock/mock_bluetooth_interface.cc
index c778c16c47..8f1423e77a 100644
--- a/system/test/mock/mock_bluetooth_interface.cc
+++ b/system/test/mock/mock_bluetooth_interface.cc
@@ -145,6 +145,10 @@ static int get_metric_id(const RawAddress& address) { return 0; }
static int set_dynamic_audio_buffer_size(int codec, int size) { return 0; }
+static bool allow_low_latency_audio(bool allowed, const RawAddress& address) {
+ return true;
+}
+
EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
sizeof(bluetoothInterface),
init,
@@ -183,7 +187,8 @@ EXPORT_SYMBOL bt_interface_t bluetoothInterface = {
obfuscate_address,
get_metric_id,
set_dynamic_audio_buffer_size,
- generate_local_oob_data};
+ generate_local_oob_data,
+ allow_low_latency_audio};
// callback reporting helpers