Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9d147a18 authored by Evan Chen's avatar Evan Chen Committed by Android (Google) Code Review
Browse files

Merge "Delay role revoke when the app is not visible to the user" into tm-qpr-dev

parents d6100324 3f9ae86e
Loading
Loading
Loading
Loading
+44 −2
Original line number Diff line number Diff line
@@ -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
@@ -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");
        }
@@ -91,6 +99,7 @@ public final class AssociationInfo implements Parcelable {

        mSelfManaged = selfManaged;
        mNotifyOnDeviceNearby = notifyOnDeviceNearby;
        mRevoked = revoked;
        mTimeApprovedMs = timeApprovedMs;
        mLastTimeConnectedMs = lastTimeConnectedMs;
    }
@@ -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
@@ -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
@@ -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)
@@ -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);
    }

@@ -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);
    }
@@ -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();
    }
@@ -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;
        }

@@ -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
         */
@@ -401,6 +435,7 @@ public final class AssociationInfo implements Parcelable {
                    mOriginalInfo.mDeviceProfile,
                    mOriginalInfo.mSelfManaged,
                    mNotifyOnDeviceNearby,
                    mRevoked,
                    mOriginalInfo.mTimeApprovedMs,
                    mLastTimeConnectedMs
            );
@@ -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);
    }
}
+16 −0
Original line number Diff line number Diff line
@@ -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) {
@@ -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) {
@@ -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(", ");
@@ -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");
        }
    }
}
+336 −30

File changed.

Preview size limit exceeded, changes collapsed.

+17 −7
Original line number Diff line number Diff line
@@ -103,7 +103,7 @@ import java.util.concurrent.ConcurrentMap;
 * Since Android T the data is stored to "companion_device_manager.xml" file in
 * {@link Environment#getDataSystemDeDirectory(int) /data/system_de/}.
 *
 * See {@link #getBaseStorageFileForUser(int) getBaseStorageFileForUser()}
 * See {@link DataStoreUtils#getBaseStorageFileForUser(int, String)}
 *
 * <p>
 * Since Android T the data is stored using the v1 schema.
@@ -120,7 +120,7 @@ import java.util.concurrent.ConcurrentMap;
 * <li> {@link #readPreviouslyUsedIdsV1(TypedXmlPullParser, Map) readPreviouslyUsedIdsV1()}
 * </ul>
 *
 * The following snippet is a sample of a file that is using v0 schema.
 * The following snippet is a sample of a file that is using v1 schema.
 * <pre>{@code
 * <state persistence-version="1">
 *     <associations>
@@ -130,6 +130,8 @@ import java.util.concurrent.ConcurrentMap;
 *             mac_address="AA:BB:CC:DD:EE:00"
 *             self_managed="false"
 *             notify_device_nearby="false"
 *             revoked="false"
 *             last_time_connected="1634641160229"
 *             time_approved="1634389553216"/>
 *
 *         <association
@@ -139,6 +141,8 @@ import java.util.concurrent.ConcurrentMap;
 *             display_name="Jhon's Chromebook"
 *             self_managed="true"
 *             notify_device_nearby="false"
 *             revoked="false"
 *             last_time_connected="1634641160229"
 *             time_approved="1634641160229"/>
 *     </associations>
 *
@@ -178,6 +182,7 @@ final class PersistentDataStore {
    private static final String XML_ATTR_PROFILE = "profile";
    private static final String XML_ATTR_SELF_MANAGED = "self_managed";
    private static final String XML_ATTR_NOTIFY_DEVICE_NEARBY = "notify_device_nearby";
    private static final String XML_ATTR_REVOKED = "revoked";
    private static final String XML_ATTR_TIME_APPROVED = "time_approved";
    private static final String XML_ATTR_LAST_TIME_CONNECTED = "last_time_connected";

@@ -415,7 +420,8 @@ final class PersistentDataStore {

        out.add(new AssociationInfo(associationId, userId, appPackage,
                MacAddress.fromString(deviceAddress), null, profile,
                /* managedByCompanionApp */false, notify, timeApproved, Long.MAX_VALUE));
                /* managedByCompanionApp */ false, notify, /* revoked */ false, timeApproved,
                Long.MAX_VALUE));
    }

    private static void readAssociationsV1(@NonNull TypedXmlPullParser parser,
@@ -444,13 +450,14 @@ final class PersistentDataStore {
        final String displayName = readStringAttribute(parser, XML_ATTR_DISPLAY_NAME);
        final boolean selfManaged = readBooleanAttribute(parser, XML_ATTR_SELF_MANAGED);
        final boolean notify = readBooleanAttribute(parser, XML_ATTR_NOTIFY_DEVICE_NEARBY);
        final boolean revoked = readBooleanAttribute(parser, XML_ATTR_REVOKED, false);
        final long timeApproved = readLongAttribute(parser, XML_ATTR_TIME_APPROVED, 0L);
        final long lastTimeConnected = readLongAttribute(
                parser, XML_ATTR_LAST_TIME_CONNECTED, Long.MAX_VALUE);

        final AssociationInfo associationInfo = createAssociationInfoNoThrow(associationId, userId,
                appPackage, macAddress, displayName, profile, selfManaged, notify, timeApproved,
                lastTimeConnected);
                appPackage, macAddress, displayName, profile, selfManaged, notify, revoked,
                timeApproved, lastTimeConnected);
        if (associationInfo != null) {
            out.add(associationInfo);
        }
@@ -503,6 +510,8 @@ final class PersistentDataStore {
        writeBooleanAttribute(serializer, XML_ATTR_SELF_MANAGED, a.isSelfManaged());
        writeBooleanAttribute(
                serializer, XML_ATTR_NOTIFY_DEVICE_NEARBY, a.isNotifyOnDeviceNearby());
        writeBooleanAttribute(
                serializer, XML_ATTR_REVOKED, a.isRevoked());
        writeLongAttribute(serializer, XML_ATTR_TIME_APPROVED, a.getTimeApprovedMs());
        writeLongAttribute(
                serializer, XML_ATTR_LAST_TIME_CONNECTED, a.getLastTimeConnectedMs());
@@ -544,11 +553,12 @@ final class PersistentDataStore {
    private static AssociationInfo createAssociationInfoNoThrow(int associationId,
            @UserIdInt int userId, @NonNull String appPackage, @Nullable MacAddress macAddress,
            @Nullable CharSequence displayName, @Nullable String profile, boolean selfManaged,
            boolean notify, long timeApproved, long lastTimeConnected) {
            boolean notify, boolean revoked, long timeApproved, long lastTimeConnected) {
        AssociationInfo associationInfo = null;
        try {
            associationInfo = new AssociationInfo(associationId, userId, appPackage, macAddress,
                    displayName, profile, selfManaged, notify, timeApproved, lastTimeConnected);
                    displayName, profile, selfManaged, notify, revoked, timeApproved,
                    lastTimeConnected);
        } catch (Exception e) {
            if (DEBUG) Log.w(TAG, "Could not create AssociationInfo", e);
        }
+2 −0
Original line number Diff line number Diff line
@@ -85,6 +85,8 @@ final class RolesUtils {
        final int userId = associationInfo.getUserId();
        final UserHandle userHandle = UserHandle.of(userId);

        Slog.i(TAG, "Removing CDM role holder, role=" + deviceProfile
                + ", package=u" + userId + "\\" + packageName);
        roleManager.removeRoleHolderAsUser(deviceProfile, packageName,
                MANAGE_HOLDERS_FLAG_DONT_KILL_APP, userHandle, context.getMainExecutor(),
                success -> {