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

Commit fc6e7a30 authored by Michael Wachenschwanz's avatar Michael Wachenschwanz Committed by Automerger Merge Worker
Browse files

Merge "Add BlobStore atoms" into rvc-dev am: 38da493a

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/11818786

Change-Id: Ie797d997f2c1a44965a07c053a54ae0c092bbf44
parents 6178c4a9 38da493a
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -127,6 +127,14 @@ class BlobAccessMode {
        return false;
    }

    int getAccessType() {
        return mAccessType;
    }

    int getNumWhitelistedPackages() {
        return mWhitelistedPackages.size();
    }

    void dump(IndentingPrintWriter fout) {
        fout.println("accessType: " + DebugUtils.flagsToString(
                BlobAccessMode.class, "ACCESS_TYPE_", mAccessType));
+45 −0
Original line number Diff line number Diff line
@@ -54,6 +54,8 @@ import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;
import android.util.SparseArray;
import android.util.StatsEvent;
import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
@@ -414,6 +416,49 @@ class BlobMetadata {
        return true;
    }

    StatsEvent dumpAsStatsEvent(int atomTag) {
        synchronized (mMetadataLock) {
            ProtoOutputStream proto = new ProtoOutputStream();
            // Write Committer data to proto format
            for (int i = 0, size = mCommitters.size(); i < size; ++i) {
                final Committer committer = mCommitters.valueAt(i);
                final long token = proto.start(
                        BlobStatsEventProto.BlobCommitterListProto.COMMITTER);
                proto.write(BlobStatsEventProto.BlobCommitterProto.UID, committer.uid);
                proto.write(BlobStatsEventProto.BlobCommitterProto.COMMIT_TIMESTAMP_MILLIS,
                        committer.commitTimeMs);
                proto.write(BlobStatsEventProto.BlobCommitterProto.ACCESS_MODE,
                        committer.blobAccessMode.getAccessType());
                proto.write(BlobStatsEventProto.BlobCommitterProto.NUM_WHITELISTED_PACKAGE,
                        committer.blobAccessMode.getNumWhitelistedPackages());
                proto.end(token);
            }
            final byte[] committersBytes = proto.getBytes();

            proto = new ProtoOutputStream();
            // Write Leasee data to proto format
            for (int i = 0, size = mLeasees.size(); i < size; ++i) {
                final Leasee leasee = mLeasees.valueAt(i);
                final long token = proto.start(BlobStatsEventProto.BlobLeaseeListProto.LEASEE);
                proto.write(BlobStatsEventProto.BlobLeaseeProto.UID, leasee.uid);
                proto.write(BlobStatsEventProto.BlobLeaseeProto.LEASE_EXPIRY_TIMESTAMP_MILLIS,
                        leasee.expiryTimeMillis);
                proto.end(token);
            }
            final byte[] leaseesBytes = proto.getBytes();

            // Construct the StatsEvent to represent this Blob
            return StatsEvent.newBuilder()
                    .setAtomId(atomTag)
                    .writeLong(mBlobId)
                    .writeLong(getSize())
                    .writeLong(mBlobHandle.getExpiryTimeMillis())
                    .writeByteArray(committersBytes)
                    .writeByteArray(leaseesBytes)
                    .build();
        }
    }

    void dump(IndentingPrintWriter fout, DumpArgs dumpArgs) {
        fout.println("blobHandle:");
        fout.increaseIndent();
+3 −0
Original line number Diff line number Diff line
@@ -49,6 +49,9 @@ class BlobStoreConfig {

    public static final int XML_VERSION_CURRENT = XML_VERSION_ADD_SESSION_CREATION_TIME;

    public static final long INVALID_BLOB_ID = 0;
    public static final long INVALID_BLOB_SIZE = 0;

    private static final String ROOT_DIR_NAME = "blobstore";
    private static final String BLOBS_DIR_NAME = "blobs";
    private static final String SESSIONS_INDEX_FILE_NAME = "sessions_index.xml";
+86 −1
Original line number Diff line number Diff line
@@ -28,6 +28,8 @@ import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
import static android.os.UserHandle.USER_CURRENT;
import static android.os.UserHandle.USER_NULL;

import static com.android.server.blob.BlobStoreConfig.INVALID_BLOB_ID;
import static com.android.server.blob.BlobStoreConfig.INVALID_BLOB_SIZE;
import static com.android.server.blob.BlobStoreConfig.LOGV;
import static com.android.server.blob.BlobStoreConfig.TAG;
import static com.android.server.blob.BlobStoreConfig.XML_VERSION_CURRENT;
@@ -48,6 +50,7 @@ import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.StatsManager;
import android.app.blob.BlobHandle;
import android.app.blob.BlobInfo;
import android.app.blob.IBlobStoreManager;
@@ -80,6 +83,7 @@ import android.util.ExceptionUtils;
import android.util.LongSparseArray;
import android.util.Slog;
import android.util.SparseArray;
import android.util.StatsEvent;
import android.util.Xml;

import com.android.internal.annotations.GuardedBy;
@@ -88,6 +92,7 @@ import com.android.internal.os.BackgroundThread;
import com.android.internal.util.CollectionUtils;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
@@ -159,6 +164,8 @@ public class BlobStoreManagerService extends SystemService {
            new SessionStateChangeListener();

    private PackageManagerInternal mPackageManagerInternal;
    private StatsManager mStatsManager;
    private StatsPullAtomCallbackImpl mStatsCallbackImpl = new StatsPullAtomCallbackImpl();

    private final Runnable mSaveBlobsInfoRunnable = this::writeBlobsInfo;
    private final Runnable mSaveSessionsRunnable = this::writeBlobSessions;
@@ -192,6 +199,7 @@ public class BlobStoreManagerService extends SystemService {
        LocalServices.addService(BlobStoreManagerInternal.class, new LocalService());

        mPackageManagerInternal = LocalServices.getService(PackageManagerInternal.class);
        mStatsManager = getContext().getSystemService(StatsManager.class);
        registerReceivers();
        LocalServices.getService(StorageStatsManagerInternal.class)
                .registerStorageStatsAugmenter(new BlobStorageStatsAugmenter(), TAG);
@@ -207,6 +215,7 @@ public class BlobStoreManagerService extends SystemService {
                readBlobSessionsLocked(allPackages);
                readBlobsInfoLocked(allPackages);
            }
            registerBlobStorePuller();
        } else if (phase == PHASE_BOOT_COMPLETED) {
            BlobStoreIdleJobService.schedule(mContext);
        }
@@ -219,7 +228,7 @@ public class BlobStoreManagerService extends SystemService {
        long sessionId;
        do {
            sessionId = Math.abs(mRandom.nextLong());
            if (mKnownBlobIds.indexOf(sessionId) < 0 && sessionId != 0) {
            if (mKnownBlobIds.indexOf(sessionId) < 0 && sessionId != INVALID_BLOB_ID) {
                return sessionId;
            }
        } while (n++ < 32);
@@ -376,9 +385,23 @@ public class BlobStoreManagerService extends SystemService {
                    .get(blobHandle);
            if (blobMetadata == null || !blobMetadata.isAccessAllowedForCaller(
                    callingPackage, callingUid)) {
                if (blobMetadata == null) {
                    FrameworkStatsLog.write(FrameworkStatsLog.BLOB_OPENED, callingUid,
                            INVALID_BLOB_ID, INVALID_BLOB_SIZE,
                            FrameworkStatsLog.BLOB_OPENED__RESULT__BLOB_DNE);
                } else {
                    FrameworkStatsLog.write(FrameworkStatsLog.BLOB_OPENED, callingUid,
                            blobMetadata.getBlobId(), blobMetadata.getSize(),
                            FrameworkStatsLog.BLOB_LEASED__RESULT__ACCESS_NOT_ALLOWED);
                }
                throw new SecurityException("Caller not allowed to access " + blobHandle
                        + "; callingUid=" + callingUid + ", callingPackage=" + callingPackage);
            }

            FrameworkStatsLog.write(FrameworkStatsLog.BLOB_OPENED, callingUid,
                    blobMetadata.getBlobId(), blobMetadata.getSize(),
                    FrameworkStatsLog.BLOB_OPENED__RESULT__SUCCESS);

            return blobMetadata.openForRead(callingPackage);
        }
    }
@@ -391,19 +414,41 @@ public class BlobStoreManagerService extends SystemService {
                    .get(blobHandle);
            if (blobMetadata == null || !blobMetadata.isAccessAllowedForCaller(
                    callingPackage, callingUid)) {
                if (blobMetadata == null) {
                    FrameworkStatsLog.write(FrameworkStatsLog.BLOB_LEASED, callingUid,
                            INVALID_BLOB_ID, INVALID_BLOB_SIZE,
                            FrameworkStatsLog.BLOB_LEASED__RESULT__BLOB_DNE);
                } else {
                    FrameworkStatsLog.write(FrameworkStatsLog.BLOB_LEASED, callingUid,
                            blobMetadata.getBlobId(), blobMetadata.getSize(),
                            FrameworkStatsLog.BLOB_LEASED__RESULT__ACCESS_NOT_ALLOWED);
                }
                throw new SecurityException("Caller not allowed to access " + blobHandle
                        + "; callingUid=" + callingUid + ", callingPackage=" + callingPackage);
            }
            if (leaseExpiryTimeMillis != 0 && blobHandle.expiryTimeMillis != 0
                    && leaseExpiryTimeMillis > blobHandle.expiryTimeMillis) {

                FrameworkStatsLog.write(FrameworkStatsLog.BLOB_LEASED, callingUid,
                        blobMetadata.getBlobId(), blobMetadata.getSize(),
                        FrameworkStatsLog.BLOB_LEASED__RESULT__LEASE_EXPIRY_INVALID);
                throw new IllegalArgumentException(
                        "Lease expiry cannot be later than blobs expiry time");
            }
            if (blobMetadata.getSize()
                    > getRemainingLeaseQuotaBytesInternal(callingUid, callingPackage)) {

                FrameworkStatsLog.write(FrameworkStatsLog.BLOB_LEASED, callingUid,
                        blobMetadata.getBlobId(), blobMetadata.getSize(),
                        FrameworkStatsLog.BLOB_LEASED__RESULT__DATA_SIZE_LIMIT_EXCEEDED);
                throw new LimitExceededException("Total amount of data with an active lease"
                        + " is exceeding the max limit");
            }

            FrameworkStatsLog.write(FrameworkStatsLog.BLOB_LEASED, callingUid,
                    blobMetadata.getBlobId(), blobMetadata.getSize(),
                    FrameworkStatsLog.BLOB_LEASED__RESULT__SUCCESS);

            blobMetadata.addOrReplaceLeasee(callingPackage, callingUid,
                    descriptionResId, description, leaseExpiryTimeMillis);
            if (LOGV) {
@@ -587,6 +632,9 @@ public class BlobStoreManagerService extends SystemService {
                    blob.addOrReplaceCommitter(newCommitter);
                    try {
                        writeBlobsInfoLocked();
                        FrameworkStatsLog.write(FrameworkStatsLog.BLOB_COMMITTED,
                                session.getOwnerUid(), blob.getBlobId(), blob.getSize(),
                                FrameworkStatsLog.BLOB_COMMITTED__RESULT__SUCCESS);
                        session.sendCommitCallbackResult(COMMIT_RESULT_SUCCESS);
                    } catch (Exception e) {
                        if (existingCommitter == null) {
@@ -595,6 +643,9 @@ public class BlobStoreManagerService extends SystemService {
                            blob.addOrReplaceCommitter(existingCommitter);
                        }
                        Slog.d(TAG, "Error committing the blob", e);
                        FrameworkStatsLog.write(FrameworkStatsLog.BLOB_COMMITTED,
                                session.getOwnerUid(), blob.getBlobId(), blob.getSize(),
                                FrameworkStatsLog.BLOB_COMMITTED__RESULT__ERROR_DURING_COMMIT);
                        session.sendCommitCallbackResult(COMMIT_RESULT_ERROR);
                    }
                    getUserSessionsLocked(UserHandle.getUserId(session.getOwnerUid()))
@@ -1684,6 +1735,40 @@ public class BlobStoreManagerService extends SystemService {
        }
    }

    private void registerBlobStorePuller() {
        mStatsManager.setPullAtomCallback(
                FrameworkStatsLog.BLOB_INFO,
                null, // use default PullAtomMetadata values
                BackgroundThread.getExecutor(),
                mStatsCallbackImpl
        );
    }

    private class StatsPullAtomCallbackImpl implements StatsManager.StatsPullAtomCallback {
        @Override
        public int onPullAtom(int atomTag, List<StatsEvent> data) {
            switch (atomTag) {
                case FrameworkStatsLog.BLOB_INFO:
                    return pullBlobData(atomTag, data);
                default:
                    throw new UnsupportedOperationException("Unknown tagId=" + atomTag);
            }
        }
    }

    private int pullBlobData(int atomTag, List<StatsEvent> data) {
        synchronized (mBlobsLock) {
            for (int i = 0, userCount = mBlobsMap.size(); i < userCount; ++i) {
                final ArrayMap<BlobHandle, BlobMetadata> userBlobs = mBlobsMap.valueAt(i);
                for (int j = 0, blobsCount = userBlobs.size(); j < blobsCount; ++j) {
                    final BlobMetadata blob = userBlobs.valueAt(j);
                    data.add(blob.dumpAsStatsEvent(atomTag));
                }
            }
        }
        return StatsManager.PULL_SUCCESS;
    }

    private class LocalService extends BlobStoreManagerInternal {
        @Override
        public void onIdleMaintenance() {
+4 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ import android.util.Slog;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
@@ -450,6 +451,9 @@ class BlobStoreSession extends IBlobStoreSession.Stub {
                        + ") didn't match the given BlobHandle.digest ("
                        + BlobHandle.safeDigest(mBlobHandle.digest) + ")");
                mState = STATE_VERIFIED_INVALID;

                FrameworkStatsLog.write(FrameworkStatsLog.BLOB_COMMITTED, getOwnerUid(), mSessionId,
                        getSize(), FrameworkStatsLog.BLOB_COMMITTED__RESULT__DIGEST_MISMATCH);
                sendCommitCallbackResult(COMMIT_RESULT_ERROR);
            }
            mListener.onStateChanged(this);
Loading