Loading apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -242,7 +242,7 @@ class BlobMetadata { return hasOtherLeasees(null, uid); return hasOtherLeasees(null, uid); } } private boolean isALeasee(@Nullable String packageName, int uid) { boolean isALeasee(@Nullable String packageName, int uid) { synchronized (mMetadataLock) { synchronized (mMetadataLock) { // Check if the package is a leasee of the data blob. // Check if the package is a leasee of the data blob. for (int i = 0, size = mLeasees.size(); i < size; ++i) { for (int i = 0, size = mLeasees.size(); i < size; ++i) { Loading apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java +98 −0 Original line number Original line Diff line number Diff line Loading @@ -15,12 +15,23 @@ */ */ package com.android.server.blob; package com.android.server.blob; import static android.provider.DeviceConfig.NAMESPACE_BLOBSTORE; import static android.text.format.Formatter.FLAG_IEC_UNITS; import static android.text.format.Formatter.formatFileSize; import static android.util.TimeUtils.formatDuration; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.content.Context; import android.os.Environment; import android.os.Environment; import android.provider.DeviceConfig; import android.provider.DeviceConfig.Properties; import android.util.DataUnit; import android.util.Log; import android.util.Log; import android.util.Slog; import android.util.Slog; import com.android.internal.util.IndentingPrintWriter; import java.io.File; import java.io.File; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit; Loading Loading @@ -55,6 +66,76 @@ class BlobStoreConfig { */ */ public static final long SESSION_EXPIRY_TIMEOUT_MILLIS = TimeUnit.DAYS.toMillis(7); public static final long SESSION_EXPIRY_TIMEOUT_MILLIS = TimeUnit.DAYS.toMillis(7); public static class DeviceConfigProperties { /** * Denotes how low the limit for the amount of data, that an app will be allowed to acquire * a lease on, can be. */ public static final String KEY_TOTAL_BYTES_PER_APP_LIMIT_FLOOR = "total_bytes_per_app_limit_floor"; public static final long DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FLOOR = DataUnit.MEBIBYTES.toBytes(300); // 300 MiB public static long TOTAL_BYTES_PER_APP_LIMIT_FLOOR = DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FLOOR; /** * Denotes the maximum amount of data an app can acquire a lease on, in terms of fraction * of total disk space. */ public static final String KEY_TOTAL_BYTES_PER_APP_LIMIT_FRACTION = "total_bytes_per_app_limit_fraction"; public static final float DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FRACTION = 0.01f; public static float TOTAL_BYTES_PER_APP_LIMIT_FRACTION = DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FRACTION; static void refresh(Properties properties) { if (!NAMESPACE_BLOBSTORE.equals(properties.getNamespace())) { return; } properties.getKeyset().forEach(key -> { switch (key) { case KEY_TOTAL_BYTES_PER_APP_LIMIT_FLOOR: TOTAL_BYTES_PER_APP_LIMIT_FLOOR = properties.getLong(key, DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FLOOR); break; case KEY_TOTAL_BYTES_PER_APP_LIMIT_FRACTION: TOTAL_BYTES_PER_APP_LIMIT_FRACTION = properties.getFloat(key, DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FRACTION); break; default: Slog.wtf(TAG, "Unknown key in device config properties: " + key); } }); } static void dump(IndentingPrintWriter fout, Context context) { final String dumpFormat = "%s: [cur: %s, def: %s]"; fout.println(String.format(dumpFormat, KEY_TOTAL_BYTES_PER_APP_LIMIT_FLOOR, formatFileSize(context, TOTAL_BYTES_PER_APP_LIMIT_FLOOR, FLAG_IEC_UNITS), formatFileSize(context, DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FLOOR, FLAG_IEC_UNITS))); fout.println(String.format(dumpFormat, KEY_TOTAL_BYTES_PER_APP_LIMIT_FRACTION, TOTAL_BYTES_PER_APP_LIMIT_FRACTION, DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FRACTION)); } } public static void initialize(Context context) { DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_BLOBSTORE, context.getMainExecutor(), properties -> DeviceConfigProperties.refresh(properties)); DeviceConfigProperties.refresh(DeviceConfig.getProperties(NAMESPACE_BLOBSTORE)); } /** * Returns the maximum amount of data that an app can acquire a lease on. */ public static long getAppDataBytesLimit() { final long totalBytesLimit = (long) (Environment.getDataSystemDirectory().getTotalSpace() * DeviceConfigProperties.TOTAL_BYTES_PER_APP_LIMIT_FRACTION); return Math.max(DeviceConfigProperties.TOTAL_BYTES_PER_APP_LIMIT_FLOOR, totalBytesLimit); } @Nullable @Nullable public static File prepareBlobFile(long sessionId) { public static File prepareBlobFile(long sessionId) { final File blobsDir = prepareBlobsDir(); final File blobsDir = prepareBlobsDir(); Loading Loading @@ -123,4 +204,21 @@ class BlobStoreConfig { public static File getBlobStoreRootDir() { public static File getBlobStoreRootDir() { return new File(Environment.getDataSystemDirectory(), ROOT_DIR_NAME); return new File(Environment.getDataSystemDirectory(), ROOT_DIR_NAME); } } public static void dump(IndentingPrintWriter fout, Context context) { fout.println("XML current version: " + XML_VERSION_CURRENT); fout.println("Idle job ID: " + IDLE_JOB_ID); fout.println("Idle job period: " + formatDuration(IDLE_JOB_PERIOD_MILLIS)); fout.println("Session expiry timeout: " + formatDuration(SESSION_EXPIRY_TIMEOUT_MILLIS)); fout.println("Total bytes per app limit: " + formatFileSize(context, getAppDataBytesLimit(), FLAG_IEC_UNITS)); fout.println("Device config properties:"); fout.increaseIndent(); DeviceConfigProperties.dump(fout, context); fout.decreaseIndent(); } } } apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java +70 −14 Original line number Original line Diff line number Diff line Loading @@ -188,7 +188,9 @@ public class BlobStoreManagerService extends SystemService { @Override @Override public void onBootPhase(int phase) { public void onBootPhase(int phase) { if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { if (phase == PHASE_ACTIVITY_MANAGER_READY) { BlobStoreConfig.initialize(mContext); } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { synchronized (mBlobsLock) { synchronized (mBlobsLock) { final SparseArray<SparseArray<String>> allPackages = getAllPackages(); final SparseArray<SparseArray<String>> allPackages = getAllPackages(); readBlobSessionsLocked(allPackages); readBlobSessionsLocked(allPackages); Loading Loading @@ -381,6 +383,11 @@ public class BlobStoreManagerService extends SystemService { throw new IllegalArgumentException( throw new IllegalArgumentException( "Lease expiry cannot be later than blobs expiry time"); "Lease expiry cannot be later than blobs expiry time"); } } if (getTotalUsageBytesLocked(callingUid, callingPackage) + blobMetadata.getSize() > BlobStoreConfig.getAppDataBytesLimit()) { throw new IllegalStateException("Total amount of data with an active lease" + " is exceeding the max limit"); } blobMetadata.addLeasee(callingPackage, callingUid, blobMetadata.addLeasee(callingPackage, callingUid, descriptionResId, description, leaseExpiryTimeMillis); descriptionResId, description, leaseExpiryTimeMillis); if (LOGV) { if (LOGV) { Loading @@ -391,6 +398,18 @@ public class BlobStoreManagerService extends SystemService { } } } } @VisibleForTesting @GuardedBy("mBlobsLock") long getTotalUsageBytesLocked(int callingUid, String callingPackage) { final AtomicLong totalBytes = new AtomicLong(0); forEachBlobInUser((blobMetadata) -> { if (blobMetadata.isALeasee(callingPackage, callingUid)) { totalBytes.getAndAdd(blobMetadata.getSize()); } }, UserHandle.getUserId(callingUid)); return totalBytes.get(); } private void releaseLeaseInternal(BlobHandle blobHandle, int callingUid, private void releaseLeaseInternal(BlobHandle blobHandle, int callingUid, String callingPackage) { String callingPackage) { synchronized (mBlobsLock) { synchronized (mBlobsLock) { Loading Loading @@ -1236,8 +1255,10 @@ public class BlobStoreManagerService extends SystemService { } } synchronized (mBlobsLock) { synchronized (mBlobsLock) { if (dumpArgs.shouldDumpAllSections()) { fout.println("mCurrentMaxSessionId: " + mCurrentMaxSessionId); fout.println("mCurrentMaxSessionId: " + mCurrentMaxSessionId); fout.println(); fout.println(); } if (dumpArgs.shouldDumpSessions()) { if (dumpArgs.shouldDumpSessions()) { dumpSessionsLocked(fout, dumpArgs); dumpSessionsLocked(fout, dumpArgs); Loading @@ -1248,6 +1269,14 @@ public class BlobStoreManagerService extends SystemService { fout.println(); fout.println(); } } } } if (dumpArgs.shouldDumpConfig()) { fout.println("BlobStore config:"); fout.increaseIndent(); BlobStoreConfig.dump(fout, mContext); fout.decreaseIndent(); fout.println(); } } } @Override @Override Loading @@ -1260,14 +1289,16 @@ public class BlobStoreManagerService extends SystemService { } } static final class DumpArgs { static final class DumpArgs { private static final int FLAG_DUMP_SESSIONS = 1 << 0; private static final int FLAG_DUMP_BLOBS = 1 << 1; private static final int FLAG_DUMP_CONFIG = 1 << 2; private int mSelectedSectionFlags; private boolean mDumpFull; private boolean mDumpFull; private final ArrayList<String> mDumpPackages = new ArrayList<>(); private final ArrayList<String> mDumpPackages = new ArrayList<>(); private final ArrayList<Integer> mDumpUids = new ArrayList<>(); private final ArrayList<Integer> mDumpUids = new ArrayList<>(); private final ArrayList<Integer> mDumpUserIds = new ArrayList<>(); private final ArrayList<Integer> mDumpUserIds = new ArrayList<>(); private final ArrayList<Long> mDumpBlobIds = new ArrayList<>(); private final ArrayList<Long> mDumpBlobIds = new ArrayList<>(); private boolean mDumpOnlySelectedSections; private boolean mDumpSessions; private boolean mDumpBlobs; private boolean mDumpHelp; private boolean mDumpHelp; public boolean shouldDumpSession(String packageName, int uid, long blobId) { public boolean shouldDumpSession(String packageName, int uid, long blobId) { Loading @@ -1286,18 +1317,41 @@ public class BlobStoreManagerService extends SystemService { return true; return true; } } public boolean shouldDumpAllSections() { return mSelectedSectionFlags == 0; } public void allowDumpSessions() { mSelectedSectionFlags |= FLAG_DUMP_SESSIONS; } public boolean shouldDumpSessions() { public boolean shouldDumpSessions() { if (!mDumpOnlySelectedSections) { if (shouldDumpAllSections()) { return true; return true; } } return mDumpSessions; return (mSelectedSectionFlags & FLAG_DUMP_SESSIONS) != 0; } public void allowDumpBlobs() { mSelectedSectionFlags |= FLAG_DUMP_BLOBS; } } public boolean shouldDumpBlobs() { public boolean shouldDumpBlobs() { if (!mDumpOnlySelectedSections) { if (shouldDumpAllSections()) { return true; } return (mSelectedSectionFlags & FLAG_DUMP_BLOBS) != 0; } public void allowDumpConfig() { mSelectedSectionFlags |= FLAG_DUMP_CONFIG; } public boolean shouldDumpConfig() { if (shouldDumpAllSections()) { return true; return true; } } return mDumpBlobs; return (mSelectedSectionFlags & FLAG_DUMP_CONFIG) != 0; } } public boolean shouldDumpBlob(long blobId) { public boolean shouldDumpBlob(long blobId) { Loading Loading @@ -1334,11 +1388,11 @@ public class BlobStoreManagerService extends SystemService { dumpArgs.mDumpFull = true; dumpArgs.mDumpFull = true; } } } else if ("--sessions".equals(opt)) { } else if ("--sessions".equals(opt)) { dumpArgs.mDumpOnlySelectedSections = true; dumpArgs.allowDumpSessions(); dumpArgs.mDumpSessions = true; } else if ("--blobs".equals(opt)) { } else if ("--blobs".equals(opt)) { dumpArgs.mDumpOnlySelectedSections = true; dumpArgs.allowDumpBlobs(); dumpArgs.mDumpBlobs = true; } else if ("--config".equals(opt)) { dumpArgs.allowDumpConfig(); } else if ("--package".equals(opt) || "-p".equals(opt)) { } else if ("--package".equals(opt) || "-p".equals(opt)) { dumpArgs.mDumpPackages.add(getStringArgRequired(args, ++i, "packageName")); dumpArgs.mDumpPackages.add(getStringArgRequired(args, ++i, "packageName")); } else if ("--uid".equals(opt) || "-u".equals(opt)) { } else if ("--uid".equals(opt) || "-u".equals(opt)) { Loading Loading @@ -1397,6 +1451,8 @@ public class BlobStoreManagerService extends SystemService { printWithIndent(pw, "Dump only the sessions info"); printWithIndent(pw, "Dump only the sessions info"); pw.println("--blobs"); pw.println("--blobs"); printWithIndent(pw, "Dump only the committed blobs info"); printWithIndent(pw, "Dump only the committed blobs info"); pw.println("--config"); printWithIndent(pw, "Dump only the config values"); pw.println("--package | -p [package-name]"); pw.println("--package | -p [package-name]"); printWithIndent(pw, "Dump blobs info associated with the given package"); printWithIndent(pw, "Dump blobs info associated with the given package"); pw.println("--uid | -u [uid]"); pw.println("--uid | -u [uid]"); Loading api/system-current.txt +1 −0 Original line number Original line Diff line number Diff line Loading @@ -9131,6 +9131,7 @@ package android.provider { field public static final String NAMESPACE_ATTENTION_MANAGER_SERVICE = "attention_manager_service"; field public static final String NAMESPACE_ATTENTION_MANAGER_SERVICE = "attention_manager_service"; field public static final String NAMESPACE_AUTOFILL = "autofill"; field public static final String NAMESPACE_AUTOFILL = "autofill"; field public static final String NAMESPACE_BIOMETRICS = "biometrics"; field public static final String NAMESPACE_BIOMETRICS = "biometrics"; field public static final String NAMESPACE_BLOBSTORE = "blobstore"; field public static final String NAMESPACE_CONNECTIVITY = "connectivity"; field public static final String NAMESPACE_CONNECTIVITY = "connectivity"; field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture"; field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture"; field @Deprecated public static final String NAMESPACE_DEX_BOOT = "dex_boot"; field @Deprecated public static final String NAMESPACE_DEX_BOOT = "dex_boot"; core/java/android/provider/DeviceConfig.java +8 −0 Original line number Original line Diff line number Diff line Loading @@ -110,6 +110,14 @@ public final class DeviceConfig { @TestApi @TestApi public static final String NAMESPACE_AUTOFILL = "autofill"; public static final String NAMESPACE_AUTOFILL = "autofill"; /** * Namespace for blobstore feature that allows apps to share data blobs. * * @hide */ @SystemApi public static final String NAMESPACE_BLOBSTORE = "blobstore"; /** /** * Namespace for all networking connectivity related features. * Namespace for all networking connectivity related features. * * Loading Loading
apex/blobstore/service/java/com/android/server/blob/BlobMetadata.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -242,7 +242,7 @@ class BlobMetadata { return hasOtherLeasees(null, uid); return hasOtherLeasees(null, uid); } } private boolean isALeasee(@Nullable String packageName, int uid) { boolean isALeasee(@Nullable String packageName, int uid) { synchronized (mMetadataLock) { synchronized (mMetadataLock) { // Check if the package is a leasee of the data blob. // Check if the package is a leasee of the data blob. for (int i = 0, size = mLeasees.size(); i < size; ++i) { for (int i = 0, size = mLeasees.size(); i < size; ++i) { Loading
apex/blobstore/service/java/com/android/server/blob/BlobStoreConfig.java +98 −0 Original line number Original line Diff line number Diff line Loading @@ -15,12 +15,23 @@ */ */ package com.android.server.blob; package com.android.server.blob; import static android.provider.DeviceConfig.NAMESPACE_BLOBSTORE; import static android.text.format.Formatter.FLAG_IEC_UNITS; import static android.text.format.Formatter.formatFileSize; import static android.util.TimeUtils.formatDuration; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.content.Context; import android.os.Environment; import android.os.Environment; import android.provider.DeviceConfig; import android.provider.DeviceConfig.Properties; import android.util.DataUnit; import android.util.Log; import android.util.Log; import android.util.Slog; import android.util.Slog; import com.android.internal.util.IndentingPrintWriter; import java.io.File; import java.io.File; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit; Loading Loading @@ -55,6 +66,76 @@ class BlobStoreConfig { */ */ public static final long SESSION_EXPIRY_TIMEOUT_MILLIS = TimeUnit.DAYS.toMillis(7); public static final long SESSION_EXPIRY_TIMEOUT_MILLIS = TimeUnit.DAYS.toMillis(7); public static class DeviceConfigProperties { /** * Denotes how low the limit for the amount of data, that an app will be allowed to acquire * a lease on, can be. */ public static final String KEY_TOTAL_BYTES_PER_APP_LIMIT_FLOOR = "total_bytes_per_app_limit_floor"; public static final long DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FLOOR = DataUnit.MEBIBYTES.toBytes(300); // 300 MiB public static long TOTAL_BYTES_PER_APP_LIMIT_FLOOR = DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FLOOR; /** * Denotes the maximum amount of data an app can acquire a lease on, in terms of fraction * of total disk space. */ public static final String KEY_TOTAL_BYTES_PER_APP_LIMIT_FRACTION = "total_bytes_per_app_limit_fraction"; public static final float DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FRACTION = 0.01f; public static float TOTAL_BYTES_PER_APP_LIMIT_FRACTION = DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FRACTION; static void refresh(Properties properties) { if (!NAMESPACE_BLOBSTORE.equals(properties.getNamespace())) { return; } properties.getKeyset().forEach(key -> { switch (key) { case KEY_TOTAL_BYTES_PER_APP_LIMIT_FLOOR: TOTAL_BYTES_PER_APP_LIMIT_FLOOR = properties.getLong(key, DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FLOOR); break; case KEY_TOTAL_BYTES_PER_APP_LIMIT_FRACTION: TOTAL_BYTES_PER_APP_LIMIT_FRACTION = properties.getFloat(key, DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FRACTION); break; default: Slog.wtf(TAG, "Unknown key in device config properties: " + key); } }); } static void dump(IndentingPrintWriter fout, Context context) { final String dumpFormat = "%s: [cur: %s, def: %s]"; fout.println(String.format(dumpFormat, KEY_TOTAL_BYTES_PER_APP_LIMIT_FLOOR, formatFileSize(context, TOTAL_BYTES_PER_APP_LIMIT_FLOOR, FLAG_IEC_UNITS), formatFileSize(context, DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FLOOR, FLAG_IEC_UNITS))); fout.println(String.format(dumpFormat, KEY_TOTAL_BYTES_PER_APP_LIMIT_FRACTION, TOTAL_BYTES_PER_APP_LIMIT_FRACTION, DEFAULT_TOTAL_BYTES_PER_APP_LIMIT_FRACTION)); } } public static void initialize(Context context) { DeviceConfig.addOnPropertiesChangedListener(NAMESPACE_BLOBSTORE, context.getMainExecutor(), properties -> DeviceConfigProperties.refresh(properties)); DeviceConfigProperties.refresh(DeviceConfig.getProperties(NAMESPACE_BLOBSTORE)); } /** * Returns the maximum amount of data that an app can acquire a lease on. */ public static long getAppDataBytesLimit() { final long totalBytesLimit = (long) (Environment.getDataSystemDirectory().getTotalSpace() * DeviceConfigProperties.TOTAL_BYTES_PER_APP_LIMIT_FRACTION); return Math.max(DeviceConfigProperties.TOTAL_BYTES_PER_APP_LIMIT_FLOOR, totalBytesLimit); } @Nullable @Nullable public static File prepareBlobFile(long sessionId) { public static File prepareBlobFile(long sessionId) { final File blobsDir = prepareBlobsDir(); final File blobsDir = prepareBlobsDir(); Loading Loading @@ -123,4 +204,21 @@ class BlobStoreConfig { public static File getBlobStoreRootDir() { public static File getBlobStoreRootDir() { return new File(Environment.getDataSystemDirectory(), ROOT_DIR_NAME); return new File(Environment.getDataSystemDirectory(), ROOT_DIR_NAME); } } public static void dump(IndentingPrintWriter fout, Context context) { fout.println("XML current version: " + XML_VERSION_CURRENT); fout.println("Idle job ID: " + IDLE_JOB_ID); fout.println("Idle job period: " + formatDuration(IDLE_JOB_PERIOD_MILLIS)); fout.println("Session expiry timeout: " + formatDuration(SESSION_EXPIRY_TIMEOUT_MILLIS)); fout.println("Total bytes per app limit: " + formatFileSize(context, getAppDataBytesLimit(), FLAG_IEC_UNITS)); fout.println("Device config properties:"); fout.increaseIndent(); DeviceConfigProperties.dump(fout, context); fout.decreaseIndent(); } } }
apex/blobstore/service/java/com/android/server/blob/BlobStoreManagerService.java +70 −14 Original line number Original line Diff line number Diff line Loading @@ -188,7 +188,9 @@ public class BlobStoreManagerService extends SystemService { @Override @Override public void onBootPhase(int phase) { public void onBootPhase(int phase) { if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { if (phase == PHASE_ACTIVITY_MANAGER_READY) { BlobStoreConfig.initialize(mContext); } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { synchronized (mBlobsLock) { synchronized (mBlobsLock) { final SparseArray<SparseArray<String>> allPackages = getAllPackages(); final SparseArray<SparseArray<String>> allPackages = getAllPackages(); readBlobSessionsLocked(allPackages); readBlobSessionsLocked(allPackages); Loading Loading @@ -381,6 +383,11 @@ public class BlobStoreManagerService extends SystemService { throw new IllegalArgumentException( throw new IllegalArgumentException( "Lease expiry cannot be later than blobs expiry time"); "Lease expiry cannot be later than blobs expiry time"); } } if (getTotalUsageBytesLocked(callingUid, callingPackage) + blobMetadata.getSize() > BlobStoreConfig.getAppDataBytesLimit()) { throw new IllegalStateException("Total amount of data with an active lease" + " is exceeding the max limit"); } blobMetadata.addLeasee(callingPackage, callingUid, blobMetadata.addLeasee(callingPackage, callingUid, descriptionResId, description, leaseExpiryTimeMillis); descriptionResId, description, leaseExpiryTimeMillis); if (LOGV) { if (LOGV) { Loading @@ -391,6 +398,18 @@ public class BlobStoreManagerService extends SystemService { } } } } @VisibleForTesting @GuardedBy("mBlobsLock") long getTotalUsageBytesLocked(int callingUid, String callingPackage) { final AtomicLong totalBytes = new AtomicLong(0); forEachBlobInUser((blobMetadata) -> { if (blobMetadata.isALeasee(callingPackage, callingUid)) { totalBytes.getAndAdd(blobMetadata.getSize()); } }, UserHandle.getUserId(callingUid)); return totalBytes.get(); } private void releaseLeaseInternal(BlobHandle blobHandle, int callingUid, private void releaseLeaseInternal(BlobHandle blobHandle, int callingUid, String callingPackage) { String callingPackage) { synchronized (mBlobsLock) { synchronized (mBlobsLock) { Loading Loading @@ -1236,8 +1255,10 @@ public class BlobStoreManagerService extends SystemService { } } synchronized (mBlobsLock) { synchronized (mBlobsLock) { if (dumpArgs.shouldDumpAllSections()) { fout.println("mCurrentMaxSessionId: " + mCurrentMaxSessionId); fout.println("mCurrentMaxSessionId: " + mCurrentMaxSessionId); fout.println(); fout.println(); } if (dumpArgs.shouldDumpSessions()) { if (dumpArgs.shouldDumpSessions()) { dumpSessionsLocked(fout, dumpArgs); dumpSessionsLocked(fout, dumpArgs); Loading @@ -1248,6 +1269,14 @@ public class BlobStoreManagerService extends SystemService { fout.println(); fout.println(); } } } } if (dumpArgs.shouldDumpConfig()) { fout.println("BlobStore config:"); fout.increaseIndent(); BlobStoreConfig.dump(fout, mContext); fout.decreaseIndent(); fout.println(); } } } @Override @Override Loading @@ -1260,14 +1289,16 @@ public class BlobStoreManagerService extends SystemService { } } static final class DumpArgs { static final class DumpArgs { private static final int FLAG_DUMP_SESSIONS = 1 << 0; private static final int FLAG_DUMP_BLOBS = 1 << 1; private static final int FLAG_DUMP_CONFIG = 1 << 2; private int mSelectedSectionFlags; private boolean mDumpFull; private boolean mDumpFull; private final ArrayList<String> mDumpPackages = new ArrayList<>(); private final ArrayList<String> mDumpPackages = new ArrayList<>(); private final ArrayList<Integer> mDumpUids = new ArrayList<>(); private final ArrayList<Integer> mDumpUids = new ArrayList<>(); private final ArrayList<Integer> mDumpUserIds = new ArrayList<>(); private final ArrayList<Integer> mDumpUserIds = new ArrayList<>(); private final ArrayList<Long> mDumpBlobIds = new ArrayList<>(); private final ArrayList<Long> mDumpBlobIds = new ArrayList<>(); private boolean mDumpOnlySelectedSections; private boolean mDumpSessions; private boolean mDumpBlobs; private boolean mDumpHelp; private boolean mDumpHelp; public boolean shouldDumpSession(String packageName, int uid, long blobId) { public boolean shouldDumpSession(String packageName, int uid, long blobId) { Loading @@ -1286,18 +1317,41 @@ public class BlobStoreManagerService extends SystemService { return true; return true; } } public boolean shouldDumpAllSections() { return mSelectedSectionFlags == 0; } public void allowDumpSessions() { mSelectedSectionFlags |= FLAG_DUMP_SESSIONS; } public boolean shouldDumpSessions() { public boolean shouldDumpSessions() { if (!mDumpOnlySelectedSections) { if (shouldDumpAllSections()) { return true; return true; } } return mDumpSessions; return (mSelectedSectionFlags & FLAG_DUMP_SESSIONS) != 0; } public void allowDumpBlobs() { mSelectedSectionFlags |= FLAG_DUMP_BLOBS; } } public boolean shouldDumpBlobs() { public boolean shouldDumpBlobs() { if (!mDumpOnlySelectedSections) { if (shouldDumpAllSections()) { return true; } return (mSelectedSectionFlags & FLAG_DUMP_BLOBS) != 0; } public void allowDumpConfig() { mSelectedSectionFlags |= FLAG_DUMP_CONFIG; } public boolean shouldDumpConfig() { if (shouldDumpAllSections()) { return true; return true; } } return mDumpBlobs; return (mSelectedSectionFlags & FLAG_DUMP_CONFIG) != 0; } } public boolean shouldDumpBlob(long blobId) { public boolean shouldDumpBlob(long blobId) { Loading Loading @@ -1334,11 +1388,11 @@ public class BlobStoreManagerService extends SystemService { dumpArgs.mDumpFull = true; dumpArgs.mDumpFull = true; } } } else if ("--sessions".equals(opt)) { } else if ("--sessions".equals(opt)) { dumpArgs.mDumpOnlySelectedSections = true; dumpArgs.allowDumpSessions(); dumpArgs.mDumpSessions = true; } else if ("--blobs".equals(opt)) { } else if ("--blobs".equals(opt)) { dumpArgs.mDumpOnlySelectedSections = true; dumpArgs.allowDumpBlobs(); dumpArgs.mDumpBlobs = true; } else if ("--config".equals(opt)) { dumpArgs.allowDumpConfig(); } else if ("--package".equals(opt) || "-p".equals(opt)) { } else if ("--package".equals(opt) || "-p".equals(opt)) { dumpArgs.mDumpPackages.add(getStringArgRequired(args, ++i, "packageName")); dumpArgs.mDumpPackages.add(getStringArgRequired(args, ++i, "packageName")); } else if ("--uid".equals(opt) || "-u".equals(opt)) { } else if ("--uid".equals(opt) || "-u".equals(opt)) { Loading Loading @@ -1397,6 +1451,8 @@ public class BlobStoreManagerService extends SystemService { printWithIndent(pw, "Dump only the sessions info"); printWithIndent(pw, "Dump only the sessions info"); pw.println("--blobs"); pw.println("--blobs"); printWithIndent(pw, "Dump only the committed blobs info"); printWithIndent(pw, "Dump only the committed blobs info"); pw.println("--config"); printWithIndent(pw, "Dump only the config values"); pw.println("--package | -p [package-name]"); pw.println("--package | -p [package-name]"); printWithIndent(pw, "Dump blobs info associated with the given package"); printWithIndent(pw, "Dump blobs info associated with the given package"); pw.println("--uid | -u [uid]"); pw.println("--uid | -u [uid]"); Loading
api/system-current.txt +1 −0 Original line number Original line Diff line number Diff line Loading @@ -9131,6 +9131,7 @@ package android.provider { field public static final String NAMESPACE_ATTENTION_MANAGER_SERVICE = "attention_manager_service"; field public static final String NAMESPACE_ATTENTION_MANAGER_SERVICE = "attention_manager_service"; field public static final String NAMESPACE_AUTOFILL = "autofill"; field public static final String NAMESPACE_AUTOFILL = "autofill"; field public static final String NAMESPACE_BIOMETRICS = "biometrics"; field public static final String NAMESPACE_BIOMETRICS = "biometrics"; field public static final String NAMESPACE_BLOBSTORE = "blobstore"; field public static final String NAMESPACE_CONNECTIVITY = "connectivity"; field public static final String NAMESPACE_CONNECTIVITY = "connectivity"; field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture"; field public static final String NAMESPACE_CONTENT_CAPTURE = "content_capture"; field @Deprecated public static final String NAMESPACE_DEX_BOOT = "dex_boot"; field @Deprecated public static final String NAMESPACE_DEX_BOOT = "dex_boot";
core/java/android/provider/DeviceConfig.java +8 −0 Original line number Original line Diff line number Diff line Loading @@ -110,6 +110,14 @@ public final class DeviceConfig { @TestApi @TestApi public static final String NAMESPACE_AUTOFILL = "autofill"; public static final String NAMESPACE_AUTOFILL = "autofill"; /** * Namespace for blobstore feature that allows apps to share data blobs. * * @hide */ @SystemApi public static final String NAMESPACE_BLOBSTORE = "blobstore"; /** /** * Namespace for all networking connectivity related features. * Namespace for all networking connectivity related features. * * Loading