New error status for "destination file already exists".

Also changing the behavior of the local URI column slightly to better
match the spec -- it should return the client-provided destination so
that it's valid even if the download failed.

Change-Id: Ibf9c07519e647e677ebac8b334b9f2e930e47033
diff --git a/api/current.xml b/api/current.xml
index 8651c4d..af91389 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -96356,6 +96356,17 @@
  visibility="public"
 >
 </field>
+<field name="ERROR_FILE_ALREADY_EXISTS"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1009"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
 <field name="ERROR_FILE_ERROR"
  type="int"
  transient="false"
diff --git a/core/java/android/net/DownloadManager.java b/core/java/android/net/DownloadManager.java
index 5320da3..8bb747e 100644
--- a/core/java/android/net/DownloadManager.java
+++ b/core/java/android/net/DownloadManager.java
@@ -25,7 +25,6 @@
 import android.provider.BaseColumns;
 import android.provider.Downloads;
 
-import java.io.File;
 import java.io.FileNotFoundException;
 import java.util.ArrayList;
 import java.util.Arrays;
@@ -195,6 +194,12 @@
     public final static int ERROR_CANNOT_RESUME = 1008;
 
     /**
+     * Value of {@link #COLUMN_ERROR_CODE} when the requested destination file already exists (the
+     * download manager will not overwrite an existing file).
+     */
+    public final static int ERROR_FILE_ALREADY_EXISTS = 1009;
+
+    /**
      * Broadcast intent action sent by the download manager when a download completes.
      */
     public final static String ACTION_DOWNLOAD_COMPLETE = "android.intent.action.DOWNLOAD_COMPLETE";
@@ -235,10 +240,11 @@
         Downloads.COLUMN_URI,
         Downloads.COLUMN_MIME_TYPE,
         Downloads.COLUMN_TOTAL_BYTES,
-        Downloads._DATA,
         Downloads.COLUMN_STATUS,
         Downloads.COLUMN_CURRENT_BYTES,
         Downloads.COLUMN_LAST_MODIFICATION,
+        Downloads.COLUMN_DESTINATION,
+        Downloads.Impl.COLUMN_FILE_NAME_HINT,
     };
 
     private static final Set<String> LONG_COLUMNS = new HashSet<String>(
@@ -820,15 +826,10 @@
         }
 
         private String getLocalUri() {
-            String localUri = getUnderlyingString(Downloads.Impl._DATA);
-            if (localUri == null) {
-                return null;
-            }
-
             long destinationType = getUnderlyingLong(Downloads.Impl.COLUMN_DESTINATION);
             if (destinationType == Downloads.Impl.DESTINATION_FILE_URI) {
-                // return file URI for external download
-                return Uri.fromFile(new File(localUri)).toString();
+                // return client-provided file URI for external download
+                return getUnderlyingString(Downloads.Impl.COLUMN_FILE_NAME_HINT);
             }
 
             // return content URI for cache download
@@ -894,6 +895,9 @@
                 case Downloads.Impl.STATUS_CANNOT_RESUME:
                     return ERROR_CANNOT_RESUME;
 
+                case Downloads.Impl.STATUS_FILE_ALREADY_EXISTS_ERROR:
+                    return ERROR_FILE_ALREADY_EXISTS;
+
                 default:
                     return ERROR_UNKNOWN;
             }
diff --git a/core/java/android/provider/Downloads.java b/core/java/android/provider/Downloads.java
index 74c7372..871a0441 100644
--- a/core/java/android/provider/Downloads.java
+++ b/core/java/android/provider/Downloads.java
@@ -1077,7 +1077,12 @@
         /**
          * The lowest-valued error status that is not an actual HTTP status code.
          */
-        public static final int MIN_ARTIFICIAL_ERROR_STATUS = 489;
+        public static final int MIN_ARTIFICIAL_ERROR_STATUS = 488;
+
+        /**
+         * The requested destination file already exists.
+         */
+        public static final int STATUS_FILE_ALREADY_EXISTS_ERROR = 488;
 
         /**
          * Some possibly transient error occurred, but we can't resume the download.