Pipe start op throught app ops policy and delegate
bug: 185504196
Test: atest CtsAppOpsTestCases
atest CtsPermissionTestCases
atest CtsPermission2TestCases
atest CtsPermission3TestCases
atest CtsPermission4TestCases
atest CtsPermission5TestCases
Change-Id: I5869a3e9719830f59624519f2d54f0765119cf5f
diff --git a/core/java/android/app/AppOpsManagerInternal.java b/core/java/android/app/AppOpsManagerInternal.java
index 6af4d93..341b9c5 100644
--- a/core/java/android/app/AppOpsManagerInternal.java
+++ b/core/java/android/app/AppOpsManagerInternal.java
@@ -26,6 +26,7 @@
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.HexFunction;
+import com.android.internal.util.function.NonaFunction;
import com.android.internal.util.function.OctFunction;
import com.android.internal.util.function.QuadFunction;
import com.android.internal.util.function.TriFunction;
@@ -101,8 +102,31 @@
Boolean, SyncNotedAppOp> superImpl);
/**
+ * Allows overriding start operation behavior.
+ *
+ * @param token The client state.
+ * @param code The op code to start.
+ * @param uid The UID for which to note.
+ * @param packageName The package for which to note. {@code null} for system package.
+ * @param attributionTag the attribution tag.
+ * @param startIfModeDefault Whether to start the op of the mode is default.
+ * @param shouldCollectAsyncNotedOp If an {@link AsyncNotedAppOp} should be collected
+ * @param message The message in the async noted op
+ * @param shouldCollectMessage whether to collect messages
+ * @param superImpl The super implementation.
+ * @return The app op note result.
+ */
+ SyncNotedAppOp startOperation(IBinder token, int code, int uid,
+ @Nullable String packageName, @Nullable String attributionTag,
+ boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
+ @Nullable String message, boolean shouldCollectMessage, @NonNull NonaFunction<
+ IBinder, Integer, Integer, String, String, Boolean, Boolean, String,
+ Boolean, SyncNotedAppOp> superImpl);
+
+ /**
* Allows overriding start proxy operation behavior.
*
+ * @param token The client state.
* @param code The op code to start.
* @param attributionSource The permission identity of the caller.
* @param startIfModeDefault Whether to start the op of the mode is default.
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 64c914e..890f982 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -344,6 +344,7 @@
<permission name="android.permission.ACTIVITY_EMBEDDING"/>
<permission name="android.permission.FORCE_STOP_PACKAGES"/>
<permission name="android.permission.GET_APP_OPS_STATS"/>
+ <permission name="android.permission.WATCH_APPOPS"/>
<permission name="android.permission.INSTALL_DYNAMIC_SYSTEM"/>
<permission name="android.permission.INSTALL_LOCATION_PROVIDER"/>
<permission name="android.permission.INSTALL_PACKAGES"/>
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 0958e54..8cfa0cf 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -299,6 +299,7 @@
<uses-permission android:name="android.permission.COMPANION_APPROVE_WIFI_CONNECTIONS" />
<uses-permission android:name="android.permission.MANAGE_APPOPS" />
+ <uses-permission android:name="android.permission.WATCH_APPOPS" />
<!-- Permission required for IncrementalLogCollectionTest -->
<uses-permission android:name="android.permission.LOADER_USAGE_STATS" />
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 4b640a6..8094566 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -346,6 +346,7 @@
import com.android.internal.util.Preconditions;
import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.HexFunction;
+import com.android.internal.util.function.NonaFunction;
import com.android.internal.util.function.OctFunction;
import com.android.internal.util.function.QuadFunction;
import com.android.internal.util.function.TriFunction;
@@ -16737,6 +16738,29 @@
}
@Override
+ public SyncNotedAppOp startOperation(IBinder token, int code, int uid,
+ @Nullable String packageName, @Nullable String attributionTag,
+ boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
+ @Nullable String message, boolean shouldCollectMessage,
+ @NonNull NonaFunction<IBinder, Integer, Integer, String, String, Boolean,
+ Boolean, String, Boolean, SyncNotedAppOp> superImpl) {
+ if (uid == mTargetUid && isTargetOp(code)) {
+ final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
+ Process.SHELL_UID);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ return superImpl.apply(token, code, shellUid, "com.android.shell",
+ attributionTag, startIfModeDefault, shouldCollectAsyncNotedOp, message,
+ shouldCollectMessage);
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+ return superImpl.apply(token, code, uid, packageName, attributionTag,
+ startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage);
+ }
+
+ @Override
public SyncNotedAppOp startProxyOperation(IBinder token, int code,
@NonNull AttributionSource attributionSource, boolean startIfModeDefault,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index 2a0beb8..7eaf18f 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -3509,9 +3509,19 @@
}
@Override
- public SyncNotedAppOp startOperation(IBinder clientId, int code, int uid, String packageName,
- String attributionTag, boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
+ public SyncNotedAppOp startOperation(IBinder token, int code, int uid,
+ @Nullable String packageName, @Nullable String attributionTag,
+ boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
String message, boolean shouldCollectMessage) {
+ return mCheckOpsDelegateDispatcher.startOperation(token, code, uid, packageName,
+ attributionTag, startIfModeDefault, shouldCollectAsyncNotedOp, message,
+ shouldCollectMessage);
+ }
+
+ private SyncNotedAppOp startOperationImpl(@NonNull IBinder clientId, int code, int uid,
+ @Nullable String packageName, @Nullable String attributionTag,
+ boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, @NonNull String message,
+ boolean shouldCollectMessage) {
verifyIncomingUid(uid);
verifyIncomingOp(code);
verifyIncomingPackage(packageName, UserHandle.getUserId(uid));
@@ -3535,7 +3545,6 @@
return startOperationUnchecked(clientId, code, uid, packageName, attributionTag,
Process.INVALID_UID, null, null, OP_FLAG_SELF, startIfModeDefault,
shouldCollectAsyncNotedOp, message, shouldCollectMessage, false);
-
}
@Override
@@ -6973,8 +6982,8 @@
}
public SyncNotedAppOp noteProxyOperation(int code, AttributionSource attributionSource,
- boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
- boolean skipProxyOperation) {
+ boolean shouldCollectAsyncNotedOp, @Nullable String message,
+ boolean shouldCollectMessage, boolean skipProxyOperation) {
if (mPolicy != null) {
if (mCheckOpsDelegate != null) {
return mPolicy.noteProxyOperation(code, attributionSource,
@@ -7003,6 +7012,38 @@
AppOpsService.this::noteProxyOperationImpl);
}
+ public SyncNotedAppOp startOperation(IBinder token, int code, int uid,
+ @Nullable String packageName, @NonNull String attributionTag,
+ boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
+ @Nullable String message, boolean shouldCollectMessage) {
+ if (mPolicy != null) {
+ if (mCheckOpsDelegate != null) {
+ return mPolicy.startOperation(token, code, uid, packageName,
+ attributionTag, startIfModeDefault, shouldCollectAsyncNotedOp, message,
+ shouldCollectMessage, this::startDelegateOperationImpl);
+ } else {
+ return mPolicy.startOperation(token, code, uid, packageName, attributionTag,
+ startIfModeDefault, shouldCollectAsyncNotedOp, message,
+ shouldCollectMessage, AppOpsService.this::startOperationImpl);
+ }
+ } else if (mCheckOpsDelegate != null) {
+ return startDelegateOperationImpl(token, code, uid, packageName, attributionTag,
+ startIfModeDefault, shouldCollectAsyncNotedOp, message,
+ shouldCollectMessage);
+ }
+ return startOperationImpl(token, code, uid, packageName, attributionTag,
+ startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage);
+ }
+
+ private SyncNotedAppOp startDelegateOperationImpl(IBinder token, int code, int uid,
+ @Nullable String packageName, @Nullable String attributionTag,
+ boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, String message,
+ boolean shouldCollectMessage) {
+ return mCheckOpsDelegate.startOperation(token, code, uid, packageName, attributionTag,
+ startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
+ AppOpsService.this::startOperationImpl);
+ }
+
public SyncNotedAppOp startProxyOperation(IBinder clientId, int code,
@NonNull AttributionSource attributionSource, boolean startIfModeDefault,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
diff --git a/services/core/java/com/android/server/policy/AppOpsPolicy.java b/services/core/java/com/android/server/policy/AppOpsPolicy.java
index ca7406b..622b758 100644
--- a/services/core/java/com/android/server/policy/AppOpsPolicy.java
+++ b/services/core/java/com/android/server/policy/AppOpsPolicy.java
@@ -37,11 +37,11 @@
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
-import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.HexFunction;
+import com.android.internal.util.function.NonaFunction;
import com.android.internal.util.function.OctFunction;
import com.android.internal.util.function.QuadFunction;
import com.android.internal.util.function.TriFunction;
@@ -166,7 +166,7 @@
boolean shouldCollectAsyncNotedOp, @Nullable String message,
boolean shouldCollectMessage, boolean skipProxyOperation, @NonNull HexFunction<Integer,
AttributionSource, Boolean, String, Boolean, Boolean,
- SyncNotedAppOp> superImpl) {
+ SyncNotedAppOp> superImpl) {
return superImpl.apply(resolveDatasourceOp(code, attributionSource.getUid(),
attributionSource.getPackageName(), attributionSource.getAttributionTag()),
attributionSource, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
@@ -174,6 +174,17 @@
}
@Override
+ public SyncNotedAppOp startOperation(IBinder token, int code, int uid,
+ @Nullable String packageName, @Nullable String attributionTag,
+ boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, String message,
+ boolean shouldCollectMessage, @NonNull NonaFunction<IBinder, Integer, Integer, String,
+ String, Boolean, Boolean, String, Boolean, SyncNotedAppOp> superImpl) {
+ return superImpl.apply(token, resolveDatasourceOp(code, uid, packageName, attributionTag),
+ uid, packageName, attributionTag, startIfModeDefault, shouldCollectAsyncNotedOp,
+ message, shouldCollectMessage);
+ }
+
+ @Override
public SyncNotedAppOp startProxyOperation(IBinder token, int code,
@NonNull AttributionSource attributionSource, boolean startIfModeDefault,
boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,