Snap for 7478028 from 518050af6f86a7711b3068fe4f93d92afb132ea5 to mainline-documentsui-release

Change-Id: Id74fa3b2303817ff32c521b2cb9709d3c9953908
diff --git a/Android.bp b/Android.bp
index 78c8072..106ed1e 100644
--- a/Android.bp
+++ b/Android.bp
@@ -13,8 +13,28 @@
 // limitations under the License.
 //
 
+package {
+    default_applicable_licenses: [
+        "packages_providers_DownloadProvider_license",
+    ],
+}
+
+// Added automatically by a large-scale-change
+// See: http://go/android-license-faq
+license {
+    name: "packages_providers_DownloadProvider_license",
+    visibility: [":__subpackages__"],
+    license_kinds: [
+        "SPDX-license-identifier-Apache-2.0",
+    ],
+    license_text: [
+        "NOTICE",
+    ],
+}
+
 android_app {
     name: "DownloadProvider",
+    defaults: ["platform_app_defaults"],
 
     manifest: "AndroidManifest.xml",
 
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 6ef1b54..43cf258 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -60,6 +60,7 @@
     <uses-permission android:name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
     <uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
     <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.CONNECTIVITY_USE_RESTRICTED_NETWORKS"/>
 
     <application android:process="android.process.media"
                  android:label="@string/app_label"
diff --git a/MODULE_LICENSE_APACHE2 b/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/OWNERS b/OWNERS
index 8134437..ed4dc2a 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,2 +1 @@
-jsharkey@android.com
-sudheersai@google.com
+include platform/frameworks/base:/core/java/android/os/storage/OWNERS
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index af2995e..75a81bf 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -41,7 +41,7 @@
     <string name="wifi_recommended_body" msgid="8710820743211704403">"Ovim preuzimanjem od <xliff:g id="SIZE">%1$s </xliff:g> možete da skratite vek trajanja baterije i/ili preterano koristite mobilnu vezu za prenos podataka, što može da dovede do troškova kod mobilnog operatera shodno tarifnom paketu.\n\n Dodirnite <xliff:g id="QUEUE_TEXT">%2$s</xliff:g> da biste započeli ovo preuzimanje kada se ponovo povežete sa WiFi mrežom."</string>
     <string name="button_queue_for_wifi" msgid="6650185573566994738">"Red"</string>
     <string name="button_cancel_download" msgid="4135046775536601831">"Otkaži"</string>
-    <string name="button_start_now" msgid="3817100969365441730">"Započni odmah"</string>
+    <string name="button_start_now" msgid="3817100969365441730">"Započni"</string>
     <plurals name="notif_summary_active" formatted="false" msgid="8652501374845637331">
       <item quantity="one">Preuzima se <xliff:g id="NUMBER">%d</xliff:g> datoteka</item>
       <item quantity="few">Preuzimaju se <xliff:g id="NUMBER">%d</xliff:g> datoteke</item>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index 4cf0e88..d6907f7 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -41,7 +41,7 @@
     <string name="wifi_recommended_body" msgid="8710820743211704403">"यस <xliff:g id="SIZE">%1$s </xliff:g> डाउनलोडलाई सुरु गर्दा तपाईंको ब्याट्रिको काल छोट्टिन सक्छ र/वा तपाईंको मोबाइल डेटा जडानको अधिकतम प्रयोग भई तपाईंको डेटा योजना अनुसार मोबाइल अपरेटरले थप शुल्क लिन सक्छ। \n\n छुनुहोस् <xliff:g id="QUEUE_TEXT">%2$s</xliff:g>तल यस डाउनलोडलाई सुरु गर्न अर्को पटक तपाईं Wi-Fi सन्जालमा जडित हुने बेला।"</string>
     <string name="button_queue_for_wifi" msgid="6650185573566994738">"लाम"</string>
     <string name="button_cancel_download" msgid="4135046775536601831">"रद्द गर्नुहोस्"</string>
-    <string name="button_start_now" msgid="3817100969365441730">"अहिले सुरु गर्नुहोस्"</string>
+    <string name="button_start_now" msgid="3817100969365441730">"अहिले न"</string>
     <plurals name="notif_summary_active" formatted="false" msgid="8652501374845637331">
       <item quantity="other"><xliff:g id="NUMBER">%d</xliff:g> फाइलहरू डाउनलोड हुँदैछन्</item>
       <item quantity="one">१ फाइल डाउनलोड हुँदैछ</item>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 3121473..4470f93 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -40,7 +40,7 @@
     <string name="wifi_recommended_title" msgid="6488158053932133804">"ପରେ ଡାଉନଲୋଡ୍‌ କରିବା ପାଇଁ ଧାଡ଼ିରେ ରଖିବେ?"</string>
     <string name="wifi_recommended_body" msgid="8710820743211704403">"ଏହି <xliff:g id="SIZE">%1$s </xliff:g>ର ଡାଉନଲୋଡ୍‌ ଆରମ୍ଭ କଲେ ଆପଣଙ୍କ ବ୍ୟାଟେରୀ ଶୀଘ୍ର ସରିଯାଇପାରେ ଏବଂ/କିମ୍ୱା ମୋବାଇଲ୍‌ର ଅନେକ ଡାଟା ଖର୍ଚ୍ଚ ହୋଇପାରେ, ଯାହା ପାଇଁ ମୋବାଇଲ୍‌ ଅପରେଟର୍‌, ଆପଣଙ୍କ ଡାଟା ପ୍ଲାନ୍‌ ହିସାବରେ ଆପଣଙ୍କଠାରୁ ପଇସା ନେଇପାରେ|\n\n ଆଗାମୀ ଥର ଯେତେବେଳେ ଆପଣ ୱାଇ-ଫାଇ ନେଟୱର୍କ ସହିତ ଯୋଡ଼ିହେବେ, ଏହି ଡାଉନଲୋଡ୍‌ ଆରମ୍ଭ କରିବା ପାଇଁ <xliff:g id="QUEUE_TEXT">%2$s</xliff:g>କୁ ସ୍ପର୍ଶ କରନ୍ତୁ|"</string>
     <string name="button_queue_for_wifi" msgid="6650185573566994738">"ଧାଡ଼ିରେ ରଖନ୍ତୁ"</string>
-    <string name="button_cancel_download" msgid="4135046775536601831">"ବାତିଲ୍‍"</string>
+    <string name="button_cancel_download" msgid="4135046775536601831">"ବାତିଲ୍ କରନ୍ତୁ"</string>
     <string name="button_start_now" msgid="3817100969365441730">"ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ"</string>
     <plurals name="notif_summary_active" formatted="false" msgid="8652501374845637331">
       <item quantity="other"><xliff:g id="NUMBER">%d</xliff:g>ଟି ଫାଇଲ୍‌ ଡାଉନଲୋଡ୍‌ ହେଉଛି</item>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 38e41b3..6a259cb 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -41,7 +41,7 @@
     <string name="wifi_recommended_body" msgid="8710820743211704403">"Овим преузимањем од <xliff:g id="SIZE">%1$s </xliff:g> можете да скратите век трајања батерије и/или претерано користите мобилну везу за пренос података, што може да доведе до трошкова код мобилног оператера сходно тарифном пакету.\n\n Додирните <xliff:g id="QUEUE_TEXT">%2$s</xliff:g> да бисте започели ово преузимање када се поново повежете са WiFi мрежом."</string>
     <string name="button_queue_for_wifi" msgid="6650185573566994738">"Ред"</string>
     <string name="button_cancel_download" msgid="4135046775536601831">"Откажи"</string>
-    <string name="button_start_now" msgid="3817100969365441730">"Започни одмах"</string>
+    <string name="button_start_now" msgid="3817100969365441730">"Започни"</string>
     <plurals name="notif_summary_active" formatted="false" msgid="8652501374845637331">
       <item quantity="one">Преузима се <xliff:g id="NUMBER">%d</xliff:g> датотека</item>
       <item quantity="few">Преузимају се <xliff:g id="NUMBER">%d</xliff:g> датотеке</item>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 1aa5f1c..e8fc369 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -33,12 +33,12 @@
     <string name="download_unknown_title" msgid="1017800350818840396">"&lt;Okänd&gt;"</string>
     <string name="notification_download_complete" msgid="466652037490092787">"Nedladdningen har slutförts."</string>
     <string name="notification_download_failed" msgid="3932167763860605874">"Det gick inte att ladda ned."</string>
-    <string name="notification_need_wifi_for_size" msgid="4743443900432303646">"Nedladdningen kräver Wi-Fi."</string>
+    <string name="notification_need_wifi_for_size" msgid="4743443900432303646">"Nedladdningen kräver wifi."</string>
     <string name="notification_paused_in_background" msgid="6393408819031041778">"Pausad i bakgrunden."</string>
     <string name="wifi_required_title" msgid="7266700488421122218">"Nedladdningen är för stor för operatörsnätverket"</string>
-    <string name="wifi_required_body" msgid="4005023496578941958">"Du måste använda Wi-Fi om du vill slutföra nedladdningen på <xliff:g id="SIZE">%1$s </xliff:g>. \n \n Tryck på <xliff:g id="QUEUE_TEXT">%2$s </xliff:g> om du vill påbörja nedladdningen nästa gång du är ansluten till ett Wi-Fi-nätverk."</string>
+    <string name="wifi_required_body" msgid="4005023496578941958">"Du måste använda wifi om du vill slutföra nedladdningen på <xliff:g id="SIZE">%1$s </xliff:g>. \n \n Tryck på <xliff:g id="QUEUE_TEXT">%2$s </xliff:g> om du vill påbörja nedladdningen nästa gång du är ansluten till ett wifi-nätverk."</string>
     <string name="wifi_recommended_title" msgid="6488158053932133804">"Vill du ställa den i kö för nedladdning senare?"</string>
-    <string name="wifi_recommended_body" msgid="8710820743211704403">"Om du laddar ned <xliff:g id="SIZE">%1$s </xliff:g> kan det leda till att batteritiden minskar eller att dataanslutningen överbelastas. Det kan i sin tur innebära att operatören tar ut högre avgifter, beroende på abonnemang.\n\n Tryck på <xliff:g id="QUEUE_TEXT">%2$s</xliff:g> om du vill starta nedladdningen nästa gång mobilen är ansluten till ett Wi-Fi-nätverk."</string>
+    <string name="wifi_recommended_body" msgid="8710820743211704403">"Om du laddar ned <xliff:g id="SIZE">%1$s </xliff:g> kan det leda till att batteritiden minskar eller att dataanslutningen överbelastas. Det kan i sin tur innebära att operatören tar ut högre avgifter, beroende på abonnemang.\n\n Tryck på <xliff:g id="QUEUE_TEXT">%2$s</xliff:g> om du vill starta nedladdningen nästa gång mobilen är ansluten till ett wifi-nätverk."</string>
     <string name="button_queue_for_wifi" msgid="6650185573566994738">"Kö"</string>
     <string name="button_cancel_download" msgid="4135046775536601831">"Avbryt"</string>
     <string name="button_start_now" msgid="3817100969365441730">"Starta nu"</string>
diff --git a/src/com/android/providers/downloads/DownloadNotifier.java b/src/com/android/providers/downloads/DownloadNotifier.java
index d38aa75..224aee4 100644
--- a/src/com/android/providers/downloads/DownloadNotifier.java
+++ b/src/com/android/providers/downloads/DownloadNotifier.java
@@ -233,7 +233,8 @@
                 intent.putExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS,
                         downloadIds);
                 builder.setContentIntent(PendingIntent.getBroadcast(mContext,
-                        0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
+                        0, intent,
+                        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE));
                 if (type == TYPE_ACTIVE) {
                     builder.setOngoing(true);
                 }
