API to discover granted Uri permissions.

Now that granted Uri permissions can be persisted across reboots,
offer APIs to discover them. Returns incoming or outgoing grants
matching the requested flags and mask. Add helper method to discover
"open" documents using this new API and filtering for non-documents.

Require that callers own at least of the filtering packages to avoid
exposing all grants. Switch internal grant tracking to use ArrayMap.

Change-Id: I0a755f221d0d160b411f8d3cfc48279b64345733
diff --git a/core/java/android/app/ActivityManagerNative.java b/core/java/android/app/ActivityManagerNative.java
index cc964c2..6a29552 100644
--- a/core/java/android/app/ActivityManagerNative.java
+++ b/core/java/android/app/ActivityManagerNative.java
@@ -1980,6 +1980,19 @@
             reply.writeNoException();
             return true;
         }
+
+        case GET_GRANTED_URI_PERMISSIONS_TRANSACTION: {
+            data.enforceInterface(IActivityManager.descriptor);
+            final String sourcePackage = data.readString();
+            final String targetPackage = data.readString();
+            final int modeFlags = data.readInt();
+            final int modeMask = data.readInt();
+            final Uri[] uris = getGrantedUriPermissions(
+                    sourcePackage, targetPackage, modeFlags, modeMask);
+            reply.writeNoException();
+            reply.writeParcelableArray(uris, 0);
+            return true;
+        }
         }
 
         return super.onTransact(code, data, reply, flags);
@@ -4540,5 +4553,23 @@
         reply.recycle();
     }
 
+    public Uri[] getGrantedUriPermissions(
+            String sourcePackage, String targetPackage, int modeFlags, int modeMask)
+            throws RemoteException {
+        Parcel data = Parcel.obtain();
+        Parcel reply = Parcel.obtain();
+        data.writeInterfaceToken(IActivityManager.descriptor);
+        data.writeString(sourcePackage);
+        data.writeString(targetPackage);
+        data.writeInt(modeFlags);
+        data.writeInt(modeMask);
+        mRemote.transact(GET_GRANTED_URI_PERMISSIONS_TRANSACTION, data, reply, 0);
+        reply.readException();
+        final Uri[] uris = (Uri[]) reply.readParcelableArray(null);
+        data.recycle();
+        reply.recycle();
+        return uris;
+    }
+
     private IBinder mRemote;
 }