Respond to API council feedback.

Move aggressive allocation to @SystemApi, which means we can hide
the "flags" API variants.

Remove UUID APIs, since we should use existing Serializable APIs.

Relax permission checks to allow apps to ask for their own stats.

Improve docs.

Test: cts-tradefed run commandAndExit cts-dev -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.StorageHostTest
Bug: 37534687, 37534941, 37718184, 37738770
Change-Id: I6a763fb3ab3169c8d3329765bb31e1ee08d9ced7
diff --git a/api/current.txt b/api/current.txt
index 58d617a..46b3abc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -15,7 +15,6 @@
     field public static final java.lang.String ACCESS_WIFI_STATE = "android.permission.ACCESS_WIFI_STATE";
     field public static final java.lang.String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER";
     field public static final java.lang.String ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL";
-    field public static final java.lang.String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE";
     field public static final java.lang.String ANSWER_PHONE_CALLS = "android.permission.ANSWER_PHONE_CALLS";
     field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
     field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
@@ -6991,8 +6990,8 @@
 
   public final class StorageStats implements android.os.Parcelable {
     method public int describeContents();
+    method public long getAppBytes();
     method public long getCacheBytes();
-    method public long getCodeBytes();
     method public long getDataBytes();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.usage.StorageStats> CREATOR;
@@ -30748,7 +30747,6 @@
     method public android.util.SizeF getSizeF(java.lang.String);
     method public <T extends android.os.Parcelable> android.util.SparseArray<T> getSparseParcelableArray(java.lang.String);
     method public java.util.ArrayList<java.lang.String> getStringArrayList(java.lang.String);
-    method public java.util.UUID getUuid(java.lang.String);
     method public boolean hasFileDescriptors();
     method public void putAll(android.os.Bundle);
     method public void putBinder(java.lang.String, android.os.IBinder);
@@ -30773,7 +30771,6 @@
     method public void putSizeF(java.lang.String, android.util.SizeF);
     method public void putSparseParcelableArray(java.lang.String, android.util.SparseArray<? extends android.os.Parcelable>);
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
-    method public void putUuid(java.lang.String, java.util.UUID);
     method public void readFromParcel(android.os.Parcel);
     method public void setClassLoader(java.lang.ClassLoader);
     method public void writeToParcel(android.os.Parcel, int);
@@ -31303,7 +31300,6 @@
     method public final <T> void readTypedArray(T[], android.os.Parcelable.Creator<T>);
     method public final <T> void readTypedList(java.util.List<T>, android.os.Parcelable.Creator<T>);
     method public final <T> T readTypedObject(android.os.Parcelable.Creator<T>);
-    method public final java.util.UUID readUuid();
     method public final java.lang.Object readValue(java.lang.ClassLoader);
     method public final void recycle();
     method public final void setDataCapacity(int);
@@ -31349,7 +31345,6 @@
     method public final <T extends android.os.Parcelable> void writeTypedArray(T[], int);
     method public final <T extends android.os.Parcelable> void writeTypedList(java.util.List<T>);
     method public final <T extends android.os.Parcelable> void writeTypedObject(T, int);
-    method public final void writeUuid(java.util.UUID);
     method public final void writeValue(java.lang.Object);
     field public static final android.os.Parcelable.Creator<java.lang.String> STRING_CREATOR;
   }
@@ -31980,9 +31975,9 @@
   }
 
   public class StorageManager {
-    method public void allocateBytes(java.util.UUID, long, int) throws java.io.IOException;
-    method public void allocateBytes(java.io.FileDescriptor, long, int) throws java.io.IOException;
-    method public long getAllocatableBytes(java.util.UUID, int) throws java.io.IOException;
+    method public void allocateBytes(java.util.UUID, long) throws java.io.IOException;
+    method public void allocateBytes(java.io.FileDescriptor, long) throws java.io.IOException;
+    method public long getAllocatableBytes(java.util.UUID) throws java.io.IOException;
     method public long getCacheQuotaBytes(java.util.UUID) throws java.io.IOException;
     method public long getCacheSizeBytes(java.util.UUID) throws java.io.IOException;
     method public java.lang.String getMountedObbPath(java.lang.String);
@@ -32003,7 +31998,6 @@
     field public static final java.lang.String ACTION_MANAGE_STORAGE = "android.os.storage.action.MANAGE_STORAGE";
     field public static final java.lang.String EXTRA_REQUESTED_BYTES = "android.os.storage.extra.REQUESTED_BYTES";
     field public static final java.lang.String EXTRA_UUID = "android.os.storage.extra.UUID";
-    field public static final int FLAG_ALLOCATE_AGGRESSIVE = 1; // 0x1
     field public static final java.util.UUID UUID_DEFAULT;
   }
 
