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

Commit 521ef546 authored by Philip P. Moltmann's avatar Philip P. Moltmann Committed by android-build-merger
Browse files

Also trigger PermPolicySvc on app-ops changes am: fad1a8fb

am: 1b3d97ca

Change-Id: Ic32879e243b781f7dbff384af5a63c72ca92120c
parents e42c4f3e 1b3d97ca
Loading
Loading
Loading
Loading
+21 −0
Original line number Original line Diff line number Diff line
@@ -3126,6 +3126,27 @@ public class PermissionManagerService {
            }
            }
        }
        }


        @Override
        public @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtectionLevel(
                @PermissionInfo.Protection int protectionLevel) {
            ArrayList<PermissionInfo> matchingPermissions = new ArrayList<>();

            synchronized (PermissionManagerService.this.mLock) {
                int numTotalPermissions = mSettings.mPermissions.size();

                for (int i = 0; i < numTotalPermissions; i++) {
                    BasePermission bp = mSettings.mPermissions.valueAt(i);

                    if (bp.perm != null && bp.perm.info != null
                            && bp.protectionLevel == protectionLevel) {
                        matchingPermissions.add(bp.perm.info);
                    }
                }
            }

            return matchingPermissions;
        }

        @Override
        @Override
        public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
        public @Nullable byte[] backupRuntimePermissions(@NonNull UserHandle user) {
            return PermissionManagerService.this.backupRuntimePermissions(user);
            return PermissionManagerService.this.backupRuntimePermissions(user);
+4 −0
Original line number Original line Diff line number Diff line
@@ -195,4 +195,8 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager


    /** HACK HACK methods to allow for partial migration of data to the PermissionManager class */
    /** HACK HACK methods to allow for partial migration of data to the PermissionManager class */
    public abstract @Nullable BasePermission getPermissionTEMP(@NonNull String permName);
    public abstract @Nullable BasePermission getPermissionTEMP(@NonNull String permName);

    /** Get all permission that have a certain protection level */
    public abstract @NonNull ArrayList<PermissionInfo> getAllPermissionWithProtectionLevel(
            @PermissionInfo.Protection int protectionLevel);
}
}
+64 −12
Original line number Original line Diff line number Diff line
@@ -41,10 +41,11 @@ import android.content.pm.PackageParser;
import android.content.pm.PermissionInfo;
import android.content.pm.PermissionInfo;
import android.os.Build;
import android.os.Build;
import android.os.Process;
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
import android.os.UserHandle;
import android.os.UserManagerInternal;
import android.os.UserManagerInternal;
import android.permission.PermissionControllerManager;
import android.permission.PermissionControllerManager;
import android.permission.PermissionManagerInternal;
import android.provider.Telephony;
import android.provider.Telephony;
import android.telecom.TelecomManager;
import android.telecom.TelecomManager;
import android.util.ArraySet;
import android.util.ArraySet;
@@ -54,10 +55,13 @@ import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.SparseIntArray;


import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.app.IAppOpsCallback;
import com.android.internal.app.IAppOpsService;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.internal.util.function.pooled.PooledLambda;
import com.android.server.FgThread;
import com.android.server.FgThread;
import com.android.server.LocalServices;
import com.android.server.LocalServices;
import com.android.server.SystemService;
import com.android.server.SystemService;
import com.android.server.pm.permission.PermissionManagerServiceInternal;


