OSDN Git Service

Improve developer docs for storage APIs.
authorJeff Sharkey <jsharkey@android.com>
Mon, 12 Jun 2017 20:17:10 +0000 (14:17 -0600)
committerJeff Sharkey <jsharkey@google.com>
Mon, 12 Jun 2017 20:19:53 +0000 (20:19 +0000)
No code changes; only docs.

Test: builds
Bug: 385088333798719737978296
Change-Id: Idfeb680480b2f818d18f787cbf20ceab896763a2

core/java/android/content/ContentProvider.java
core/java/android/os/storage/StorageManager.java

index 9d46da1..64e464c 100644 (file)
@@ -44,6 +44,7 @@ import android.os.ParcelFileDescriptor;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.UserHandle;
+import android.os.storage.StorageManager;
 import android.text.TextUtils;
 import android.util.Log;
 import android.util.MathUtils;
@@ -1376,6 +1377,12 @@ public abstract class ContentProvider implements ComponentCallbacks2 {
      * android.os.Handler, android.os.ParcelFileDescriptor.OnCloseListener)},
      * {@link ParcelFileDescriptor#createReliablePipe()}, or
      * {@link ParcelFileDescriptor#createReliableSocketPair()}.
+     * <p>
+     * If you need to return a large file that isn't backed by a real file on
+     * disk, such as a file on a network share or cloud storage service,
+     * consider using
+     * {@link StorageManager#openProxyFileDescriptor(int, android.os.ProxyFileDescriptorCallback, android.os.Handler)}
+     * which will let you to stream the content on-demand.
      *
      * <p class="note">For use in Intents, you will want to implement {@link #getType}
      * to return the appropriate MIME type for the data returned here with
index 5046735..f42edcd 100644 (file)
@@ -29,6 +29,7 @@ import android.annotation.SuppressLint;
 import android.annotation.SystemApi;
 import android.annotation.SystemService;
 import android.annotation.WorkerThread;
+import android.app.Activity;
 import android.app.ActivityThread;
 import android.content.ContentResolver;
 import android.content.Context;
@@ -159,6 +160,12 @@ public class StorageManager {
      * If the sending application has a specific storage device or allocation
      * size in mind, they can optionally define {@link #EXTRA_UUID} or
      * {@link #EXTRA_REQUESTED_BYTES}, respectively.
+     * <p>
+     * This intent should be launched using
+     * {@link Activity#startActivityForResult(Intent, int)} so that the user
+     * knows which app is requesting the storage space. The returned result will
+     * be {@link Activity#RESULT_OK} if the requested space was made available,
+     * or {@link Activity#RESULT_CANCELED} otherwise.
      */
     @SdkConstant(SdkConstant.SdkConstantType.ACTIVITY_INTENT_ACTION)
     public static final String ACTION_MANAGE_STORAGE = "android.os.storage.action.MANAGE_STORAGE";
@@ -1467,15 +1474,26 @@ public class StorageManager {
     }
 
     /**
-     * Opens seekable ParcelFileDescriptor that routes file operation requests to
-     * ProxyFileDescriptorCallback.
+     * Opens a seekable {@link ParcelFileDescriptor} that proxies all low-level
+     * I/O requests back to the given {@link ProxyFileDescriptorCallback}.
+     * <p>
+     * This can be useful when you want to provide quick access to a large file
+     * that isn't backed by a real file on disk, such as a file on a network
+     * share, cloud storage service, etc. As an example, you could respond to a
+     * {@link ContentResolver#openFileDescriptor(android.net.Uri, String)}
+     * request by returning a {@link ParcelFileDescriptor} created with this
+     * method, and then stream the content on-demand as requested.
+     * <p>
+     * Another useful example might be where you have an encrypted file that
+     * you're willing to decrypt on-demand, but where you want to avoid
+     * persisting the cleartext version.
      *
      * @param mode The desired access mode, must be one of
-     *     {@link ParcelFileDescriptor#MODE_READ_ONLY},
-     *     {@link ParcelFileDescriptor#MODE_WRITE_ONLY}, or
-     *     {@link ParcelFileDescriptor#MODE_READ_WRITE}
-     * @param callback Callback to process file operation requests issued on returned file
-     *     descriptor.
+     *            {@link ParcelFileDescriptor#MODE_READ_ONLY},
+     *            {@link ParcelFileDescriptor#MODE_WRITE_ONLY}, or
+     *            {@link ParcelFileDescriptor#MODE_READ_WRITE}
+     * @param callback Callback to process file operation requests issued on
+     *            returned file descriptor.
      * @param handler Handler that invokes callback methods.
      * @return Seekable ParcelFileDescriptor.
      * @throws IOException
@@ -1487,7 +1505,6 @@ public class StorageManager {
         return openProxyFileDescriptor(mode, callback, handler, null);
     }
 
-
     /** {@hide} */
     @VisibleForTesting
     public int getProxyFileDescriptorMountPointId() {
@@ -1660,6 +1677,10 @@ public class StorageManager {
      * 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>
+     * If you're progressively allocating an unbounded amount of storage space
+     * (such as when recording a video) you should avoid calling this method
+     * more than once every 30 seconds.
      * <p class="note">
      * Note: if your app uses the {@code android:sharedUserId} manifest feature,
      * then allocatable space for all packages in your shared UID is tracked
@@ -1677,6 +1698,7 @@ public class StorageManager {
      * @throws IOException when the storage device isn't present, or when it
      *             doesn't support allocating space.
      */
+    @WorkerThread
     public @BytesLong long getAllocatableBytes(@NonNull UUID storageUuid)
             throws IOException {
         return getAllocatableBytes(storageUuid, 0);
@@ -1684,6 +1706,7 @@ public class StorageManager {
 
     /** @hide */
     @SystemApi
+    @WorkerThread
     @SuppressLint("Doclava125")
     public long getAllocatableBytes(@NonNull UUID storageUuid,
             @RequiresPermission @AllocateFlags int flags) throws IOException {
@@ -1699,6 +1722,7 @@ public class StorageManager {
 
     /** @removed */
     @Deprecated
+    @WorkerThread
     @SuppressLint("Doclava125")
     public long getAllocatableBytes(@NonNull File path,
             @RequiresPermission @AllocateFlags int flags) throws IOException {
@@ -1717,6 +1741,10 @@ public class StorageManager {
      * subject to race conditions. If possible, consider using
      * {@link #allocateBytes(FileDescriptor, long, int)} which will guarantee
      * that bytes are allocated to an opened file.
+     * <p>
+     * If you're progressively allocating an unbounded amount of storage space
+     * (such as when recording a video) you should avoid calling this method
+     * more than once every 60 seconds.
      *
      * @param storageUuid the UUID of the storage volume where you'd like to
      *            allocate disk space. The UUID for a specific path can be
@@ -1727,6 +1755,7 @@ public class StorageManager {
      *             trouble allocating the requested space.
      * @see #getAllocatableBytes(UUID, int)
      */
+    @WorkerThread
     public void allocateBytes(@NonNull UUID storageUuid, @BytesLong long bytes)
             throws IOException {
         allocateBytes(storageUuid, bytes, 0);
@@ -1734,6 +1763,7 @@ public class StorageManager {
 
     /** @hide */
     @SystemApi
+    @WorkerThread
     @SuppressLint("Doclava125")
     public void allocateBytes(@NonNull UUID storageUuid, @BytesLong long bytes,
             @RequiresPermission @AllocateFlags int flags) throws IOException {
@@ -1748,6 +1778,7 @@ public class StorageManager {
 
     /** @removed */
     @Deprecated
+    @WorkerThread
     @SuppressLint("Doclava125")
     public void allocateBytes(@NonNull File path, @BytesLong long bytes,
             @RequiresPermission @AllocateFlags int flags) throws IOException {
@@ -1766,6 +1797,10 @@ public class StorageManager {
      * otherwise it will throw if fast allocation is not possible. Fast
      * allocation is typically only supported in private app data directories,
      * and on shared/external storage devices which are emulated.
+     * <p>
+     * If you're progressively allocating an unbounded amount of storage space
+     * (such as when recording a video) you should avoid calling this method
+     * more than once every 60 seconds.
      *
      * @param fd the open file that you'd like to allocate disk space for.
      * @param bytes the number of bytes to allocate. This is the desired final
@@ -1779,12 +1814,14 @@ public class StorageManager {
      * @see #getAllocatableBytes(UUID, int)
      * @see Environment#isExternalStorageEmulated(File)
      */
+    @WorkerThread
     public void allocateBytes(FileDescriptor fd, @BytesLong long bytes) throws IOException {
         allocateBytes(fd, bytes, 0);
     }
 
     /** @hide */
     @SystemApi
+    @WorkerThread
     @SuppressLint("Doclava125")
     public void allocateBytes(FileDescriptor fd, @BytesLong long bytes,
             @RequiresPermission @AllocateFlags int flags) throws IOException {