@@ -250,7 +251,8 @@
                     android.R.drawable.ic_menu_close_clear_cancel,
                     res.getString(R.string.button_cancel_download),
                     PendingIntent.getBroadcast(mContext,
-                            0, cancelIntent, PendingIntent.FLAG_UPDATE_CURRENT));
+                            0, cancelIntent,
+                            PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE));
 
             } else if (type == TYPE_COMPLETE) {
                 cursor.moveToPosition(cluster.get(0));
@@ -274,12 +276,14 @@
                 intent.putExtra(DownloadManager.EXTRA_NOTIFICATION_CLICK_DOWNLOAD_IDS,
                         getDownloadIds(cursor, cluster));
                 builder.setContentIntent(PendingIntent.getBroadcast(mContext,
-                        0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
+                        0, intent,
+                        PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE));
 
                 final Intent hideIntent = new Intent(Constants.ACTION_HIDE,
                         uri, mContext, DownloadReceiver.class);
                 hideIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
-                builder.setDeleteIntent(PendingIntent.getBroadcast(mContext, 0, hideIntent, 0));
+                builder.setDeleteIntent(PendingIntent.getBroadcast(mContext, 0, hideIntent,
+                            PendingIntent.FLAG_IMMUTABLE));
             }
 
             // Calculate and show progress