diff --git a/api/removed.txt b/api/removed.txt
index c132385..ee2e84e 100644
--- a/api/removed.txt
+++ b/api/removed.txt
@@ -23,6 +23,10 @@
 
 package android.app.usage {
 
+  public final class StorageStats implements android.os.Parcelable {
+    method public deprecated long getCodeBytes();
+  }
+
   public class StorageStatsManager {
     method public deprecated long getFreeBytes(java.lang.String) throws java.io.IOException;
     method public deprecated long getTotalBytes(java.lang.String) throws java.io.IOException;
diff --git a/api/system-current.txt b/api/system-current.txt
index 3723e7e..5fc51f8 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -7457,8 +7457,8 @@
 
   public final class StorageStats implements android.os.Parcelable {
     method public int describeContents();
+    method public long getAppBytes();
     method public long getCacheBytes();
-    method public long getCodeBytes();
     method public long getDataBytes();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.usage.StorageStats> CREATOR;
@@ -33508,7 +33508,6 @@
     method public android.util.SizeF getSizeF(java.lang.String);
     method public <T extends android.os.Parcelable> android.util.SparseArray<T> getSparseParcelableArray(java.lang.String);
     method public java.util.ArrayList<java.lang.String> getStringArrayList(java.lang.String);
-    method public java.util.UUID getUuid(java.lang.String);
     method public boolean hasFileDescriptors();
     method public void putAll(android.os.Bundle);
     method public void putBinder(java.lang.String, android.os.IBinder);
@@ -33533,7 +33532,6 @@
     method public void putSizeF(java.lang.String, android.util.SizeF);
     method public void putSparseParcelableArray(java.lang.String, android.util.SparseArray<? extends android.os.Parcelable>);
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
-    method public void putUuid(java.lang.String, java.util.UUID);
     method public void readFromParcel(android.os.Parcel);
     method public void setClassLoader(java.lang.ClassLoader);
     method public void writeToParcel(android.os.Parcel, int);
@@ -34095,7 +34093,6 @@
     method public final <T> void readTypedArray(T[], android.os.Parcelable.Creator<T>);
     method public final <T> void readTypedList(java.util.List<T>, android.os.Parcelable.Creator<T>);
     method public final <T> T readTypedObject(android.os.Parcelable.Creator<T>);
-    method public final java.util.UUID readUuid();
     method public final java.lang.Object readValue(java.lang.ClassLoader);
     method public final void recycle();
     method public final void setDataCapacity(int);
@@ -34141,7 +34138,6 @@
     method public final <T extends android.os.Parcelable> void writeTypedArray(T[], int);
     method public final <T extends android.os.Parcelable> void writeTypedList(java.util.List<T>);
     method public final <T extends android.os.Parcelable> void writeTypedObject(T, int);
-    method public final void writeUuid(java.util.UUID);
     method public final void writeValue(java.lang.Object);
     field public static final android.os.Parcelable.Creator<java.lang.String> STRING_CREATOR;
   }
@@ -34878,8 +34874,11 @@
   }
 
   public class StorageManager {
+    method public void allocateBytes(java.util.UUID, long) throws java.io.IOException;
     method public void allocateBytes(java.util.UUID, long, int) throws java.io.IOException;
+    method public void allocateBytes(java.io.FileDescriptor, long) throws java.io.IOException;
     method public void allocateBytes(java.io.FileDescriptor, long, int) throws java.io.IOException;
+    method public long getAllocatableBytes(java.util.UUID) throws java.io.IOException;
     method public long getAllocatableBytes(java.util.UUID, int) throws java.io.IOException;
     method public long getCacheQuotaBytes(java.util.UUID) throws java.io.IOException;
     method public long getCacheSizeBytes(java.util.UUID) throws java.io.IOException;
diff --git a/api/system-removed.txt b/api/system-removed.txt
index 039cd74..89bc6bd0 100644
--- a/api/system-removed.txt
+++ b/api/system-removed.txt
@@ -21,6 +21,10 @@
 
 package android.app.usage {
 
+  public final class StorageStats implements android.os.Parcelable {
+    method public deprecated long getCodeBytes();
+  }
+
   public class StorageStatsManager {
     method public deprecated long getFreeBytes(java.lang.String) throws java.io.IOException;
     method public deprecated long getTotalBytes(java.lang.String) throws java.io.IOException;
diff --git a/api/test-current.txt b/api/test-current.txt
index 9f7441c..0f40c78 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -15,7 +15,6 @@
     field public static final java.lang.String ACCESS_WIFI_STATE = "android.permission.ACCESS_WIFI_STATE";
     field public static final java.lang.String ACCOUNT_MANAGER = "android.permission.ACCOUNT_MANAGER";
     field public static final java.lang.String ADD_VOICEMAIL = "com.android.voicemail.permission.ADD_VOICEMAIL";
-    field public static final java.lang.String ALLOCATE_AGGRESSIVE = "android.permission.ALLOCATE_AGGRESSIVE";
     field public static final java.lang.String ANSWER_PHONE_CALLS = "android.permission.ANSWER_PHONE_CALLS";
     field public static final java.lang.String BATTERY_STATS = "android.permission.BATTERY_STATS";
     field public static final java.lang.String BIND_ACCESSIBILITY_SERVICE = "android.permission.BIND_ACCESSIBILITY_SERVICE";
@@ -7021,8 +7020,8 @@
 
   public final class StorageStats implements android.os.Parcelable {
     method public int describeContents();
+    method public long getAppBytes();
     method public long getCacheBytes();
-    method public long getCodeBytes();
     method public long getDataBytes();
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator<android.app.usage.StorageStats> CREATOR;
@@ -30856,7 +30855,6 @@
     method public android.util.SizeF getSizeF(java.lang.String);
     method public <T extends android.os.Parcelable> android.util.SparseArray<T> getSparseParcelableArray(java.lang.String);
     method public java.util.ArrayList<java.lang.String> getStringArrayList(java.lang.String);
-    method public java.util.UUID getUuid(java.lang.String);
     method public boolean hasFileDescriptors();
     method public void putAll(android.os.Bundle);
     method public void putBinder(java.lang.String, android.os.IBinder);
@@ -30881,7 +30879,6 @@
     method public void putSizeF(java.lang.String, android.util.SizeF);
     method public void putSparseParcelableArray(java.lang.String, android.util.SparseArray<? extends android.os.Parcelable>);
     method public void putStringArrayList(java.lang.String, java.util.ArrayList<java.lang.String>);
-    method public void putUuid(java.lang.String, java.util.UUID);
     method public void readFromParcel(android.os.Parcel);
     method public void setClassLoader(java.lang.ClassLoader);
     method public void writeToParcel(android.os.Parcel, int);
@@ -31432,7 +31429,6 @@
     method public final <T> void readTypedArray(T[], android.os.Parcelable.Creator<T>);
     method public final <T> void readTypedList(java.util.List<T>, android.os.Parcelable.Creator<T>);
     method public final <T> T readTypedObject(android.os.Parcelable.Creator<T>);
-    method public final java.util.UUID readUuid();
     method public final java.lang.Object readValue(java.lang.ClassLoader);
     method public final void recycle();
     method public final void setDataCapacity(int);
@@ -31478,7 +31474,6 @@
     method public final <T extends android.os.Parcelable> void writeTypedArray(T[], int);
     method public final <T extends android.os.Parcelable> void writeTypedList(java.util.List<T>);
     method public final <T extends android.os.Parcelable> void writeTypedObject(T, int);
-    method public final void writeUuid(java.util.UUID);
     method public final void writeValue(java.lang.Object);
     field public static final android.os.Parcelable.Creator<java.lang.String> STRING_CREATOR;
   }
@@ -32113,9 +32108,9 @@
   }
 
   public class StorageManager {
-    method public void allocateBytes(java.util.UUID, long, int) throws java.io.IOException;
-    method public void allocateBytes(java.io.FileDescriptor, long, int) throws java.io.IOException;
-    method public long getAllocatableBytes(java.util.UUID, int) throws java.io.IOException;
+    method public void allocateBytes(java.util.UUID, long) throws java.io.IOException;
+    method public void allocateBytes(java.io.FileDescriptor, long) throws java.io.IOException;
+    method public long getAllocatableBytes(java.util.UUID) throws java.io.IOException;
     method public long getCacheQuotaBytes(java.util.UUID) throws java.io.IOException;
     method public long getCacheSizeBytes(java.util.UUID) throws java.io.IOException;
     method public java.lang.String getMountedObbPath(java.lang.String);
@@ -32136,7 +32131,6 @@
     field public static final java.lang.String ACTION_MANAGE_STORAGE = "android.os.storage.action.MANAGE_STORAGE";
     field public static final java.lang.String EXTRA_REQUESTED_BYTES = "android.os.storage.extra.REQUESTED_BYTES";
     field public static final java.lang.String EXTRA_UUID = "android.os.storage.extra.UUID";
-    field public static final int FLAG_ALLOCATE_AGGRESSIVE = 1; // 0x1
     field public static final java.util.UUID UUID_DEFAULT;
   }
 
diff --git a/api/test-removed.txt b/api/test-removed.txt
index c132385..ee2e84e 100644
--- a/api/test-removed.txt
+++ b/api/test-removed.txt
@@ -23,6 +23,10 @@
 
 package android.app.usage {
 
+  public final class StorageStats implements android.os.Parcelable {
+    method public deprecated long getCodeBytes();
+  }
+
   public class StorageStatsManager {
     method public deprecated long getFreeBytes(java.lang.String) throws java.io.IOException;
     method public deprecated long getTotalBytes(java.lang.String) throws java.io.IOException;
diff --git a/core/java/android/app/usage/ExternalStorageStats.java b/core/java/android/app/usage/ExternalStorageStats.java
index 10c9b5f..83ac779 100644
--- a/core/java/android/app/usage/ExternalStorageStats.java
+++ b/core/java/android/app/usage/ExternalStorageStats.java
@@ -16,6 +16,7 @@
 
 package android.app.usage;
 
+import android.annotation.BytesLong;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.UserHandle;
@@ -37,7 +38,7 @@
      * Return the total bytes used by all files in the shared/external storage
      * hosted on this volume.
      */
-    public long getTotalBytes() {
+    public @BytesLong long getTotalBytes() {
         return totalBytes;
     }
 
@@ -45,7 +46,7 @@
      * Return the total bytes used by audio files in the shared/external storage
      * hosted on this volume.
      */
-    public long getAudioBytes() {
+    public @BytesLong long getAudioBytes() {
         return audioBytes;
     }
 
@@ -53,7 +54,7 @@
      * Return the total bytes used by video files in the shared/external storage
      * hosted on this volume.
      */
-    public long getVideoBytes() {
+    public @BytesLong long getVideoBytes() {
         return videoBytes;
     }
 
@@ -61,7 +62,7 @@
      * Return the total bytes used by image files in the shared/external storage
      * hosted on this volume.
      */
-    public long getImageBytes() {
+    public @BytesLong long getImageBytes() {
         return imageBytes;
     }
 
@@ -72,7 +73,7 @@
      * This data is already accounted against individual apps as returned
      * through {@link StorageStats}.
      */
-    public long getAppBytes() {
+    public @BytesLong long getAppBytes() {
         return appBytes;
     }
 
diff --git a/core/java/android/app/usage/StorageStats.java b/core/java/android/app/usage/StorageStats.java
index 26c702c0..3a27751 100644
--- a/core/java/android/app/usage/StorageStats.java
+++ b/core/java/android/app/usage/StorageStats.java
@@ -16,6 +16,7 @@
 
 package android.app.usage;
 
+import android.annotation.BytesLong;
 import android.content.Context;
 import android.os.Parcel;
 import android.os.Parcelable;
@@ -33,18 +34,24 @@
     /** {@hide} */ public long cacheBytes;
 
     /**
-     * Return the size of all code. This includes {@code APK} files and
-     * optimized compiler output.
+     * Return the size of app. This includes {@code APK} files, optimized
+     * compiler output, and unpacked native libraries.
      * <p>
      * If the primary external/shared storage is hosted on this storage device,
      * then this includes files stored under {@link Context#getObbDir()}.
      * <p>
      * Code is shared between all users on a multiuser device.
      */
-    public long getCodeBytes() {
+    public @BytesLong long getAppBytes() {
         return codeBytes;
     }
 
+    /** @removed */
+    @Deprecated
+    public long getCodeBytes() {
+        return getAppBytes();
+    }
+
     /**
      * Return the size of all data. This includes files stored under
      * {@link Context#getDataDir()}, {@link Context#getCacheDir()},
@@ -58,7 +65,7 @@
      * <p>
      * Data is isolated for each user on a multiuser device.
      */
-    public long getDataBytes() {
+    public @BytesLong long getDataBytes() {
         return dataBytes;
     }
 
@@ -72,7 +79,7 @@
      * <p>
      * Cached data is isolated for each user on a multiuser device.
      */
-    public long getCacheBytes() {
+    public @BytesLong long getCacheBytes() {
         return cacheBytes;
     }
 
diff --git a/core/java/android/app/usage/StorageStatsManager.java b/core/java/android/app/usage/StorageStatsManager.java
index 5497d57..d9d958c 100644
--- a/core/java/android/app/usage/StorageStatsManager.java
+++ b/core/java/android/app/usage/StorageStatsManager.java
@@ -18,6 +18,7 @@
 
 import static android.os.storage.StorageManager.convert;
 
+import android.annotation.BytesLong;
 import android.annotation.NonNull;
 import android.annotation.TestApi;
 import android.annotation.WorkerThread;
@@ -37,13 +38,16 @@
 import java.util.UUID;
 
 /**
- * Provides access to detailed storage statistics.
+ * Access to detailed storage statistics. This provides a summary of how apps,
+ * users, and external/shared storage is utilizing disk space.
  * <p class="note">
- * Note: this API requires the permission
- * {@code android.permission.PACKAGE_USAGE_STATS}, which is a system-level
- * permission that will not be granted to normal apps. However, declaring the
- * permission expresses your intention to use this API and an end user can then
- * choose to grant this permission through the Settings application.
+ * Note: no permissions are required when calling these APIs for your own
+ * package or UID. However, requesting details for any other package requires
+ * the {@code android.Manifest.permission#PACKAGE_USAGE_STATS} permission, which
+ * is a system-level permission that will not be granted to normal apps.
+ * Declaring that permission expresses your intention to use this API and an end
+ * user can then choose to grant this permission through the Settings
+ * application.
  * </p>
  */
 public class StorageStatsManager {
@@ -73,19 +77,22 @@
     }
 
     /**
-     * Return the total size of the underlying media that is hosting this
-     * storage volume.
+     * Return the total size of the underlying physical media that is hosting
+     * this storage volume.
      * <p>
-     * To reduce end user confusion, this value matches the total storage size
-     * advertised in a retail environment, which is typically larger than the
-     * actual usable partition space.
+     * This value is best suited for visual display to end users, since it's
+     * designed to reflect the total storage size advertised in a retail
+     * environment.
+     * <p>
+     * Apps making logical decisions about disk space should always use
+     * {@link File#getTotalSpace()} instead of this value.
      *
      * @param storageUuid the UUID of the storage volume you're interested in,
      *            such as {@link StorageManager#UUID_DEFAULT}.
      * @throws IOException when the storage device isn't present.
      */
     @WorkerThread
-    public long getTotalBytes(@NonNull UUID storageUuid) throws IOException {
+    public @BytesLong long getTotalBytes(@NonNull UUID storageUuid) throws IOException {
         try {
             return mService.getTotalBytes(convert(storageUuid), mContext.getOpPackageName());
         } catch (ParcelableException e) {
@@ -105,19 +112,20 @@
     /**
      * Return the free space on the requested storage volume.
      * <p>
-     * The free space is equivalent to {@link File#getUsableSpace()} plus the
-     * size of any cached data that can be automatically deleted by the system
-     * as additional space is needed.
+     * This value is best suited for visual display to end users, since it's
+     * designed to reflect both unused space <em>and</em> and cached space that
+     * could be reclaimed by the system.
      * <p>
-     * This method may take several seconds to calculate the requested values,
-     * so it should only be called from a worker thread.
+     * Apps making logical decisions about disk space should always use
+     * {@link StorageManager#getAllocatableBytes(UUID, int)} instead of this
+     * value.
      *
      * @param storageUuid the UUID of the storage volume you're interested in,
      *            such as {@link StorageManager#UUID_DEFAULT}.
      * @throws IOException when the storage device isn't present.
      */
     @WorkerThread
-    public long getFreeBytes(@NonNull UUID storageUuid) throws IOException {
+    public @BytesLong long getFreeBytes(@NonNull UUID storageUuid) throws IOException {
         try {
             return mService.getFreeBytes(convert(storageUuid), mContext.getOpPackageName());
         } catch (ParcelableException e) {
@@ -137,9 +145,15 @@
     /**
      * Return storage statistics for a specific package on the requested storage
      * volume.
-     * <p>
-     * This method may take several seconds to calculate the requested values,
-     * so it should only be called from a worker thread.
+     * <p class="note">
+     * Note: no permissions are required when calling this API for your own
+     * package. However, requesting details for any other package requires the
+     * {@code android.Manifest.permission#PACKAGE_USAGE_STATS} permission, which
+     * is a system-level permission that will not be granted to normal apps.
+     * Declaring that permission expresses your intention to use this API and an
+     * end user can then choose to grant this permission through the Settings
+     * application.
+     * </p>
      * <p class="note">
      * Note: if the requested package uses the {@code android:sharedUserId}
      * manifest feature, this call will be forced into a slower manual
@@ -158,8 +172,9 @@
      * @see PackageInfo#packageName
      */
     @WorkerThread
-    public @NonNull StorageStats queryStatsForPackage(@NonNull UUID storageUuid, String packageName,
-            UserHandle user) throws PackageManager.NameNotFoundException, IOException {
+    public @NonNull StorageStats queryStatsForPackage(@NonNull UUID storageUuid,
+            @NonNull String packageName, @NonNull UserHandle user)
+            throws PackageManager.NameNotFoundException, IOException {
         try {
             return mService.queryStatsForPackage(convert(storageUuid), packageName,
                     user.getIdentifier(), mContext.getOpPackageName());
@@ -182,9 +197,15 @@
     /**
      * Return storage statistics for a specific UID on the requested storage
      * volume.
-     * <p>
-     * This method may take several seconds to calculate the requested values,
-     * so it should only be called from a worker thread.
+     * <p class="note">
+     * Note: no permissions are required when calling this API for your own UID.
+     * However, requesting details for any other UID requires the
+     * {@code android.Manifest.permission#PACKAGE_USAGE_STATS} permission, which
+     * is a system-level permission that will not be granted to normal apps.
+     * Declaring that permission expresses your intention to use this API and an
+     * end user can then choose to grant this permission through the Settings
+     * application.
+     * </p>
      *
      * @param storageUuid the UUID of the storage volume you're interested in,
      *            such as {@link StorageManager#UUID_DEFAULT}.
@@ -194,7 +215,8 @@
      * @see ApplicationInfo#uid
      */
     @WorkerThread
-    public StorageStats queryStatsForUid(@NonNull UUID storageUuid, int uid) throws IOException {
+    public @NonNull StorageStats queryStatsForUid(@NonNull UUID storageUuid, int uid)
+            throws IOException {
         try {
             return mService.queryStatsForUid(convert(storageUuid), uid,
                     mContext.getOpPackageName());
@@ -215,9 +237,14 @@
     /**
      * Return storage statistics for a specific {@link UserHandle} on the
      * requested storage volume.
-     * <p>
-     * This method may take several seconds to calculate the requested values,
-     * so it should only be called from a worker thread.
+     * <p class="note">
+     * Note: this API requires the
+     * {@code android.Manifest.permission#PACKAGE_USAGE_STATS} permission, which
+     * is a system-level permission that will not be granted to normal apps.
+     * Declaring that permission expresses your intention to use this API and an
+     * end user can then choose to grant this permission through the Settings
+     * application.
+     * </p>
      *
      * @param storageUuid the UUID of the storage volume you're interested in,
      *            such as {@link StorageManager#UUID_DEFAULT}.
@@ -226,8 +253,8 @@
      * @see android.os.Process#myUserHandle()
      */
     @WorkerThread
-    public StorageStats queryStatsForUser(@NonNull UUID storageUuid, UserHandle user)
-            throws IOException {
+    public @NonNull StorageStats queryStatsForUser(@NonNull UUID storageUuid,
+            @NonNull UserHandle user) throws IOException {
         try {
             return mService.queryStatsForUser(convert(storageUuid), user.getIdentifier(),
                     mContext.getOpPackageName());
@@ -248,9 +275,14 @@
     /**
      * Return shared/external storage statistics for a specific
      * {@link UserHandle} on the requested storage volume.
-     * <p>
-     * This method may take several seconds to calculate the requested values,
-     * so it should only be called from a worker thread.
+     * <p class="note">
+     * Note: this API requires the
+     * {@code android.Manifest.permission#PACKAGE_USAGE_STATS} permission, which
+     * is a system-level permission that will not be granted to normal apps.
+     * Declaring that permission expresses your intention to use this API and an
+     * end user can then choose to grant this permission through the Settings
+     * application.
+     * </p>
      *
      * @param storageUuid the UUID of the storage volume you're interested in,
      *            such as {@link StorageManager#UUID_DEFAULT}.
@@ -258,8 +290,8 @@
      * @see android.os.Process#myUserHandle()
      */
     @WorkerThread
-    public ExternalStorageStats queryExternalStatsForUser(@NonNull UUID storageUuid,
-            UserHandle user) throws IOException {
+    public @NonNull ExternalStorageStats queryExternalStatsForUser(@NonNull UUID storageUuid,
+            @NonNull UserHandle user) throws IOException {
         try {
             return mService.queryExternalStatsForUser(convert(storageUuid), user.getIdentifier(),
                     mContext.getOpPackageName());
diff --git a/core/java/android/content/pm/ApplicationInfo.java b/core/java/android/content/pm/ApplicationInfo.java
index 6c5d26a..06f7916 100644
--- a/core/java/android/content/pm/ApplicationInfo.java
+++ b/core/java/android/content/pm/ApplicationInfo.java
@@ -1205,7 +1205,8 @@
         dest.writeInt(largestWidthLimitDp);
         if (storageUuid != null) {
             dest.writeInt(1);
-            dest.writeUuid(storageUuid);
+            dest.writeLong(storageUuid.getMostSignificantBits());
+            dest.writeLong(storageUuid.getLeastSignificantBits());
         } else {
             dest.writeInt(0);
         }
@@ -1271,7 +1272,7 @@
         compatibleWidthLimitDp = source.readInt();
         largestWidthLimitDp = source.readInt();
         if (source.readInt() != 0) {
-            storageUuid = source.readUuid();
+            storageUuid = new UUID(source.readLong(), source.readLong());
             volumeUuid = StorageManager.convert(storageUuid);
         }
         scanSourceDir = source.readString();
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index 167c46d..9b5ff29 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -25,7 +25,6 @@
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
-import java.util.UUID;
 
 /**
  * A mapping from String keys to various {@link Parcelable} values.
@@ -477,18 +476,6 @@
     }
 
     /**
-     * Inserts a UUID value into the mapping of this Bundle, replacing
-     * any existing value for the given key.  Either key or value may be null.
-     *
-     * @param key a String, or null
-     * @param value a UUID object, or null
-     */
-    public void putUuid(@Nullable String key, @Nullable UUID value) {
-        unparcel();
-        mMap.put(key, value);
-    }
-
-    /**
      * Inserts an array of Parcelable values into the mapping of this Bundle,
      * replacing any existing value for the given key.  Either key or value may
      * be null.
@@ -871,26 +858,6 @@
      * value is explicitly associated with the key.
      *
      * @param key a String, or null
-     * @return a UUID value, or null
-     */
-    @Nullable
-    public UUID getUuid(@Nullable String key) {
-        unparcel();
-        final Object o = mMap.get(key);
-        try {
-            return (UUID) o;
-        } catch (ClassCastException e) {
-            typeWarning(key, o, "UUID", e);
-            return null;
-        }
-    }
-
-    /**
-     * Returns the value associated with the given key, or null if
-     * no mapping of the desired type exists for the given key or a null
-     * value is explicitly associated with the key.
-     *
-     * @param key a String, or null
      * @return a Bundle value, or null
      */
     @Nullable
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index c1647c7..28bdacf 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -50,7 +50,6 @@
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.UUID;
 
 /**
  * Container for a message (data and object references) that can
@@ -242,7 +241,6 @@
     private static final int VAL_SIZE = 26;
     private static final int VAL_SIZEF = 27;
     private static final int VAL_DOUBLEARRAY = 28;
-    private static final int VAL_UUID = 29;
 
     // The initial int32 in a Binder call's reply Parcel header:
     // Keep these in sync with libbinder's binder/Status.h.
@@ -831,15 +829,6 @@
     }
 
     /**
-     * Flatten a UUID into the parcel at the current dataPosition(),
-     * growing dataCapacity() if needed.
-     */
-    public final void writeUuid(UUID val) {
-        writeLong(val.getMostSignificantBits());
-        writeLong(val.getLeastSignificantBits());
-    }
-
-    /**
      * Flatten a List into the parcel at the current dataPosition(), growing
      * dataCapacity() if needed.  The List values are written using
      * {@link #writeValue} and must follow the specification there.
@@ -1687,9 +1676,6 @@
         } else if (v instanceof double[]) {
             writeInt(VAL_DOUBLEARRAY);
             writeDoubleArray((double[]) v);
-        } else if (v instanceof UUID) {
-            writeInt(VAL_UUID);
-            writeUuid((UUID) v);
         } else {
             Class<?> clazz = v.getClass();
             if (clazz.isArray() && clazz.getComponentType() == Object.class) {
@@ -2194,13 +2180,6 @@
     }
 
     /**
-     * Read a UUID from the parcel at the current dataPosition().
-     */
-    public final UUID readUuid() {
-        return new UUID(readLong(), readLong());
-    }
-
-    /**
      * Read and return a byte[] object from the parcel.
      */
     public final byte[] createByteArray() {
@@ -2750,9 +2729,6 @@
         case VAL_DOUBLEARRAY:
             return createDoubleArray();
 
-        case VAL_UUID:
-            return readUuid();
-
         default:
             int off = dataPosition() - 4;
             throw new RuntimeException(
diff --git a/core/java/android/os/storage/StorageManager.java b/core/java/android/os/storage/StorageManager.java
index baa29b0..4b4cabf 100644
--- a/core/java/android/os/storage/StorageManager.java
+++ b/core/java/android/os/storage/StorageManager.java
@@ -19,14 +19,18 @@
 import static android.net.TrafficStats.GB_IN_BYTES;
 import static android.net.TrafficStats.MB_IN_BYTES;
 
+import android.annotation.BytesLong;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.RequiresPermission;
 import android.annotation.SdkConstant;
+import android.annotation.SystemApi;
+import android.annotation.WorkerThread;
 import android.app.ActivityThread;
 import android.content.ContentResolver;
 import android.content.Context;
+import android.content.Intent;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.IPackageMoveObserver;
 import android.content.pm.PackageManager;
@@ -135,6 +139,7 @@
      * thus it cannot be used to uniquely identify a particular physical device.
      *
      * @see #getUuidForPath(File)
+     * @see ApplicationInfo#storageUuid
      */
     public static final UUID UUID_DEFAULT = UUID
             .fromString("41217664-9172-527a-b3d5-edabb50a7d69");
@@ -166,6 +171,7 @@
      * @see #ACTION_MANAGE_STORAGE
      * @see #UUID_DEFAULT
      * @see #getUuidForPath(File)
+     * @see Intent#putExtra(String, java.io.Serializable)
      */
     public static final String EXTRA_UUID = "android.os.storage.extra.UUID";
 
@@ -1533,7 +1539,8 @@
      *             doesn't support cache quotas.
      * @see #getCacheSizeBytes(UUID)
      */
-    public long getCacheQuotaBytes(@NonNull UUID storageUuid) throws IOException {
+    @WorkerThread
+    public @BytesLong long getCacheQuotaBytes(@NonNull UUID storageUuid) throws IOException {
         try {
             final ApplicationInfo app = mContext.getApplicationInfo();
             return mStorageManager.getCacheQuotaBytes(convert(storageUuid), app.uid);
@@ -1573,7 +1580,8 @@
      *             doesn't support cache quotas.
      * @see #getCacheQuotaBytes(UUID)
      */
-    public long getCacheSizeBytes(@NonNull UUID storageUuid) throws IOException {
+    @WorkerThread
+    public @BytesLong long getCacheSizeBytes(@NonNull UUID storageUuid) throws IOException {
         try {
             final ApplicationInfo app = mContext.getApplicationInfo();
             return mStorageManager.getCacheSizeBytes(convert(storageUuid), app.uid);
@@ -1631,8 +1639,10 @@
      * @see #getAllocatableBytes(UUID, int)
      * @see #allocateBytes(UUID, long, int)
      * @see #allocateBytes(FileDescriptor, long, int)
+     * @hide
      */
     @RequiresPermission(android.Manifest.permission.ALLOCATE_AGGRESSIVE)
+    @SystemApi
     public static final int FLAG_ALLOCATE_AGGRESSIVE = 1;
 
     /** @hide */
@@ -1656,7 +1666,7 @@
      * the returned value will fail.
      * <p>
      * If the returned value is not large enough for the data you'd like to
-     * store, you can launch {@link #ACTION_MANAGE_STORAGE} with the
+     * persist, you can launch {@link #ACTION_MANAGE_STORAGE} with the
      * {@link #EXTRA_UUID} and {@link #EXTRA_REQUESTED_BYTES} options to help
      * involve the user in freeing up disk space.
      * <p class="note">
@@ -1670,13 +1680,19 @@
      *            vary widely depending on the underlying storage device. The
      *            UUID for a specific path can be obtained using
      *            {@link #getUuidForPath(File)}.
-     * @param flags to apply to the request.
      * @return the maximum number of new bytes that the calling app can allocate
      *         using {@link #allocateBytes(UUID, long, int)} or
      *         {@link #allocateBytes(FileDescriptor, long, int)}.
      * @throws IOException when the storage device isn't present, or when it
      *             doesn't support allocating space.
      */
+    public @BytesLong long getAllocatableBytes(@NonNull UUID storageUuid)
+            throws IOException {
+        return getAllocatableBytes(storageUuid, 0);
+    }
+
+    /** @hide */
+    @SystemApi
     public long getAllocatableBytes(@NonNull UUID storageUuid, @AllocateFlags int flags)
             throws IOException {
         try {
@@ -1713,14 +1729,20 @@
      *            allocate disk space. The UUID for a specific path can be
      *            obtained using {@link #getUuidForPath(File)}.
      * @param bytes the number of bytes to allocate.
-     * @param flags to apply to the request.
      * @throws IOException when the storage device isn't present, or when it
      *             doesn't support allocating space, or if the device had
      *             trouble allocating the requested space.
      * @see #getAllocatableBytes(UUID, int)
      */
-    public void allocateBytes(@NonNull UUID storageUuid, long bytes, @AllocateFlags int flags)
+    public void allocateBytes(@NonNull UUID storageUuid, @BytesLong long bytes)
             throws IOException {
+        allocateBytes(storageUuid, bytes, 0);
+    }
+
+    /** @hide */
+    @SystemApi
+    public void allocateBytes(@NonNull UUID storageUuid, @BytesLong long bytes,
+            @AllocateFlags int flags) throws IOException {
         try {
             mStorageManager.allocateBytes(convert(storageUuid), bytes, flags);
         } catch (ParcelableException e) {
@@ -1732,7 +1754,7 @@
 
     /** @removed */
     @Deprecated
-    public void allocateBytes(@NonNull File path, long bytes, @AllocateFlags int flags)
+    public void allocateBytes(@NonNull File path, @BytesLong long bytes, @AllocateFlags int flags)
             throws IOException {
         allocateBytes(getUuidForPath(path), bytes, flags);
     }
@@ -1756,14 +1778,19 @@
      *            requested size, it will be extended without modifying any
      *            existing contents. If the open file is larger than this
      *            requested size, it will be truncated.
-     * @param flags to apply to the request.
      * @throws IOException when the storage device isn't present, or when it
      *             doesn't support allocating space, or if the device had
      *             trouble allocating the requested space.
      * @see #getAllocatableBytes(UUID, int)
      * @see Environment#isExternalStorageEmulated(File)
      */
-    public void allocateBytes(FileDescriptor fd, long bytes, @AllocateFlags int flags)
+    public void allocateBytes(FileDescriptor fd, @BytesLong long bytes) throws IOException {
+        allocateBytes(fd, bytes, 0);
+    }
+
+    /** @hide */
+    @SystemApi
+    public void allocateBytes(FileDescriptor fd, @BytesLong long bytes, @AllocateFlags int flags)
             throws IOException {
         final File file = ParcelFileDescriptor.getFile(fd);
         for (int i = 0; i < 3; i++) {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 3131302..7c7daf7 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1697,7 +1697,8 @@
     <permission android:name="android.permission.CACHE_CONTENT"
         android:protectionLevel="signature" />
 
-    <!-- Allows an application to aggressively allocate disk space.
+    <!-- @SystemApi @hide
+         Allows an application to aggressively allocate disk space.
          <p>Not for use by third-party applications.
     -->
     <permission android:name="android.permission.ALLOCATE_AGGRESSIVE"
diff --git a/services/usage/java/com/android/server/usage/StorageStatsService.java b/services/usage/java/com/android/server/usage/StorageStatsService.java
index 2ebf5fc..e13665b 100644
--- a/services/usage/java/com/android/server/usage/StorageStatsService.java
+++ b/services/usage/java/com/android/server/usage/StorageStatsService.java
@@ -157,7 +157,7 @@
 
     @Override
     public long getTotalBytes(String volumeUuid, String callingPackage) {
-        enforcePermission(Binder.getCallingUid(), callingPackage);
+        // NOTE: No permissions required
 
         if (volumeUuid == StorageManager.UUID_PRIVATE_INTERNAL) {
             return FileUtils.roundStorageSize(mStorage.getPrimaryStorageSize());
@@ -173,7 +173,7 @@
 
     @Override
     public long getFreeBytes(String volumeUuid, String callingPackage) {
-        enforcePermission(Binder.getCallingUid(), callingPackage);
+        // NOTE: No permissions required
 
         long cacheBytes = 0;
         final long token = Binder.clearCallingIdentity();
@@ -187,14 +187,14 @@
         }
 
         if (volumeUuid == StorageManager.UUID_PRIVATE_INTERNAL) {
-            return Environment.getDataDirectory().getUsableSpace() + cacheBytes;
+            return Environment.getDataDirectory().getFreeSpace() + cacheBytes;
         } else {
             final VolumeInfo vol = mStorage.findVolumeByUuid(volumeUuid);
             if (vol == null) {
                 throw new ParcelableException(
                         new IOException("Failed to find storage device for UUID " + volumeUuid));
             }
-            return vol.getPath().getUsableSpace() + cacheBytes;
+            return vol.getPath().getFreeSpace() + cacheBytes;
         }
     }
 
@@ -213,7 +213,6 @@
     @Override
     public StorageStats queryStatsForPackage(String volumeUuid, String packageName, int userId,
             String callingPackage) {
-        enforcePermission(Binder.getCallingUid(), callingPackage);
         if (userId != UserHandle.getCallingUserId()) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.INTERACT_ACROSS_USERS, TAG);
@@ -227,6 +226,12 @@
             throw new ParcelableException(e);
         }
 
+        if (Binder.getCallingUid() == appInfo.uid) {
+            // No permissions required when asking about themselves
+        } else {
+            enforcePermission(Binder.getCallingUid(), callingPackage);
+        }
+
         if (mPackage.getPackagesForUid(appInfo.uid).length == 1) {
             // Only one package inside UID means we can fast-path
             return queryStatsForUid(volumeUuid, appInfo.uid, callingPackage);
@@ -257,14 +262,19 @@
 
     @Override
     public StorageStats queryStatsForUid(String volumeUuid, int uid, String callingPackage) {
-        enforcePermission(Binder.getCallingUid(), callingPackage);
-        if (UserHandle.getUserId(uid) != UserHandle.getCallingUserId()) {
+        final int userId = UserHandle.getUserId(uid);
+        final int appId = UserHandle.getAppId(uid);
+
+        if (userId != UserHandle.getCallingUserId()) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.INTERACT_ACROSS_USERS, TAG);
         }
 
-        final int userId = UserHandle.getUserId(uid);
-        final int appId = UserHandle.getAppId(uid);
+        if (Binder.getCallingUid() == uid) {
+            // No permissions required when asking about themselves
+        } else {
+            enforcePermission(Binder.getCallingUid(), callingPackage);
+        }
 
         final String[] packageNames = mPackage.getPackagesForUid(uid);
         final long[] ceDataInodes = new long[packageNames.length];
@@ -304,12 +314,14 @@
 
     @Override
     public StorageStats queryStatsForUser(String volumeUuid, int userId, String callingPackage) {
-        enforcePermission(Binder.getCallingUid(), callingPackage);
         if (userId != UserHandle.getCallingUserId()) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.INTERACT_ACROSS_USERS, TAG);
         }
 
+        // Always require permission to see user-level stats
+        enforcePermission(Binder.getCallingUid(), callingPackage);
+
         final int[] appIds = getAppIds(userId);
         final PackageStats stats = new PackageStats(TAG);
         try {
@@ -329,12 +341,14 @@
     @Override
     public ExternalStorageStats queryExternalStatsForUser(String volumeUuid, int userId,
             String callingPackage) {
-        enforcePermission(Binder.getCallingUid(), callingPackage);
         if (userId != UserHandle.getCallingUserId()) {
             mContext.enforceCallingOrSelfPermission(
                     android.Manifest.permission.INTERACT_ACROSS_USERS, TAG);
         }
 
+        // Always require permission to see user-level stats
+        enforcePermission(Binder.getCallingUid(), callingPackage);
+
         final int[] appIds = getAppIds(userId);
         final long[] stats;
         try {