diff --git a/core/api/system-current.txt b/core/api/system-current.txt index e28ac6ea9146a..32c10b001965a 100644 --- a/core/api/system-current.txt +++ b/core/api/system-current.txt @@ -2246,7 +2246,7 @@ package android.bluetooth.le { package android.companion { public final class CompanionDeviceManager { - method @RequiresPermission(android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES) public void associate(@NonNull String, @NonNull android.net.MacAddress); + method @RequiresPermission(android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES) public void associate(@NonNull String, @NonNull android.net.MacAddress, @NonNull byte[]); method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean canPairWithoutPrompt(@NonNull String, @NonNull String, @NonNull android.os.UserHandle); method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public boolean isDeviceAssociatedForWifiConnection(@NonNull String, @NonNull android.net.MacAddress, @NonNull android.os.UserHandle); } diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java index e6ffded2b8dcf..b99ad5125149e 100644 --- a/core/java/android/companion/CompanionDeviceManager.java +++ b/core/java/android/companion/CompanionDeviceManager.java @@ -442,13 +442,18 @@ public final class CompanionDeviceManager { /** * Associates given device with given app for the given user directly, without UI prompt. * + * @param packageName package name of the companion app + * @param macAddress mac address of the device to associate + * @param certificate The SHA256 digest of the companion app's signing certificate + * * @hide */ @SystemApi @RequiresPermission(android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES) public void associate( @NonNull String packageName, - @NonNull MacAddress macAddress) { + @NonNull MacAddress macAddress, + @NonNull byte[] certificate) { if (!checkFeaturePresent()) { return; } @@ -458,7 +463,7 @@ public final class CompanionDeviceManager { UserHandle user = android.os.Process.myUserHandle(); try { mService.createAssociation( - packageName, macAddress.toString(), user.getIdentifier()); + packageName, macAddress.toString(), user.getIdentifier(), certificate); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl index cc3749cc2a249..d113b929db383 100644 --- a/core/java/android/companion/ICompanionDeviceManager.aidl +++ b/core/java/android/companion/ICompanionDeviceManager.aidl @@ -52,5 +52,6 @@ interface ICompanionDeviceManager { boolean canPairWithoutPrompt(in String packageName, in String deviceMacAddress, int userId); - void createAssociation(in String packageName, in String macAddress, int userId); + void createAssociation(in String packageName, in String macAddress, int userId, + in byte[] certificate); } diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index ab85b5e5cdf67..83dfe8ed25767 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -20,6 +20,7 @@ package com.android.server.companion; import static android.bluetooth.le.ScanSettings.CALLBACK_TYPE_ALL_MATCHES; import static android.bluetooth.le.ScanSettings.SCAN_MODE_BALANCED; import static android.content.Context.BIND_IMPORTANT; +import static android.content.pm.PackageManager.CERT_INPUT_SHA256; import static android.content.pm.PackageManager.MATCH_ALL; import static android.content.pm.PackageManager.PERMISSION_GRANTED; @@ -657,7 +658,14 @@ public class CompanionDeviceManagerService extends SystemService implements Bind } @Override - public void createAssociation(String packageName, String macAddress, int userId) { + public void createAssociation(String packageName, String macAddress, int userId, + byte[] certificate) { + if (!getContext().getPackageManager().hasSigningCertificate( + packageName, certificate, CERT_INPUT_SHA256)) { + Slog.e(LOG_TAG, "Given certificate doesn't match the package certificate."); + return; + } + getContext().enforceCallingOrSelfPermission( android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES, "createAssociation");