diff options
author | Michael Wachenschwanz <mwachens@google.com> | 2020-06-13 09:17:54 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-06-13 09:17:54 +0000 |
commit | 38da493ae4d0d02fba3e5a474776a29cf2afd82b (patch) | |
tree | abadc8ee218fd1c87a865b60c86c1e81468b6e29 | |
parent | 5c4b92a1b9600b93ea06afe8a07f778a04f7cf25 (diff) | |
parent | 1a7f7ab4aaea394809b617b532588b9d010f3115 (diff) |
Merge "Add BlobStore atoms" into rvc-dev
7 files changed, 378 insertions, 3 deletions
diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java b/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java index 96bb5ef4e45e..ba0fab6b4bc5 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobAccessMode.java @@ -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)); diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java index 03573d966cd0..7e8c90632fd9 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java @@ -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(); diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java index 656726622cfd..08ee24460722 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java @@ -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"; diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java index 68c4bb675907..850a1d25339c 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java @@ -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() { diff --git a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java index a10b0b324f83..51cf805aa000 100644 --- a/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java +++ b/apex/blobstore/service/java/com/android/server/blob/BlobStoreSession.java @@ -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); diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto index e998711ef3c0..278278fc18c4 100644 --- a/cmds/statsd/src/atoms.proto +++ b/cmds/statsd/src/atoms.proto @@ -478,13 +478,16 @@ message Atom { 296; MediametricsAudioDeviceConnectionReported mediametrics_audiodeviceconnection_reported = 297; + BlobCommitted blob_committed = 298 [(module) = "framework"]; + BlobLeased blob_leased = 299 [(module) = "framework"]; + BlobOpened blob_opened = 300 [(module) = "framework"]; // StatsdStats tracks platform atoms with ids upto 500. // Update StatsdStats::kMaxPushedAtomId when atom ids here approach that value. } // Pulled events will start at field 10000. - // Next: 10081 + // Next: 10084 oneof pulled { WifiBytesTransfer wifi_bytes_transfer = 10000 [(module) = "framework"]; WifiBytesTransferByFgBg wifi_bytes_transfer_by_fg_bg = 10001 [(module) = "framework"]; @@ -575,7 +578,7 @@ message Atom { SimSlotState sim_slot_state = 10078 [(module) = "telephony"]; SupportedRadioAccessFamily supported_radio_access_family = 10079 [(module) = "telephony"]; SettingSnapshot setting_snapshot = 10080 [(module) = "framework"]; - //10081 free for use + BlobInfo blob_info = 10081 [(module) = "framework"]; DataUsageBytesTransfer data_usage_bytes_transfer = 10082 [(module) = "framework"]; BytesTransferByTagAndMetered bytes_transfer_by_tag_and_metered = 10083 [(module) = "framework"]; @@ -4905,6 +4908,94 @@ message SnapshotMergeReported { optional int64 cow_file_size_bytes = 5; } +/** + * Event representing when BlobStoreManager.Session#commit() is called + * + * Logged from: + * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java + */ +message BlobCommitted { + // Uid of the Blob committer + optional int32 uid = 1 [(is_uid) = true]; + + // Id of the Blob committed + optional int64 blob_id = 2; + + // Size of the Blob + optional int64 size = 3; + + enum Result { + UNKNOWN = 0; + // Commit Succeeded + SUCCESS = 1; + // Commit Failed: Error occurred during commit + ERROR_DURING_COMMIT = 2; + // Commit Failed: Digest of the data did not match Blob digest + DIGEST_MISMATCH = 3; + } + optional Result result = 4; +} + +/** + * Event representing when BlobStoreManager#acquireLease() is called + * + * Logged from: + * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java + */ +message BlobLeased{ + // Uid of the Blob leasee + optional int32 uid = 1 [(is_uid) = true]; + + // Id of the Blob leased or 0 if the Blob does not exist + optional int64 blob_id = 2; + + // Size of the Blob or 0 if the Blob does not exist + optional int64 size = 3; + + enum Result { + UNKNOWN = 0; + // Lease Succeeded + SUCCESS = 1; + // Lease Failed: Blob does not exist + BLOB_DNE = 2; + // Lease Failed: Leasee does not have access to the Blob + ACCESS_NOT_ALLOWED = 3; + // Lease Failed: Leasee requested an invalid expiry duration + LEASE_EXPIRY_INVALID = 4; + // Lease Failed: Leasee has exceeded the total data lease limit + DATA_SIZE_LIMIT_EXCEEDED = 5; + } + optional Result result = 4; +} + +/** + * Event representing when BlobStoreManager#openBlob() is called + * + * Logged from: + * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java + */ +message BlobOpened{ + // Uid of the Blob opener + optional int32 uid = 1 [(is_uid) = true]; + + // Id of the Blob opened or 0 if the Blob does not exist + optional int64 blob_id = 2; + + // Size of the Blob or 0 if the Blob does not exist + optional int64 size = 3; + + enum Result { + UNKNOWN = 0; + // Open Succeeded + SUCCESS = 1; + // Open Failed: Blob does not exist + BLOB_DNE = 2; + // Open Failed: Opener does not have access to the Blob + ACCESS_NOT_ALLOWED = 3; + } + optional Result result = 4; +} + ////////////////////////////////////////////////////////////////////// // Pulled atoms below this line // ////////////////////////////////////////////////////////////////////// @@ -10791,3 +10882,72 @@ message MediametricsAudioDeviceConnectionReported { // Number of connections if aggregated statistics, otherwise 1. optional int32 connection_count = 6; } + +// Blob Committer stats +// Keep in sync between: +// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto +// frameworks/base/cmds/statsd/src/atoms.proto +message BlobCommitterProto { + // Committer app's uid + optional int32 uid = 1 [(is_uid) = true]; + + // Unix epoch timestamp of the commit in milliseconds + optional int64 commit_timestamp_millis = 2; + + // Flags of what access types the committer has set for the Blob + optional int32 access_mode = 3; + + // Number of packages that have been whitelisted for ACCESS_TYPE_WHITELIST + optional int32 num_whitelisted_package = 4; +} + +// Blob Leasee stats +// Keep in sync between: +// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto +// frameworks/base/cmds/statsd/src/atoms.proto +message BlobLeaseeProto { + // Leasee app's uid + optional int32 uid = 1 [(is_uid) = true]; + + // Unix epoch timestamp for lease expiration in milliseconds + optional int64 lease_expiry_timestamp_millis = 2; +} + +// List of Blob Committers +// Keep in sync between: +// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto +// frameworks/base/cmds/statsd/src/atoms.proto +message BlobCommitterListProto { + repeated BlobCommitterProto committer = 1; +} + +// List of Blob Leasees +// Keep in sync between: +// frameworks/base/core/proto/android/server/blobstoremanagerservice.proto +// frameworks/base/cmds/statsd/src/atoms.proto +message BlobLeaseeListProto { + repeated BlobLeaseeProto leasee = 1; +} + +/** + * Logs the current state of a Blob committed with BlobStoreManager + * + * Pulled from: + * frameworks/base/apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java + */ +message BlobInfo { + // Id of the Blob + optional int64 blob_id = 1; + + // Size of the Blob data + optional int64 size = 2; + + // Unix epoch timestamp of the Blob's expiration in milliseconds + optional int64 expiry_timestamp_millis = 3; + + // List of committers of this Blob + optional BlobCommitterListProto committers = 4; + + // List of leasees of this Blob + optional BlobLeaseeListProto leasees = 5; +} diff --git a/core/proto/android/server/blobstoremanagerservice.proto b/core/proto/android/server/blobstoremanagerservice.proto new file mode 100644 index 000000000000..583b646eb9c7 --- /dev/null +++ b/core/proto/android/server/blobstoremanagerservice.proto @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2020 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +syntax = "proto2"; +package com.android.server.blob; + +option java_multiple_files = true; + +// The nested messages are used for statsd logging and should be kept in sync with the messages +// of the same name in frameworks/base/cmds/statsd/src/atoms.proto +message BlobStatsEventProto { + // Blob Committer stats + // Keep in sync between: + // frameworks/base/core/proto/android/server/blobstoremanagerservice.proto + // frameworks/base/cmds/statsd/src/atoms.proto + message BlobCommitterProto { + // Committer app's uid + optional int32 uid = 1; + + // Unix epoch timestamp of the commit in milliseconds + optional int64 commit_timestamp_millis = 2; + + // Flags of what access types the committer has set for the Blob + optional int32 access_mode = 3; + + // Number of packages that have been whitelisted for ACCESS_TYPE_WHITELIST + optional int32 num_whitelisted_package = 4; + } + + // Blob Leasee stats + // Keep in sync between: + // frameworks/base/core/proto/android/server/blobstoremanagerservice.proto + // frameworks/base/cmds/statsd/src/atoms.proto + message BlobLeaseeProto { + // Leasee app's uid + optional int32 uid = 1; + + // Unix epoch timestamp for lease expiration in milliseconds + optional int64 lease_expiry_timestamp_millis = 2; + } + + // List of Blob Committers + // Keep in sync between: + // frameworks/base/core/proto/android/server/blobstoremanagerservice.proto + // frameworks/base/cmds/statsd/src/atoms.proto + message BlobCommitterListProto { + repeated BlobCommitterProto committer = 1; + } + + // List of Blob Leasees + // Keep in sync between: + // frameworks/base/core/proto/android/server/blobstoremanagerservice.proto + // frameworks/base/cmds/statsd/src/atoms.proto + message BlobLeaseeListProto { + repeated BlobLeaseeProto leasee = 1; + } +}
\ No newline at end of file |