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

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

Merge "[DeviceAware] Make AppOpsCheckingServiceInterface device-aware" into main

parents 35b0ec9c 319379cf
Loading
Loading
Loading
Loading
+19 −7
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import static android.app.AppOpsManager.MODE_ALLOWED;
import static android.app.AppOpsManager.MODE_FOREGROUND;
import static android.app.AppOpsManager.OP_SCHEDULE_EXACT_ALARM;
import static android.app.AppOpsManager.OP_USE_FULL_SCREEN_INTENT;
import static android.companion.virtual.VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT;

import android.annotation.NonNull;
import android.annotation.UserIdInt;
@@ -150,7 +151,7 @@ public class AppOpsCheckingServiceImpl implements AppOpsCheckingServiceInterface
    }

    @Override
    public SparseIntArray getNonDefaultUidModes(int uid) {
    public SparseIntArray getNonDefaultUidModes(int uid, String persistentDeviceId) {
        synchronized (mLock) {
            SparseIntArray opModes = mUidModes.get(uid, null);
            if (opModes == null) {
@@ -176,7 +177,7 @@ public class AppOpsCheckingServiceImpl implements AppOpsCheckingServiceInterface
    }

    @Override
    public int getUidMode(int uid, int op) {
    public int getUidMode(int uid, String persistentDeviceId, int op) {
        synchronized (mLock) {
            SparseIntArray opModes = mUidModes.get(uid, null);
            if (opModes == null) {
@@ -187,7 +188,7 @@ public class AppOpsCheckingServiceImpl implements AppOpsCheckingServiceInterface
    }

    @Override
    public boolean setUidMode(int uid, int op, int mode) {
    public boolean setUidMode(int uid, String persistentDeviceId, int op, int mode) {
        final int defaultMode = AppOpsManager.opToDefaultMode(op);
        List<AppOpsModeChangedListener> listenersCopy;
        synchronized (mLock) {
@@ -329,7 +330,7 @@ public class AppOpsCheckingServiceImpl implements AppOpsCheckingServiceInterface
    }

    @Override
    public SparseBooleanArray getForegroundOps(int uid) {
    public SparseBooleanArray getForegroundOps(int uid, String persistentDeviceId) {
        SparseBooleanArray result = new SparseBooleanArray();
        synchronized (mLock) {
            SparseIntArray modes = mUidModes.get(uid);
@@ -606,9 +607,17 @@ public class AppOpsCheckingServiceImpl implements AppOpsCheckingServiceInterface
        for (final String pkg : packagesDeclaringPermission) {
            for (int userId : userIds) {
                final int uid = pmi.getPackageUid(pkg, 0, userId);
                final int oldMode = getUidMode(uid, OP_SCHEDULE_EXACT_ALARM);
                final int oldMode =
                        getUidMode(
                                uid,
                                PERSISTENT_DEVICE_ID_DEFAULT,
                                OP_SCHEDULE_EXACT_ALARM);
                if (oldMode == AppOpsManager.opToDefaultMode(OP_SCHEDULE_EXACT_ALARM)) {
                    setUidMode(uid, OP_SCHEDULE_EXACT_ALARM, MODE_ALLOWED);
                    setUidMode(
                            uid,
                            PERSISTENT_DEVICE_ID_DEFAULT,
                            OP_SCHEDULE_EXACT_ALARM,
                            MODE_ALLOWED);
                }
            }
            // This appop is meant to be controlled at a uid level. So we leave package modes as
@@ -641,7 +650,10 @@ public class AppOpsCheckingServiceImpl implements AppOpsCheckingServiceInterface
                final int flags = permissionManager.getPermissionFlags(pkg, permissionName,
                        UserHandle.of(userId));
                if ((flags & PackageManager.FLAG_PERMISSION_USER_SET) == 0) {
                    setUidMode(uid, OP_USE_FULL_SCREEN_INTENT,
                    setUidMode(
                            uid,
                            PERSISTENT_DEVICE_ID_DEFAULT,
                            OP_USE_FULL_SCREEN_INTENT,
                            AppOpsManager.opToDefaultMode(OP_USE_FULL_SCREEN_INTENT));
                }
            }
+8 −4
Original line number Diff line number Diff line
@@ -59,8 +59,9 @@ public interface AppOpsCheckingServiceInterface {
     * Returns a copy of non-default app-ops with op as keys and their modes as values for a uid.
     * Returns an empty SparseIntArray if nothing is set.
     * @param uid for which we need the app-ops and their modes.
     * @param persistentDeviceId device for which we need the app-ops and their modes
     */
    SparseIntArray getNonDefaultUidModes(int uid);
    SparseIntArray getNonDefaultUidModes(int uid, String persistentDeviceId);

    /**
     * Returns a copy of non-default app-ops with op as keys and their modes as values for a package
@@ -75,20 +76,22 @@ public interface AppOpsCheckingServiceInterface {
     * Returns the app-op mode for a particular app-op of a uid.
     * Returns default op mode if the op mode for particular uid and op is not set.
     * @param uid user id for which we need the mode.
     * @param persistentDeviceId device for which we need the mode
     * @param op app-op for which we need the mode.
     * @return mode of the app-op.
     */
    int getUidMode(int uid, int op);
    int getUidMode(int uid, String persistentDeviceId, int op);

    /**
     * Set the app-op mode for a particular uid and op.
     * The mode is not set if the mode is the same as the default mode for the op.
     * @param uid user id for which we want to set the mode.
     * @param persistentDeviceId device for which we want to set the mode.
     * @param op app-op for which we want to set the mode.
     * @param mode mode for the app-op.
     * @return true if op mode is changed.
     */
    boolean setUidMode(int uid, int op, @Mode int mode);
    boolean setUidMode(int uid, String persistentDeviceId, int op, @Mode int mode);

    /**
     * Gets the app-op mode for a particular package.
@@ -130,10 +133,11 @@ public interface AppOpsCheckingServiceInterface {

    /**
     * @param uid UID to query foreground ops for.
     * @param persistentDeviceId device to query foreground ops for
     * @return SparseBooleanArray where the keys are the op codes for which their modes are
     * MODE_FOREGROUND for the passed UID.
     */
    SparseBooleanArray getForegroundOps(int uid);
    SparseBooleanArray getForegroundOps(int uid, String persistentDeviceId);

    /**
     *
+8 −8
Original line number Diff line number Diff line
@@ -60,9 +60,9 @@ public class AppOpsCheckingServiceLoggingDecorator implements AppOpsCheckingServ
    }

    @Override
    public SparseIntArray getNonDefaultUidModes(int uid) {
    public SparseIntArray getNonDefaultUidModes(int uid, String persistentDeviceId) {
        Log.i(LOG_TAG, "getNonDefaultUidModes(uid = " + uid + ")");
        return mService.getNonDefaultUidModes(uid);
        return mService.getNonDefaultUidModes(uid, persistentDeviceId);
    }

    @Override
@@ -73,15 +73,15 @@ public class AppOpsCheckingServiceLoggingDecorator implements AppOpsCheckingServ
    }

    @Override
    public int getUidMode(int uid, int op) {
    public int getUidMode(int uid, String persistentDeviceId, int op) {
        Log.i(LOG_TAG, "getUidMode(uid = " + uid + ", op = " + op + ")");
        return mService.getUidMode(uid, op);
        return mService.getUidMode(uid, persistentDeviceId, op);
    }

    @Override
    public boolean setUidMode(int uid, int op, int mode) {
    public boolean setUidMode(int uid, String persistentDeviceId, int op, int mode) {
        Log.i(LOG_TAG, "setUidMode(uid = " + uid + ", op = " + op + ", mode = " + mode + ")");
        return mService.setUidMode(uid, op, mode);
        return mService.setUidMode(uid, persistentDeviceId, op, mode);
    }

    @Override
@@ -117,9 +117,9 @@ public class AppOpsCheckingServiceLoggingDecorator implements AppOpsCheckingServ
    }

    @Override
    public SparseBooleanArray getForegroundOps(int uid) {
    public SparseBooleanArray getForegroundOps(int uid, String persistentDeviceId) {
        Log.i(LOG_TAG, "getForegroundOps(uid = " + uid + ")");
        return mService.getForegroundOps(uid);
        return mService.getForegroundOps(uid, persistentDeviceId);
    }

    @Override
+9 −8
Original line number Diff line number Diff line
@@ -81,11 +81,11 @@ public class AppOpsCheckingServiceTracingDecorator implements AppOpsCheckingServ
    }

    @Override
    public SparseIntArray getNonDefaultUidModes(int uid) {
    public SparseIntArray getNonDefaultUidModes(int uid, String persistentDeviceId) {
        Trace.traceBegin(TRACE_TAG,
                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#getNonDefaultUidModes");
        try {
            return mService.getNonDefaultUidModes(uid);
            return mService.getNonDefaultUidModes(uid, persistentDeviceId);
        } finally {
            Trace.traceEnd(TRACE_TAG);
        }
@@ -103,20 +103,21 @@ public class AppOpsCheckingServiceTracingDecorator implements AppOpsCheckingServ
    }

    @Override
    public int getUidMode(int uid, int op) {
    public int getUidMode(int uid, String persistentDeviceId, int op) {
        Trace.traceBegin(TRACE_TAG, "TaggedTracingAppOpsCheckingServiceInterfaceImpl#getUidMode");
        try {
            return mService.getUidMode(uid, op);
            return mService.getUidMode(uid, persistentDeviceId, op);
        } finally {
            Trace.traceEnd(TRACE_TAG);
        }
    }

    @Override
    public boolean setUidMode(int uid, int op, @AppOpsManager.Mode int mode) {
    public boolean setUidMode(
            int uid, String persistentDeviceId, int op, @AppOpsManager.Mode int mode) {
        Trace.traceBegin(TRACE_TAG, "TaggedTracingAppOpsCheckingServiceInterfaceImpl#setUidMode");
        try {
            return mService.setUidMode(uid, op, mode);
            return mService.setUidMode(uid, persistentDeviceId, op, mode);
        } finally {
            Trace.traceEnd(TRACE_TAG);
        }
@@ -179,11 +180,11 @@ public class AppOpsCheckingServiceTracingDecorator implements AppOpsCheckingServ
    }

    @Override
    public SparseBooleanArray getForegroundOps(int uid) {
    public SparseBooleanArray getForegroundOps(int uid, String persistentDeviceId) {
        Trace.traceBegin(TRACE_TAG,
                "TaggedTracingAppOpsCheckingServiceInterfaceImpl#getForegroundOps");
        try {
            return mService.getForegroundOps(uid);
            return mService.getForegroundOps(uid, persistentDeviceId);
        } finally {
            Trace.traceEnd(TRACE_TAG);
        }
+71 −20
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ import static android.app.AppOpsManager.opAllowSystemBypassRestriction;
import static android.app.AppOpsManager.opRestrictsRead;
import static android.app.AppOpsManager.opToName;
import static android.app.AppOpsManager.opToPublicName;
import static android.companion.virtual.VirtualDeviceManager.PERSISTENT_DEVICE_ID_DEFAULT;
import static android.content.pm.PermissionInfo.PROTECTION_DANGEROUS;
import static android.content.pm.PermissionInfo.PROTECTION_FLAG_APPOP;

@@ -1349,7 +1350,10 @@ public class AppOpsService extends IAppOpsService.Stub {

                SparseBooleanArray foregroundOps = new SparseBooleanArray();

                SparseBooleanArray uidForegroundOps = mAppOpsCheckingService.getForegroundOps(uid);
                // TODO(b/299330771): Check uidForegroundOps for all devices.
                SparseBooleanArray uidForegroundOps =
                        mAppOpsCheckingService.getForegroundOps(
                                uid, PERSISTENT_DEVICE_ID_DEFAULT);
                for (int i = 0; i < uidForegroundOps.size(); i++) {
                    foregroundOps.put(uidForegroundOps.keyAt(i), true);
                }
@@ -1369,10 +1373,16 @@ public class AppOpsService extends IAppOpsService.Stub {
                        continue;
                    }
                    final int code = foregroundOps.keyAt(fgi);

                    if (mAppOpsCheckingService.getUidMode(uidState.uid, code)
                    // TODO(b/299330771): Notify op changes for all relevant devices.
                    if (mAppOpsCheckingService.getUidMode(
                                            uidState.uid,
                                            PERSISTENT_DEVICE_ID_DEFAULT,
                                            code)
                                    != AppOpsManager.opToDefaultMode(code)
                            && mAppOpsCheckingService.getUidMode(uidState.uid, code)
                            && mAppOpsCheckingService.getUidMode(
                                            uidState.uid,
                                            PERSISTENT_DEVICE_ID_DEFAULT,
                                            code)
                                    == AppOpsManager.MODE_FOREGROUND) {
                        mHandler.sendMessage(PooledLambda.obtainMessage(
                                AppOpsService::notifyOpChangedForAllPkgsInUid,
@@ -1489,7 +1499,11 @@ public class AppOpsService extends IAppOpsService.Stub {
    @Nullable
    private ArrayList<AppOpsManager.OpEntry> collectUidOps(@NonNull UidState uidState,
            @Nullable int[] ops) {
        final SparseIntArray opModes = mAppOpsCheckingService.getNonDefaultUidModes(uidState.uid);
        // TODO(b/299330771): Make this methods device-aware, currently it represents only the
        // primary device.
        final SparseIntArray opModes =
                mAppOpsCheckingService.getNonDefaultUidModes(
                        uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT);
        if (opModes == null) {
            return null;
        }
@@ -1844,16 +1858,22 @@ public class AppOpsService extends IAppOpsService.Stub {
                uidState = new UidState(uid);
                mUidStates.put(uid, uidState);
            }
            if (mAppOpsCheckingService.getUidMode(uidState.uid, code)
            // TODO(b/266164193): Ensure this behavior is device-aware after uid op mode for runtime
            //  permissions is deprecated.
            if (mAppOpsCheckingService.getUidMode(
                            uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, code)
                    != AppOpsManager.opToDefaultMode(code)) {
                previousMode = mAppOpsCheckingService.getUidMode(uidState.uid, code);
                previousMode =
                        mAppOpsCheckingService.getUidMode(
                                uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, code);
            } else {
                // doesn't look right but is legacy behavior.
                previousMode = MODE_DEFAULT;
            }

            mIgnoredCallback = permissionPolicyCallback;
            if (!mAppOpsCheckingService.setUidMode(uidState.uid, code, mode)) {
            if (!mAppOpsCheckingService.setUidMode(
                    uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, code, mode)) {
                return;
            }
            if (mode != MODE_ERRORED && mode != previousMode) {
@@ -2275,8 +2295,10 @@ public class AppOpsService extends IAppOpsService.Stub {
            boolean changed = false;
            for (int i = mUidStates.size() - 1; i >= 0; i--) {
                UidState uidState = mUidStates.valueAt(i);

                SparseIntArray opModes = mAppOpsCheckingService.getNonDefaultUidModes(uidState.uid);
                // TODO(b/299330771): Check non default modes for all devices.
                SparseIntArray opModes =
                        mAppOpsCheckingService.getNonDefaultUidModes(
                                uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT);
                if (opModes != null && (uidState.uid == reqUid || reqUid == -1)) {
                    final int uidOpCount = opModes.size();
                    for (int j = uidOpCount - 1; j >= 0; j--) {
@@ -2285,7 +2307,12 @@ public class AppOpsService extends IAppOpsService.Stub {
                            int previousMode = opModes.valueAt(j);
                            int newMode = isUidOpGrantedByRole(uidState.uid, code) ? MODE_ALLOWED :
                                    AppOpsManager.opToDefaultMode(code);
                            mAppOpsCheckingService.setUidMode(uidState.uid, code, newMode);
                            // TODO(b/299330771): Set mode for all necessary devices.
                            mAppOpsCheckingService.setUidMode(
                                    uidState.uid,
                                    PERSISTENT_DEVICE_ID_DEFAULT,
                                    code,
                                    newMode);
                            for (String packageName : getPackagesForUid(uidState.uid)) {
                                callbacks = addCallbacks(callbacks, code, uidState.uid, packageName,
                                        previousMode, mOpModeWatchers.get(code));
@@ -2601,10 +2628,14 @@ public class AppOpsService extends IAppOpsService.Stub {
            }
            code = AppOpsManager.opToSwitch(code);
            UidState uidState = getUidStateLocked(uid, false);
            // TODO(b/299330771): Check mode for the relevant device.
            if (uidState != null
                    && mAppOpsCheckingService.getUidMode(uidState.uid, code)
                    && mAppOpsCheckingService.getUidMode(
                                    uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, code)
                            != AppOpsManager.opToDefaultMode(code)) {
                final int rawMode = mAppOpsCheckingService.getUidMode(uidState.uid, code);
                final int rawMode =
                        mAppOpsCheckingService.getUidMode(
                                uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, code);
                return raw ? rawMode : uidState.evalMode(code, rawMode);
            }
            Op op = getOpLocked(code, uid, packageName, null, false, pvr.bypass, /* edit */ false);
@@ -2851,13 +2882,19 @@ public class AppOpsService extends IAppOpsService.Stub {
                return new SyncNotedAppOp(AppOpsManager.MODE_IGNORED, code, attributionTag,
                        packageName);
            }
            // TODO(b/299330771): Check mode for the relevant device.
            // If there is a non-default per UID policy (we set UID op mode only if
            // non-default) it takes over, otherwise use the per package policy.
            if (mAppOpsCheckingService.getUidMode(uidState.uid, switchCode)
            if (mAppOpsCheckingService.getUidMode(
                            uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, switchCode)
                    != AppOpsManager.opToDefaultMode(switchCode)) {
                final int uidMode =
                        uidState.evalMode(
                                code, mAppOpsCheckingService.getUidMode(uidState.uid, switchCode));
                                code,
                                mAppOpsCheckingService.getUidMode(
                                        uidState.uid,
                                        PERSISTENT_DEVICE_ID_DEFAULT,
                                        switchCode));
                if (uidMode != AppOpsManager.MODE_ALLOWED) {
                    if (DEBUG) Slog.d(TAG, "noteOperation: uid reject #" + uidMode + " for code "
                            + switchCode + " (" + code + ") uid " + uid + " package "
@@ -3396,13 +3433,19 @@ public class AppOpsService extends IAppOpsService.Stub {
            isRestricted = isOpRestrictedLocked(uid, code, packageName, attributionTag, pvr.bypass,
                    false);
            final int switchCode = AppOpsManager.opToSwitch(code);
            // TODO(b/299330771): Check mode for the relevant device.
            // If there is a non-default per UID policy (we set UID op mode only if
            // non-default) it takes over, otherwise use the per package policy.
            if (mAppOpsCheckingService.getUidMode(uidState.uid, switchCode)
            if (mAppOpsCheckingService.getUidMode(
                            uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, switchCode)
                    != AppOpsManager.opToDefaultMode(switchCode)) {
                final int uidMode =
                        uidState.evalMode(
                                code, mAppOpsCheckingService.getUidMode(uidState.uid, switchCode));
                                code,
                                mAppOpsCheckingService.getUidMode(
                                        uidState.uid,
                                        PERSISTENT_DEVICE_ID_DEFAULT,
                                        switchCode));
                if (!shouldStartForMode(uidMode, startIfModeDefault)) {
                    if (DEBUG) {
                        Slog.d(TAG, "startOperation: uid reject #" + uidMode + " for code "
@@ -3511,13 +3554,19 @@ public class AppOpsService extends IAppOpsService.Stub {
            isRestricted = isOpRestrictedLocked(uid, code, packageName, attributionTag, pvr.bypass,
                    false);
            final int switchCode = AppOpsManager.opToSwitch(code);
            // TODO(b/299330771): Check mode for the relevant device.
            // 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 (mAppOpsCheckingService.getUidMode(uidState.uid, switchCode)
            if (mAppOpsCheckingService.getUidMode(
                            uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT, switchCode)
                    != AppOpsManager.opToDefaultMode(switchCode)) {
                final int uidMode =
                        uidState.evalMode(
                                code, mAppOpsCheckingService.getUidMode(uidState.uid, switchCode));
                                code,
                                mAppOpsCheckingService.getUidMode(
                                        uidState.uid,
                                        PERSISTENT_DEVICE_ID_DEFAULT,
                                        switchCode));
                if (!shouldStartForMode(uidMode, startIfModeDefault)) {
                    if (DEBUG) {
                        Slog.d(TAG, "startOperation: uid reject #" + uidMode + " for code "
@@ -5664,8 +5713,10 @@ public class AppOpsService extends IAppOpsService.Stub {
            }
            for (int i=0; i<mUidStates.size(); i++) {
                UidState uidState = mUidStates.valueAt(i);
                // TODO(b/299330771): Get modes for all devices.
                final SparseIntArray opModes =
                        mAppOpsCheckingService.getNonDefaultUidModes(uidState.uid);
                        mAppOpsCheckingService.getNonDefaultUidModes(
                                uidState.uid, PERSISTENT_DEVICE_ID_DEFAULT);
                final ArrayMap<String, Ops> pkgOps = uidState.pkgOps;

                if (dumpWatchers || dumpHistory) {
Loading