diff --git a/src/com/android/providers/downloads/DownloadProvider.java b/src/com/android/providers/downloads/DownloadProvider.java
index b629f14..f7e25d5 100644
--- a/src/com/android/providers/downloads/DownloadProvider.java
+++ b/src/com/android/providers/downloads/DownloadProvider.java
@@ -1246,6 +1246,7 @@
                     error.append(", ");
                 }
                 error.append(entry.getKey());
+                first = false;
             }
             throw new SecurityException(error.toString());
         }
@@ -1809,7 +1810,7 @@
                         final ContentValues values = new ContentValues();
                         values.put(Downloads.Impl.COLUMN_TOTAL_BYTES, file.length());
                         values.put(Downloads.Impl.COLUMN_LAST_MODIFICATION,
-                                System.currentTimeMillis());
+                                mSystemFacade.currentTimeMillis());
                         update(uri, values, null, null);
 
                         if (shouldScan) {
diff --git a/src/com/android/providers/downloads/DownloadStorageProvider.java b/src/com/android/providers/downloads/DownloadStorageProvider.java
index 36304aa..421c261 100644
--- a/src/com/android/providers/downloads/DownloadStorageProvider.java
+++ b/src/com/android/providers/downloads/DownloadStorageProvider.java
@@ -18,7 +18,7 @@
 
 import static com.android.providers.downloads.MediaStoreDownloadsHelper.getDocIdForMediaStoreDownload;
 import static com.android.providers.downloads.MediaStoreDownloadsHelper.getMediaStoreIdString;
-import static com.android.providers.downloads.MediaStoreDownloadsHelper.getMediaStoreUri;
+import static com.android.providers.downloads.MediaStoreDownloadsHelper.getMediaStoreUriForQuery;
 import static com.android.providers.downloads.MediaStoreDownloadsHelper.isMediaStoreDownload;
 import static com.android.providers.downloads.MediaStoreDownloadsHelper.isMediaStoreDownloadDir;
 
@@ -28,7 +28,6 @@
 import android.app.DownloadManager.Query;
 import android.content.ContentResolver;
 import android.content.ContentUris;
-import android.content.ContentValues;
 import android.content.Context;
 import android.content.UriPermission;
 import android.database.Cursor;
@@ -67,6 +66,7 @@
 import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
+import java.util.Locale;
 import java.util.Set;
 
 /**
@@ -251,7 +251,7 @@
 
             displayName = FileUtils.buildValidFatFilename(displayName);
             if (isMediaStoreDownload(docId)) {
-                renameMediaStoreDownload(docId, displayName);
+                return renameMediaStoreDownload(docId, displayName);
             } else {
                 final long id = Long.parseLong(docId);
                 if (!mDm.rename(getContext(), id, displayName)) {
@@ -281,7 +281,7 @@
             if (DOC_ID_ROOT.equals(docId)) {
                 includeDefaultDocument(result);
             } else if (isMediaStoreDownload(docId)) {
-                cursor = getContext().getContentResolver().query(getMediaStoreUri(docId),
+                cursor = getContext().getContentResolver().query(getMediaStoreUriForQuery(docId),
                         null, null, null);
                 copyNotificationUri(result, cursor);
                 if (cursor.moveToFirst()) {
@@ -513,7 +513,7 @@
             final ContentResolver resolver = getContext().getContentResolver();
             final Uri contentUri;
             if (isMediaStoreDownload(docId)) {
-                contentUri = getMediaStoreUri(docId);
+                contentUri = getMediaStoreUriForQuery(docId);
             } else {
                 final long id = Long.parseLong(docId);
                 contentUri = mDm.getDownloadUri(id);
@@ -537,7 +537,7 @@
             final ContentResolver resolver = getContext().getContentResolver();
             final Uri contentUri;
             if (isMediaStoreDownload(docId)) {
-                contentUri = getMediaStoreUri(docId);
+                contentUri = getMediaStoreUriForQuery(docId);
             } else {
                 final long id = Long.parseLong(docId);
                 contentUri = mDm.getDownloadUri(id);
@@ -769,7 +769,7 @@
         return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
     }
 
-    private void renameMediaStoreDownload(String docId, String displayName) {
+    private String renameMediaStoreDownload(String docId, String displayName) {
         final File before = getFileForMediaStoreDownload(docId);
         final File after = new File(before.getParentFile(), displayName);
 
@@ -780,25 +780,34 @@
             throw new IllegalStateException("Failed to rename from " + before + " to " + after);
         }
 
-        final long token = Binder.clearCallingIdentity();
-        try {
-            final Uri mediaStoreUri = getMediaStoreUri(docId);
-            final ContentValues values = new ContentValues();
-            values.put(DownloadColumns.DATA, after.getAbsolutePath());
-            values.put(DownloadColumns.DISPLAY_NAME, displayName);
-            final int count = getContext().getContentResolver().update(mediaStoreUri, values,
-                    null, null);
-            if (count != 1) {
-                throw new IllegalStateException("Failed to update " + mediaStoreUri
-                        + ", values=" + values);
-            }
-        } finally {
-            Binder.restoreCallingIdentity(token);
+        final String noMedia = ".nomedia";
+        // Scan the file to update the database
+        // For file, check whether the file is renamed to .nomedia. If yes, to scan the parent
+        // directory to update all files in the directory. We don't consider the case of renaming
+        // .nomedia file. We don't show .nomedia file.
+        if (!after.isDirectory() && displayName.toLowerCase(Locale.ROOT).endsWith(noMedia)) {
+            final Uri newUri = MediaStore.scanFile(getContext().getContentResolver(),
+                    after.getParentFile());
+            // the file will not show in the list, return the parent docId to avoid not finding
+            // the detail for the file.
+            return getDocIdForMediaStoreDownloadUri(newUri, true /* isDir */);
         }
