Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a2e5ff93 authored by Karishma Vakil's avatar Karishma Vakil Committed by Android (Google) Code Review
Browse files

Merge "[AppOps] Remove dry run boolean parameter from...

Merge "[AppOps] Remove dry run boolean parameter from AppOpsService#startOperationUnchecked  and create separate dry run method for better readability" into main
parents 772f5ace d32f9de3
Loading
Loading
Loading
Loading
+115 −44
Original line number Diff line number Diff line
@@ -3207,7 +3207,7 @@ public class AppOpsService extends IAppOpsService.Stub {
        return startOperationUnchecked(clientId, code, uid, packageName, attributionTag,
                Process.INVALID_UID, null, null, OP_FLAG_SELF, startIfModeDefault,
                shouldCollectAsyncNotedOp, message, shouldCollectMessage, attributionFlags,
                attributionChainId, /*dryRun*/ false);
                attributionChainId);
    }

    @Override
@@ -3275,11 +3275,10 @@ public class AppOpsService extends IAppOpsService.Stub {

        if (!skipProxyOperation) {
            // Test if the proxied operation will succeed before starting the proxy operation
            final SyncNotedAppOp testProxiedOp = startOperationUnchecked(clientId, code,
                    proxiedUid, resolvedProxiedPackageName, proxiedAttributionTag, proxyUid,
                    resolvedProxyPackageName, proxyAttributionTag, proxiedFlags, startIfModeDefault,
                    shouldCollectAsyncNotedOp, message, shouldCollectMessage,
                    proxiedAttributionFlags, attributionChainId, /*dryRun*/ true);
            final SyncNotedAppOp testProxiedOp = startOperationDryRun(code,
                    proxiedUid, resolvedProxiedPackageName, proxiedAttributionTag,
                    resolvedProxyPackageName, proxiedFlags, startIfModeDefault);

            if (!shouldStartForMode(testProxiedOp.getOpMode(), startIfModeDefault)) {
                return testProxiedOp;
            }
@@ -3290,8 +3289,7 @@ public class AppOpsService extends IAppOpsService.Stub {
            final SyncNotedAppOp proxyAppOp = startOperationUnchecked(clientId, code, proxyUid,
                    resolvedProxyPackageName, proxyAttributionTag, Process.INVALID_UID, null, null,
                    proxyFlags, startIfModeDefault, !isProxyTrusted, "proxy " + message,
                    shouldCollectMessage, proxyAttributionFlags, attributionChainId,
                    /*dryRun*/ false);
                    shouldCollectMessage, proxyAttributionFlags, attributionChainId);
            if (!shouldStartForMode(proxyAppOp.getOpMode(), startIfModeDefault)) {
                return proxyAppOp;
            }
@@ -3300,8 +3298,7 @@ public class AppOpsService extends IAppOpsService.Stub {
        return startOperationUnchecked(clientId, code, proxiedUid, resolvedProxiedPackageName,
                proxiedAttributionTag, proxyUid, resolvedProxyPackageName, proxyAttributionTag,
                proxiedFlags, startIfModeDefault, shouldCollectAsyncNotedOp, message,
                shouldCollectMessage, proxiedAttributionFlags, attributionChainId,
                /*dryRun*/ false);
                shouldCollectMessage, proxiedAttributionFlags, attributionChainId);
    }

    private boolean shouldStartForMode(int mode, boolean startIfModeDefault) {
@@ -3313,7 +3310,7 @@ public class AppOpsService extends IAppOpsService.Stub {
            String proxyPackageName, @Nullable String proxyAttributionTag, @OpFlags int flags,
            boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, @Nullable String message,
            boolean shouldCollectMessage, @AttributionFlags int attributionFlags,
            int attributionChainId, boolean dryRun) {
            int attributionChainId) {
        PackageVerificationResult pvr;
        try {
            pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName);
@@ -3332,11 +3329,9 @@ public class AppOpsService extends IAppOpsService.Stub {
            final Ops ops = getOpsLocked(uid, packageName, attributionTag,
                    pvr.isAttributionTagValid, pvr.bypass, /* edit */ true);
            if (ops == null) {
                if (!dryRun) {
                scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag,
                        flags, AppOpsManager.MODE_IGNORED, startType, attributionFlags,
                        attributionChainId);
                }
                if (DEBUG) Slog.d(TAG, "startOperation: no op for code " + code + " uid " + uid
                        + " package " + packageName + " flags: "
                        + AppOpsManager.flagsToString(flags));
@@ -3359,11 +3354,9 @@ public class AppOpsService extends IAppOpsService.Stub {
                                + switchCode + " (" + code + ") uid " + uid + " package "
                                + packageName + " flags: " + AppOpsManager.flagsToString(flags));
                    }
                    if (!dryRun) {
                    attributedOp.rejected(uidState.getState(), flags);
                    scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag,
                            flags, uidMode, startType, attributionFlags, attributionChainId);
                    }
                    return new SyncNotedAppOp(uidMode, code, attributionTag, packageName);
                }
            } else {
@@ -3375,18 +3368,15 @@ public class AppOpsService extends IAppOpsService.Stub {
                    if (DEBUG) Slog.d(TAG, "startOperation: reject #" + mode + " for code "
                            + switchCode + " (" + code + ") uid " + uid + " package "
                            + packageName + " flags: " + AppOpsManager.flagsToString(flags));
                    if (!dryRun) {
                    attributedOp.rejected(uidState.getState(), flags);
                    scheduleOpStartedIfNeededLocked(code, uid, packageName, attributionTag,
                            flags, mode, startType, attributionFlags, attributionChainId);
                    }
                    return new SyncNotedAppOp(mode, code, attributionTag, packageName);
                }
            }
            if (DEBUG) Slog.d(TAG, "startOperation: allowing code " + code + " uid " + uid
                    + " package " + packageName + " restricted: " + isRestricted
                    + " flags: " + AppOpsManager.flagsToString(flags));
            if (!dryRun) {
            try {
                if (isRestricted) {
                    attributedOp.createPaused(clientId, proxyUid, proxyPackageName,
@@ -3405,9 +3395,8 @@ public class AppOpsService extends IAppOpsService.Stub {
                    isRestricted ? MODE_IGNORED : MODE_ALLOWED, startType, attributionFlags,
                    attributionChainId);
        }
        }

        if (shouldCollectAsyncNotedOp && !dryRun && !isRestricted) {
        if (shouldCollectAsyncNotedOp && !isRestricted) {
            collectAsyncNotedOp(uid, packageName, code, attributionTag, AppOpsManager.OP_FLAG_SELF,
                    message, shouldCollectMessage);
        }
@@ -3416,6 +3405,88 @@ public class AppOpsService extends IAppOpsService.Stub {
                packageName);
    }

    /**
     * Performs a dry run of the start operation i.e. determines the result of the start operation
     * without actually updating the op state to be started.
     *
     * <p>This is used for proxy operations; before starting the op as the proxy, we must check that
     * the proxied app can successfully start the operation.
     */
    private SyncNotedAppOp startOperationDryRun(int code, int uid,
            @NonNull String packageName, @Nullable String attributionTag,
            String proxyPackageName, @OpFlags int flags,
            boolean startIfModeDefault) {
        PackageVerificationResult pvr;
        try {
            pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName);
            if (!pvr.isAttributionTagValid) {
                attributionTag = null;
            }
        } catch (SecurityException e) {
            if (Process.isIsolated(uid)) {
                Slog.e(TAG, "Cannot startOperation: isolated process");
            } else {
                Slog.e(TAG, "Cannot startOperation", e);
            }
            return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag,
                    packageName);
        }

        boolean isRestricted = false;
        synchronized (this) {
            final Ops ops = getOpsLocked(uid, packageName, attributionTag,
                    pvr.isAttributionTagValid, pvr.bypass, /* edit */ true);
            if (ops == null) {
                if (DEBUG) {
                    Slog.d(TAG, "startOperation: no op for code " + code + " uid " + uid
                            + " package " + packageName + " flags: "
                            + AppOpsManager.flagsToString(flags));
                }
                return new SyncNotedAppOp(AppOpsManager.MODE_ERRORED, code, attributionTag,
                        packageName);
            }
            final Op op = getOpLocked(ops, code, uid, true);
            final UidState uidState = ops.uidState;
            isRestricted = isOpRestrictedLocked(uid, code, packageName, attributionTag, pvr.bypass,
                    false);
            final int switchCode = AppOpsManager.opToSwitch(code);
            // If there is a non-default mode per UID policy (we set UID op mode only if
            // non-default) it takes over, otherwise use the per package policy.
            if (uidState.getUidMode(switchCode) != AppOpsManager.opToDefaultMode(switchCode)) {
                final int uidMode = uidState.evalMode(code, uidState.getUidMode(switchCode));
                if (!shouldStartForMode(uidMode, startIfModeDefault)) {
                    if (DEBUG) {
                        Slog.d(TAG, "startOperation: uid reject #" + uidMode + " for code "
                                + switchCode + " (" + code + ") uid " + uid + " package "
                                + packageName + " flags: " + AppOpsManager.flagsToString(flags));
                    }
                    return new SyncNotedAppOp(uidMode, code, attributionTag, packageName);
                }
            } else {
                final Op switchOp = switchCode != code ? getOpLocked(ops, switchCode, uid, true)
                        : op;
                final int mode = switchOp.uidState.evalMode(switchOp.op, switchOp.getMode());
                if (mode != AppOpsManager.MODE_ALLOWED
                        && (!startIfModeDefault || mode != MODE_DEFAULT)) {
                    if (DEBUG) {
                        Slog.d(TAG, "startOperation: reject #" + mode + " for code "
                                + switchCode + " (" + code + ") uid " + uid + " package "
                                + packageName + " flags: " + AppOpsManager.flagsToString(flags));
                    }
                    return new SyncNotedAppOp(mode, code, attributionTag, packageName);
                }
            }
            if (DEBUG) {
                Slog.d(TAG, "startOperation: allowing code " + code + " uid " + uid
                        + " package " + packageName + " restricted: " + isRestricted
                        + " flags: " + AppOpsManager.flagsToString(flags));
            }
        }

        return new SyncNotedAppOp(isRestricted ? MODE_IGNORED : MODE_ALLOWED, code, attributionTag,
                packageName);
    }

    @Override
    public void finishOperation(IBinder clientId, int code, int uid, String packageName,
            String attributionTag) {