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

Commit 87969723 authored by Philip P. Moltmann's avatar Philip P. Moltmann Committed by Android (Google) Code Review
Browse files

Merge "Reset per-pkg app-ops for runtime permissions"

parents 94f1dbb4 dde07852
Loading
Loading
Loading
Loading
+9 −1
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ public abstract class AppOpsManagerInternal {
    /**
     * Sets the app-ops mode for a certain app-op and uid.
     *
     * <p>Similar as {@link AppOpsManager#setMode} but does not require the package manager to be
     * <p>Similar as {@link AppOpsManager#setUidMode} but does not require the package manager to be
     * working. Hence this can be used very early during boot.
     *
     * <p>Only for internal callers. Does <u>not</u> verify that package name belongs to uid.
@@ -88,4 +88,12 @@ public abstract class AppOpsManagerInternal {
     * @param mode The new mode to set.
     */
    public abstract void setUidMode(int code, int uid, int mode);

    /**
     * Set all {@link #setMode (package) modes} for this uid to the default value.
     *
     * @param code The app-op
     * @param uid The uid
     */
    public abstract void setAllPkgModesToDefault(int code, int uid);
}
+47 −2
Original line number Diff line number Diff line
@@ -16,8 +16,8 @@

package com.android.server.appop;

import static android.app.AppOpsManager.OP_PLAY_AUDIO;
import static android.app.AppOpsManager.OP_NONE;
import static android.app.AppOpsManager.OP_PLAY_AUDIO;
import static android.app.AppOpsManager.UID_STATE_BACKGROUND;
import static android.app.AppOpsManager.UID_STATE_CACHED;
import static android.app.AppOpsManager.UID_STATE_FOREGROUND;
@@ -94,9 +94,9 @@ import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
import com.android.internal.util.function.pooled.PooledLambda;

import com.android.server.LocalServices;
import com.android.server.LockGuard;

import libcore.util.EmptyArray;

import org.xmlpull.v1.XmlPullParser;
@@ -1282,6 +1282,46 @@ public class AppOpsService extends IAppOpsService.Stub {
        }
    }

    /**
     * Set all {@link #setMode (package) modes} for this uid to the default value.
     *
     * @param code The app-op
     * @param uid The uid
     */
    private void setAllPkgModesToDefault(int code, int uid) {
        synchronized (this) {
            UidState uidState = getUidStateLocked(uid, false);
            if (uidState == null) {
                return;
            }

            ArrayMap<String, Ops> pkgOps = uidState.pkgOps;
            if (pkgOps == null) {
                return;
            }

            int numPkgs = pkgOps.size();
            for (int pkgNum = 0; pkgNum < numPkgs; pkgNum++) {
                Ops ops = pkgOps.valueAt(pkgNum);

                Op op = ops.get(code);
                if (op == null) {
                    continue;
                }

                int defaultMode = AppOpsManager.opToDefaultMode(code);
                if (op.mode != defaultMode) {
                    Slog.w(TAG, "resetting app-op mode for " + AppOpsManager.opToName(code) + " of "
                            + pkgOps.keyAt(pkgNum));

                    op.mode = defaultMode;

                    scheduleWriteLocked();
                }
            }
        }
    }

    @Override
    public void setMode(int code, int uid, String packageName, int mode) {
        setMode(code, uid, packageName, mode, true, false);
@@ -4387,5 +4427,10 @@ public class AppOpsService extends IAppOpsService.Stub {
        public void setUidMode(int code, int uid, int mode) {
            AppOpsService.this.setUidMode(code, uid, mode);
        }

        @Override
        public void setAllPkgModesToDefault(int code, int uid) {
            AppOpsService.this.setAllPkgModesToDefault(code, uid);
        }
    }
}
+56 −0
Original line number Diff line number Diff line
@@ -1049,6 +1049,8 @@ public class PermissionManagerService {
                    updatedUserIds);
            updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions,
                    permissionsState, pkg, updatedUserIds);

            setAppOpsLocked(permissionsState, pkg);
        }

        // Persist the runtime permissions state for users with changes. If permissions
@@ -1387,6 +1389,60 @@ public class PermissionManagerService {
        return updatedUserIds;
    }

    /**
     * Fix app-op modes for runtime permissions.
     *
     * @param permsState The state of the permissions of the package
     * @param pkg The package information
     */
    private void setAppOpsLocked(@NonNull PermissionsState permsState,
            @NonNull PackageParser.Package pkg) {
        for (int userId : UserManagerService.getInstance().getUserIds()) {
            int numPerms = pkg.requestedPermissions.size();
            for (int i = 0; i < numPerms; i++) {
                String permission = pkg.requestedPermissions.get(i);

                int op = permissionToOpCode(permission);
                if (op == OP_NONE) {
                    continue;
                }

                // Runtime permissions are per uid, not per package, hence per package app-op
                // modes should never have been set. It is possible to set them via the shell
                // though. Revert such settings during boot to get the device back into a good
                // state.
                LocalServices.getService(AppOpsManagerInternal.class).setAllPkgModesToDefault(
                        op, getUid(userId, getAppId(pkg.applicationInfo.uid)));

                // For pre-M apps the runtime permission do not store the state
                if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
                    continue;
                }

                PermissionState state = permsState.getRuntimePermissionState(permission, userId);
                if (state == null) {
                    continue;
                }

                // Adjust app-op mods for foreground/background permissions. If an package used to
                // have both fg and bg permission granted and it lost the bg permission during an
                // upgrade the app-op mode should get downgraded to foreground.
                if (state.isGranted()) {
                    BasePermission bp = mSettings.getPermission(permission);

                    if (bp != null && bp.perm != null && bp.perm.info != null
                            && bp.perm.info.backgroundPermission != null) {
                        PermissionState bgState = permsState.getRuntimePermissionState(
                                bp.perm.info.backgroundPermission, userId);

                        setAppOpMode(permission, pkg, userId, bgState != null && bgState.isGranted()
                                        ? MODE_ALLOWED : MODE_FOREGROUND);
                    }
                }
            }
        }
    }

    private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
        boolean allowed = false;
        final int NP = PackageParser.NEW_PERMISSIONS.length;
+11 −0
Original line number Diff line number Diff line
@@ -7,6 +7,17 @@
                    "include-filter": "com.google.android.permission.gts.DefaultPermissionGrantPolicyTest"
                }
            ]
        },
        {
            "name": "CtsPermissionTestCases",
            "options": [
                {
                    "include-filter": "android.permission.cts.BackgroundPermissionsTest"
                },
                {
                    "include-filter": "android.permission.cts.SplitPermissionTest"
                }
            ]
        }
    ]
}
 No newline at end of file