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

Commit d083ff4f authored by Karishma Vakil's avatar Karishma Vakil
Browse files

[DeviceAware] Pass AttributionSource to AppOpsManager from

PermissionCheckerService

This CL allows passing in device id from PermissionCheckerService in the
least invasive way wrt existing app ops methods. More details in
b/308786093.

Bug: 299330213
Bug: 307795738
Test: atest FrameworksCoreTests:PermissionCheckerTest
Test: atest CtsAttributionSourceTestCases:PermissionCheckerTest
Change-Id: Ia50261a349ec9e928cc26ec03788b28b898ed225
parent 5e2068ff
Loading
Loading
Loading
Loading
+126 −8
Original line number Diff line number Diff line
@@ -8368,14 +8368,34 @@ public class AppOpsManager {
        return unsafeCheckOpRawNoThrow(strOpToOp(op), uid, packageName);
    }

    /**
     * Returns the <em>raw</em> mode associated with the op.
     * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}.
     * @hide
     */
    public int unsafeCheckOpRawNoThrow(int op, @NonNull AttributionSource attributionSource) {
        return unsafeCheckOpRawNoThrow(op, attributionSource.getUid(),
                attributionSource.getPackageName(), attributionSource.getDeviceId());
    }

    /**
     * Returns the <em>raw</em> mode associated with the op.
     * Does not throw a security exception, does not translate {@link #MODE_FOREGROUND}.
     * @hide
     */
    public int unsafeCheckOpRawNoThrow(int op, int uid, @NonNull String packageName) {
        return unsafeCheckOpRawNoThrow(op, uid, packageName, Context.DEVICE_ID_DEFAULT);
    }

    private int unsafeCheckOpRawNoThrow(int op, int uid, @NonNull String packageName,
            int virtualDeviceId) {
        try {
            if (virtualDeviceId == Context.DEVICE_ID_DEFAULT) {
                return mService.checkOperationRaw(op, uid, packageName, null);
            } else {
                return mService.checkOperationRawForDevice(op, uid, packageName, null,
                        Context.DEVICE_ID_DEFAULT);
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
@@ -8519,6 +8539,17 @@ public class AppOpsManager {
        return noteOpNoThrow(strOpToOp(op), uid, packageName, attributionTag, message);
    }

    /**
     * @see #noteOp(String, int, String, String, String)
     *
     * @hide
     */
    public int noteOpNoThrow(int op, @NonNull AttributionSource attributionSource,
            @Nullable String message) {
        return noteOpNoThrow(op, attributionSource.getUid(), attributionSource.getPackageName(),
                attributionSource.getAttributionTag(), attributionSource.getDeviceId(), message);
    }

    /**
     * @see #noteOpNoThrow(String, int, String, String, String)
     *
@@ -8526,6 +8557,12 @@ public class AppOpsManager {
     */
    public int noteOpNoThrow(int op, int uid, @Nullable String packageName,
            @Nullable String attributionTag, @Nullable String message) {
        return noteOpNoThrow(op, uid, packageName, attributionTag, Context.DEVICE_ID_DEFAULT,
                message);
    }

    private int noteOpNoThrow(int op, int uid, @Nullable String packageName,
            @Nullable String attributionTag, int virtualDeviceId, @Nullable String message) {
        try {
            collectNoteOpCallsForValidation(op);
            int collectionMode = getNotedOpCollectionMode(uid, packageName, op);
@@ -8538,9 +8575,15 @@ public class AppOpsManager {
                }
            }

            SyncNotedAppOp syncOp = mService.noteOperation(op, uid, packageName, attributionTag,
            SyncNotedAppOp syncOp;
            if (virtualDeviceId == Context.DEVICE_ID_DEFAULT) {
                syncOp = mService.noteOperation(op, uid, packageName, attributionTag,
                    collectionMode == COLLECT_ASYNC, message, shouldCollectMessage);

            } else {
                syncOp = mService.noteOperationForDevice(op, uid, packageName, attributionTag,
                    virtualDeviceId, collectionMode == COLLECT_ASYNC, message,
                    shouldCollectMessage);
            }
            if (syncOp.getOpMode() == MODE_ALLOWED) {
                if (collectionMode == COLLECT_SELF) {
                    collectNotedOpForSelf(syncOp);
@@ -8778,7 +8821,8 @@ public class AppOpsManager {
    @UnsupportedAppUsage
    public int checkOp(int op, int uid, String packageName) {
        try {
            int mode = mService.checkOperation(op, uid, packageName);
            int mode = mService.checkOperationForDevice(op, uid, packageName,
                Context.DEVICE_ID_DEFAULT);
            if (mode == MODE_ERRORED) {
                throw new SecurityException(buildSecurityExceptionMsg(op, uid, packageName));
            }
@@ -8788,6 +8832,19 @@ public class AppOpsManager {
        }
    }

    /**
     * Like {@link #checkOp} but instead of throwing a {@link SecurityException}, it
     * returns {@link #MODE_ERRORED}.
     *
     * @see #checkOp(int, int, String)
     *
     * @hide
     */
    public int checkOpNoThrow(int op, AttributionSource attributionSource) {
        return checkOpNoThrow(op, attributionSource.getUid(), attributionSource.getPackageName(),
                attributionSource.getDeviceId());
    }

    /**
     * Like {@link #checkOp} but instead of throwing a {@link SecurityException} it
     * returns {@link #MODE_ERRORED}.
@@ -8798,8 +8855,18 @@ public class AppOpsManager {
     */
    @UnsupportedAppUsage
    public int checkOpNoThrow(int op, int uid, String packageName) {
        return checkOpNoThrow(op, uid, packageName, Context.DEVICE_ID_DEFAULT);
    }

    private int checkOpNoThrow(int op, int uid, String packageName, int virtualDeviceId) {
        try {
            int mode = mService.checkOperation(op, uid, packageName);
            int mode;
            if (virtualDeviceId == Context.DEVICE_ID_DEFAULT) {
                mode = mService.checkOperation(op, uid, packageName);
            } else {
                mode = mService.checkOperationForDevice(op, uid, packageName, virtualDeviceId);
            }

            return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode;
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
@@ -9024,6 +9091,21 @@ public class AppOpsManager {
                message, ATTRIBUTION_FLAGS_NONE, ATTRIBUTION_CHAIN_ID_NONE);
    }

    /**
     * @see #startOpNoThrow(String, int, String, String, String)
     *
     * @hide
     */
    public int startOpNoThrow(@NonNull IBinder token, int op,
            @NonNull AttributionSource attributionSource,
            boolean startIfModeDefault, @Nullable String message,
            @AttributionFlags int attributionFlags, int attributionChainId) {
        return startOpNoThrow(token, op, attributionSource.getUid(),
                attributionSource.getPackageName(), startIfModeDefault,
                attributionSource.getAttributionTag(), attributionSource.getDeviceId(),
                message, attributionFlags, attributionChainId);
    }

    /**
     * @see #startOpNoThrow(String, int, String, String, String)
     *
@@ -9032,6 +9114,14 @@ public class AppOpsManager {
    public int startOpNoThrow(@NonNull IBinder token, int op, int uid, @NonNull String packageName,
            boolean startIfModeDefault, @Nullable String attributionTag, @Nullable String message,
            @AttributionFlags int attributionFlags, int attributionChainId) {
        return startOpNoThrow(token, op, uid, packageName, startIfModeDefault, attributionTag,
                Context.DEVICE_ID_DEFAULT, message, attributionFlags, attributionChainId);
    }

    private int startOpNoThrow(@NonNull IBinder token, int op, int uid, @NonNull String packageName,
            boolean startIfModeDefault, @Nullable String attributionTag, int virtualDeviceId,
            @Nullable String message, @AttributionFlags int attributionFlags,
            int attributionChainId) {
        try {
            collectNoteOpCallsForValidation(op);
            int collectionMode = getNotedOpCollectionMode(uid, packageName, op);
@@ -9044,10 +9134,17 @@ public class AppOpsManager {
                }
            }

            SyncNotedAppOp syncOp = mService.startOperation(token, op, uid, packageName,
            SyncNotedAppOp syncOp;
            if (virtualDeviceId == Context.DEVICE_ID_DEFAULT) {
                syncOp = mService.startOperation(token, op, uid, packageName,
                    attributionTag, startIfModeDefault, collectionMode == COLLECT_ASYNC, message,
                    shouldCollectMessage, attributionFlags, attributionChainId);

            } else {
                syncOp = mService.startOperationForDevice(token, op, uid, packageName,
                    attributionTag, virtualDeviceId, startIfModeDefault,
                    collectionMode == COLLECT_ASYNC, message, shouldCollectMessage,
                    attributionFlags, attributionChainId);
            }
            if (syncOp.getOpMode() == MODE_ALLOWED) {
                if (collectionMode == COLLECT_SELF) {
                    collectNotedOpForSelf(syncOp);
@@ -9250,6 +9347,17 @@ public class AppOpsManager {
        finishOp(mContext.getAttributionSource().getToken(), op, uid, packageName, attributionTag);
    }

    /**
     * @see #finishOp(String, int, String, String)
     *
     * @hide
     */
    public void finishOp(IBinder token, int op, @NonNull AttributionSource attributionSource) {
        finishOp(token, op, attributionSource.getUid(),
                attributionSource.getPackageName(), attributionSource.getAttributionTag(),
                attributionSource.getDeviceId());
    }

    /**
     * @see #finishOp(String, int, String, String)
     *
@@ -9257,8 +9365,18 @@ public class AppOpsManager {
     */
    public void finishOp(IBinder token, int op, int uid, @NonNull String packageName,
            @Nullable String attributionTag) {
        finishOp(token, op, uid, packageName, attributionTag, Context.DEVICE_ID_DEFAULT);
    }

    private void finishOp(IBinder token, int op, int uid, @NonNull String packageName,
            @Nullable String attributionTag, int virtualDeviceId ) {
        try {
            if (virtualDeviceId == Context.DEVICE_ID_DEFAULT) {
                mService.finishOperation(token, op, uid, packageName, attributionTag);
            } else {
                mService.finishOperationForDevice(token, op, uid, packageName, attributionTag,
                    virtualDeviceId);
            }
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }
+18 −13
Original line number Diff line number Diff line
@@ -26,11 +26,11 @@ import android.util.SparseArray;
import android.util.SparseIntArray;

import com.android.internal.app.IAppOpsCallback;
import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.DodecFunction;
import com.android.internal.util.function.HexConsumer;
import com.android.internal.util.function.HexFunction;
import com.android.internal.util.function.OctFunction;
import com.android.internal.util.function.QuadFunction;
import com.android.internal.util.function.QuintConsumer;
import com.android.internal.util.function.QuintFunction;
import com.android.internal.util.function.UndecFunction;

/**
@@ -48,13 +48,14 @@ public abstract class AppOpsManagerInternal {
         * @param uid The UID for which to check.
         * @param packageName The package for which to check.
         * @param attributionTag The attribution tag for which to check.
         * @param virtualDeviceId the device for which to check the op
         * @param raw Whether to check the raw op i.e. not interpret the mode based on UID state.
         * @param superImpl The super implementation.
         * @return The app op check result.
         */
        int checkOperation(int code, int uid, String packageName, @Nullable String attributionTag,
                boolean raw, QuintFunction<Integer, Integer, String, String, Boolean, Integer>
                superImpl);
                int virtualDeviceId, boolean raw, HexFunction<Integer, Integer, String, String,
                Integer, Boolean, Integer> superImpl);

        /**
         * Allows overriding check audio operation behavior.
@@ -76,16 +77,17 @@ public abstract class AppOpsManagerInternal {
         * @param uid The UID for which to note.
         * @param packageName The package for which to note. {@code null} for system package.
         * @param featureId Id of the feature in the package
         * @param virtualDeviceId the device for which to note the op
         * @param shouldCollectAsyncNotedOp If an {@link AsyncNotedAppOp} should be collected
         * @param message The message in the async noted op
         * @param superImpl The super implementation.
         * @return The app op note result.
         */
        SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
                @Nullable String featureId, boolean shouldCollectAsyncNotedOp,
                @Nullable String featureId, int virtualDeviceId, boolean shouldCollectAsyncNotedOp,
                @Nullable String message, boolean shouldCollectMessage,
                @NonNull HeptFunction<Integer, Integer, String, String, Boolean, String, Boolean,
                        SyncNotedAppOp> superImpl);
                @NonNull OctFunction<Integer, Integer, String, String, Integer, Boolean, String,
                        Boolean, SyncNotedAppOp> superImpl);

        /**
         * Allows overriding note proxy operation behavior.
@@ -113,6 +115,7 @@ public abstract class AppOpsManagerInternal {
         * @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 virtualDeviceId the device for which to start the op
         * @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
@@ -123,11 +126,11 @@ public abstract class AppOpsManagerInternal {
         * @return The app op note result.
         */
        SyncNotedAppOp startOperation(IBinder token, int code, int uid,
                @Nullable String packageName, @Nullable String attributionTag,
                @Nullable String packageName, @Nullable String attributionTag, int virtualDeviceId,
                boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
                @Nullable String message, boolean shouldCollectMessage,
                @AttributionFlags int attributionFlags, int attributionChainId,
                @NonNull UndecFunction<IBinder, Integer, Integer, String, String, Boolean,
                @NonNull DodecFunction<IBinder, Integer, Integer, String, String, Integer, Boolean,
                        Boolean, String, Boolean, Integer, Integer, SyncNotedAppOp> superImpl);

        /**
@@ -164,11 +167,13 @@ public abstract class AppOpsManagerInternal {
         * @param uid The UID for which the op was noted.
         * @param packageName The package for which it was noted. {@code null} for system package.
         * @param attributionTag the attribution tag.
         * @param virtualDeviceId the device for which to finish the op
         * @param superImpl
         */
        default void finishOperation(IBinder clientId, int code, int uid, String packageName,
                String attributionTag,
                @NonNull QuintConsumer<IBinder, Integer, Integer, String, String> superImpl) {
            superImpl.accept(clientId, code, uid, packageName, attributionTag);
                String attributionTag, int virtualDeviceId, @NonNull HexConsumer<IBinder, Integer,
                        Integer, String, String, Integer> superImpl) {
            superImpl.accept(clientId, code, uid, packageName, attributionTag, virtualDeviceId);
        }

        /**
+7 −0
Original line number Diff line number Diff line
@@ -106,6 +106,13 @@ public final class AttributionSource implements Parcelable {
        this(uid, Process.INVALID_PID, packageName, attributionTag, sDefaultToken);
    }

    /** @hide */
    public AttributionSource(int uid, @Nullable String packageName,
            @Nullable String attributionTag, int virtualDeviceId) {
        this(uid, Process.INVALID_PID, packageName, attributionTag, sDefaultToken, null,
                virtualDeviceId, null);
    }

    /** @hide */
    public AttributionSource(int uid, int pid, @Nullable String packageName,
            @Nullable String attributionTag) {
+20 −8
Original line number Diff line number Diff line
@@ -150,4 +150,16 @@ interface IAppOpsService {
            int attributionChainId);
    void finishProxyOperationWithState(IBinder clientId, int code,
            in AttributionSourceState attributionSourceStateState, boolean skipProxyOperation);
    int checkOperationRawForDevice(int code, int uid, String packageName,
            @nullable String attributionTag, int virtualDeviceId);
    int checkOperationForDevice(int code, int uid, String packageName, int virtualDeviceId);
    SyncNotedAppOp noteOperationForDevice(int code, int uid, String packageName,
            @nullable String attributionTag, int virtualDeviceId,
            boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage);
    SyncNotedAppOp startOperationForDevice(IBinder clientId, int code, int uid, String packageName,
            @nullable String attributionTag,  int virtualDeviceId, boolean startIfModeDefault,
            boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage,
            int attributionFlags, int attributionChainId);
    void finishOperationForDevice(IBinder clientId, int code, int uid, String packageName,
            @nullable String attributionTag, int virtualDeviceId);
}
+21 −19
Original line number Diff line number Diff line
@@ -79,7 +79,6 @@ import static android.os.PowerExemptionManager.REASON_ACTIVITY_VISIBILITY_GRACE_
import static android.os.PowerExemptionManager.REASON_BACKGROUND_ACTIVITY_PERMISSION;
import static android.os.PowerExemptionManager.REASON_BOOT_COMPLETED;
import static android.os.PowerExemptionManager.REASON_COMPANION_DEVICE_MANAGER;
import static android.os.PowerExemptionManager.REASON_DENIED;
import static android.os.PowerExemptionManager.REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION;
import static android.os.PowerExemptionManager.REASON_LOCKED_BOOT_COMPLETED;
import static android.os.PowerExemptionManager.REASON_PROC_STATE_BTOP;
@@ -430,10 +429,10 @@ import com.android.internal.util.FastPrintWriter;
import com.android.internal.util.FrameworkStatsLog;
import com.android.internal.util.MemInfoReader;
import com.android.internal.util.Preconditions;
import com.android.internal.util.function.HeptFunction;
import com.android.internal.util.function.DodecFunction;
import com.android.internal.util.function.HexFunction;
import com.android.internal.util.function.OctFunction;
import com.android.internal.util.function.QuadFunction;
import com.android.internal.util.function.QuintFunction;
import com.android.internal.util.function.UndecFunction;
import com.android.server.AlarmManagerInternal;
import com.android.server.BootReceiver;
@@ -20149,20 +20148,21 @@ public class ActivityManagerService extends IActivityManager.Stub
        }
        @Override
        public int checkOperation(int code, int uid, String packageName,
                String attributionTag, boolean raw,
                QuintFunction<Integer, Integer, String, String, Boolean, Integer> superImpl) {
        public int checkOperation(int code, int uid, String packageName, String attributionTag,
                int virtualDeviceId, boolean raw, HexFunction<Integer, Integer, String, String,
                        Integer, Boolean, Integer> 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(code, shellUid, "com.android.shell", null, raw);
                    return superImpl.apply(code, shellUid, "com.android.shell", null,
                            virtualDeviceId, raw);
                } finally {
                    Binder.restoreCallingIdentity(identity);
                }
            }
            return superImpl.apply(code, uid, packageName, attributionTag, raw);
            return superImpl.apply(code, uid, packageName, attributionTag, virtualDeviceId, raw);
        }
        @Override
@@ -20183,23 +20183,24 @@ public class ActivityManagerService extends IActivityManager.Stub
        @Override
        public SyncNotedAppOp noteOperation(int code, int uid, @Nullable String packageName,
                @Nullable String featureId, boolean shouldCollectAsyncNotedOp,
                @Nullable String featureId, int virtualDeviceId, boolean shouldCollectAsyncNotedOp,
                @Nullable String message, boolean shouldCollectMessage,
                @NonNull HeptFunction<Integer, Integer, String, String, Boolean, String, Boolean,
                        SyncNotedAppOp> superImpl) {
                @NonNull OctFunction<Integer, Integer, String, String, Integer, 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(code, shellUid, "com.android.shell", featureId,
                            shouldCollectAsyncNotedOp, message, shouldCollectMessage);
                            virtualDeviceId, shouldCollectAsyncNotedOp, message,
                            shouldCollectMessage);
                } finally {
                    Binder.restoreCallingIdentity(identity);
                }
            }
            return superImpl.apply(code, uid, packageName, featureId, shouldCollectAsyncNotedOp,
                    message, shouldCollectMessage);
            return superImpl.apply(code, uid, packageName, featureId, virtualDeviceId,
                    shouldCollectAsyncNotedOp, message, shouldCollectMessage);
        }
        @Override
@@ -20230,11 +20231,11 @@ public class ActivityManagerService extends IActivityManager.Stub
        @Override
        public SyncNotedAppOp startOperation(IBinder token, int code, int uid,
                @Nullable String packageName, @Nullable String attributionTag,
                @Nullable String packageName, @Nullable String attributionTag, int virtualDeviceId,
                boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp,
                @Nullable String message, boolean shouldCollectMessage,
                @AttributionFlags int attributionFlags, int attributionChainId,
                @NonNull UndecFunction<IBinder, Integer, Integer, String, String, Boolean,
                @NonNull DodecFunction<IBinder, Integer, Integer, String, String, Integer, Boolean,
                        Boolean, String, Boolean, Integer, Integer, SyncNotedAppOp> superImpl) {
            if (uid == mTargetUid && isTargetOp(code)) {
                final int shellUid = UserHandle.getUid(UserHandle.getUserId(uid),
@@ -20242,13 +20243,14 @@ public class ActivityManagerService extends IActivityManager.Stub
                final long identity = Binder.clearCallingIdentity();
                try {
                    return superImpl.apply(token, code, shellUid, "com.android.shell",
                            attributionTag, startIfModeDefault, shouldCollectAsyncNotedOp, message,
                            shouldCollectMessage, attributionFlags, attributionChainId);
                            attributionTag, virtualDeviceId, startIfModeDefault,
                            shouldCollectAsyncNotedOp, message, shouldCollectMessage,
                            attributionFlags, attributionChainId);
                } finally {
                    Binder.restoreCallingIdentity(identity);
                }
            }
            return superImpl.apply(token, code, uid, packageName, attributionTag,
            return superImpl.apply(token, code, uid, packageName, attributionTag, virtualDeviceId,
                    startIfModeDefault, shouldCollectAsyncNotedOp, message, shouldCollectMessage,
                    attributionFlags, attributionChainId);
        }
Loading