+        // update the database for the old file
+        MediaStore.scanFile(getContext().getContentResolver(), before);
+        // Update tne database for the new file and get the new uri
+        final Uri newUri = MediaStore.scanFile(getContext().getContentResolver(), after);
+        return getDocIdForMediaStoreDownloadUri(newUri, after.isDirectory());
+    }
+
+    private static String getDocIdForMediaStoreDownloadUri(Uri uri, boolean isDir) {
+        if (uri != null) {
+            return getDocIdForMediaStoreDownload(Long.parseLong(uri.getLastPathSegment()), isDir);
+        }
+        return null;
     }
 
     private File getFileForMediaStoreDownload(String docId) {
-        final Uri mediaStoreUri = getMediaStoreUri(docId);
+        final Uri mediaStoreUri = getMediaStoreUriForQuery(docId);
         final long token = Binder.clearCallingIdentity();
         try (Cursor cursor = queryForSingleItem(mediaStoreUri,
                 new String[] { DownloadColumns.DATA }, null, null, null)) {
diff --git a/src/com/android/providers/downloads/DownloadThread.java b/src/com/android/providers/downloads/DownloadThread.java
index 752dbfc..00fa30a 100644
--- a/src/com/android/providers/downloads/DownloadThread.java
+++ b/src/com/android/providers/downloads/DownloadThread.java
@@ -90,6 +90,7 @@
 import java.net.URL;
 import java.net.URLConnection;
 import java.security.GeneralSecurityException;
+import java.util.Arrays;
 
 import javax.net.ssl.HttpsURLConnection;
 import javax.net.ssl.SSLContext;
@@ -233,8 +234,6 @@
     private boolean mIgnoreBlocked;
     private Network mNetwork;
 
-    private int mNetworkType = ConnectivityManager.TYPE_NONE;
-
     /** Historical bytes/second speed of this download. */
     private long mSpeed;
     /** Time when current sample started. */
@@ -294,14 +293,6 @@
                         "No network associated with requesting UID");
             }
 
-            // Remember which network this download started on; used to
-            // determine if errors were due to network changes.
-            final NetworkInfo info = mSystemFacade.getNetworkInfo(mNetwork, mInfo.mUid,
-                    mIgnoreBlocked);
-            if (info != null) {
-                mNetworkType = info.getType();
-            }
-
             // Network traffic on this thread should be counted against the
             // requesting UID, and is tagged with well-known value.
             TrafficStats.setThreadStatsTag(TrafficStats.TAG_SYSTEM_DOWNLOAD);
