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

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

Merge changes from topic "TestSplitRuntimePermissions"

* changes:
  Apply fg/bg state in default grant policy
  Do not inherit grant of background location
  Split permissions inherit state from their parents
  Have a map of background -> foreground permssions
  Give 'restorePermissionState' a better name
parents db0e08c7 12d0ee09
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package android.app;

import android.annotation.NonNull;
import android.util.SparseIntArray;

import com.android.internal.util.function.QuadFunction;
@@ -73,4 +74,21 @@ public abstract class AppOpsManagerInternal {
     * access to app ops for their user.
     */
    public abstract void setDeviceAndProfileOwners(SparseIntArray owners);

    /**
     * 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
     * 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.
     *
     * @param code The op code to set.
     * @param uid The UID for which to set.
     * @param packageName The package for which to set.
     * @param mode The new mode to set.
     * @param isPrivileged If the package is privileged
     */
    public abstract void setMode(int code, int uid, @NonNull String packageName, int mode,
            boolean isPrivileged);
}
+14 −1
Original line number Diff line number Diff line
@@ -2947,6 +2947,15 @@ public abstract class PackageManager {
    @SystemApi
    public static final int FLAG_PERMISSION_REVIEW_REQUIRED =  1 << 6;

    /**
     * Permission flag: The permission has not been explicitly requested by
     * the app but has been added automatically by the system. Revoke once
     * the app does explicitly request it.
     *
     * @hide
     */
    public static final int FLAG_PERMISSION_REVOKE_WHEN_REQUESTED =  1 << 7;

    /**
     * Mask for all permission flags.
     *
@@ -3598,7 +3607,10 @@ public abstract class PackageManager {
            FLAG_PERMISSION_POLICY_FIXED,
            FLAG_PERMISSION_REVOKE_ON_UPGRADE,
            FLAG_PERMISSION_SYSTEM_FIXED,
            FLAG_PERMISSION_GRANTED_BY_DEFAULT
            FLAG_PERMISSION_GRANTED_BY_DEFAULT,
            /*
            FLAG_PERMISSION_REVOKE_WHEN_REQUESED
            */
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface PermissionFlags {}
@@ -6138,6 +6150,7 @@ public abstract class PackageManager {
            case FLAG_PERMISSION_REVOKE_ON_UPGRADE: return "REVOKE_ON_UPGRADE";
            case FLAG_PERMISSION_USER_FIXED: return "USER_FIXED";
            case FLAG_PERMISSION_REVIEW_REQUIRED: return "REVIEW_REQUIRED";
            case FLAG_PERMISSION_REVOKE_WHEN_REQUESTED: return "REVOKE_WHEN_REQUESTED";
            default: return Integer.toString(flag);
        }
    }
