summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/api/current.txt3
-rw-r--r--core/java/android/app/ContextImpl.java32
-rw-r--r--core/java/android/app/IActivityManager.aidl2
-rw-r--r--core/java/android/content/Context.java75
-rw-r--r--core/java/android/content/ContextWrapper.java20
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java18
6 files changed, 150 insertions, 0 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index e264f1ddddb6..583bbcf370c0 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -10226,12 +10226,15 @@ package android.content {
method @RequiresPermission(anyOf={"android.permission.INTERACT_ACROSS_USERS", android.Manifest.permission.INTERACT_ACROSS_PROFILES}) public boolean bindServiceAsUser(@NonNull @RequiresPermission android.content.Intent, @NonNull android.content.ServiceConnection, int, @NonNull android.os.UserHandle);
method @CheckResult(suggest="#enforceCallingOrSelfPermission(String,String)") public abstract int checkCallingOrSelfPermission(@NonNull String);
method @CheckResult(suggest="#enforceCallingOrSelfUriPermission(Uri,int,String)") public abstract int checkCallingOrSelfUriPermission(android.net.Uri, int);
+ method @NonNull public int[] checkCallingOrSelfUriPermissions(@NonNull java.util.List<android.net.Uri>, int);
method @CheckResult(suggest="#enforceCallingPermission(String,String)") public abstract int checkCallingPermission(@NonNull String);
method @CheckResult(suggest="#enforceCallingUriPermission(Uri,int,String)") public abstract int checkCallingUriPermission(android.net.Uri, int);
+ method @NonNull public int[] checkCallingUriPermissions(@NonNull java.util.List<android.net.Uri>, int);
method @CheckResult(suggest="#enforcePermission(String,int,int,String)") public abstract int checkPermission(@NonNull String, int, int);
method public abstract int checkSelfPermission(@NonNull String);
method @CheckResult(suggest="#enforceUriPermission(Uri,int,int,String)") public abstract int checkUriPermission(android.net.Uri, int, int, int);
method @CheckResult(suggest="#enforceUriPermission(Uri,String,String,int,int,int,String)") public abstract int checkUriPermission(@Nullable android.net.Uri, @Nullable String, @Nullable String, int, int, int);
+ method @NonNull public int[] checkUriPermissions(@NonNull java.util.List<android.net.Uri>, int, int, int);
method @Deprecated public abstract void clearWallpaper() throws java.io.IOException;
method @NonNull public android.content.Context createAttributionContext(@Nullable String);
method public abstract android.content.Context createConfigurationContext(@NonNull android.content.res.Configuration);
diff --git a/core/java/android/app/ContextImpl.java b/core/java/android/app/ContextImpl.java
index 9a20e0fefd33..85fb543a3967 100644
--- a/core/java/android/app/ContextImpl.java
+++ b/core/java/android/app/ContextImpl.java
@@ -16,6 +16,7 @@
package android.app;
+import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.StrictMode.vmIncorrectContextUseEnabled;
@@ -105,6 +106,7 @@ import java.lang.annotation.RetentionPolicy;
import java.nio.ByteOrder;
import java.nio.file.Path;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.Executor;
@@ -2181,6 +2183,18 @@ class ContextImpl extends Context {
}
}
+ @NonNull
+ @Override
+ public int[] checkUriPermissions(@NonNull List<Uri> uris, int pid, int uid,
+ int modeFlags) {
+ try {
+ return ActivityManager.getService().checkUriPermissions(uris, pid, uid, modeFlags,
+ null);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
/** @hide */
@Override
public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) {
@@ -2207,12 +2221,30 @@ class ContextImpl extends Context {
return PackageManager.PERMISSION_DENIED;
}
+ @NonNull
+ @Override
+ public int[] checkCallingUriPermissions(@NonNull List<Uri> uris, int modeFlags) {
+ int pid = Binder.getCallingPid();
+ if (pid != Process.myPid()) {
+ return checkUriPermissions(uris, pid, Binder.getCallingUid(), modeFlags);
+ }
+ int[] res = new int[uris.size()];
+ Arrays.fill(res, PERMISSION_DENIED);
+ return res;
+ }
+
@Override
public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
return checkUriPermission(uri, Binder.getCallingPid(),
Binder.getCallingUid(), modeFlags);
}
+ @NonNull
+ @Override
+ public int[] checkCallingOrSelfUriPermissions(@NonNull List<Uri> uris, int modeFlags) {
+ return checkUriPermissions(uris, Binder.getCallingPid(), Binder.getCallingUid(), modeFlags);
+ }
+
@Override
public int checkUriPermission(Uri uri, String readPermission,
String writePermission, int pid, int uid, int modeFlags) {
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index e73636fe7fd0..4ad13e1932dd 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -220,6 +220,8 @@ interface IActivityManager {
int getProcessLimit();
int checkUriPermission(in Uri uri, int pid, int uid, int mode, int userId,
in IBinder callerToken);
+ int[] checkUriPermissions(in List<Uri> uris, int pid, int uid, int mode,
+ in IBinder callerToken);
void grantUriPermission(in IApplicationThread caller, in String targetPkg, in Uri uri,
int mode, int userId);
void revokeUriPermission(in IApplicationThread caller, in String targetPkg, in Uri uri,
diff --git a/core/java/android/content/Context.java b/core/java/android/content/Context.java
index 025d777f2053..24b76292fb7b 100644
--- a/core/java/android/content/Context.java
+++ b/core/java/android/content/Context.java
@@ -93,6 +93,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.util.List;
import java.util.concurrent.Executor;
/**
@@ -5725,6 +5726,32 @@ public abstract class Context {
public abstract int checkUriPermission(Uri uri, int pid, int uid,
@Intent.AccessUriMode int modeFlags);
+ /**
+ * Determine whether a particular process and user ID has been granted
+ * permission to access a list of URIs. This only checks for permissions
+ * that have been explicitly granted -- if the given process/uid has
+ * more general access to the URI's content provider then this check will
+ * always fail.
+ *
+ * @param uris The list of URIs that is being checked.
+ * @param pid The process ID being checked against. Must be &gt; 0.
+ * @param uid The user ID being checked against. A uid of 0 is the root
+ * user, which will pass every permission check.
+ * @param modeFlags The access modes to check for the list of uris
+ *
+ * @return Array of permission grants corresponding to each entry in the list of uris.
+ * {@link PackageManager#PERMISSION_GRANTED} if the given pid/uid is allowed to access that uri,
+ * or {@link PackageManager#PERMISSION_DENIED} if it is not.
+ *
+ * @see #checkCallingUriPermission
+ */
+ @NonNull
+ @PackageManager.PermissionResult
+ public int[] checkUriPermissions(@NonNull List<Uri> uris, int pid, int uid,
+ @Intent.AccessUriMode int modeFlags) {
+ throw new RuntimeException("Not implemented. Must override in a subclass.");
+ }
+
/** @hide */
@SuppressWarnings("HiddenAbstractMethod")
@PackageManager.PermissionResult
@@ -5755,6 +5782,32 @@ public abstract class Context {
public abstract int checkCallingUriPermission(Uri uri, @Intent.AccessUriMode int modeFlags);
/**
+ * Determine whether the calling process and user ID has been
+ * granted permission to access a list of URIs. This is basically
+ * the same as calling {@link #checkUriPermissions(List, int, int, int)}
+ * with the pid and uid returned by {@link
+ * android.os.Binder#getCallingPid} and {@link
+ * android.os.Binder#getCallingUid}. One important difference is
+ * that if you are not currently processing an IPC, this function
+ * will always fail.
+ *
+ * @param uris The list of URIs that is being checked.
+ * @param modeFlags The access modes to check.
+ *
+ * @return Array of permission grants corresponding to each entry in the list of uris.
+ * {@link PackageManager#PERMISSION_GRANTED} if the given pid/uid is allowed to access that uri,
+ * or {@link PackageManager#PERMISSION_DENIED} if it is not.
+ *
+ * @see #checkUriPermission(Uri, int, int, int)
+ */
+ @NonNull
+ @PackageManager.PermissionResult
+ public int[] checkCallingUriPermissions(@NonNull List<Uri> uris,
+ @Intent.AccessUriMode int modeFlags) {
+ throw new RuntimeException("Not implemented. Must override in a subclass.");
+ }
+
+ /**
* Determine whether the calling process of an IPC <em>or you</em> has been granted
* permission to access a specific URI. This is the same as
* {@link #checkCallingUriPermission}, except it grants your own permissions
@@ -5775,6 +5828,28 @@ public abstract class Context {
@Intent.AccessUriMode int modeFlags);
/**
+ * Determine whether the calling process of an IPC <em>or you</em> has been granted
+ * permission to access a list of URIs. This is the same as
+ * {@link #checkCallingUriPermission}, except it grants your own permissions
+ * if you are not currently processing an IPC. Use with care!
+ *
+ * @param uris The list of URIs that is being checked.
+ * @param modeFlags The access modes to check.
+ *
+ * @return Array of permission grants corresponding to each entry in the list of uris.
+ * {@link PackageManager#PERMISSION_GRANTED} if the given pid/uid is allowed to access that uri,
+ * or {@link PackageManager#PERMISSION_DENIED} if it is not.
+ *
+ * @see #checkCallingUriPermission
+ */
+ @NonNull
+ @PackageManager.PermissionResult
+ public int[] checkCallingOrSelfUriPermissions(@NonNull List<Uri> uris,
+ @Intent.AccessUriMode int modeFlags) {
+ throw new RuntimeException("Not implemented. Must override in a subclass.");
+ }
+
+ /**
* Check both a Uri and normal permission. This allows you to perform
* both {@link #checkPermission} and {@link #checkUriPermission} in one
* call.
diff --git a/core/java/android/content/ContextWrapper.java b/core/java/android/content/ContextWrapper.java
index c1c213eee81b..b71fb2712c24 100644
--- a/core/java/android/content/ContextWrapper.java
+++ b/core/java/android/content/ContextWrapper.java
@@ -53,6 +53,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.util.List;
import java.util.concurrent.Executor;
/**
@@ -905,6 +906,13 @@ public class ContextWrapper extends Context {
return mBase.checkUriPermission(uri, pid, uid, modeFlags);
}
+ @NonNull
+ @Override
+ public int[] checkUriPermissions(@NonNull List<Uri> uris, int pid, int uid,
+ int modeFlags) {
+ return mBase.checkUriPermissions(uris, pid, uid, modeFlags);
+ }
+
/** @hide */
@Override
public int checkUriPermission(Uri uri, int pid, int uid, int modeFlags, IBinder callerToken) {
@@ -916,11 +924,23 @@ public class ContextWrapper extends Context {
return mBase.checkCallingUriPermission(uri, modeFlags);
}
+ @NonNull
+ @Override
+ public int[] checkCallingUriPermissions(@NonNull List<Uri> uris, int modeFlags) {
+ return mBase.checkCallingUriPermissions(uris, modeFlags);
+ }
+
@Override
public int checkCallingOrSelfUriPermission(Uri uri, int modeFlags) {
return mBase.checkCallingOrSelfUriPermission(uri, modeFlags);
}
+ @NonNull
+ @Override
+ public int[] checkCallingOrSelfUriPermissions(@NonNull List<Uri> uris, int modeFlags) {
+ return mBase.checkCallingOrSelfUriPermissions(uris, modeFlags);
+ }
+
@Override
public int checkUriPermission(@Nullable Uri uri, @Nullable String readPermission,
@Nullable String writePermission, int pid, int uid, int modeFlags) {
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index bedd19b6864a..163845c2e0a8 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -186,6 +186,7 @@ import android.content.BroadcastReceiver;
import android.content.ComponentCallbacks2;
import android.content.ComponentName;
import android.content.ContentCaptureOptions;
+import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.Context;
import android.content.IIntentReceiver;
@@ -5626,6 +5627,23 @@ public class ActivityManagerService extends IActivityManager.Stub
? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED;
}
+ @Override
+ public int[] checkUriPermissions(@NonNull List<Uri> uris, int pid, int uid,
+ final int modeFlags, IBinder callerToken) {
+ final int size = uris.size();
+ int[] res = new int[size];
+ // Default value DENIED.
+ Arrays.fill(res, PackageManager.PERMISSION_DENIED);
+
+ for (int i = 0; i < size; i++) {
+ final Uri uri = uris.get(i);
+ final int userId = ContentProvider.getUserIdFromUri(uri, mContext.getUserId());
+ res[i] = checkUriPermission(ContentProvider.getUriWithoutUserId(uri), pid, uid,
+ modeFlags, userId, callerToken);
+ }
+ return res;
+ }
+
/**
* @param uri This uri must NOT contain an embedded userId.
* @param userId The userId in which the uri is to be resolved.