@@ -340,13 +331,11 @@
                 }
 
                 if (mInfoDelta.mNumFailed < Constants.MAX_RETRIES) {
-                    final NetworkInfo info = mSystemFacade.getNetworkInfo(mNetwork, mInfo.mUid,
-                            mIgnoreBlocked);
-                    if (info != null && info.getType() == mNetworkType && info.isConnected()) {
+                    if (null != mSystemFacade.getNetworkCapabilities(mNetwork)) {
                         // Underlying network is still intact, use normal backoff
                         mInfoDelta.mStatus = STATUS_WAITING_TO_RETRY;
                     } else {
-                        // Network changed, retry on any next available
+                        // Network unavailable, retry on any next available
                         mInfoDelta.mStatus = STATUS_WAITING_FOR_NETWORK;
                     }
 
@@ -724,9 +713,8 @@
         // checking connectivity will apply current policy
         mPolicyDirty = false;
 
-        final NetworkInfo info = mSystemFacade.getNetworkInfo(mNetwork, mInfo.mUid, mIgnoreBlocked);
         final NetworkCapabilities caps = mSystemFacade.getNetworkCapabilities(mNetwork);
-        if (info == null || !info.isConnected()) {
+        if (caps == null) {
             throw new StopRequestException(STATUS_WAITING_FOR_NETWORK, "Network is disconnected");
         }
         if (!caps.hasCapability(NET_CAPABILITY_NOT_ROAMING)
diff --git a/src/com/android/providers/downloads/MediaStoreDownloadsHelper.java b/src/com/android/providers/downloads/MediaStoreDownloadsHelper.java
index c4f347c..9c86d53 100644
--- a/src/com/android/providers/downloads/MediaStoreDownloadsHelper.java
+++ b/src/com/android/providers/downloads/MediaStoreDownloadsHelper.java
@@ -47,8 +47,18 @@
         return docId != null && docId.startsWith(MEDIASTORE_DOWNLOAD_DIR_PREFIX);
     }
 
-    public static Uri getMediaStoreUri(String docId) {
-        return ContentUris.withAppendedId(MediaStore.Downloads.EXTERNAL_CONTENT_URI,
-                getMediaStoreId(docId));
+    /**
+     * The returned uri always appends external volume {@link MediaStore#VOLUME_EXTERNAL}.
+     * It doesn't consider the item is located on second volume. It can't be used to update
+     * or insert.
+     * @param docId the doc id
+     * @return external uri for query
+     */
+    public static Uri getMediaStoreUriForQuery(String docId) {
+        return getMediaStoreUri(MediaStore.VOLUME_EXTERNAL, docId);
+    }
+
+    public static Uri getMediaStoreUri(String volume, String docId) {
+        return MediaStore.Downloads.getContentUri(volume, getMediaStoreId(docId));
     }
 }
diff --git a/src/com/android/providers/downloads/RealSystemFacade.java b/src/com/android/providers/downloads/RealSystemFacade.java
index 94461a6..ba4068e 100644
--- a/src/com/android/providers/downloads/RealSystemFacade.java
+++ b/src/com/android/providers/downloads/RealSystemFacade.java
@@ -57,12 +57,6 @@
     }
 
     @Override
-    public NetworkInfo getNetworkInfo(Network network, int uid, boolean ignoreBlocked) {
-        return mContext.getSystemService(ConnectivityManager.class)
-                .getNetworkInfoForUid(network, uid, ignoreBlocked);
-    }
-
-    @Override
     public NetworkCapabilities getNetworkCapabilities(Network network) {
         return mContext.getSystemService(ConnectivityManager.class)
                 .getNetworkCapabilities(network);
diff --git a/src/com/android/providers/downloads/SystemFacade.java b/src/com/android/providers/downloads/SystemFacade.java
index d73fe11..1fda858 100644
--- a/src/com/android/providers/downloads/SystemFacade.java
+++ b/src/com/android/providers/downloads/SystemFacade.java
@@ -37,7 +37,6 @@
 
     public Network getNetwork(JobParameters params);
 
-    public NetworkInfo getNetworkInfo(Network network, int uid, boolean ignoreBlocked);
     public NetworkCapabilities getNetworkCapabilities(Network network);
 
     /**
diff --git a/tests/Android.bp b/tests/Android.bp
index 3c03c82..d0ba0a5 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -13,6 +13,17 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "packages_providers_DownloadProvider_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: [
+        "packages_providers_DownloadProvider_license",
+    ],
+}
+
 android_test {
     name: "DownloadProviderTests",
 
@@ -27,6 +38,8 @@
     ],
 
     static_libs: [
+        "androidx.core_core",
+        "androidx.test.rules",
         "mockito-target",
         "mockwebserver",
     ],
diff --git a/tests/permission/Android.bp b/tests/permission/Android.bp
index 274106f..a96621f 100644
--- a/tests/permission/Android.bp
+++ b/tests/permission/Android.bp
@@ -13,6 +13,17 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "packages_providers_DownloadProvider_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: [
+        "packages_providers_DownloadProvider_license",
+    ],
+}
+
 android_test {
     name: "DownloadProviderPermissionTests",
     test_suites: ["device-tests"],
diff --git a/tests/public_api_access/Android.bp b/tests/public_api_access/Android.bp
index 1f982b3..3d2cd98 100644
--- a/tests/public_api_access/Android.bp
+++ b/tests/public_api_access/Android.bp
@@ -13,6 +13,17 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "packages_providers_DownloadProvider_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: [
+        "packages_providers_DownloadProvider_license",
+    ],
+}
+
 android_test {
     name: "DownloadPublicApiAccessTests",
     test_suites: ["device-tests"],
diff --git a/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java b/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java
index a505632..4afe3b7 100644
--- a/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java
+++ b/tests/src/com/android/providers/downloads/AbstractDownloadProviderFunctionalTest.java
@@ -127,11 +127,6 @@
         public Bundle call(String method, String request, Bundle args) {
           return new Bundle();
         }
-
-        @Override
-        public IBinder getIContentProviderBinder() {
-            return new Binder();
-        }
     }
 
     /**
@@ -213,6 +208,7 @@
         setupService();
         Helpers.setSystemFacade(mSystemFacade);
 
+        cleanUpDownloads();
         mSystemFacade.setUp();
         assertDatabaseEmpty(); // ensure we're not messing with real data
         assertDatabaseSecureAgainstBadSelection();
diff --git a/tests/src/com/android/providers/downloads/FakeInputStream.java b/tests/src/com/android/providers/downloads/FakeInputStream.java
index 3f68e31..65724ac 100644
--- a/tests/src/com/android/providers/downloads/FakeInputStream.java
+++ b/tests/src/com/android/providers/downloads/FakeInputStream.java
@@ -16,8 +16,6 @@
 
 package com.android.providers.downloads;
 
-import libcore.util.ArrayUtils;
-
 import java.io.InputStream;
 
 /**
@@ -43,7 +41,7 @@
 
     @Override
     public int read(byte[] buffer, int offset, int length) {
-        ArrayUtils.throwsIfOutOfBounds(buffer.length, offset, length);
+        throwsIfOutOfBounds(buffer.length, offset, length);
 
         if (length > mRemaining) {
             length = (int) mRemaining;
@@ -56,4 +54,15 @@
             return length;
         }
     }
+
+    private static void throwsIfOutOfBounds(int len, int offset, int count) {
+        if (len < 0) {
+            throw new ArrayIndexOutOfBoundsException("Negative length: " + len);
+        }
+
+        if ((offset | count) < 0 || offset > len - count) {
+            throw new ArrayIndexOutOfBoundsException(
+                    "length=" + len + "; regionStart=" + offset + "; regionLength=" + count);
+        }
+    }
 }
diff --git a/tests/src/com/android/providers/downloads/FakeSystemFacade.java b/tests/src/com/android/providers/downloads/FakeSystemFacade.java
index d11e0ac..fadcd36 100644
--- a/tests/src/com/android/providers/downloads/FakeSystemFacade.java
+++ b/tests/src/com/android/providers/downloads/FakeSystemFacade.java
@@ -93,25 +93,14 @@
     }
 
     @Override
-    public NetworkInfo getNetworkInfo(Network network, int uid, boolean ignoreBlocked) {
-        if (mActiveNetworkType == null) {
-            return null;
-        } else {
-            final NetworkInfo info = new NetworkInfo(mActiveNetworkType, 0, null, null);
-            info.setDetailedState(DetailedState.CONNECTED, null, null);
-            return info;
-        }
-    }
-
-    @Override
     public NetworkCapabilities getNetworkCapabilities(Network network) {
         if (mActiveNetworkType == null) {
             return null;
         } else {
-            final NetworkCapabilities caps = new NetworkCapabilities();
-            caps.setCapability(NET_CAPABILITY_NOT_METERED, !mIsMetered);
-            caps.setCapability(NET_CAPABILITY_NOT_ROAMING, !mIsRoaming);
-            return caps;
+            final NetworkCapabilities.Builder builder = new NetworkCapabilities.Builder();
+            if (!mIsMetered) builder.addCapability(NET_CAPABILITY_NOT_METERED);
+            if (!mIsRoaming) builder.addCapability(NET_CAPABILITY_NOT_ROAMING);
+            return builder.build();
         }
     }
 
diff --git a/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
index 0652f24..3ec3940 100644
--- a/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
+++ b/tests/src/com/android/providers/downloads/PublicApiFunctionalTest.java
@@ -52,6 +52,8 @@
 import android.test.suitebuilder.annotation.Suppress;
 import android.text.format.DateUtils;
 
+import androidx.test.filters.FlakyTest;
+
 import libcore.io.IoUtils;
 
 import com.google.mockwebserver.MockResponse;
@@ -691,6 +693,7 @@
         download.runUntilStatus(DownloadManager.STATUS_SUCCESSFUL);
     }
 
+    @FlakyTest(bugId = 177499952)
     public void testManyInterruptions() throws Exception {
         final int length = FILE_CONTENT.length();
         for (int i = 0; i < length; i++) {
diff --git a/ui/Android.bp b/ui/Android.bp
index 5192ead..04606c2 100644
--- a/ui/Android.bp
+++ b/ui/Android.bp
@@ -13,6 +13,17 @@
 // limitations under the License.
 //
 
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "packages_providers_DownloadProvider_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: [
+        "packages_providers_DownloadProvider_license",
+    ],
+}
+
 android_app {
     name: "DownloadProviderUi",
 
diff --git a/ui/AndroidManifest.xml b/ui/AndroidManifest.xml
index d08ec19..8eae933 100644
--- a/ui/AndroidManifest.xml
+++ b/ui/AndroidManifest.xml
@@ -1,30 +1,30 @@
 <?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.android.providers.downloads.ui"
-        android:sharedUserId="android.media">
 
-    <uses-permission android:name="android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS" />
-    <uses-permission android:name="android.permission.ACCESS_ALL_DOWNLOADS" />
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+     package="com.android.providers.downloads.ui"
+     android:sharedUserId="android.media">
+
+    <uses-permission android:name="android.permission.SEND_DOWNLOAD_COMPLETED_INTENTS"/>
+    <uses-permission android:name="android.permission.ACCESS_ALL_DOWNLOADS"/>
 
     <application android:process="android.process.media"
-                 android:label="@string/app_label"
-                 android:icon="@mipmap/ic_launcher_download"
-                 android:hardwareAccelerated="true"
-                 android:supportsRtl="true"
-                 android:requiredForAllUsers="true"
-                 android:usesCleartextTraffic="true">
+         android:label="@string/app_label"
+         android:icon="@mipmap/ic_launcher_download"
+         android:hardwareAccelerated="true"
+         android:supportsRtl="true"
+         android:requiredForAllUsers="true"
+         android:usesCleartextTraffic="true">
 
-        <activity
-            android:name=".TrampolineActivity"
-            android:theme="@android:style/Theme.Translucent.NoTitleBar"
-            android:permission="android.permission.MANAGE_DOCUMENTS">
+        <activity android:name=".TrampolineActivity"
+             android:theme="@android:style/Theme.Translucent.NoTitleBar"
+             android:permission="android.permission.MANAGE_DOCUMENTS"
+             android:exported="true">
             <intent-filter>
-                <action android:name="android.provider.action.MANAGE_DOCUMENT" />
-                <category android:name="android.intent.category.DEFAULT" />
-                <data
-                    android:scheme="content"
-                    android:host="com.android.providers.downloads.documents"
-                    android:mimeType="*/*" />
+                <action android:name="android.provider.action.MANAGE_DOCUMENT"/>
+                <category android:name="android.intent.category.DEFAULT"/>
+                <data android:scheme="content"
+                     android:host="com.android.providers.downloads.documents"
+                     android:mimeType="*/*"/>
             </intent-filter>
         </activity>
     </application>
diff --git a/ui/res/values-b+sr+Latn/strings.xml b/ui/res/values-b+sr+Latn/strings.xml
index 7722211..2f83c97 100644
--- a/ui/res/values-b+sr+Latn/strings.xml
+++ b/ui/res/values-b+sr+Latn/strings.xml
@@ -43,7 +43,7 @@
     <string name="keep_queued_download" msgid="6905870466259272973">"Zadrži"</string>
     <string name="cancel_running_download" msgid="8586888328847044473">"Otkaži"</string>
     <string name="retry_download" msgid="6957856437473044831">"Probaj ponovo"</string>
-    <string name="start_now_download" msgid="1518778561803897734">"Započni odmah"</string>
+    <string name="start_now_download" msgid="1518778561803897734">"Započni"</string>
     <string name="deselect_all" msgid="4673983454506880405">"Opozovi sve izbore"</string>
     <string name="select_all" msgid="7469093306474000460">"Izaberi sve"</string>
     <string name="selected_count" msgid="5876842902167894010">"Izabrano je <xliff:g id="NUMBER">%1$d</xliff:g> od <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
diff --git a/ui/res/values-gl/strings.xml b/ui/res/values-gl/strings.xml
index df24c3a..0370c41 100644
--- a/ui/res/values-gl/strings.xml
+++ b/ui/res/values-gl/strings.xml
@@ -38,7 +38,7 @@
     <string name="dialog_file_already_exists" msgid="6849168874901909994">"Non se pode descargar. O ficheiro de destino xa existe."</string>
     <string name="dialog_media_not_found" msgid="7376030905821161865">"Non se pode realizar a descarga. O soporte externo non está dispoñible."</string>
     <string name="download_no_application_title" msgid="1209223807604231431">"Non se pode abrir o ficheiro"</string>
-    <string name="remove_download" msgid="244394809285977300">"Eliminar"</string>
+    <string name="remove_download" msgid="244394809285977300">"Quitar"</string>
     <string name="delete_download" msgid="1861638125603383676">"Eliminar"</string>
     <string name="keep_queued_download" msgid="6905870466259272973">"Manter"</string>
     <string name="cancel_running_download" msgid="8586888328847044473">"Cancelar"</string>
diff --git a/ui/res/values-ky/strings.xml b/ui/res/values-ky/strings.xml
index 6f80d70..142adaa 100644
--- a/ui/res/values-ky/strings.xml
+++ b/ui/res/values-ky/strings.xml
@@ -38,7 +38,7 @@
     <string name="dialog_file_already_exists" msgid="6849168874901909994">"Жүктөө мүмкүн эмес. Мындай файл мурунтан бар."</string>
     <string name="dialog_media_not_found" msgid="7376030905821161865">"Жүктөөнү аягына чыгаруу мүмкүн эмес. Тышкы медиа жеткиликтүү эмес."</string>
     <string name="download_no_application_title" msgid="1209223807604231431">"Файл ачылбады"</string>
-    <string name="remove_download" msgid="244394809285977300">"Алып салуу"</string>
+    <string name="remove_download" msgid="244394809285977300">"Өчүрүү"</string>
     <string name="delete_download" msgid="1861638125603383676">"Жок кылуу"</string>
     <string name="keep_queued_download" msgid="6905870466259272973">"Калтыруу"</string>
     <string name="cancel_running_download" msgid="8586888328847044473">"Токтотуу"</string>
diff --git a/ui/res/values-ne/strings.xml b/ui/res/values-ne/strings.xml
index 0df4d5a..21c01cd 100644
--- a/ui/res/values-ne/strings.xml
+++ b/ui/res/values-ne/strings.xml
@@ -43,7 +43,7 @@
     <string name="keep_queued_download" msgid="6905870466259272973">"राख्नुहोस्"</string>
     <string name="cancel_running_download" msgid="8586888328847044473">"रद्द गर्नुहोस्"</string>
     <string name="retry_download" msgid="6957856437473044831">"पुनःप्रयास गर्नुहोस्"</string>
-    <string name="start_now_download" msgid="1518778561803897734">"अहिले सुरु गर्नुहोस्"</string>
+    <string name="start_now_download" msgid="1518778561803897734">"अहिले न"</string>
     <string name="deselect_all" msgid="4673983454506880405">"सबै अचयन गर्नुहोस्"</string>
     <string name="select_all" msgid="7469093306474000460">"सबै चयन गर्नुहोस्"</string>
     <string name="selected_count" msgid="5876842902167894010">"छानिएको <xliff:g id="TOTAL">%2$d</xliff:g> को <xliff:g id="NUMBER">%1$d</xliff:g> बाट"</string>
diff --git a/ui/res/values-or/strings.xml b/ui/res/values-or/strings.xml
index 62079ee..fc75304 100644
--- a/ui/res/values-or/strings.xml
+++ b/ui/res/values-or/strings.xml
@@ -41,7 +41,7 @@
     <string name="remove_download" msgid="244394809285977300">"କାଢ଼ିଦିଅନ୍ତୁ"</string>
     <string name="delete_download" msgid="1861638125603383676">"ଡିଲିଟ୍‌ କରନ୍ତୁ"</string>
     <string name="keep_queued_download" msgid="6905870466259272973">"Keep"</string>
-    <string name="cancel_running_download" msgid="8586888328847044473">"ବାତିଲ୍‍"</string>
+    <string name="cancel_running_download" msgid="8586888328847044473">"ବାତିଲ୍ କରନ୍ତୁ"</string>
     <string name="retry_download" msgid="6957856437473044831">"ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ"</string>
     <string name="start_now_download" msgid="1518778561803897734">"ବର୍ତ୍ତମାନ ଆରମ୍ଭ କରନ୍ତୁ"</string>
     <string name="deselect_all" msgid="4673983454506880405">"କିଛି ବି ଚୟନ କରନ୍ତୁ ନାହିଁ"</string>
diff --git a/ui/res/values-sr/strings.xml b/ui/res/values-sr/strings.xml
index 801ebd2..2892c79 100644
--- a/ui/res/values-sr/strings.xml
+++ b/ui/res/values-sr/strings.xml
@@ -43,7 +43,7 @@
     <string name="keep_queued_download" msgid="6905870466259272973">"Задржи"</string>
     <string name="cancel_running_download" msgid="8586888328847044473">"Откажи"</string>
     <string name="retry_download" msgid="6957856437473044831">"Пробај поново"</string>
-    <string name="start_now_download" msgid="1518778561803897734">"Започни одмах"</string>
+    <string name="start_now_download" msgid="1518778561803897734">"Започни"</string>
     <string name="deselect_all" msgid="4673983454506880405">"Опозови све изборе"</string>
     <string name="select_all" msgid="7469093306474000460">"Изабери све"</string>
     <string name="selected_count" msgid="5876842902167894010">"Изабрано је <xliff:g id="NUMBER">%1$d</xliff:g> од <xliff:g id="TOTAL">%2$d</xliff:g>"</string>
diff --git a/ui/res/values-te/strings.xml b/ui/res/values-te/strings.xml
index b6afeb1..8fb2c86 100644
--- a/ui/res/values-te/strings.xml
+++ b/ui/res/values-te/strings.xml
@@ -47,5 +47,5 @@
     <string name="deselect_all" msgid="4673983454506880405">"అన్నింటి ఎంపికను తీసివేయి"</string>
     <string name="select_all" msgid="7469093306474000460">"అన్నీ ఎంచుకోండి"</string>
     <string name="selected_count" msgid="5876842902167894010">"<xliff:g id="TOTAL">%2$d</xliff:g>లో <xliff:g id="NUMBER">%1$d</xliff:g> ఎంచుకోబడ్డాయి"</string>
-    <string name="download_share_dialog" msgid="5212760257251501969">"వీటి ద్వారా భాగస్వామ్యం చేయండి"</string>
+    <string name="download_share_dialog" msgid="5212760257251501969">"వీటి ద్వారా షేర్ చేయండి"</string>
 </resources>