summaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorJeff Sharkey <jsharkey@android.com>2013-08-12 03:59:58 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2013-08-12 03:59:58 +0000
commit998cfa2c63c54a73d0c51d062408d370ed0b3107 (patch)
tree96744ed8f740850b5933ac043855b4b7da533520 /core
parentc2f8da8756553bb682e0e202779063965a89dced (diff)
parent08da7a1143b0c9cfb703971d882e0886bbd7d9de (diff)
downloadframeworks_base-998cfa2c63c54a73d0c51d062408d370ed0b3107.zip
frameworks_base-998cfa2c63c54a73d0c51d062408d370ed0b3107.tar.gz
frameworks_base-998cfa2c63c54a73d0c51d062408d370ed0b3107.tar.bz2
Merge "API to discover granted Uri permissions." into klp-dev
Diffstat (limited to 'core')
-rw-r--r--core/java/android/app/ActivityManagerNative.java31
-rw-r--r--core/java/android/app/IActivityManager.java5
-rw-r--r--core/java/android/content/ContentResolver.java57
-rw-r--r--core/java/android/provider/DocumentsContract.java46
4 files changed, 133 insertions, 6 deletions
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 @@ public abstract class ActivityManagerNative extends Binder implements IActivityM
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 @@ class ActivityManagerProxy implements IActivityManager
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;
}
diff --git a/core/java/android/app/IActivityManager.java b/core/java/android/app/IActivityManager.java
index 3851eb3..6d1b6fc 100644
--- a/core/java/android/app/IActivityManager.java
+++ b/core/java/android/app/IActivityManager.java
@@ -399,6 +399,10 @@ public interface IActivityManager extends IInterface {
public void restart() throws RemoteException;
+ public Uri[] getGrantedUriPermissions(
+ String sourcePackage, String targetPackage, int modeFlags, int modeMask)
+ throws RemoteException;
+
/*
* Private non-Binder interfaces
*/
@@ -680,4 +684,5 @@ public interface IActivityManager extends IInterface {
int NOTIFY_ACTIVITY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+175;
int REPORT_ACTIVITY_FULLY_DRAWN_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+176;
int RESTART_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+177;
+ int GET_GRANTED_URI_PERMISSIONS_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+178;
}
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 243c91a..45fed2d 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -16,8 +16,6 @@
package android.content;
-import dalvik.system.CloseGuard;
-
import android.accounts.Account;
import android.app.ActivityManagerNative;
import android.app.ActivityThread;
@@ -44,7 +42,8 @@ import android.os.UserHandle;
import android.text.TextUtils;
import android.util.EventLog;
import android.util.Log;
-import android.util.Pair;
+
+import dalvik.system.CloseGuard;
import java.io.File;
import java.io.FileInputStream;
@@ -1389,6 +1388,58 @@ public abstract class ContentResolver {
}
/**
+ * Return list of all Uri permissions that have been granted <em>to</em> the
+ * calling package, and which exactly match the requested flags. For
+ * example, to return all Uris that the calling application has
+ * <em>non-persistent</em> read access to:
+ *
+ * <pre class="prettyprint">
+ * getIncomingUriPermissionGrants(Intent.FLAG_GRANT_READ_URI_PERMISSION,
+ * Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
+ * </pre>
+ *
+ * @param modeFlags any combination of
+ * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION},
+ * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}, or
+ * {@link Intent#FLAG_PERSIST_GRANT_URI_PERMISSION}.
+ * @param modeMask mask indicating which flags must match.
+ */
+ public Uri[] getIncomingUriPermissionGrants(int modeFlags, int modeMask) {
+ try {
+ return ActivityManagerNative.getDefault()
+ .getGrantedUriPermissions(null, getPackageName(), modeFlags, modeMask);
+ } catch (RemoteException e) {
+ return new Uri[0];
+ }
+ }
+
+ /**
+ * Return list of all Uri permissions that have been granted <em>from</em> the
+ * calling package, and which exactly match the requested flags. For
+ * example, to return all Uris that the calling application has granted
+ * <em>non-persistent</em> read access to:
+ *
+ * <pre class="prettyprint">
+ * getOutgoingUriPermissionGrants(Intent.FLAG_GRANT_READ_URI_PERMISSION,
+ * Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION);
+ * </pre>
+ *
+ * @param modeFlags any combination of
+ * {@link Intent#FLAG_GRANT_READ_URI_PERMISSION},
+ * {@link Intent#FLAG_GRANT_WRITE_URI_PERMISSION}, or
+ * {@link Intent#FLAG_PERSIST_GRANT_URI_PERMISSION}.
+ * @param modeMask mask indicating which flags must match.
+ */
+ public Uri[] getOutgoingUriPermissionGrants(int modeFlags, int modeMask) {
+ try {
+ return ActivityManagerNative.getDefault()
+ .getGrantedUriPermissions(getPackageName(), null, modeFlags, modeMask);
+ } catch (RemoteException e) {
+ return new Uri[0];
+ }
+ }
+
+ /**
* Start an asynchronous sync operation. If you want to monitor the progress
* of the sync you may register a SyncObserver. Only values of the following
* types may be used in the extras bundle:
diff --git a/core/java/android/provider/DocumentsContract.java b/core/java/android/provider/DocumentsContract.java
index acaed73..53f5d58 100644
--- a/core/java/android/provider/DocumentsContract.java
+++ b/core/java/android/provider/DocumentsContract.java
@@ -19,7 +19,9 @@ package android.provider;
import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
+import android.content.Context;
import android.content.Intent;
+import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.res.AssetFileDescriptor;
import android.database.Cursor;
@@ -30,6 +32,8 @@ import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
+import com.google.android.collect.Lists;
+
import libcore.io.IoUtils;
import java.io.IOException;
@@ -201,19 +205,25 @@ public final class DocumentsContract {
public static String getRootId(Uri documentUri) {
final List<String> paths = documentUri.getPathSegments();
+ if (paths.size() < 2) {
+ throw new IllegalArgumentException("Not a root: " + documentUri);
+ }
if (!PATH_ROOTS.equals(paths.get(0))) {
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Not a root: " + documentUri);
}
return paths.get(1);
}
public static String getDocId(Uri documentUri) {
final List<String> paths = documentUri.getPathSegments();
+ if (paths.size() < 4) {
+ throw new IllegalArgumentException("Not a document: " + documentUri);
+ }
if (!PATH_ROOTS.equals(paths.get(0))) {
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Not a document: " + documentUri);
}
if (!PATH_DOCS.equals(paths.get(2))) {
- throw new IllegalArgumentException();
+ throw new IllegalArgumentException("Not a document: " + documentUri);
}
return paths.get(3);
}
@@ -359,6 +369,36 @@ public final class DocumentsContract {
}
/**
+ * Return list of all documents that the calling package has "open." These
+ * are Uris matching {@link DocumentsContract} to which persistent
+ * read/write access has been granted, usually through
+ * {@link Intent#ACTION_OPEN_DOCUMENT} or
+ * {@link Intent#ACTION_CREATE_DOCUMENT}.
+ *
+ * @see Context#grantUriPermission(String, Uri, int)
+ * @see ContentResolver#getIncomingUriPermissionGrants(int, int)
+ */
+ public static Uri[] getOpenDocuments(Context context) {
+ final int openedFlags = Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_PERSIST_GRANT_URI_PERMISSION;
+ final Uri[] uris = context.getContentResolver()
+ .getIncomingUriPermissionGrants(openedFlags, openedFlags);
+
+ // Filter to only include document providers
+ final PackageManager pm = context.getPackageManager();
+ final List<Uri> result = Lists.newArrayList();
+ for (Uri uri : uris) {
+ final ProviderInfo info = pm.resolveContentProvider(
+ uri.getAuthority(), PackageManager.GET_META_DATA);
+ if (info.metaData.containsKey(META_DATA_DOCUMENT_PROVIDER)) {
+ result.add(uri);
+ }
+ }
+
+ return result.toArray(new Uri[result.size()]);
+ }
+
+ /**
* Return thumbnail representing the document at the given URI. Callers are
* responsible for their own caching. Given document must have
* {@link #FLAG_SUPPORTS_THUMBNAIL} set.