summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Raphael Kim <raphk@google.com> 2024-06-07 21:47:12 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-06-07 21:47:12 +0000
commitabdb133c5cfc750fafc67d04ff5511a9768c5cf7 (patch)
treed6a0e6657231c07cb03f27fa45633d5197623581
parentc870608e6ab54135b04969d7aa2716d7fb10212f (diff)
parent6053fd7f66a4122bd2072f3c36a9b810cc17a631 (diff)
Merge "[CDM] Add new API to remove bluetooth bond" into main
-rw-r--r--core/api/current.txt1
-rw-r--r--core/java/android/companion/CompanionDeviceManager.java26
-rw-r--r--core/java/android/companion/ICompanionDeviceManager.aidl3
-rw-r--r--core/java/android/companion/flags.aconfig7
-rw-r--r--services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java29
5 files changed, 66 insertions, 0 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index c0bc6d96f7ef..a819b6e27152 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -9801,6 +9801,7 @@ package android.companion {
method @NonNull public java.util.List<android.companion.AssociationInfo> getMyAssociations();
method @Deprecated public boolean hasNotificationAccess(android.content.ComponentName);
method @FlaggedApi("android.companion.perm_sync_user_consent") public boolean isPermissionTransferUserConsented(int);
+ method @FlaggedApi("android.companion.unpair_associated_device") @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT) public boolean removeBond(int);
method public void requestNotificationAccess(android.content.ComponentName);
method @FlaggedApi("android.companion.association_tag") public void setAssociationTag(int, @NonNull String);
method @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull String) throws android.companion.DeviceNotAssociatedException;
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index 8fe5ae09a36d..b4ad1c8fff12 100644
--- a/core/java/android/companion/CompanionDeviceManager.java
+++ b/core/java/android/companion/CompanionDeviceManager.java
@@ -1149,6 +1149,32 @@ public final class CompanionDeviceManager {
}
}
+ /**
+ * Remove bonding between this device and an associated companion device.
+ *
+ * <p>This is an asynchronous call, it will return immediately. Register for {@link
+ * BluetoothDevice#ACTION_BOND_STATE_CHANGED} intents to be notified when the bond removal
+ * process completes, and its result.
+ *
+ * @param associationId an already-associated companion device to remove bond from
+ * @return false on immediate error, true if bond removal process will begin
+ */
+ @FlaggedApi(Flags.FLAG_UNPAIR_ASSOCIATED_DEVICE)
+ @RequiresPermission(android.Manifest.permission.BLUETOOTH_CONNECT)
+ public boolean removeBond(int associationId) {
+ if (mService == null) {
+ Log.w(TAG, "CompanionDeviceManager service is not available.");
+ return false;
+ }
+
+ try {
+ return mService.removeBond(associationId, mContext.getOpPackageName(),
+ mContext.getUserId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
// TODO(b/315163162) Add @Deprecated keyword after 24Q2 cut.
/**
* Register to receive callbacks whenever the associated device comes in and out of range.
diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl
index 1b00f90e1fb3..de3ddec05d27 100644
--- a/core/java/android/companion/ICompanionDeviceManager.aidl
+++ b/core/java/android/companion/ICompanionDeviceManager.aidl
@@ -141,4 +141,7 @@ interface ICompanionDeviceManager {
byte[] getBackupPayload(int userId);
void applyRestoredPayload(in byte[] payload, int userId);
+
+ @EnforcePermission("BLUETOOTH_CONNECT")
+ boolean removeBond(int associationId, in String packageName, int userId);
}
diff --git a/core/java/android/companion/flags.aconfig b/core/java/android/companion/flags.aconfig
index 36d0e081af2a..fd4ba83b02e3 100644
--- a/core/java/android/companion/flags.aconfig
+++ b/core/java/android/companion/flags.aconfig
@@ -46,4 +46,11 @@ flag {
namespace: "companion"
description: "Enable ongoing perm sync"
bug: "338469649"
+}
+
+flag {
+ name: "unpair_associated_device"
+ namespace: "companion"
+ description: "Unpair with an associated bluetooth device"
+ bug: "322237619"
} \ No newline at end of file
diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
index 0d0c21dcf49c..c9cce1568335 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -18,6 +18,7 @@
package com.android.server.companion;
import static android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES;
+import static android.Manifest.permission.BLUETOOTH_CONNECT;
import static android.Manifest.permission.DELIVER_COMPANION_MESSAGES;
import static android.Manifest.permission.MANAGE_COMPANION_DEVICES;
import static android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED;
@@ -52,6 +53,9 @@ import android.app.AppOpsManager;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.ecm.EnhancedConfirmationManager;
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothManager;
import android.companion.AssociationInfo;
import android.companion.AssociationRequest;
import android.companion.IAssociationRequestCallback;
@@ -541,6 +545,31 @@ public class CompanionDeviceManagerService extends SystemService {
}
@Override
+ @EnforcePermission(BLUETOOTH_CONNECT)
+ public boolean removeBond(int associationId, String packageName, int userId) {
+ removeBond_enforcePermission();
+
+ Slog.i(TAG, "removeBond() "
+ + "associationId=" + associationId + ", "
+ + "package=u" + userId + "/" + packageName);
+ enforceCallerCanManageAssociationsForPackage(getContext(), userId, packageName,
+ "remove bonds");
+
+ AssociationInfo association = mAssociationStore
+ .getAssociationWithCallerChecks(associationId);
+ MacAddress address = association.getDeviceMacAddress();
+ if (address == null) {
+ throw new IllegalArgumentException(
+ "Association id=[" + associationId + "] doesn't have a device address.");
+ }
+
+ BluetoothAdapter btAdapter = getContext().getSystemService(BluetoothManager.class)
+ .getAdapter();
+ BluetoothDevice btDevice = btAdapter.getRemoteDevice(address.toString().toUpperCase());
+ return btDevice.removeBond();
+ }
+
+ @Override
public PendingIntent buildPermissionTransferUserConsentIntent(String packageName,
int userId, int associationId) {
return mSystemDataTransferProcessor.buildPermissionTransferUserConsentIntent(