Merge cherrypicks of [3192228, 3193161, 3192849, 3192850, 3192851, 3193150, 3193193, 3193195, 3193196, 3192852, 3193233, 3193234, 3192311, 3192312, 3193273, 3193218] into oc-r4-release

Change-Id: Id455639b828adbb339c6cb46fc8c65ea43f93509
diff --git a/core/java/android/os/ParcelableException.java b/core/java/android/os/ParcelableException.java
index d84d629..7f71905 100644
--- a/core/java/android/os/ParcelableException.java
+++ b/core/java/android/os/ParcelableException.java
@@ -52,10 +52,12 @@
         final String msg = in.readString();
         try {
             final Class<?> clazz = Class.forName(name, true, Parcelable.class.getClassLoader());
-            return (Throwable) clazz.getConstructor(String.class).newInstance(msg);
+            if (Throwable.class.isAssignableFrom(clazz)) {
+                return (Throwable) clazz.getConstructor(String.class).newInstance(msg);
+            }
         } catch (ReflectiveOperationException e) {
-            throw new RuntimeException(name + ": " + msg);
         }
+        return new RuntimeException(name + ": " + msg);
     }
 
     /** {@hide} */
diff --git a/services/core/java/com/android/server/accounts/AccountManagerService.java b/services/core/java/com/android/server/accounts/AccountManagerService.java
index f0b1b3b..ef8a575 100644
--- a/services/core/java/com/android/server/accounts/AccountManagerService.java
+++ b/services/core/java/com/android/server/accounts/AccountManagerService.java
@@ -4703,6 +4703,10 @@
         protected void checkKeyIntent(
                 int authUid,
                 Intent intent) throws SecurityException {
+            intent.setFlags(intent.getFlags() & ~(Intent.FLAG_GRANT_READ_URI_PERMISSION
+                    | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
+                    | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
+                    | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION));
             long bid = Binder.clearCallingIdentity();
             try {
                 PackageManager pm = mContext.getPackageManager();
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 186d0f4..64eb970 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -8629,6 +8629,19 @@
             return -1;
         }
 
+        // Bail early if system is trying to hand out permissions directly; it
+        // must always grant permissions on behalf of someone explicit.
+        final int callingAppId = UserHandle.getAppId(callingUid);
+        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
+            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
+                // Exempted authority for cropping user photos in Settings app
+            } else {
+                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
+                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
+                return -1;
+            }
+        }
+
         final String authority = grantUri.uri.getAuthority();
         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
                 MATCH_DEBUG_TRIAGED_MISSING);
@@ -8724,16 +8737,6 @@
 
         // Third...  does the caller itself have permission to access
         // this uri?
-        final int callingAppId = UserHandle.getAppId(callingUid);
-        if ((callingAppId == SYSTEM_UID) || (callingAppId == ROOT_UID)) {
-            if ("com.android.settings.files".equals(grantUri.uri.getAuthority())) {
-                // Exempted authority for cropping user photos in Settings app
-            } else {
-                Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
-                        + " grant to " + grantUri + "; use startActivityAsCaller() instead");
-                return -1;
-            }
-        }
         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
             // Require they hold a strong enough Uri permission
             if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {