diff options
4 files changed, 189 insertions, 124 deletions
diff --git a/core/api/test-current.txt b/core/api/test-current.txt index e61c39ff2525..209759dc04ac 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -837,6 +837,23 @@ package android.appwidget { package android.companion { + public static final class AssociationInfo.Builder { + ctor public AssociationInfo.Builder(int, int, @NonNull String); + ctor public AssociationInfo.Builder(@NonNull android.companion.AssociationInfo); + method @NonNull public android.companion.AssociationInfo build(); + method @NonNull public android.companion.AssociationInfo.Builder setAssociatedDevice(@Nullable android.companion.AssociatedDevice); + method @NonNull public android.companion.AssociationInfo.Builder setDeviceMacAddress(@Nullable android.net.MacAddress); + method @NonNull public android.companion.AssociationInfo.Builder setDeviceProfile(@Nullable String); + method @NonNull public android.companion.AssociationInfo.Builder setDisplayName(@Nullable CharSequence); + method @NonNull public android.companion.AssociationInfo.Builder setLastTimeConnected(long); + method @NonNull public android.companion.AssociationInfo.Builder setNotifyOnDeviceNearby(boolean); + method @NonNull public android.companion.AssociationInfo.Builder setRevoked(boolean); + method @NonNull public android.companion.AssociationInfo.Builder setSelfManaged(boolean); + method @NonNull public android.companion.AssociationInfo.Builder setSystemDataSyncFlags(int); + method @NonNull public android.companion.AssociationInfo.Builder setTag(@Nullable String); + method @NonNull public android.companion.AssociationInfo.Builder setTimeApproved(long); + } + public final class CompanionDeviceManager { method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public void enableSecureTransport(boolean); field public static final int MESSAGE_REQUEST_PING = 1669362552; // 0x63807378 diff --git a/core/java/android/companion/AssociationInfo.java b/core/java/android/companion/AssociationInfo.java index 7d62c79e7519..083fa0041b26 100644 --- a/core/java/android/companion/AssociationInfo.java +++ b/core/java/android/companion/AssociationInfo.java @@ -17,7 +17,9 @@ package android.companion; import android.annotation.NonNull; import android.annotation.Nullable; +import android.annotation.SuppressLint; import android.annotation.SystemApi; +import android.annotation.TestApi; import android.annotation.UserIdInt; import android.net.MacAddress; import android.os.Parcel; @@ -41,24 +43,26 @@ public final class AssociationInfo implements Parcelable { private static final String LAST_TIME_CONNECTED_NONE = "None"; /** * A unique ID of this Association record. - * Disclosed to the clients (ie. companion applications) for referring to this record (eg. in + * Disclosed to the clients (i.e. companion applications) for referring to this record (e.g. in * {@code disassociate()} API call). */ private final int mId; - - private final @UserIdInt int mUserId; - private final @NonNull String mPackageName; - - private final @Nullable MacAddress mDeviceMacAddress; - private final @Nullable CharSequence mDisplayName; - private final @Nullable String mDeviceProfile; - private final @Nullable AssociatedDevice mAssociatedDevice; - + @UserIdInt + private final int mUserId; + @NonNull + private final String mPackageName; + @Nullable + private final String mTag; + @Nullable + private final MacAddress mDeviceMacAddress; + @Nullable + private final CharSequence mDisplayName; + @Nullable + private final String mDeviceProfile; + @Nullable + private final AssociatedDevice mAssociatedDevice; private final boolean mSelfManaged; private final boolean mNotifyOnDeviceNearby; - private final int mSystemDataSyncFlags; - private final String mTag; - /** * Indicates that the association has been revoked (removed), but we keep the association * record for final clean up (e.g. removing the app from the list of the role holders). @@ -72,6 +76,7 @@ public final class AssociationInfo implements Parcelable { * Default value is Long.MAX_VALUE. */ private final long mLastTimeConnectedMs; + private final int mSystemDataSyncFlags; /** * Creates a new Association. @@ -93,16 +98,13 @@ public final class AssociationInfo implements Parcelable { } mId = id; - mUserId = userId; mPackageName = packageName; - mDeviceMacAddress = macAddress; mDisplayName = displayName; mTag = tag; mDeviceProfile = deviceProfile; mAssociatedDevice = associatedDevice; - mSelfManaged = selfManaged; mNotifyOnDeviceNearby = notifyOnDeviceNearby; mRevoked = revoked; @@ -119,18 +121,11 @@ public final class AssociationInfo implements Parcelable { } /** - * @return the tag of this association. - * @see CompanionDeviceManager#setAssociationTag(int, String) - */ - public @Nullable String getTag() { - return mTag; - } - - /** * @return the ID of the user who "owns" this association. * @hide */ - public @UserIdInt int getUserId() { + @UserIdInt + public int getUserId() { return mUserId; } @@ -139,19 +134,31 @@ public final class AssociationInfo implements Parcelable { * @hide */ @SystemApi - public @NonNull String getPackageName() { + @NonNull + public String getPackageName() { return mPackageName; } /** + * @return the tag of this association. + * @see CompanionDeviceManager#setAssociationTag(int, String) + */ + @Nullable + public String getTag() { + return mTag; + } + + /** * @return the MAC address of the device. */ - public @Nullable MacAddress getDeviceMacAddress() { + @Nullable + public MacAddress getDeviceMacAddress() { return mDeviceMacAddress; } /** @hide */ - public @Nullable String getDeviceMacAddressAsString() { + @Nullable + public String getDeviceMacAddressAsString() { return mDeviceMacAddress != null ? mDeviceMacAddress.toString().toUpperCase() : null; } @@ -161,7 +168,8 @@ public final class AssociationInfo implements Parcelable { * * @see AssociationRequest.Builder#setDisplayName(CharSequence) */ - public @Nullable CharSequence getDisplayName() { + @Nullable + public CharSequence getDisplayName() { return mDisplayName; } @@ -170,7 +178,8 @@ public final class AssociationInfo implements Parcelable { * association, or {@code null} if no specific profile was used. * @see AssociationRequest.Builder#setDeviceProfile(String) */ - public @Nullable String getDeviceProfile() { + @Nullable + public String getDeviceProfile() { return mDeviceProfile; } @@ -187,7 +196,8 @@ public final class AssociationInfo implements Parcelable { * @return the companion device that was associated, or {@code null} if the device is * self-managed or this association info was retrieved from persistent storage. */ - public @Nullable AssociatedDevice getAssociatedDevice() { + @Nullable + public AssociatedDevice getAssociatedDevice() { return mAssociatedDevice; } @@ -228,14 +238,14 @@ public final class AssociationInfo implements Parcelable { * @return the last time self reported disconnected for selfManaged only. * @hide */ - public Long getLastTimeConnectedMs() { + public long getLastTimeConnectedMs() { return mLastTimeConnectedMs; } /** * @return Enabled system data sync flags set via - * {@link CompanionDeviceManager#enableSystemDataSync(int, int)} and - * {@link CompanionDeviceManager#disableSystemDataSync(int, int)}. + * {@link CompanionDeviceManager#enableSystemDataSyncForTypes(int, int)} (int, int)} and + * {@link CompanionDeviceManager#disableSystemDataSyncForTypes(int, int)} (int, int)}. * Or by default all flags are 1 (enabled). */ public int getSystemDataSyncFlags() { @@ -279,7 +289,8 @@ public final class AssociationInfo implements Parcelable { } /** @hide */ - public @NonNull String toShortString() { + @NonNull + public String toShortString() { final StringBuilder sb = new StringBuilder(); sb.append("id=").append(mId); if (mDeviceMacAddress != null) { @@ -350,16 +361,13 @@ public final class AssociationInfo implements Parcelable { @Override public void writeToParcel(@NonNull Parcel dest, int flags) { dest.writeInt(mId); - dest.writeInt(mUserId); dest.writeString(mPackageName); dest.writeString(mTag); - dest.writeTypedObject(mDeviceMacAddress, 0); dest.writeCharSequence(mDisplayName); dest.writeString(mDeviceProfile); dest.writeTypedObject(mAssociatedDevice, 0); - dest.writeBoolean(mSelfManaged); dest.writeBoolean(mNotifyOnDeviceNearby); dest.writeBoolean(mRevoked); @@ -370,16 +378,13 @@ public final class AssociationInfo implements Parcelable { private AssociationInfo(@NonNull Parcel in) { mId = in.readInt(); - mUserId = in.readInt(); mPackageName = in.readString(); mTag = in.readString(); - mDeviceMacAddress = in.readTypedObject(MacAddress.CREATOR); mDisplayName = in.readCharSequence(); mDeviceProfile = in.readString(); mAssociatedDevice = in.readTypedObject(AssociatedDevice.CREATOR); - mSelfManaged = in.readBoolean(); mNotifyOnDeviceNearby = in.readBoolean(); mRevoked = in.readBoolean(); @@ -403,139 +408,182 @@ public final class AssociationInfo implements Parcelable { }; /** - * Use this method to obtain a builder that you can use to create a copy of the - * given {@link AssociationInfo} with modified values of {@code mLastTimeConnected} - * or {@code mNotifyOnDeviceNearby}. - * <p> - * Note that you <b>must</b> call either {@link Builder#setLastTimeConnected(long) - * setLastTimeConnected} or {@link Builder#setNotifyOnDeviceNearby(boolean) - * setNotifyOnDeviceNearby} before you will be able to call {@link Builder#build() build}. - * - * This is ensured statically at compile time. + * Builder for {@link AssociationInfo} * * @hide */ - @NonNull - public static NonActionableBuilder builder(@NonNull AssociationInfo info) { - return new Builder(info); - } - - /** @hide */ - public static final class Builder implements NonActionableBuilder { - @NonNull - private final AssociationInfo mOriginalInfo; + @TestApi + public static final class Builder { + private final int mId; + private final int mUserId; + private final String mPackageName; + private String mTag; + private MacAddress mDeviceMacAddress; + private CharSequence mDisplayName; + private String mDeviceProfile; + private AssociatedDevice mAssociatedDevice; + private boolean mSelfManaged; private boolean mNotifyOnDeviceNearby; private boolean mRevoked; + private long mTimeApprovedMs; private long mLastTimeConnectedMs; private int mSystemDataSyncFlags; - private String mTag; - private Builder(@NonNull AssociationInfo info) { - mOriginalInfo = info; + /** @hide */ + @TestApi + public Builder(int id, int userId, @NonNull String packageName) { + mId = id; + mUserId = userId; + mPackageName = packageName; + } + + /** @hide */ + @TestApi + public Builder(@NonNull AssociationInfo info) { + mId = info.mId; + mUserId = info.mUserId; + mPackageName = info.mPackageName; mTag = info.mTag; + mDeviceMacAddress = info.mDeviceMacAddress; + mDisplayName = info.mDisplayName; + mDeviceProfile = info.mDeviceProfile; + mAssociatedDevice = info.mAssociatedDevice; + mSelfManaged = info.mSelfManaged; mNotifyOnDeviceNearby = info.mNotifyOnDeviceNearby; mRevoked = info.mRevoked; + mTimeApprovedMs = info.mTimeApprovedMs; mLastTimeConnectedMs = info.mLastTimeConnectedMs; mSystemDataSyncFlags = info.mSystemDataSyncFlags; } /** @hide */ - @Override + @TestApi @NonNull - public Builder setLastTimeConnected(long lastTimeConnectedMs) { - if (lastTimeConnectedMs < 0) { - throw new IllegalArgumentException( - "lastTimeConnectedMs must not be negative! (Given " + lastTimeConnectedMs - + " )"); - } - mLastTimeConnectedMs = lastTimeConnectedMs; + public Builder setTag(@Nullable String tag) { + mTag = tag; return this; } /** @hide */ - @Override + @TestApi @NonNull - public Builder setNotifyOnDeviceNearby(boolean notifyOnDeviceNearby) { - mNotifyOnDeviceNearby = notifyOnDeviceNearby; + public Builder setDeviceMacAddress(@Nullable MacAddress deviceMacAddress) { + mDeviceMacAddress = deviceMacAddress; return this; } /** @hide */ - @Override + @TestApi @NonNull - public Builder setRevoked(boolean revoked) { - mRevoked = revoked; + public Builder setDisplayName(@Nullable CharSequence displayName) { + mDisplayName = displayName; return this; } /** @hide */ - @Override + @TestApi @NonNull - public Builder setSystemDataSyncFlags(int flags) { - mSystemDataSyncFlags = flags; + public Builder setDeviceProfile(@Nullable String deviceProfile) { + mDeviceProfile = deviceProfile; return this; } /** @hide */ - @Override + @TestApi @NonNull - public Builder setTag(String tag) { - mTag = tag; + public Builder setAssociatedDevice(@Nullable AssociatedDevice associatedDevice) { + mAssociatedDevice = associatedDevice; return this; } /** @hide */ + @TestApi @NonNull - public AssociationInfo build() { - return new AssociationInfo( - mOriginalInfo.mId, - mOriginalInfo.mUserId, - mOriginalInfo.mPackageName, - mTag, - mOriginalInfo.mDeviceMacAddress, - mOriginalInfo.mDisplayName, - mOriginalInfo.mDeviceProfile, - mOriginalInfo.mAssociatedDevice, - mOriginalInfo.mSelfManaged, - mNotifyOnDeviceNearby, - mRevoked, - mOriginalInfo.mTimeApprovedMs, - mLastTimeConnectedMs, - mSystemDataSyncFlags - ); + public Builder setSelfManaged(boolean selfManaged) { + mSelfManaged = selfManaged; + return this; } - } - /** - * This interface is returned from the - * {@link AssociationInfo#builder(android.companion.AssociationInfo) builder} entry point - * to indicate that this builder is not yet in a state that can produce a meaningful - * {@link AssociationInfo} object that is different from the one originally passed in. - * - * <p> - * Only by calling one of the setter methods is this builder turned into one where calling - * {@link Builder#build() build()} makes sense. - * - * @hide - */ - public interface NonActionableBuilder { /** @hide */ + @TestApi @NonNull - Builder setNotifyOnDeviceNearby(boolean notifyOnDeviceNearby); + @SuppressLint("MissingGetterMatchingBuilder") + public Builder setNotifyOnDeviceNearby(boolean notifyOnDeviceNearby) { + mNotifyOnDeviceNearby = notifyOnDeviceNearby; + return this; + } + + /** @hide */ + @TestApi + @NonNull + @SuppressLint("MissingGetterMatchingBuilder") + public Builder setRevoked(boolean revoked) { + mRevoked = revoked; + return this; + } /** @hide */ + @TestApi @NonNull - Builder setLastTimeConnected(long lastTimeConnectedMs); + @SuppressLint("MissingGetterMatchingBuilder") + public Builder setTimeApproved(long timeApprovedMs) { + if (timeApprovedMs < 0) { + throw new IllegalArgumentException("timeApprovedMs must be positive. Was given (" + + timeApprovedMs + ")"); + } + mTimeApprovedMs = timeApprovedMs; + return this; + } /** @hide */ + @TestApi @NonNull - Builder setRevoked(boolean revoked); + @SuppressLint("MissingGetterMatchingBuilder") + public Builder setLastTimeConnected(long lastTimeConnectedMs) { + if (lastTimeConnectedMs < 0) { + throw new IllegalArgumentException( + "lastTimeConnectedMs must not be negative! (Given " + lastTimeConnectedMs + + " )"); + } + mLastTimeConnectedMs = lastTimeConnectedMs; + return this; + } /** @hide */ + @TestApi @NonNull - Builder setSystemDataSyncFlags(int flags); + public Builder setSystemDataSyncFlags(int flags) { + mSystemDataSyncFlags = flags; + return this; + } /** @hide */ - Builder setTag(String tag); + @TestApi + @NonNull + public AssociationInfo build() { + if (mId <= 0) { + throw new IllegalArgumentException("Association ID should be greater than 0"); + } + if (mDeviceMacAddress == null && mDisplayName == null) { + throw new IllegalArgumentException("MAC address and the display name must NOT be " + + "null at the same time"); + } + return new AssociationInfo( + mId, + mUserId, + mPackageName, + mTag, + mDeviceMacAddress, + mDisplayName, + mDeviceProfile, + mAssociatedDevice, + mSelfManaged, + mNotifyOnDeviceNearby, + mRevoked, + mTimeApprovedMs, + mLastTimeConnectedMs, + mSystemDataSyncFlags + ); + } } } diff --git a/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java b/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java index fd45d2423227..69647633eaff 100644 --- a/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java +++ b/services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java @@ -313,14 +313,14 @@ class AssociationRequestsProcessor { public void enableSystemDataSync(int associationId, int flags) { AssociationInfo association = mAssociationStore.getAssociationById(associationId); - AssociationInfo updated = AssociationInfo.builder(association) + AssociationInfo updated = (new AssociationInfo.Builder(association)) .setSystemDataSyncFlags(association.getSystemDataSyncFlags() | flags).build(); mAssociationStore.updateAssociation(updated); } public void disableSystemDataSync(int associationId, int flags) { AssociationInfo association = mAssociationStore.getAssociationById(associationId); - AssociationInfo updated = AssociationInfo.builder(association) + AssociationInfo updated = (new AssociationInfo.Builder(association)) .setSystemDataSyncFlags(association.getSystemDataSyncFlags() & (~flags)).build(); mAssociationStore.updateAssociation(updated); } diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index 996c68b5bf83..1ce7d9691fb5 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -891,7 +891,7 @@ public class CompanionDeviceManagerService extends SystemService { } // AssociationInfo class is immutable: create a new AssociationInfo object with updated // timestamp. - association = AssociationInfo.builder(association) + association = (new AssociationInfo.Builder(association)) .setLastTimeConnected(System.currentTimeMillis()) .build(); mAssociationStore.updateAssociation(association); @@ -945,7 +945,7 @@ public class CompanionDeviceManagerService extends SystemService { // AssociationInfo class is immutable: create a new AssociationInfo object with updated // flag. - association = AssociationInfo.builder(association) + association = (new AssociationInfo.Builder(association)) .setNotifyOnDeviceNearby(active) .build(); // Do not need to call {@link BleCompanionDeviceScanner#restartScan()} since it will @@ -1016,7 +1016,7 @@ public class CompanionDeviceManagerService extends SystemService { @Override public void setAssociationTag(int associationId, String tag) { AssociationInfo association = getAssociationWithCallerChecks(associationId); - association = AssociationInfo.builder(association).setTag(tag).build(); + association = (new AssociationInfo.Builder(association)).setTag(tag).build(); mAssociationStore.updateAssociation(association); } @@ -1255,7 +1255,7 @@ public class CompanionDeviceManagerService extends SystemService { */ private void addToPendingRoleHolderRemoval(@NonNull AssociationInfo association) { // First: set revoked flag. - association = AssociationInfo.builder(association) + association = (new AssociationInfo.Builder(association)) .setRevoked(true) .build(); |