Merge cherrypicks of [2310999, 2310925, 2310891, 2311000, 2310892, 2310858, 2310986, 2310963, 2311043, 2310928, 2311044, 2310990, 2311022, 2311023, 2310917, 2310994, 2311024, 2311045, 2310967, 2310995, 2311003, 2311059, 2311025, 2311060, 2310953, 2311061, 2311004, 2311046, 2311005, 2311047, 2311006, 2311079, 2310954, 2311026, 2310896, 2310898, 2310997, 2311062, 2310955, 2311029, 2310998, 2311080, 2311119, 2311030, 2310933, 2311140, 2311063, 2310934, 2311049, 2311050, 2311084, 2311031, 2311145, 2311164] into nyc-mr2-security-c-release

Change-Id: I41c96e77d1fb3294f30f69c6a4d34ee5c136326a
diff --git a/src/com/android/providers/downloads/DownloadProvider.java b/src/com/android/providers/downloads/DownloadProvider.java
index 7297558..e95eb50 100644
--- a/src/com/android/providers/downloads/DownloadProvider.java
+++ b/src/com/android/providers/downloads/DownloadProvider.java
@@ -473,17 +473,42 @@
         final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
         final Cursor cursor = db.query(DB_TABLE, new String[] {
                 Downloads.Impl._ID, Constants.UID }, null, null, null, null, null);
+        final ArrayList<Long> idsToDelete = new ArrayList<>();
         try {
             while (cursor.moveToNext()) {
-                grantAllDownloadsPermission(cursor.getLong(0), cursor.getInt(1));
+                final long downloadId = cursor.getLong(0);
+                final int uid = cursor.getInt(1);
+                final String ownerPackage = getPackageForUid(uid);
+                if (ownerPackage == null) {
+                    idsToDelete.add(downloadId);
+                } else {
+                    grantAllDownloadsPermission(ownerPackage, downloadId);
+                }
             }
         } finally {
             cursor.close();
         }
-
+        if (idsToDelete.size() > 0) {
+            Log.i(Constants.TAG,
+                    "Deleting downloads with ids " + idsToDelete + " as owner package is missing");
+            deleteDownloadsWithIds(idsToDelete);
+        }
         return true;
     }
 
+    private void deleteDownloadsWithIds(ArrayList<Long> downloadIds) {
+        final int N = downloadIds.size();
+        if (N == 0) {
+            return;
+        }
+        final StringBuilder queryBuilder = new StringBuilder(Downloads.Impl._ID + " in (");
+        for (int i = 0; i < N; i++) {
+            queryBuilder.append(downloadIds.get(i));
+            queryBuilder.append((i == N - 1) ? ")" : ",");
+        }
+        delete(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, queryBuilder.toString(), null);
+    }
+
     /**
      * Returns the content-provider-style MIME types of the various
      * types accessible through this content provider.
@@ -703,7 +728,13 @@
         }
 
         insertRequestHeaders(db, rowID, values);
-        grantAllDownloadsPermission(rowID, Binder.getCallingUid());
+
+        final String callingPackage = getPackageForUid(Binder.getCallingUid());
+        if (callingPackage == null) {
+            Log.e(Constants.TAG, "Package does not exist for calling uid");
+            return null;
+        }
+        grantAllDownloadsPermission(callingPackage, rowID);
         notifyContentChanged(uri, match);
 
         final long token = Binder.clearCallingIdentity();
@@ -722,6 +753,15 @@
         return ContentUris.withAppendedId(Downloads.Impl.CONTENT_URI, rowID);
     }
 
+    private String getPackageForUid(int uid) {
+        String[] packages = getContext().getPackageManager().getPackagesForUid(uid);
+        if (packages == null || packages.length == 0) {
+            return null;
+        }
+        // For permission related purposes, any package belonging to the given uid should work.
+        return packages[0];
+    }
+
     /**
      * Check that the file URI provided for DESTINATION_FILE_URI is valid.
      */
@@ -1499,14 +1539,9 @@
         }
     }
 
-    private void grantAllDownloadsPermission(long id, int uid) {
-        final String[] packageNames = getContext().getPackageManager().getPackagesForUid(uid);
-        if (packageNames == null || packageNames.length == 0) return;
-
-        // We only need to grant to the first package, since the
-        // platform internally tracks based on UIDs
+    private void grantAllDownloadsPermission(String toPackage, long id) {
         final Uri uri = ContentUris.withAppendedId(Downloads.Impl.ALL_DOWNLOADS_CONTENT_URI, id);
-        getContext().grantUriPermission(packageNames[0], uri,
+        getContext().grantUriPermission(toPackage, uri,
                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
     }