+17 −9
Original line number Diff line number Diff line
@@ -2435,7 +2435,7 @@ public class PackageParser {
        }

        final int NP = PackageParser.NEW_PERMISSIONS.length;
        StringBuilder implicitPerms = null;
        StringBuilder newPermsMsg = null;
        for (int ip=0; ip<NP; ip++) {
            final PackageParser.NewPermissionInfo npi
                    = PackageParser.NEW_PERMISSIONS[ip];
@@ -2443,19 +2443,20 @@ public class PackageParser {
                break;
            }
            if (!pkg.requestedPermissions.contains(npi.name)) {
                if (implicitPerms == null) {
                    implicitPerms = new StringBuilder(128);
                    implicitPerms.append(pkg.packageName);
                    implicitPerms.append(": compat added ");
                if (newPermsMsg == null) {
                    newPermsMsg = new StringBuilder(128);
                    newPermsMsg.append(pkg.packageName);
                    newPermsMsg.append(": compat added ");
                } else {
                    implicitPerms.append(' ');
                    newPermsMsg.append(' ');
                }
                implicitPerms.append(npi.name);
                newPermsMsg.append(npi.name);
                pkg.requestedPermissions.add(npi.name);
                pkg.implicitPermissions.add(npi.name);
            }
        }
        if (implicitPerms != null) {
            Slog.i(TAG, implicitPerms.toString());
        if (newPermsMsg != null) {
            Slog.i(TAG, newPermsMsg.toString());
        }


@@ -2472,6 +2473,7 @@ public class PackageParser {
                final String perm = newPerms.get(in);
                if (!pkg.requestedPermissions.contains(perm)) {
                    pkg.requestedPermissions.add(perm);
                    pkg.implicitPermissions.add(perm);
                }
            }
        }
@@ -6394,6 +6396,9 @@ public class PackageParser {
        @UnsupportedAppUsage
        public final ArrayList<String> requestedPermissions = new ArrayList<String>();

        /** Permissions requested but not in the manifest. */
        public final ArrayList<String> implicitPermissions = new ArrayList<>();

        @UnsupportedAppUsage
        public ArrayList<String> protectedBroadcasts;

@@ -6923,6 +6928,8 @@ public class PackageParser {

            dest.readStringList(requestedPermissions);
            internStringArrayList(requestedPermissions);
            dest.readStringList(implicitPermissions);
            internStringArrayList(implicitPermissions);
            protectedBroadcasts = dest.createStringArrayList();
            internStringArrayList(protectedBroadcasts);

@@ -7087,6 +7094,7 @@ public class PackageParser {
            dest.writeParcelableList(instrumentation, flags);

            dest.writeStringList(requestedPermissions);
            dest.writeStringList(implicitPermissions);
            dest.writeStringList(protectedBroadcasts);

            // TODO: This doesn't work: b/64295061
+2 −3
Original line number Diff line number Diff line
@@ -67,15 +67,14 @@ public final class PermissionManager {
     * such an old app asks for a location permission (i.e. the
     * {@link SplitPermissionInfo#getSplitPermission()}), then the
     * {@link Manifest.permission#ACCESS_BACKGROUND_LOCATION} permission (inside
     * {@{@link SplitPermissionInfo#getNewPermissions}) is added.
     * {@link SplitPermissionInfo#getNewPermissions}) is added.
     *
     * <p>Note: Regular apps do not have to worry about this. The platform and permission controller
     * automatically add the new permissions where needed.
     *
     * @return All permissions that are split.
     */
    public @NonNull
    List<SplitPermissionInfo> getSplitPermissions() {
    public @NonNull List<SplitPermissionInfo> getSplitPermissions() {
        return SPLIT_PERMISSIONS;
    }

+85 −6
Original line number Diff line number Diff line
@@ -1210,13 +1210,29 @@ public class AppOpsService extends IAppOpsService.Stub {

    @Override
    public void setMode(int code, int uid, String packageName, int mode) {
        setMode(code, uid, packageName, mode, true, false);
    }

    /**
     * Sets the mode for a certain op and uid.
     *
     * @param code The op code to set
     * @param uid The UID for which to set
     * @param packageName The package for which to set
     * @param mode The new mode to set
     * @param verifyUid Iff {@code true}, check that the package name belongs to the uid
     * @param isPrivileged Whether the package is privileged. (Only used if {@code verifyUid ==
     *                     false})
     */
    private void setMode(int code, int uid, @NonNull String packageName, int mode,
            boolean verifyUid, boolean isPrivileged) {
        enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid);
        verifyIncomingOp(code);
        ArraySet<ModeCallback> repCbs = null;
        code = AppOpsManager.opToSwitch(code);
        synchronized (this) {
            UidState uidState = getUidStateLocked(uid, false);
            Op op = getOpLocked(code, uid, packageName, true);
            Op op = getOpLocked(code, uid, packageName, true, verifyUid, isPrivileged);
            if (op != null) {
                if (op.mode != mode) {
                    op.mode = mode;
@@ -1575,7 +1591,7 @@ public class AppOpsService extends IAppOpsService.Stub {
                    && uidState.opModes.indexOfKey(code) >= 0) {
                return uidState.opModes.get(code);
            }
            Op op = getOpLocked(code, uid, resolvedPackageName, false);
            Op op = getOpLocked(code, uid, resolvedPackageName, false, true, false);
            if (op == null) {
                return AppOpsManager.opToDefaultMode(code);
            }
@@ -1918,7 +1934,7 @@ public class AppOpsService extends IAppOpsService.Stub {
        }
        ClientState client = (ClientState) token;
        synchronized (this) {
            Op op = getOpLocked(code, uid, resolvedPackageName, true);
            Op op = getOpLocked(code, uid, resolvedPackageName, true, true, false);
            if (op == null) {
                return;
            }
@@ -2172,6 +2188,43 @@ public class AppOpsService extends IAppOpsService.Stub {
        return ops;
    }

    /**
     * Get the state of all ops for a package, <b>don't verify that package belongs to uid</b>.
     *
     * <p>Usually callers should use {@link #getOpLocked} and not call this directly.
     *
     * @param uid The uid the of the package
     * @param packageName The package name for which to get the state for
     * @param edit Iff {@code true} create the {@link Ops} object if not yet created
     * @param isPrivileged Whether the package is privileged or not
     *
     * @return The {@link Ops state} of all ops for the package
     */
    private @Nullable Ops getOpsRawNoVerifyLocked(int uid, @NonNull String packageName,
            boolean edit, boolean isPrivileged) {
        UidState uidState = getUidStateLocked(uid, edit);
        if (uidState == null) {
            return null;
        }

        if (uidState.pkgOps == null) {
            if (!edit) {
                return null;
            }
            uidState.pkgOps = new ArrayMap<>();
        }

        Ops ops = uidState.pkgOps.get(packageName);
        if (ops == null) {
            if (!edit) {
                return null;
            }
            ops = new Ops(packageName, uidState, isPrivileged);
            uidState.pkgOps.put(packageName, ops);
        }
        return ops;
    }

    private void scheduleWriteLocked() {
        if (!mWriteScheduled) {
            mWriteScheduled = true;
@@ -2188,9 +2241,29 @@ public class AppOpsService extends IAppOpsService.Stub {
        }
    }

    private Op getOpLocked(int code, int uid, String packageName, boolean edit) {
        Ops ops = getOpsRawLocked(uid, packageName, edit,
                false /* uidMismatchExpected */);
    /**
     * Get the state of an op for a uid.
     *
     * @param code The code of the op
     * @param uid The uid the of the package
     * @param packageName The package name for which to get the state for
     * @param edit Iff {@code true} create the {@link Op} object if not yet created
     * @param verifyUid Iff {@code true} check that the package belongs to the uid
     * @param isPrivileged Whether the package is privileged or not (only used if {@code verifyUid
     *                     == false})
     *
     * @return The {@link Op state} of the op
     */
    private @Nullable Op getOpLocked(int code, int uid, @NonNull String packageName, boolean edit,
            boolean verifyUid, boolean isPrivileged) {
        Ops ops;

        if (verifyUid) {
            ops = getOpsRawLocked(uid, packageName, edit, false /* uidMismatchExpected */);
        }  else {
            ops = getOpsRawNoVerifyLocked(uid, packageName, edit, isPrivileged);
        }

        if (ops == null) {
            return null;
        }
@@ -3948,5 +4021,11 @@ public class AppOpsService extends IAppOpsService.Stub {
                mProfileOwners = owners;
            }
        }

        @Override
        public void setMode(int code, int uid, @NonNull String packageName, int mode,
                boolean isPrivileged) {
            AppOpsService.this.setMode(code, uid, packageName, mode, false, isPrivileged);
        }
    }
}
Loading