Handle external storage errors uniformly.

Bug: 6777728
Change-Id: I021db160bc959fdf02bfd448edf977961bd1d9d0
diff --git a/core/java/android/app/DownloadManager.java b/core/java/android/app/DownloadManager.java
index 26dc60d..165c3db 100644
--- a/core/java/android/app/DownloadManager.java
+++ b/core/java/android/app/DownloadManager.java
@@ -461,39 +461,63 @@
         }
 
         /**
-         * Set the local destination for the downloaded file to a path within the application's
-         * external files directory (as returned by {@link Context#getExternalFilesDir(String)}.
+         * Set the local destination for the downloaded file to a path within
+         * the application's external files directory (as returned by
+         * {@link Context#getExternalFilesDir(String)}.
          * <p>
-         * The downloaded file is not scanned by MediaScanner.
-         * But it can be made scannable by calling {@link #allowScanningByMediaScanner()}.
+         * The downloaded file is not scanned by MediaScanner. But it can be
+         * made scannable by calling {@link #allowScanningByMediaScanner()}.
          *
-         * @param context the {@link Context} to use in determining the external files directory
-         * @param dirType the directory type to pass to {@link Context#getExternalFilesDir(String)}
-         * @param subPath the path within the external directory, including the destination filename
+         * @param context the {@link Context} to use in determining the external
+         *            files directory
+         * @param dirType the directory type to pass to
+         *            {@link Context#getExternalFilesDir(String)}
+         * @param subPath the path within the external directory, including the
+         *            destination filename
          * @return this object
+         * @throws IllegalStateException If the external storage directory
+         *             cannot be found or created.
          */
         public Request setDestinationInExternalFilesDir(Context context, String dirType,
                 String subPath) {
-            setDestinationFromBase(context.getExternalFilesDir(dirType), subPath);
+            final File file = context.getExternalFilesDir(dirType);
+            if (file == null) {
+                throw new IllegalStateException("Failed to get external storage files directory");
+            } else if (file.exists()) {
+                if (!file.isDirectory()) {
+                    throw new IllegalStateException(file.getAbsolutePath() +
+                            " already exists and is not a directory");
+                }
+            } else {
+                if (!file.mkdirs()) {
+                    throw new IllegalStateException("Unable to create directory: "+
+                            file.getAbsolutePath());
+                }
+            }
+            setDestinationFromBase(file, subPath);
             return this;
         }
 
         /**
-         * Set the local destination for the downloaded file to a path within the public external
-         * storage directory (as returned by
-         * {@link Environment#getExternalStoragePublicDirectory(String)}.
-         *<p>
-         * The downloaded file is not scanned by MediaScanner.
-         * But it can be made scannable by calling {@link #allowScanningByMediaScanner()}.
+         * Set the local destination for the downloaded file to a path within
+         * the public external storage directory (as returned by
+         * {@link Environment#getExternalStoragePublicDirectory(String)}).
+         * <p>
+         * The downloaded file is not scanned by MediaScanner. But it can be
+         * made scannable by calling {@link #allowScanningByMediaScanner()}.
          *
-         * @param dirType the directory type to pass to
-         *        {@link Environment#getExternalStoragePublicDirectory(String)}
-         * @param subPath the path within the external directory, including the destination filename
+         * @param dirType the directory type to pass to {@link Environment#getExternalStoragePublicDirectory(String)}
+         * @param subPath the path within the external directory, including the
+         *            destination filename
          * @return this object
+         * @throws IllegalStateException If the external storage directory
+         *             cannot be found or created.
          */
         public Request setDestinationInExternalPublicDir(String dirType, String subPath) {
             File file = Environment.getExternalStoragePublicDirectory(dirType);
-            if (file.exists()) {
+            if (file == null) {
+                throw new IllegalStateException("Failed to get external storage public directory");
+            } else if (file.exists()) {
                 if (!file.isDirectory()) {
                     throw new IllegalStateException(file.getAbsolutePath() +
                             " already exists and is not a directory");