summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2019-02-16 22:35:22 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2019-02-16 22:35:22 +0000
commitcbb05a317b39ef314c5fb2e2a017f70c50ee68f5 (patch)
treeccdc8e6d66c1091d9aab875762be097a5f24ccd1
parent2f9b0bd21e624a6578f1b383f40a7f945cc905a2 (diff)
parentcfd2fbc4e3223afd79ed32fdfbdf09fa7ddfa43b (diff)
Merge changes I9ed87db1,Ic0b766f6
* changes: Make PermissionControllerManager user aware Check same uid for permission and app-op
-rw-r--r--api/system-current.txt1
-rw-r--r--core/java/android/app/AppOpsManager.java40
-rw-r--r--core/java/android/content/PermissionChecker.java6
-rw-r--r--core/java/android/permission/PermissionControllerManager.java55
4 files changed, 75 insertions, 27 deletions
diff --git a/api/system-current.txt b/api/system-current.txt
index 50a2553d7f1a..142068cdb48f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -309,6 +309,7 @@ package android.app {
method @Deprecated @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, String, int[]);
method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getOpsForPackage(int, @NonNull String, @Nullable java.lang.String...);
method @NonNull @RequiresPermission(android.Manifest.permission.GET_APP_OPS_STATS) public java.util.List<android.app.AppOpsManager.PackageOps> getPackagesForOps(@Nullable String[]);
+ method public int noteProxyOpNoThrow(@NonNull String, @Nullable String, int);
method public static int opToDefaultMode(@NonNull String);
method @Nullable public static String opToPermission(@NonNull String);
method @RequiresPermission("android.permission.MANAGE_APP_OPS_MODES") public void setMode(String, int, String, int);
diff --git a/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java
index f76f7b9a7fc7..13eec580ec14 100644
--- a/core/java/android/app/AppOpsManager.java
+++ b/core/java/android/app/AppOpsManager.java
@@ -4291,12 +4291,35 @@ public class AppOpsManager {
/**
* Like {@link #noteProxyOp(String, String)} but instead
* of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
+ *
+ * <p>This API requires the package with the {@code proxiedPackageName} to belongs to
+ * {@link Binder#getCallingUid()}.
*/
public int noteProxyOpNoThrow(String op, String proxiedPackageName) {
return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName);
}
/**
+ * Like {@link #noteProxyOp(String, String)} but instead
+ * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
+ *
+ * <p>This API requires package with the {@code proxiedPackageName} to belong to
+ * {@code proxiedUid}.
+ *
+ * @param op The op to note
+ * @param proxiedPackageName The package to note the op for or {@code null} if the op should be
+ * noted for the "android" package
+ * @param proxiedUid The uid the package belongs to
+ *
+ * @hide
+ */
+ @SystemApi
+ public int noteProxyOpNoThrow(@NonNull String op, @Nullable String proxiedPackageName,
+ int proxiedUid) {
+ return noteProxyOpNoThrow(strOpToOp(op), proxiedPackageName, proxiedUid);
+ }
+
+ /**
* Report that an application has started executing a long-running operation. Note that you
* must pass in both the uid and name of the application to be checked; this function will
* verify that these two match, and if not, return {@link #MODE_IGNORED}. If this call
@@ -4495,17 +4518,30 @@ public class AppOpsManager {
* of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
* @hide
*/
- public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
+ public int noteProxyOpNoThrow(int op, String proxiedPackageName, int proxiedUid) {
logOperationIfNeeded(op, mContext.getOpPackageName(), proxiedPackageName);
try {
return mService.noteProxyOperation(op, Process.myUid(), mContext.getOpPackageName(),
- Binder.getCallingUid(), proxiedPackageName);
+ proxiedUid, proxiedPackageName);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
/**
+ * Like {@link #noteProxyOp(int, String)} but instead
+ * of throwing a {@link SecurityException} it returns {@link #MODE_ERRORED}.
+ *
+ * <p>This API requires the package with {@code proxiedPackageName} to belongs to
+ * {@link Binder#getCallingUid()}.
+ *
+ * @hide
+ */
+ public int noteProxyOpNoThrow(int op, String proxiedPackageName) {
+ return noteProxyOpNoThrow(op, proxiedPackageName, Binder.getCallingUid());
+ }
+
+ /**
* Like {@link #noteOp} but instead of throwing a {@link SecurityException} it
* returns {@link #MODE_ERRORED}.
* @hide
diff --git a/core/java/android/content/PermissionChecker.java b/core/java/android/content/PermissionChecker.java
index 9f5c877e7081..6fe6e991fb1e 100644
--- a/core/java/android/content/PermissionChecker.java
+++ b/core/java/android/content/PermissionChecker.java
@@ -108,8 +108,7 @@ public final class PermissionChecker {
packageName = packageNames[0];
}
- if (appOpsManager.noteProxyOpNoThrow(op, packageName)
- != AppOpsManager.MODE_ALLOWED) {
+ if (appOpsManager.noteProxyOpNoThrow(op, packageName, uid) != AppOpsManager.MODE_ALLOWED) {
return PERMISSION_DENIED_APP_OP;
}
@@ -120,6 +119,9 @@ public final class PermissionChecker {
* Checks whether your app has a given permission and whether the app op
* that corresponds to this permission is allowed.
*
+ * <p>This API assumes the the {@link Binder#getCallingUid()} is the same as
+ * {@link Process#myUid()}.
+ *
* @param context Context for accessing resources.
* @param permission The permission to check.
* @return The permission check result which is either {@link #PERMISSION_GRANTED}
diff --git a/core/java/android/permission/PermissionControllerManager.java b/core/java/android/permission/PermissionControllerManager.java
index addfe3da39b3..d62bc6c5a872 100644
--- a/core/java/android/permission/PermissionControllerManager.java
+++ b/core/java/android/permission/PermissionControllerManager.java
@@ -51,6 +51,7 @@ import android.os.RemoteException;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Log;
+import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.infra.AbstractMultiplePendingRequestsRemoteService;
@@ -85,9 +86,11 @@ public final class PermissionControllerManager {
private static final Object sLock = new Object();
- /** App global remote service used by all {@link PermissionControllerManager managers} */
+ /**
+ * Global remote services (per user) used by all {@link PermissionControllerManager managers}
+ */
@GuardedBy("sLock")
- private static RemoteService sRemoteService;
+ private static SparseArray<RemoteService> sRemoteServices = new SparseArray<>(1);
/**
* The key for retrieving the result from the returned bundle.
@@ -203,6 +206,7 @@ public final class PermissionControllerManager {
}
private final @NonNull Context mContext;
+ private final @NonNull RemoteService mRemoteService;
/**
* Create a new {@link PermissionControllerManager}.
@@ -213,14 +217,18 @@ public final class PermissionControllerManager {
*/
public PermissionControllerManager(@NonNull Context context) {
synchronized (sLock) {
- if (sRemoteService == null) {
+ RemoteService remoteService = sRemoteServices.get(context.getUserId(), null);
+ if (remoteService == null) {
Intent intent = new Intent(SERVICE_INTERFACE);
intent.setPackage(context.getPackageManager().getPermissionControllerPackageName());
ResolveInfo serviceInfo = context.getPackageManager().resolveService(intent, 0);
- sRemoteService = new RemoteService(context.getApplicationContext(),
- serviceInfo.getComponentInfo().getComponentName());
+ remoteService = new RemoteService(context.getApplicationContext(),
+ serviceInfo.getComponentInfo().getComponentName(), context.getUser());
+ sRemoteServices.put(context.getUserId(), remoteService);
}
+
+ mRemoteService = remoteService;
}
mContext = context;
@@ -255,7 +263,7 @@ public final class PermissionControllerManager {
+ " required");
}
- sRemoteService.scheduleRequest(new PendingRevokeRuntimePermissionRequest(sRemoteService,
+ mRemoteService.scheduleRequest(new PendingRevokeRuntimePermissionRequest(mRemoteService,
request, doDryRun, reason, mContext.getPackageName(), executor, callback));
}
@@ -276,7 +284,7 @@ public final class PermissionControllerManager {
checkNotNull(executor);
checkNotNull(callback);
- sRemoteService.scheduleRequest(new PendingGetRuntimePermissionBackup(sRemoteService,
+ mRemoteService.scheduleRequest(new PendingGetRuntimePermissionBackup(mRemoteService,
user, executor, callback));
}
@@ -294,8 +302,8 @@ public final class PermissionControllerManager {
checkNotNull(backup);
checkNotNull(user);
- sRemoteService.scheduleAsyncRequest(
- new PendingRestoreRuntimePermissionBackup(sRemoteService, backup, user));
+ mRemoteService.scheduleAsyncRequest(
+ new PendingRestoreRuntimePermissionBackup(mRemoteService, backup, user));
}
/**
@@ -318,8 +326,8 @@ public final class PermissionControllerManager {
checkNotNull(executor);
checkNotNull(callback);
- sRemoteService.scheduleRequest(
- new PendingRestoreDelayedRuntimePermissionBackup(sRemoteService, packageName,
+ mRemoteService.scheduleRequest(
+ new PendingRestoreDelayedRuntimePermissionBackup(mRemoteService, packageName,
user, executor, callback));
}
@@ -338,8 +346,8 @@ public final class PermissionControllerManager {
checkNotNull(packageName);
checkNotNull(callback);
- sRemoteService.scheduleRequest(new PendingGetAppPermissionRequest(sRemoteService,
- packageName, callback, handler == null ? sRemoteService.getHandler() : handler));
+ mRemoteService.scheduleRequest(new PendingGetAppPermissionRequest(mRemoteService,
+ packageName, callback, handler == null ? mRemoteService.getHandler() : handler));
}
/**
@@ -356,7 +364,7 @@ public final class PermissionControllerManager {
checkNotNull(packageName);
checkNotNull(permissionName);
- sRemoteService.scheduleAsyncRequest(new PendingRevokeAppPermissionRequest(packageName,
+ mRemoteService.scheduleAsyncRequest(new PendingRevokeAppPermissionRequest(packageName,
permissionName));
}
@@ -379,9 +387,9 @@ public final class PermissionControllerManager {
checkFlagsArgument(flags, COUNT_WHEN_SYSTEM | COUNT_ONLY_WHEN_GRANTED);
checkNotNull(callback);
- sRemoteService.scheduleRequest(new PendingCountPermissionAppsRequest(sRemoteService,
+ mRemoteService.scheduleRequest(new PendingCountPermissionAppsRequest(mRemoteService,
permissionNames, flags, callback,
- handler == null ? sRemoteService.getHandler() : handler));
+ handler == null ? mRemoteService.getHandler() : handler));
}
/**
@@ -402,7 +410,7 @@ public final class PermissionControllerManager {
checkNotNull(executor);
checkNotNull(callback);
- sRemoteService.scheduleRequest(new PendingGetPermissionUsagesRequest(sRemoteService,
+ mRemoteService.scheduleRequest(new PendingGetPermissionUsagesRequest(mRemoteService,
countSystem, numMillis, executor, callback));
}
@@ -424,8 +432,8 @@ public final class PermissionControllerManager {
checkNotNull(executor);
checkNotNull(callback);
- sRemoteService.scheduleRequest(new PendingIsApplicationQualifiedForRoleRequest(
- sRemoteService, roleName, packageName, executor, callback));
+ mRemoteService.scheduleRequest(new PendingIsApplicationQualifiedForRoleRequest(
+ mRemoteService, roleName, packageName, executor, callback));
}
/**
@@ -441,11 +449,12 @@ public final class PermissionControllerManager {
*
* @param context A context to use
* @param componentName The component of the service to connect to
+ * @param user User the remote service should be connected as
*/
- RemoteService(@NonNull Context context, @NonNull ComponentName componentName) {
- super(context, SERVICE_INTERFACE, componentName, UserHandle.myUserId(),
- service -> Log.e(TAG, "RuntimePermPresenterService " + service + " died"),
- false, false, 1);
+ RemoteService(@NonNull Context context, @NonNull ComponentName componentName,
+ @NonNull UserHandle user) {
+ super(context, SERVICE_INTERFACE, componentName, user.getIdentifier(),
+ service -> Log.e(TAG, "RemoteService " + service + " died"), false, false, 1);
}
/**