import java.util.ArrayList;
import java.util.ArrayList;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.CountDownLatch;
@@ -96,8 +100,10 @@ public final class PermissionPolicyService extends SystemService {
    public void onStart() {
    public void onStart() {
        final PackageManagerInternal packageManagerInternal = LocalServices.getService(
        final PackageManagerInternal packageManagerInternal = LocalServices.getService(
                PackageManagerInternal.class);
                PackageManagerInternal.class);
        final PermissionManagerInternal permManagerInternal = LocalServices.getService(
        final PermissionManagerServiceInternal permManagerInternal = LocalServices.getService(
                PermissionManagerInternal.class);
                PermissionManagerServiceInternal.class);
        final IAppOpsService appOpsService = IAppOpsService.Stub.asInterface(
                ServiceManager.getService(Context.APP_OPS_SERVICE));


        packageManagerInternal.getPackageList(new PackageListObserver() {
        packageManagerInternal.getPackageList(new PackageListObserver() {
            @Override
            @Override
@@ -122,6 +128,42 @@ public final class PermissionPolicyService extends SystemService {


        permManagerInternal.addOnRuntimePermissionStateChangedListener(
        permManagerInternal.addOnRuntimePermissionStateChangedListener(
                this::synchronizePackagePermissionsAndAppOpsAsyncForUser);
                this::synchronizePackagePermissionsAndAppOpsAsyncForUser);

        IAppOpsCallback appOpsListener = new IAppOpsCallback.Stub() {
            public void opChanged(int op, int uid, String packageName) {
                synchronizePackagePermissionsAndAppOpsAsyncForUser(packageName,
                        UserHandle.getUserId(uid));
            }
        };

        final ArrayList<PermissionInfo> dangerousPerms =
                permManagerInternal.getAllPermissionWithProtectionLevel(
                        PermissionInfo.PROTECTION_DANGEROUS);

        try {
            int numDangerousPerms = dangerousPerms.size();
            for (int i = 0; i < numDangerousPerms; i++) {
                PermissionInfo perm = dangerousPerms.get(i);

                if (perm.isHardRestricted() || perm.backgroundPermission != null) {
                    appOpsService.startWatchingMode(AppOpsManager.permissionToOpCode(perm.name),
                            null, appOpsListener);
                } else if (perm.isSoftRestricted()) {
                    appOpsService.startWatchingMode(AppOpsManager.permissionToOpCode(perm.name),
                            null, appOpsListener);

                    SoftRestrictedPermissionPolicy policy =
                            SoftRestrictedPermissionPolicy.forPermission(null, null, null,
                                    perm.name);
                    if (policy.resolveAppOp() != OP_NONE) {
                        appOpsService.startWatchingMode(policy.resolveAppOp(), null,
                                appOpsListener);
                    }
                }
            }
        } catch (RemoteException doesNotHappen) {
            Slog.wtf(LOG_TAG, "Cannot set up app-ops listener");
        }
    }
    }


    private void synchronizePackagePermissionsAndAppOpsAsyncForUser(@NonNull String packageName,
    private void synchronizePackagePermissionsAndAppOpsAsyncForUser(@NonNull String packageName,
@@ -380,7 +422,7 @@ public final class PermissionPolicyService extends SystemService {
            final int allowCount = mOpsToAllow.size();
            final int allowCount = mOpsToAllow.size();
            for (int i = 0; i < allowCount; i++) {
            for (int i = 0; i < allowCount; i++) {
                final OpToUnrestrict op = mOpsToAllow.get(i);
                final OpToUnrestrict op = mOpsToAllow.get(i);
                setUidModeAllowed(op.code, op.uid);
                setUidModeAllowed(op.code, op.uid, op.packageName);
            }
            }
            final int allowIfDefaultCount = mOpsToAllowIfDefault.size();
            final int allowIfDefaultCount = mOpsToAllowIfDefault.size();
            for (int i = 0; i < allowIfDefaultCount; i++) {
            for (int i = 0; i < allowIfDefaultCount; i++) {
@@ -390,12 +432,12 @@ public final class PermissionPolicyService extends SystemService {
            final int foregroundCount = mOpsToForeground.size();
            final int foregroundCount = mOpsToForeground.size();
            for (int i = 0; i < foregroundCount; i++) {
            for (int i = 0; i < foregroundCount; i++) {
                final OpToUnrestrict op = mOpsToForeground.get(i);
                final OpToUnrestrict op = mOpsToForeground.get(i);
                setUidModeForeground(op.code, op.uid);
                setUidModeForeground(op.code, op.uid, op.packageName);
            }
            }
            final int ignoreCount = mOpsToIgnore.size();
            final int ignoreCount = mOpsToIgnore.size();
            for (int i = 0; i < ignoreCount; i++) {
            for (int i = 0; i < ignoreCount; i++) {
                final OpToUnrestrict op = mOpsToIgnore.get(i);
                final OpToUnrestrict op = mOpsToIgnore.get(i);
                setUidModeIgnored(op.code, op.uid);
                setUidModeIgnored(op.code, op.uid, op.packageName);
            }
            }
            final int ignoreIfDefaultCount = mOpsToIgnoreIfDefault.size();
            final int ignoreIfDefaultCount = mOpsToIgnoreIfDefault.size();
            for (int i = 0; i < ignoreIfDefaultCount; i++) {
            for (int i = 0; i < ignoreIfDefaultCount; i++) {
@@ -586,20 +628,30 @@ public final class PermissionPolicyService extends SystemService {
            setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_ALLOWED, packageName);
            setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_ALLOWED, packageName);
        }
        }


        private void setUidModeAllowed(int opCode, int uid) {
        private void setUidModeAllowed(int opCode, int uid, @NonNull String packageName) {
            mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_ALLOWED);
            setUidMode(opCode, uid, MODE_ALLOWED, packageName);
        }
        }


        private void setUidModeForeground(int opCode, int uid) {
        private void setUidModeForeground(int opCode, int uid, @NonNull String packageName) {
            mAppOpsManager.setUidMode(opCode, uid, AppOpsManager.MODE_FOREGROUND);
            setUidMode(opCode, uid, MODE_FOREGROUND, packageName);
        }
        }


        private void setUidModeIgnoredIfDefault(int opCode, int uid, @NonNull String packageName) {
        private void setUidModeIgnoredIfDefault(int opCode, int uid, @NonNull String packageName) {
            setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_IGNORED, packageName);
            setUidModeIfDefault(opCode, uid, AppOpsManager.MODE_IGNORED, packageName);
        }
        }


        private void setUidModeIgnored(int opCode, int uid) {
        private void setUidModeIgnored(int opCode, int uid, @NonNull String packageName) {
            mAppOpsManager.setUidMode(opCode, uid, MODE_IGNORED);
            setUidMode(opCode, uid, MODE_IGNORED, packageName);
        }

        private void setUidMode(int opCode, int uid, int mode,
                @NonNull String packageName) {
            final int currentMode = mAppOpsManager.unsafeCheckOpRaw(AppOpsManager
                    .opToPublicName(opCode), uid, packageName);

            if (currentMode != mode) {
                mAppOpsManager.setUidMode(opCode, uid, mode);
            }
        }
        }


        private void setUidModeIfDefault(int opCode, int uid, int mode,
        private void setUidModeIfDefault(int opCode, int uid, int mode,
+26 −10
Original line number Original line Diff line number Diff line
@@ -29,6 +29,7 @@ import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_SYST
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT;


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.app.AppOpsManager;
import android.content.Context;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.ApplicationInfo;
@@ -75,14 +76,16 @@ public abstract class SoftRestrictedPermissionPolicy {
     * Get the policy for a soft restricted permission.
     * Get the policy for a soft restricted permission.
     *
     *
     * @param context A context to use
     * @param context A context to use
     * @param appInfo The application the permission belongs to
     * @param appInfo The application the permission belongs to. Can be {@code null}, but then
     * @param user The user the app belongs to
     *                only {@link #resolveAppOp} will work.
     * @param user The user the app belongs to. Can be {@code null}, but then only
     *             {@link #resolveAppOp} will work.
     * @param permission The name of the permission
     * @param permission The name of the permission
     *
     *
     * @return The policy for this permission
     * @return The policy for this permission
     */
     */
    public static @NonNull SoftRestrictedPermissionPolicy forPermission(@NonNull Context context,
    public static @NonNull SoftRestrictedPermissionPolicy forPermission(@NonNull Context context,
            @NonNull ApplicationInfo appInfo, @NonNull UserHandle user,
            @Nullable ApplicationInfo appInfo, @Nullable UserHandle user,
            @NonNull String permission) {
            @NonNull String permission) {
        switch (permission) {
        switch (permission) {
            // Storage uses a special app op to decide the mount state and supports soft restriction
            // Storage uses a special app op to decide the mount state and supports soft restriction
@@ -90,13 +93,26 @@ public abstract class SoftRestrictedPermissionPolicy {
            // collections.
            // collections.
            case READ_EXTERNAL_STORAGE:
            case READ_EXTERNAL_STORAGE:
            case WRITE_EXTERNAL_STORAGE: {
            case WRITE_EXTERNAL_STORAGE: {
                int flags = context.getPackageManager().getPermissionFlags(
                final int flags;
                        permission, appInfo.packageName, user);
                final boolean applyRestriction;
                boolean applyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
                final boolean isWhiteListed;
                boolean isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
                final boolean hasRequestedLegacyExternalStorage;
                boolean hasRequestedLegacyExternalStorage =
                final int targetSDK;
                        appInfo.hasRequestedLegacyExternalStorage();

                int targetSDK = appInfo.targetSdkVersion;
                if (appInfo != null) {
                    flags = context.getPackageManager().getPermissionFlags(permission,
                            appInfo.packageName, user);
                    applyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
                    isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
                    hasRequestedLegacyExternalStorage = appInfo.hasRequestedLegacyExternalStorage();
                    targetSDK = appInfo.targetSdkVersion;
                } else {
                    flags = 0;
                    applyRestriction = false;
                    isWhiteListed = false;
                    hasRequestedLegacyExternalStorage = false;
                    targetSDK = 0;
                }


                return new SoftRestrictedPermissionPolicy() {
                return new SoftRestrictedPermissionPolicy() {
                    @Override
                    @Override