Add BluetoothDevice#getCreateBondCaller API
Add a system API for system app to track which application initiated
bonding with a device
Bug: 175931562
Test: BluetoothInstrumentationTest
Change-Id: I622560a87ef5de2b035b9e654f2cd31acc437824
diff --git a/android/app/src/com/android/bluetooth/btservice/AdapterService.java b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
index a7aa133..19f885b 100644
--- a/android/app/src/com/android/bluetooth/btservice/AdapterService.java
+++ b/android/app/src/com/android/bluetooth/btservice/AdapterService.java
@@ -32,6 +32,7 @@
import static com.android.bluetooth.Utils.isPackageNameAccurate;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SuppressLint;
import android.app.AlarmManager;
@@ -2591,6 +2592,32 @@
}
@Override
+ public void getCreateBondCaller(BluetoothDevice device,
+ SynchronousResultReceiver receiver) {
+ try {
+ receiver.send(getCreateBondCaller(device));
+ } catch (RuntimeException e) {
+ receiver.propagateException(e);
+ }
+ }
+
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
+ private String getCreateBondCaller(BluetoothDevice device) {
+ AdapterService service = getService();
+
+ if (service == null) {
+ return null;
+ }
+
+ enforceBluetoothPrivilegedPermission(service);
+
+ return service.getCreateBondCaller(device);
+ }
+
+ @Override
public void removeActiveDevice(@ActiveDeviceUse int profiles,
AttributionSource source, SynchronousResultReceiver receiver) {
try {
@@ -4826,6 +4853,19 @@
}
/**
+ * Returns the package name of the most recent caller that called
+ * {@link BluetoothDevice#createBond} on the given device.
+ */
+ @Nullable
+ public String getCreateBondCaller(BluetoothDevice device) {
+ CallerInfo info = mBondAttemptCallerInfo.get(device.getAddress());
+ if (info == null) {
+ return null;
+ }
+ return info.callerPackageName;
+ }
+
+ /**
* Sets device as the active devices for the profiles passed into the function
*
* @param device is the remote bluetooth device
diff --git a/framework/api/system-current.txt b/framework/api/system-current.txt
index 8f225bf..89e66ad 100644
--- a/framework/api/system-current.txt
+++ b/framework/api/system-current.txt
@@ -184,6 +184,7 @@
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getAudioPolicyRemoteSupported();
method @IntRange(from=0xffffff9c, to=100) @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getBatteryLevel();
method @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public int getConnectionHandle(int);
+ method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public String getCreateBondCaller();
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public String getIdentityAddress();
method @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public int getMessageAccessPermission();
method @Nullable @RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT, android.Manifest.permission.BLUETOOTH_PRIVILEGED}) public byte[] getMetadata(int);
diff --git a/framework/java/android/bluetooth/BluetoothDevice.java b/framework/java/android/bluetooth/BluetoothDevice.java
index fc26848..850105f 100644
--- a/framework/java/android/bluetooth/BluetoothDevice.java
+++ b/framework/java/android/bluetooth/BluetoothDevice.java
@@ -2088,6 +2088,39 @@
return defaultValue;
}
+ /**
+ * Gets the package name of the application that initiate bonding with this device
+ *
+ * @return package name of the application, or null of no application initiate bonding with
+ * this device
+ *
+ * @hide
+ */
+ @SystemApi
+ @Nullable
+ @RequiresPermission(allOf = {
+ android.Manifest.permission.BLUETOOTH_CONNECT,
+ android.Manifest.permission.BLUETOOTH_PRIVILEGED,
+ })
+ public String getCreateBondCaller() {
+ if (DBG) log("getCreateBondCaller()");
+ final IBluetooth service = getService();
+ final String defaultValue = null;
+ if (service == null || !isBluetoothEnabled()) {
+ Log.w(TAG, "BT not enabled, getCreateBondCaller failed");
+ if (DBG) log(Log.getStackTraceString(new Throwable()));
+ } else {
+ try {
+ final SynchronousResultReceiver<String> recv = SynchronousResultReceiver.get();
+ service.getCreateBondCaller(this, recv);
+ return recv.awaitResultNoInterrupt(getSyncTimeout()).getValue(defaultValue);
+ } catch (RemoteException | TimeoutException e) {
+ Log.e(TAG, e.toString() + "\n" + Log.getStackTraceString(new Throwable()));
+ }
+ }
+ return defaultValue;
+ }
+
/** @hide */
@Retention(RetentionPolicy.SOURCE)
@IntDef(value = {
diff --git a/system/binder/android/bluetooth/IBluetooth.aidl b/system/binder/android/bluetooth/IBluetooth.aidl
index b8bc62c..83a9425 100644
--- a/system/binder/android/bluetooth/IBluetooth.aidl
+++ b/system/binder/android/bluetooth/IBluetooth.aidl
@@ -256,6 +256,8 @@
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
oneway void canBondWithoutDialog(in BluetoothDevice device, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
+ oneway void getCreateBondCaller(in BluetoothDevice device, in SynchronousResultReceiver receiver);
+ @JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")
oneway void generateLocalOobData(in int transport, IBluetoothOobDataCallback callback, in AttributionSource attributionSource, in SynchronousResultReceiver receiver);
@JavaPassthrough(annotation="@android.annotation.RequiresPermission(allOf={android.Manifest.permission.BLUETOOTH_CONNECT,android.Manifest.permission.BLUETOOTH_PRIVILEGED})")