From f89fcec4b7624828a36dd6edf3c6b77f92caab63 Mon Sep 17 00:00:00 2001 From: Eugene Susla Date: Wed, 27 Jan 2021 16:18:29 -0800 Subject: [DO NOT MERGE] Provide CDM util to check if ok to pair BT without prompt Test: presubmit Bug: 172006481 Merged-In: Ibc544466ccd8f1f24fc9899a740024e8c324e721 Change-Id: Ibc544466ccd8f1f24fc9899a740024e8c324e721 (cherry picked from commit ff7c1ea5728f0f04e914c7e99feb1157e38a2d73) --- core/java/android/companion/Association.java | 31 +++++++++++++--- .../android/companion/ICompanionDeviceManager.aidl | 2 ++ .../DeviceDiscoveryService.java | 3 +- .../companion/CompanionDeviceManagerService.java | 42 +++++++++++++++++++--- 4 files changed, 68 insertions(+), 10 deletions(-) diff --git a/core/java/android/companion/Association.java b/core/java/android/companion/Association.java index 960a08755cb8..9007d9d8bbcc 100644 --- a/core/java/android/companion/Association.java +++ b/core/java/android/companion/Association.java @@ -23,6 +23,7 @@ import android.os.Parcelable; import com.android.internal.util.DataClass; +import java.util.Date; import java.util.Objects; /** @@ -39,12 +40,19 @@ public final class Association implements Parcelable { private final @NonNull String mPackageName; private final @Nullable String mDeviceProfile; private final boolean mNotifyOnDeviceNearby; + private final long mTimeApprovedMs; /** @hide */ public int getUserId() { return mUserId; } + private String timeApprovedMsToString() { + return new Date(mTimeApprovedMs).toString(); + } + + + // Code below generated by codegen v1.0.22. @@ -71,7 +79,8 @@ public final class Association implements Parcelable { @NonNull String deviceMacAddress, @NonNull String packageName, @Nullable String deviceProfile, - boolean notifyOnDeviceNearby) { + boolean notifyOnDeviceNearby, + long timeApprovedMs) { this.mUserId = userId; com.android.internal.util.AnnotationValidations.validate( UserIdInt.class, null, mUserId); @@ -83,6 +92,7 @@ public final class Association implements Parcelable { NonNull.class, null, mPackageName); this.mDeviceProfile = deviceProfile; this.mNotifyOnDeviceNearby = notifyOnDeviceNearby; + this.mTimeApprovedMs = timeApprovedMs; // onConstructed(); // You can define this method to get a callback } @@ -107,6 +117,11 @@ public final class Association implements Parcelable { return mNotifyOnDeviceNearby; } + @DataClass.Generated.Member + public long getTimeApprovedMs() { + return mTimeApprovedMs; + } + @Override @DataClass.Generated.Member public String toString() { @@ -118,7 +133,8 @@ public final class Association implements Parcelable { "deviceMacAddress = " + mDeviceMacAddress + ", " + "packageName = " + mPackageName + ", " + "deviceProfile = " + mDeviceProfile + ", " + - "notifyOnDeviceNearby = " + mNotifyOnDeviceNearby + + "notifyOnDeviceNearby = " + mNotifyOnDeviceNearby + ", " + + "timeApprovedMs = " + timeApprovedMsToString() + " }"; } @@ -139,7 +155,8 @@ public final class Association implements Parcelable { && Objects.equals(mDeviceMacAddress, that.mDeviceMacAddress) && Objects.equals(mPackageName, that.mPackageName) && Objects.equals(mDeviceProfile, that.mDeviceProfile) - && mNotifyOnDeviceNearby == that.mNotifyOnDeviceNearby; + && mNotifyOnDeviceNearby == that.mNotifyOnDeviceNearby + && mTimeApprovedMs == that.mTimeApprovedMs; } @Override @@ -154,6 +171,7 @@ public final class Association implements Parcelable { _hash = 31 * _hash + Objects.hashCode(mPackageName); _hash = 31 * _hash + Objects.hashCode(mDeviceProfile); _hash = 31 * _hash + Boolean.hashCode(mNotifyOnDeviceNearby); + _hash = 31 * _hash + Long.hashCode(mTimeApprovedMs); return _hash; } @@ -171,6 +189,7 @@ public final class Association implements Parcelable { dest.writeString(mDeviceMacAddress); dest.writeString(mPackageName); if (mDeviceProfile != null) dest.writeString(mDeviceProfile); + dest.writeLong(mTimeApprovedMs); } @Override @@ -190,6 +209,7 @@ public final class Association implements Parcelable { String deviceMacAddress = in.readString(); String packageName = in.readString(); String deviceProfile = (flg & 0x8) == 0 ? null : in.readString(); + long timeApprovedMs = in.readLong(); this.mUserId = userId; com.android.internal.util.AnnotationValidations.validate( @@ -202,6 +222,7 @@ public final class Association implements Parcelable { NonNull.class, null, mPackageName); this.mDeviceProfile = deviceProfile; this.mNotifyOnDeviceNearby = notifyOnDeviceNearby; + this.mTimeApprovedMs = timeApprovedMs; // onConstructed(); // You can define this method to get a callback } @@ -221,10 +242,10 @@ public final class Association implements Parcelable { }; @DataClass.Generated( - time = 1610482674799L, + time = 1612832377589L, codegenVersion = "1.0.22", sourceFile = "frameworks/base/core/java/android/companion/Association.java", - inputSignatures = "private final @android.annotation.UserIdInt int mUserId\nprivate final @android.annotation.NonNull java.lang.String mDeviceMacAddress\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.Nullable java.lang.String mDeviceProfile\nprivate final boolean mNotifyOnDeviceNearby\npublic int getUserId()\nclass Association extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstructor=true)") + inputSignatures = "private final @android.annotation.UserIdInt int mUserId\nprivate final @android.annotation.NonNull java.lang.String mDeviceMacAddress\nprivate final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.Nullable java.lang.String mDeviceProfile\nprivate final boolean mNotifyOnDeviceNearby\nprivate final long mTimeApprovedMs\npublic int getUserId()\nprivate java.lang.String timeApprovedMsToString()\nclass Association extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genEqualsHashCode=true, genToString=true, genHiddenConstructor=true)") @Deprecated private void __metadata() {} diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl index 527d8df94ea0..95d3515abb80 100644 --- a/core/java/android/companion/ICompanionDeviceManager.aidl +++ b/core/java/android/companion/ICompanionDeviceManager.aidl @@ -49,4 +49,6 @@ interface ICompanionDeviceManager { void registerDevicePresenceListenerService(in String packageName, in String deviceAddress); void unregisterDevicePresenceListenerService(in String packageName, in String deviceAddress); + + boolean canPairWithoutPrompt(in String packageName, in String deviceMacAddress, int userId); } diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java index fd71670ee404..606cd5718d98 100644 --- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java +++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceDiscoveryService.java @@ -322,7 +322,8 @@ public class DeviceDiscoveryService extends Service { void onDeviceSelected(String callingPackage, String deviceAddress) { mServiceCallback.complete(new Association( - getUserId(), deviceAddress, callingPackage, mRequest.getDeviceProfile(), false)); + getUserId(), deviceAddress, callingPackage, mRequest.getDeviceProfile(), false, + System.currentTimeMillis())); } void onCancel() { diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index a36e7acd6612..1e1c18ba5a0b 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -154,6 +154,8 @@ public class CompanionDeviceManagerService extends SystemService implements Bind private static final boolean DEBUG = false; private static final String LOG_TAG = "CompanionDeviceManagerService"; + private static final long PAIR_WITHOUT_PROMPT_WINDOW_MS = 10 * 60 * 1000; // 10 min + private static final String PREF_FILE_NAME = "companion_device_preferences.xml"; private static final String PREF_KEY_AUTO_REVOKE_GRANTS_DONE = "auto_revoke_grants_done"; @@ -163,6 +165,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind private static final String XML_ATTR_DEVICE = "device"; private static final String XML_ATTR_PROFILE = "profile"; private static final String XML_ATTR_NOTIFY_DEVICE_NEARBY = "notify_device_nearby"; + private static final String XML_ATTR_TIME_APPROVED = "time_approved"; private static final String XML_FILE_NAME = "companion_device_manager_associations.xml"; private final CompanionDeviceManagerImpl mImpl; @@ -595,7 +598,8 @@ public class CompanionDeviceManagerService extends SystemService implements Bind association.getDeviceMacAddress(), association.getPackageName(), association.getDeviceProfile(), - active /* notifyOnDeviceNearby */); + active, /* notifyOnDeviceNearby */ + association.getTimeApprovedMs()); } else { return association; } @@ -627,6 +631,15 @@ public class CompanionDeviceManagerService extends SystemService implements Bind + " in manifest to use this API"); } + @Override + public boolean canPairWithoutPrompt( + String packageName, String deviceMacAddress, int userId) { + return CollectionUtils.any( + getAllAssociations(userId, packageName, deviceMacAddress), + a -> System.currentTimeMillis() - a.getTimeApprovedMs() + < PAIR_WITHOUT_PROMPT_WINDOW_MS); + } + @Override public void onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ShellCallback callback, ResultReceiver resultReceiver) @@ -866,6 +879,8 @@ public class CompanionDeviceManagerService extends SystemService implements Bind Boolean.toString( association.isNotifyOnDeviceNearby())); } + tag.attribute(null, XML_ATTR_TIME_APPROVED, + Long.toString(association.getTimeApprovedMs())); tag.endTag(null, XML_TAG_ASSOCIATION); }); @@ -905,7 +920,6 @@ public class CompanionDeviceManagerService extends SystemService implements Bind return getContext().getSystemService(UserManager.class).getUsers(); } - @Nullable private Set getAllAssociations(int userId, @Nullable String packageFilter) { return CollectionUtils.filter( getAllAssociations(userId), @@ -920,6 +934,14 @@ public class CompanionDeviceManagerService extends SystemService implements Bind return result; } + private Set getAllAssociations( + int userId, @Nullable String packageFilter, @Nullable String addressFilter) { + return CollectionUtils.filter( + getAllAssociations(userId), + a -> Objects.equals(packageFilter, a.getPackageName()) + && Objects.equals(addressFilter, a.getDeviceMacAddress())); + } + private Set readAllAssociations(int userId) { final AtomicFile file = getStorageFileForUser(userId); @@ -941,12 +963,14 @@ public class CompanionDeviceManagerService extends SystemService implements Bind final String profile = parser.getAttributeValue(null, XML_ATTR_PROFILE); final boolean persistentGrants = Boolean.valueOf( parser.getAttributeValue(null, XML_ATTR_NOTIFY_DEVICE_NEARBY)); + final long timeApproved = parseLongOrDefault( + parser.getAttributeValue(null, XML_ATTR_TIME_APPROVED), 0L); if (appPackage == null || deviceAddress == null) continue; result = ArrayUtils.add(result, new Association(userId, deviceAddress, appPackage, - profile, persistentGrants)); + profile, persistentGrants, timeApproved)); } return result; } catch (XmlPullParserException | IOException e) { @@ -1215,6 +1239,15 @@ public class CompanionDeviceManagerService extends SystemService implements Bind return result; } + private static long parseLongOrDefault(String str, long def) { + try { + return Long.parseLong(str); + } catch (NumberFormatException e) { + Log.w(LOG_TAG, "Failed to parse", e); + return def; + } + } + private class ShellCmd extends ShellCommand { public static final String USAGE = "help\n" + "list USER_ID\n" @@ -1243,7 +1276,8 @@ public class CompanionDeviceManagerService extends SystemService implements Bind int userId = getNextArgInt(); String pkg = getNextArgRequired(); String address = getNextArgRequired(); - addAssociation(new Association(userId, address, pkg, null, false)); + addAssociation(new Association(userId, address, pkg, null, false, + System.currentTimeMillis())); } break; -- cgit v1.2.3-59-g8ed1b