Loading core/java/android/companion/AssociationInfo.java +44 −2 Original line number Diff line number Diff line Loading @@ -55,6 +55,14 @@ public final class AssociationInfo implements Parcelable { private final boolean mSelfManaged; private final boolean mNotifyOnDeviceNearby; /** * 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). * * @see CompanionDeviceManager#disassociate(int) */ private final boolean mRevoked; private final long mTimeApprovedMs; /** * A long value indicates the last time connected reported by selfManaged devices Loading @@ -71,7 +79,7 @@ public final class AssociationInfo implements Parcelable { public AssociationInfo(int id, @UserIdInt int userId, @NonNull String packageName, @Nullable MacAddress macAddress, @Nullable CharSequence displayName, @Nullable String deviceProfile, boolean selfManaged, boolean notifyOnDeviceNearby, long timeApprovedMs, long lastTimeConnectedMs) { boolean revoked, long timeApprovedMs, long lastTimeConnectedMs) { if (id <= 0) { throw new IllegalArgumentException("Association ID should be greater than 0"); } Loading @@ -91,6 +99,7 @@ public final class AssociationInfo implements Parcelable { mSelfManaged = selfManaged; mNotifyOnDeviceNearby = notifyOnDeviceNearby; mRevoked = revoked; mTimeApprovedMs = timeApprovedMs; mLastTimeConnectedMs = lastTimeConnectedMs; } Loading Loading @@ -175,6 +184,14 @@ public final class AssociationInfo implements Parcelable { return mUserId == userId && Objects.equals(mPackageName, packageName); } /** * @return if the association has been revoked (removed). * @hide */ public boolean isRevoked() { return mRevoked; } /** * @return the last time self reported disconnected for selfManaged only. * @hide Loading Loading @@ -244,6 +261,7 @@ public final class AssociationInfo implements Parcelable { + ", mDeviceProfile='" + mDeviceProfile + '\'' + ", mSelfManaged=" + mSelfManaged + ", mNotifyOnDeviceNearby=" + mNotifyOnDeviceNearby + ", mRevoked=" + mRevoked + ", mTimeApprovedMs=" + new Date(mTimeApprovedMs) + ", mLastTimeConnectedMs=" + ( mLastTimeConnectedMs == Long.MAX_VALUE Loading @@ -260,6 +278,7 @@ public final class AssociationInfo implements Parcelable { && mUserId == that.mUserId && mSelfManaged == that.mSelfManaged && mNotifyOnDeviceNearby == that.mNotifyOnDeviceNearby && mRevoked == that.mRevoked && mTimeApprovedMs == that.mTimeApprovedMs && mLastTimeConnectedMs == that.mLastTimeConnectedMs && Objects.equals(mPackageName, that.mPackageName) Loading @@ -271,7 +290,7 @@ public final class AssociationInfo implements Parcelable { @Override public int hashCode() { return Objects.hash(mId, mUserId, mPackageName, mDeviceMacAddress, mDisplayName, mDeviceProfile, mSelfManaged, mNotifyOnDeviceNearby, mTimeApprovedMs, mDeviceProfile, mSelfManaged, mNotifyOnDeviceNearby, mRevoked, mTimeApprovedMs, mLastTimeConnectedMs); } Loading @@ -293,6 +312,7 @@ public final class AssociationInfo implements Parcelable { dest.writeBoolean(mSelfManaged); dest.writeBoolean(mNotifyOnDeviceNearby); dest.writeBoolean(mRevoked); dest.writeLong(mTimeApprovedMs); dest.writeLong(mLastTimeConnectedMs); } Loading @@ -309,6 +329,7 @@ public final class AssociationInfo implements Parcelable { mSelfManaged = in.readBoolean(); mNotifyOnDeviceNearby = in.readBoolean(); mRevoked = in.readBoolean(); mTimeApprovedMs = in.readLong(); mLastTimeConnectedMs = in.readLong(); } Loading Loading @@ -352,11 +373,13 @@ public final class AssociationInfo implements Parcelable { @NonNull private final AssociationInfo mOriginalInfo; private boolean mNotifyOnDeviceNearby; private boolean mRevoked; private long mLastTimeConnectedMs; private Builder(@NonNull AssociationInfo info) { mOriginalInfo = info; mNotifyOnDeviceNearby = info.mNotifyOnDeviceNearby; mRevoked = info.mRevoked; mLastTimeConnectedMs = info.mLastTimeConnectedMs; } Loading Loading @@ -387,6 +410,17 @@ public final class AssociationInfo implements Parcelable { return this; } /** * Should only be used by the CompanionDeviceManagerService. * @hide */ @Override @NonNull public Builder setRevoked(boolean revoked) { mRevoked = revoked; return this; } /** * @hide */ Loading @@ -401,6 +435,7 @@ public final class AssociationInfo implements Parcelable { mOriginalInfo.mDeviceProfile, mOriginalInfo.mSelfManaged, mNotifyOnDeviceNearby, mRevoked, mOriginalInfo.mTimeApprovedMs, mLastTimeConnectedMs ); Loading Loading @@ -433,5 +468,12 @@ public final class AssociationInfo implements Parcelable { */ @NonNull Builder setLastTimeConnected(long lastTimeConnectedMs); /** * Should only be used by the CompanionDeviceManagerService. * @hide */ @NonNull Builder setRevoked(boolean revoked); } } services/companion/java/com/android/server/companion/AssociationStoreImpl.java +16 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,9 @@ class AssociationStoreImpl implements AssociationStore { private final Set<OnChangeListener> mListeners = new LinkedHashSet<>(); void addAssociation(@NonNull AssociationInfo association) { // Validity check first. checkNotRevoked(association); final int id = association.getId(); if (DEBUG) { Loading @@ -99,6 +102,9 @@ class AssociationStoreImpl implements AssociationStore { } void updateAssociation(@NonNull AssociationInfo updated) { // Validity check first. checkNotRevoked(updated); final int id = updated.getId(); if (DEBUG) { Loading Loading @@ -292,6 +298,9 @@ class AssociationStoreImpl implements AssociationStore { } void setAssociations(Collection<AssociationInfo> allAssociations) { // Validity check first. allAssociations.forEach(AssociationStoreImpl::checkNotRevoked); if (DEBUG) { Log.i(TAG, "setAssociations() n=" + allAssociations.size()); final StringJoiner stringJoiner = new StringJoiner(", "); Loading Loading @@ -324,4 +333,11 @@ class AssociationStoreImpl implements AssociationStore { mAddressMap.clear(); mCachedPerUser.clear(); } private static void checkNotRevoked(@NonNull AssociationInfo association) { if (association.isRevoked()) { throw new IllegalArgumentException( "Revoked (removed) associations MUST NOT appear in the AssociationStore"); } } } Loading
core/java/android/companion/AssociationInfo.java +44 −2 Original line number Diff line number Diff line Loading @@ -55,6 +55,14 @@ public final class AssociationInfo implements Parcelable { private final boolean mSelfManaged; private final boolean mNotifyOnDeviceNearby; /** * 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). * * @see CompanionDeviceManager#disassociate(int) */ private final boolean mRevoked; private final long mTimeApprovedMs; /** * A long value indicates the last time connected reported by selfManaged devices Loading @@ -71,7 +79,7 @@ public final class AssociationInfo implements Parcelable { public AssociationInfo(int id, @UserIdInt int userId, @NonNull String packageName, @Nullable MacAddress macAddress, @Nullable CharSequence displayName, @Nullable String deviceProfile, boolean selfManaged, boolean notifyOnDeviceNearby, long timeApprovedMs, long lastTimeConnectedMs) { boolean revoked, long timeApprovedMs, long lastTimeConnectedMs) { if (id <= 0) { throw new IllegalArgumentException("Association ID should be greater than 0"); } Loading @@ -91,6 +99,7 @@ public final class AssociationInfo implements Parcelable { mSelfManaged = selfManaged; mNotifyOnDeviceNearby = notifyOnDeviceNearby; mRevoked = revoked; mTimeApprovedMs = timeApprovedMs; mLastTimeConnectedMs = lastTimeConnectedMs; } Loading Loading @@ -175,6 +184,14 @@ public final class AssociationInfo implements Parcelable { return mUserId == userId && Objects.equals(mPackageName, packageName); } /** * @return if the association has been revoked (removed). * @hide */ public boolean isRevoked() { return mRevoked; } /** * @return the last time self reported disconnected for selfManaged only. * @hide Loading Loading @@ -244,6 +261,7 @@ public final class AssociationInfo implements Parcelable { + ", mDeviceProfile='" + mDeviceProfile + '\'' + ", mSelfManaged=" + mSelfManaged + ", mNotifyOnDeviceNearby=" + mNotifyOnDeviceNearby + ", mRevoked=" + mRevoked + ", mTimeApprovedMs=" + new Date(mTimeApprovedMs) + ", mLastTimeConnectedMs=" + ( mLastTimeConnectedMs == Long.MAX_VALUE Loading @@ -260,6 +278,7 @@ public final class AssociationInfo implements Parcelable { && mUserId == that.mUserId && mSelfManaged == that.mSelfManaged && mNotifyOnDeviceNearby == that.mNotifyOnDeviceNearby && mRevoked == that.mRevoked && mTimeApprovedMs == that.mTimeApprovedMs && mLastTimeConnectedMs == that.mLastTimeConnectedMs && Objects.equals(mPackageName, that.mPackageName) Loading @@ -271,7 +290,7 @@ public final class AssociationInfo implements Parcelable { @Override public int hashCode() { return Objects.hash(mId, mUserId, mPackageName, mDeviceMacAddress, mDisplayName, mDeviceProfile, mSelfManaged, mNotifyOnDeviceNearby, mTimeApprovedMs, mDeviceProfile, mSelfManaged, mNotifyOnDeviceNearby, mRevoked, mTimeApprovedMs, mLastTimeConnectedMs); } Loading @@ -293,6 +312,7 @@ public final class AssociationInfo implements Parcelable { dest.writeBoolean(mSelfManaged); dest.writeBoolean(mNotifyOnDeviceNearby); dest.writeBoolean(mRevoked); dest.writeLong(mTimeApprovedMs); dest.writeLong(mLastTimeConnectedMs); } Loading @@ -309,6 +329,7 @@ public final class AssociationInfo implements Parcelable { mSelfManaged = in.readBoolean(); mNotifyOnDeviceNearby = in.readBoolean(); mRevoked = in.readBoolean(); mTimeApprovedMs = in.readLong(); mLastTimeConnectedMs = in.readLong(); } Loading Loading @@ -352,11 +373,13 @@ public final class AssociationInfo implements Parcelable { @NonNull private final AssociationInfo mOriginalInfo; private boolean mNotifyOnDeviceNearby; private boolean mRevoked; private long mLastTimeConnectedMs; private Builder(@NonNull AssociationInfo info) { mOriginalInfo = info; mNotifyOnDeviceNearby = info.mNotifyOnDeviceNearby; mRevoked = info.mRevoked; mLastTimeConnectedMs = info.mLastTimeConnectedMs; } Loading Loading @@ -387,6 +410,17 @@ public final class AssociationInfo implements Parcelable { return this; } /** * Should only be used by the CompanionDeviceManagerService. * @hide */ @Override @NonNull public Builder setRevoked(boolean revoked) { mRevoked = revoked; return this; } /** * @hide */ Loading @@ -401,6 +435,7 @@ public final class AssociationInfo implements Parcelable { mOriginalInfo.mDeviceProfile, mOriginalInfo.mSelfManaged, mNotifyOnDeviceNearby, mRevoked, mOriginalInfo.mTimeApprovedMs, mLastTimeConnectedMs ); Loading Loading @@ -433,5 +468,12 @@ public final class AssociationInfo implements Parcelable { */ @NonNull Builder setLastTimeConnected(long lastTimeConnectedMs); /** * Should only be used by the CompanionDeviceManagerService. * @hide */ @NonNull Builder setRevoked(boolean revoked); } }
services/companion/java/com/android/server/companion/AssociationStoreImpl.java +16 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,9 @@ class AssociationStoreImpl implements AssociationStore { private final Set<OnChangeListener> mListeners = new LinkedHashSet<>(); void addAssociation(@NonNull AssociationInfo association) { // Validity check first. checkNotRevoked(association); final int id = association.getId(); if (DEBUG) { Loading @@ -99,6 +102,9 @@ class AssociationStoreImpl implements AssociationStore { } void updateAssociation(@NonNull AssociationInfo updated) { // Validity check first. checkNotRevoked(updated); final int id = updated.getId(); if (DEBUG) { Loading Loading @@ -292,6 +298,9 @@ class AssociationStoreImpl implements AssociationStore { } void setAssociations(Collection<AssociationInfo> allAssociations) { // Validity check first. allAssociations.forEach(AssociationStoreImpl::checkNotRevoked); if (DEBUG) { Log.i(TAG, "setAssociations() n=" + allAssociations.size()); final StringJoiner stringJoiner = new StringJoiner(", "); Loading Loading @@ -324,4 +333,11 @@ class AssociationStoreImpl implements AssociationStore { mAddressMap.clear(); mCachedPerUser.clear(); } private static void checkNotRevoked(@NonNull AssociationInfo association) { if (association.isRevoked()) { throw new IllegalArgumentException( "Revoked (removed) associations MUST NOT appear in the AssociationStore"); } } }