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

Commit 7ba08dbc authored by Sudheer Shanka's avatar Sudheer Shanka Committed by Automerger Merge Worker
Browse files

Merge "Keep track of commit times for each blob." into rvc-dev am: b78a0f46

Change-Id: If7ca053de693c0a84f1e7c174d1ea841035de42e
parents bde0fea3 b78a0f46
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -48,6 +48,7 @@ public final class XmlTags {


    // For committer
    // For committer
    public static final String TAG_COMMITTER = "c";
    public static final String TAG_COMMITTER = "c";
    public static final String ATTR_COMMIT_TIME_MS = "cmt";


    // For leasee
    // For leasee
    public static final String TAG_LEASEE = "l";
    public static final String TAG_LEASEE = "l";
+41 −11
Original line number Original line Diff line number Diff line
@@ -15,6 +15,7 @@
 */
 */
package com.android.server.blob;
package com.android.server.blob;


import static android.app.blob.XmlTags.ATTR_COMMIT_TIME_MS;
import static android.app.blob.XmlTags.ATTR_DESCRIPTION;
import static android.app.blob.XmlTags.ATTR_DESCRIPTION;
import static android.app.blob.XmlTags.ATTR_DESCRIPTION_RES_NAME;
import static android.app.blob.XmlTags.ATTR_DESCRIPTION_RES_NAME;
import static android.app.blob.XmlTags.ATTR_EXPIRY_TIME;
import static android.app.blob.XmlTags.ATTR_EXPIRY_TIME;
@@ -30,6 +31,7 @@ import static android.os.Process.INVALID_UID;
import static android.system.OsConstants.O_RDONLY;
import static android.system.OsConstants.O_RDONLY;


import static com.android.server.blob.BlobStoreConfig.TAG;
import static com.android.server.blob.BlobStoreConfig.TAG;
import static com.android.server.blob.BlobStoreConfig.XML_VERSION_ADD_COMMIT_TIME;
import static com.android.server.blob.BlobStoreConfig.XML_VERSION_ADD_DESC_RES_NAME;
import static com.android.server.blob.BlobStoreConfig.XML_VERSION_ADD_DESC_RES_NAME;
import static com.android.server.blob.BlobStoreConfig.XML_VERSION_ADD_STRING_DESC;
import static com.android.server.blob.BlobStoreConfig.XML_VERSION_ADD_STRING_DESC;
import static com.android.server.blob.BlobStoreConfig.hasLeaseWaitTimeElapsed;
import static com.android.server.blob.BlobStoreConfig.hasLeaseWaitTimeElapsed;
@@ -54,6 +56,7 @@ import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseArray;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.XmlUtils;
import com.android.internal.util.XmlUtils;
import com.android.server.blob.BlobStoreManagerService.DumpArgs;
import com.android.server.blob.BlobStoreManagerService.DumpArgs;
@@ -125,7 +128,7 @@ class BlobMetadata {
        }
        }
    }
    }


    void addCommitters(ArraySet<Committer> committers) {
    void setCommitters(ArraySet<Committer> committers) {
        synchronized (mMetadataLock) {
        synchronized (mMetadataLock) {
            mCommitters.clear();
            mCommitters.clear();
            mCommitters.addAll(committers);
            mCommitters.addAll(committers);
@@ -153,11 +156,16 @@ class BlobMetadata {
    }
    }


    @Nullable
    @Nullable
    Committer getExistingCommitter(@NonNull Committer newCommitter) {
    Committer getExistingCommitter(@NonNull String packageName, int uid) {
        synchronized (mCommitters) {
        synchronized (mCommitters) {
            final int index = mCommitters.indexOf(newCommitter);
            for (int i = 0, size = mCommitters.size(); i < size; ++i) {
            return index >= 0 ? mCommitters.valueAt(index) : null;
                final Committer committer = mCommitters.valueAt(i);
                if (committer.uid == uid && committer.packageName.equals(packageName)) {
                    return committer;
                }
            }
        }
        }
        return null;
    }
    }


    void addOrReplaceLeasee(String callingPackage, int callingUid, int descriptionResId,
    void addOrReplaceLeasee(String callingPackage, int callingUid, int descriptionResId,
@@ -172,7 +180,7 @@ class BlobMetadata {
        }
        }
    }
    }


    void addLeasees(ArraySet<Leasee> leasees) {
    void setLeasees(ArraySet<Leasee> leasees) {
        synchronized (mMetadataLock) {
        synchronized (mMetadataLock) {
            mLeasees.clear();
            mLeasees.clear();
            mLeasees.addAll(leasees);
            mLeasees.addAll(leasees);
@@ -380,8 +388,7 @@ class BlobMetadata {
        }
        }


        // Blobs with no active leases
        // Blobs with no active leases
        // TODO: Track commit time instead of using last modified time.
        if ((!respectLeaseWaitTime || hasLeaseWaitTimeElapsedForAll())
        if ((!respectLeaseWaitTime || hasLeaseWaitTimeElapsed(getBlobFile().lastModified()))
                && !hasLeases()) {
                && !hasLeases()) {
            return true;
            return true;
        }
        }
@@ -389,6 +396,17 @@ class BlobMetadata {
        return false;
        return false;
    }
    }


    @VisibleForTesting
    boolean hasLeaseWaitTimeElapsedForAll() {
        for (int i = 0, size = mCommitters.size(); i < size; ++i) {
            final Committer committer = mCommitters.valueAt(i);
            if (!hasLeaseWaitTimeElapsed(committer.getCommitTimeMs())) {
                return false;
            }
        }
        return true;
    }

    void dump(IndentingPrintWriter fout, DumpArgs dumpArgs) {
    void dump(IndentingPrintWriter fout, DumpArgs dumpArgs) {
        fout.println("blobHandle:");
        fout.println("blobHandle:");
        fout.increaseIndent();
        fout.increaseIndent();
@@ -492,20 +510,28 @@ class BlobMetadata {
        }
        }


        final BlobMetadata blobMetadata = new BlobMetadata(context, blobId, blobHandle, userId);
        final BlobMetadata blobMetadata = new BlobMetadata(context, blobId, blobHandle, userId);
        blobMetadata.addCommitters(committers);
        blobMetadata.setCommitters(committers);
        blobMetadata.addLeasees(leasees);
        blobMetadata.setLeasees(leasees);
        return blobMetadata;
        return blobMetadata;
    }
    }


    static final class Committer extends Accessor {
    static final class Committer extends Accessor {
        public final BlobAccessMode blobAccessMode;
        public final BlobAccessMode blobAccessMode;
        public final long commitTimeMs;


        Committer(String packageName, int uid, BlobAccessMode blobAccessMode) {
        Committer(String packageName, int uid, BlobAccessMode blobAccessMode, long commitTimeMs) {
            super(packageName, uid);
            super(packageName, uid);
            this.blobAccessMode = blobAccessMode;
            this.blobAccessMode = blobAccessMode;
            this.commitTimeMs = commitTimeMs;
        }

        long getCommitTimeMs() {
            return commitTimeMs;
        }
        }


        void dump(IndentingPrintWriter fout) {
        void dump(IndentingPrintWriter fout) {
            fout.println("commit time: "
                    + (commitTimeMs == 0 ? "<null>" : BlobStoreUtils.formatTime(commitTimeMs)));
            fout.println("accessMode:");
            fout.println("accessMode:");
            fout.increaseIndent();
            fout.increaseIndent();
            blobAccessMode.dump(fout);
            blobAccessMode.dump(fout);
@@ -515,6 +541,7 @@ class BlobMetadata {
        void writeToXml(@NonNull XmlSerializer out) throws IOException {
        void writeToXml(@NonNull XmlSerializer out) throws IOException {
            XmlUtils.writeStringAttribute(out, ATTR_PACKAGE, packageName);
            XmlUtils.writeStringAttribute(out, ATTR_PACKAGE, packageName);
            XmlUtils.writeIntAttribute(out, ATTR_UID, uid);
            XmlUtils.writeIntAttribute(out, ATTR_UID, uid);
            XmlUtils.writeLongAttribute(out, ATTR_COMMIT_TIME_MS, commitTimeMs);


            out.startTag(null, TAG_ACCESS_MODE);
            out.startTag(null, TAG_ACCESS_MODE);
            blobAccessMode.writeToXml(out);
            blobAccessMode.writeToXml(out);
@@ -526,6 +553,9 @@ class BlobMetadata {
                throws XmlPullParserException, IOException {
                throws XmlPullParserException, IOException {
            final String packageName = XmlUtils.readStringAttribute(in, ATTR_PACKAGE);
            final String packageName = XmlUtils.readStringAttribute(in, ATTR_PACKAGE);
            final int uid = XmlUtils.readIntAttribute(in, ATTR_UID);
            final int uid = XmlUtils.readIntAttribute(in, ATTR_UID);
            final long commitTimeMs = version >= XML_VERSION_ADD_COMMIT_TIME
                    ? XmlUtils.readLongAttribute(in, ATTR_COMMIT_TIME_MS)
                    : 0;


            final int depth = in.getDepth();
            final int depth = in.getDepth();
            BlobAccessMode blobAccessMode = null;
            BlobAccessMode blobAccessMode = null;
@@ -538,7 +568,7 @@ class BlobMetadata {
                Slog.wtf(TAG, "blobAccessMode should be available");
                Slog.wtf(TAG, "blobAccessMode should be available");
                return null;
                return null;
            }
            }
            return new Committer(packageName, uid, blobAccessMode);
            return new Committer(packageName, uid, blobAccessMode, commitTimeMs);
        }
        }
    }
    }


+35 −1
Original line number Original line Diff line number Diff line
@@ -45,8 +45,9 @@ class BlobStoreConfig {
    // Added a string variant of lease description.
    // Added a string variant of lease description.
    public static final int XML_VERSION_ADD_STRING_DESC = 2;
    public static final int XML_VERSION_ADD_STRING_DESC = 2;
    public static final int XML_VERSION_ADD_DESC_RES_NAME = 3;
    public static final int XML_VERSION_ADD_DESC_RES_NAME = 3;
    public static final int XML_VERSION_ADD_COMMIT_TIME = 4;


    public static final int XML_VERSION_CURRENT = XML_VERSION_ADD_DESC_RES_NAME;
    public static final int XML_VERSION_CURRENT = XML_VERSION_ADD_COMMIT_TIME;


    private static final String ROOT_DIR_NAME = "blobstore";
    private static final String ROOT_DIR_NAME = "blobstore";
    private static final String BLOBS_DIR_NAME = "blobs";
    private static final String BLOBS_DIR_NAME = "blobs";
@@ -100,6 +101,18 @@ class BlobStoreConfig {
        public static long LEASE_ACQUISITION_WAIT_DURATION_MS =
        public static long LEASE_ACQUISITION_WAIT_DURATION_MS =
                DEFAULT_LEASE_ACQUISITION_WAIT_DURATION_MS;
                DEFAULT_LEASE_ACQUISITION_WAIT_DURATION_MS;


        /**
         * Denotes the duration from the time a blob is committed that any new commits of the same
         * data blob from the same committer will be treated as if they occurred at the earlier
         * commit time.
         */
        public static final String KEY_COMMIT_COOL_OFF_DURATION_MS =
                "commit_cool_off_duration_ms";
        public static final long DEFAULT_COMMIT_COOL_OFF_DURATION_MS =
                TimeUnit.HOURS.toMillis(48);
        public static long COMMIT_COOL_OFF_DURATION_MS =
                DEFAULT_COMMIT_COOL_OFF_DURATION_MS;

        static void refresh(Properties properties) {
        static void refresh(Properties properties) {
            if (!NAMESPACE_BLOBSTORE.equals(properties.getNamespace())) {
            if (!NAMESPACE_BLOBSTORE.equals(properties.getNamespace())) {
                return;
                return;
@@ -163,6 +176,27 @@ class BlobStoreConfig {
                < System.currentTimeMillis();
                < System.currentTimeMillis();
    }
    }


    /**
     * Returns an adjusted commit time depending on whether commit cool-off period has elapsed.
     *
     * If this is the initial commit or the earlier commit cool-off period has elapsed, then
     * the new commit time is used. Otherwise, the earlier commit time is used.
     */
    public static long getAdjustedCommitTimeMs(long oldCommitTimeMs, long newCommitTimeMs) {
        if (oldCommitTimeMs == 0 || hasCommitCoolOffPeriodElapsed(oldCommitTimeMs)) {
            return newCommitTimeMs;
        }
        return oldCommitTimeMs;
    }

    /**
     * Returns whether the commit cool-off period has elapsed.
     */
    private static boolean hasCommitCoolOffPeriodElapsed(long commitTimeMs) {
        return commitTimeMs + DeviceConfigProperties.COMMIT_COOL_OFF_DURATION_MS
                < System.currentTimeMillis();
    }

    @Nullable
    @Nullable
    public static File prepareBlobFile(long sessionId) {
    public static File prepareBlobFile(long sessionId) {
        final File blobsDir = prepareBlobsDir();
        final File blobsDir = prepareBlobsDir();
+10 −4
Original line number Original line Diff line number Diff line
@@ -31,6 +31,7 @@ import static com.android.server.blob.BlobStoreConfig.LOGV;
import static com.android.server.blob.BlobStoreConfig.SESSION_EXPIRY_TIMEOUT_MILLIS;
import static com.android.server.blob.BlobStoreConfig.SESSION_EXPIRY_TIMEOUT_MILLIS;
import static com.android.server.blob.BlobStoreConfig.TAG;
import static com.android.server.blob.BlobStoreConfig.TAG;
import static com.android.server.blob.BlobStoreConfig.XML_VERSION_CURRENT;
import static com.android.server.blob.BlobStoreConfig.XML_VERSION_CURRENT;
import static com.android.server.blob.BlobStoreConfig.getAdjustedCommitTimeMs;
import static com.android.server.blob.BlobStoreSession.STATE_ABANDONED;
import static com.android.server.blob.BlobStoreSession.STATE_ABANDONED;
import static com.android.server.blob.BlobStoreSession.STATE_COMMITTED;
import static com.android.server.blob.BlobStoreSession.STATE_COMMITTED;
import static com.android.server.blob.BlobStoreSession.STATE_VERIFIED_INVALID;
import static com.android.server.blob.BlobStoreSession.STATE_VERIFIED_INVALID;
@@ -566,13 +567,18 @@ public class BlobStoreManagerService extends SystemService {
                            userId);
                            userId);
                    BlobMetadata blob = userBlobs.get(session.getBlobHandle());
                    BlobMetadata blob = userBlobs.get(session.getBlobHandle());
                    if (blob == null) {
                    if (blob == null) {
                        blob = new BlobMetadata(mContext,
                        blob = new BlobMetadata(mContext, session.getSessionId(),
                                session.getSessionId(), session.getBlobHandle(), userId);
                                session.getBlobHandle(), userId);
                        addBlobForUserLocked(blob, userBlobs);
                        addBlobForUserLocked(blob, userBlobs);
                    }
                    }
                    final Committer existingCommitter = blob.getExistingCommitter(
                            session.getOwnerPackageName(), session.getOwnerUid());
                    final long existingCommitTimeMs =
                            (existingCommitter == null) ? 0 : existingCommitter.getCommitTimeMs();
                    final Committer newCommitter = new Committer(session.getOwnerPackageName(),
                    final Committer newCommitter = new Committer(session.getOwnerPackageName(),
                            session.getOwnerUid(), session.getBlobAccessMode());
                            session.getOwnerUid(), session.getBlobAccessMode(),
                    final Committer existingCommitter = blob.getExistingCommitter(newCommitter);
                            getAdjustedCommitTimeMs(existingCommitTimeMs,
                                    System.currentTimeMillis()));
                    blob.addOrReplaceCommitter(newCommitter);
                    blob.addOrReplaceCommitter(newCommitter);
                    try {
                    try {
                        writeBlobsInfoLocked();
                        writeBlobsInfoLocked();
+6 −0
Original line number Original line Diff line number Diff line
@@ -24,6 +24,7 @@ import android.annotation.Nullable;
import android.content.Context;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.content.res.Resources;
import android.text.format.TimeMigrationUtils;
import android.util.Slog;
import android.util.Slog;


class BlobStoreUtils {
class BlobStoreUtils {
@@ -56,4 +57,9 @@ class BlobStoreUtils {
                ? Resources.ID_NULL
                ? Resources.ID_NULL
                : getDescriptionResourceId(resources, resourceEntryName, packageName);
                : getDescriptionResourceId(resources, resourceEntryName, packageName);
    }
    }

    @NonNull
    static String formatTime(long timeMs) {
        return TimeMigrationUtils.formatMillisWithFixedFormat(timeMs);
    }
}
}
Loading