Loading services/core/java/com/android/server/pm/permission/PermissionManagerService.java +22 −165 Original line number Diff line number Diff line Loading @@ -18,12 +18,6 @@ package com.android.server.pm.permission; import static android.Manifest.permission.READ_EXTERNAL_STORAGE; import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_ERRORED; import static android.app.AppOpsManager.MODE_FOREGROUND; import static android.app.AppOpsManager.OP_NONE; import static android.app.AppOpsManager.permissionToOp; import static android.app.AppOpsManager.permissionToOpCode; import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT; import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION; import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; Loading @@ -40,8 +34,6 @@ import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRAD import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL; import static android.content.pm.PackageManager.RESTRICTED_PERMISSIONS_ENABLED; import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; import static android.os.UserHandle.getAppId; import static android.os.UserHandle.getUid; import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL; import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING; Loading @@ -56,8 +48,6 @@ import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.AppOpsManager; import android.app.AppOpsManagerInternal; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManager.PermissionWhitelistFlags; Loading Loading @@ -1309,9 +1299,6 @@ public class PermissionManagerService { updatedUserIds); updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions, permissionsState, pkg, updatedUserIds); // TODO: Move to PermissionPolicyService setAppOpsLocked(permissionsState, pkg); } // Persist the runtime permissions state for users with changes. If permissions Loading @@ -1326,23 +1313,6 @@ public class PermissionManagerService { } } /** * Set app op for a app-op related to a permission. * * @param permission The permission the app-op belongs to * @param pkg The package the permission belongs to * @param userId The user to be changed * @param mode The new mode to set */ private void setAppOpMode(@NonNull String permission, @NonNull PackageParser.Package pkg, @UserIdInt int userId, int mode) { AppOpsManagerInternal appOpsInternal = LocalServices.getService( AppOpsManagerInternal.class); appOpsInternal.setUidMode(permissionToOpCode(permission), getUid(userId, getAppId(pkg.applicationInfo.uid)), mode); } /** * Revoke permissions that are not implicit anymore and that have * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set. Loading @@ -1357,8 +1327,6 @@ public class PermissionManagerService { private @NonNull int[] revokePermissionsNoLongerImplicitLocked( @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg, @NonNull int[] updatedUserIds) { AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class); String pkgName = pkg.packageName; boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M; Loading Loading @@ -1390,23 +1358,6 @@ public class PermissionManagerService { } flagsToRemove |= USER_PERMISSION_FLAGS; List<String> fgPerms = mBackgroundPermissions.get(permission); if (fgPerms != null) { int numFgPerms = fgPerms.size(); for (int fgPermNum = 0; fgPermNum < numFgPerms; fgPermNum++) { String fgPerm = fgPerms.get(fgPermNum); int mode = appOpsManager.unsafeCheckOpRaw( permissionToOp(fgPerm), getUid(userId, getAppId(pkg.applicationInfo.uid)), pkgName); if (mode == MODE_ALLOWED) { setAppOpMode(fgPerm, pkg, userId, MODE_FOREGROUND); } } } } ps.updatePermissionFlags(bp, userId, flagsToRemove, 0); Loading Loading @@ -1438,58 +1389,7 @@ public class PermissionManagerService { @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm, @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg, @UserIdInt int userId) { AppOpsManagerInternal appOpsManager = LocalServices.getService(AppOpsManagerInternal.class); String pkgName = pkg.packageName; if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { if (permissionToOp(newPerm) != null) { int mostLenientSourceMode = MODE_ERRORED; int flags = 0; // Find most lenient source permission state. int numSourcePerms = sourcePerms.size(); for (int i = 0; i < numSourcePerms; i++) { String sourcePerm = sourcePerms.valueAt(i); if (ps.hasRuntimePermission(sourcePerm, userId)) { int sourceOp = permissionToOpCode(sourcePerm); if (sourceOp != OP_NONE) { int mode = appOpsManager.checkOperationUnchecked(sourceOp, getUid(userId, getAppId(pkg.applicationInfo.uid)), pkgName); if (mode == MODE_FOREGROUND || mode == MODE_ERRORED) { Log.wtf(TAG, "split permission" + sourcePerm + " has app-op state " + AppOpsManager.MODE_NAMES[mode]); continue; } // Leniency order: allowed < ignored < default if (mode < mostLenientSourceMode) { mostLenientSourceMode = mode; flags = ps.getPermissionFlags(sourcePerm, userId); } else if (mode == mostLenientSourceMode) { flags |= ps.getPermissionFlags(sourcePerm, userId); } } } } if (mostLenientSourceMode != MODE_ERRORED) { if (DEBUG_PERMISSIONS) { Slog.i(TAG, newPerm + " inherits app-ops state " + mostLenientSourceMode + " from " + sourcePerms + " for " + pkgName); } setAppOpMode(newPerm, pkg, userId, mostLenientSourceMode); // Add permission flags ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags); } } } else { boolean isGranted = false; int flags = 0; Loading Loading @@ -1523,7 +1423,6 @@ public class PermissionManagerService { // Add permission flags ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags); } } /** * Set the state of a implicit permission that is seen for the first time. Loading Loading @@ -1632,48 +1531,6 @@ 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); // 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; Loading services/core/java/com/android/server/policy/PermissionPolicyService.java +71 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManagerInternal.PackageListObserver; import android.content.pm.PackageParser; import android.content.pm.PermissionInfo; import android.os.Build; import android.os.Process; import android.os.UserHandle; import android.permission.PermissionControllerManager; Loading Loading @@ -234,6 +235,7 @@ public final class PermissionPolicyService extends SystemService { * @see #syncRestrictedOps */ private final @NonNull ArrayList<OpToRestrict> mOpsToRestrict = new ArrayList<>(); /** * All ops that need to be unrestricted * Loading @@ -241,6 +243,13 @@ public final class PermissionPolicyService extends SystemService { */ private final @NonNull ArrayList<OpToUnrestrict> mOpsToUnrestrict = new ArrayList<>(); /** * All foreground permissions * * @see #syncOpsOfFgPermissions() */ private final @NonNull ArrayList<FgPermission> mFgPermOps = new ArrayList<>(); PermissionToOpSynchroniser(@NonNull Context context) { mContext = context; mPackageManager = context.getPackageManager(); Loading Loading @@ -339,11 +348,42 @@ public final class PermissionPolicyService extends SystemService { } } /** * Set app ops that belong to restricted permissions. * * <p>This processed ops previously added by {@link #addOpIfRestricted} */ private void syncOpsOfFgPermissions() { int numFgPermOps = mFgPermOps.size(); for (int i = 0; i < numFgPermOps; i++) { FgPermission perm = mFgPermOps.get(i); if (mPackageManager.checkPermission(perm.fgPermissionName, perm.packageName) == PackageManager.PERMISSION_GRANTED) { if (mPackageManager.checkPermission(perm.bgPermissionName, perm.packageName) == PackageManager.PERMISSION_GRANTED) { mAppOpsManager.setUidMode( AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid, AppOpsManager.MODE_ALLOWED); } else { mAppOpsManager.setUidMode( AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid, AppOpsManager.MODE_FOREGROUND); } } else { mAppOpsManager.setUidMode( AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid, AppOpsManager.MODE_IGNORED); } } } /** * Synchronize all previously {@link #addPackage added} packages. */ void syncPackages() { syncRestrictedOps(); syncOpsOfFgPermissions(); } /** Loading Loading @@ -380,6 +420,21 @@ public final class PermissionPolicyService extends SystemService { } } private void addOpIfFgPermissions(@NonNull PermissionInfo permissionInfo, @NonNull PackageInfo pkg) { if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { // Pre-M apps do not store their fg/bg state in the permissions return; } if (permissionInfo.backgroundPermission == null) { return; } mFgPermOps.add(new FgPermission(pkg.applicationInfo.uid, pkg.packageName, permissionInfo.name, permissionInfo.backgroundPermission)); } /** * Add a package for {@link #syncPackages() processing} later. * Loading Loading @@ -415,6 +470,7 @@ public final class PermissionPolicyService extends SystemService { } addOpIfRestricted(permissionInfo, pkg); addOpIfFgPermissions(permissionInfo, pkg); } } Loading Loading @@ -451,5 +507,20 @@ public final class PermissionPolicyService extends SystemService { this.code = code; } } private class FgPermission { final int uid; final @NonNull String packageName; final @NonNull String fgPermissionName; final @NonNull String bgPermissionName; private FgPermission(int uid, @NonNull String packageName, @NonNull String fgPermissionName, @NonNull String bgPermissionName) { this.uid = uid; this.packageName = packageName; this.fgPermissionName = fgPermissionName; this.bgPermissionName = bgPermissionName; } } } } Loading
services/core/java/com/android/server/pm/permission/PermissionManagerService.java +22 −165 Original line number Diff line number Diff line Loading @@ -18,12 +18,6 @@ package com.android.server.pm.permission; import static android.Manifest.permission.READ_EXTERNAL_STORAGE; import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE; import static android.app.AppOpsManager.MODE_ALLOWED; import static android.app.AppOpsManager.MODE_ERRORED; import static android.app.AppOpsManager.MODE_FOREGROUND; import static android.app.AppOpsManager.OP_NONE; import static android.app.AppOpsManager.permissionToOp; import static android.app.AppOpsManager.permissionToOpCode; import static android.content.pm.PackageManager.FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT; import static android.content.pm.PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION; import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT; Loading @@ -40,8 +34,6 @@ import static android.content.pm.PackageManager.FLAG_PERMISSION_WHITELIST_UPGRAD import static android.content.pm.PackageManager.MASK_PERMISSION_FLAGS_ALL; import static android.content.pm.PackageManager.RESTRICTED_PERMISSIONS_ENABLED; import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER; import static android.os.UserHandle.getAppId; import static android.os.UserHandle.getUid; import static com.android.server.pm.PackageManagerService.DEBUG_INSTALL; import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING; Loading @@ -56,8 +48,6 @@ import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.app.AppOpsManager; import android.app.AppOpsManagerInternal; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManager.PermissionWhitelistFlags; Loading Loading @@ -1309,9 +1299,6 @@ public class PermissionManagerService { updatedUserIds); updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origPermissions, permissionsState, pkg, updatedUserIds); // TODO: Move to PermissionPolicyService setAppOpsLocked(permissionsState, pkg); } // Persist the runtime permissions state for users with changes. If permissions Loading @@ -1326,23 +1313,6 @@ public class PermissionManagerService { } } /** * Set app op for a app-op related to a permission. * * @param permission The permission the app-op belongs to * @param pkg The package the permission belongs to * @param userId The user to be changed * @param mode The new mode to set */ private void setAppOpMode(@NonNull String permission, @NonNull PackageParser.Package pkg, @UserIdInt int userId, int mode) { AppOpsManagerInternal appOpsInternal = LocalServices.getService( AppOpsManagerInternal.class); appOpsInternal.setUidMode(permissionToOpCode(permission), getUid(userId, getAppId(pkg.applicationInfo.uid)), mode); } /** * Revoke permissions that are not implicit anymore and that have * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set. Loading @@ -1357,8 +1327,6 @@ public class PermissionManagerService { private @NonNull int[] revokePermissionsNoLongerImplicitLocked( @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg, @NonNull int[] updatedUserIds) { AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class); String pkgName = pkg.packageName; boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M; Loading Loading @@ -1390,23 +1358,6 @@ public class PermissionManagerService { } flagsToRemove |= USER_PERMISSION_FLAGS; List<String> fgPerms = mBackgroundPermissions.get(permission); if (fgPerms != null) { int numFgPerms = fgPerms.size(); for (int fgPermNum = 0; fgPermNum < numFgPerms; fgPermNum++) { String fgPerm = fgPerms.get(fgPermNum); int mode = appOpsManager.unsafeCheckOpRaw( permissionToOp(fgPerm), getUid(userId, getAppId(pkg.applicationInfo.uid)), pkgName); if (mode == MODE_ALLOWED) { setAppOpMode(fgPerm, pkg, userId, MODE_FOREGROUND); } } } } ps.updatePermissionFlags(bp, userId, flagsToRemove, 0); Loading Loading @@ -1438,58 +1389,7 @@ public class PermissionManagerService { @NonNull ArraySet<String> sourcePerms, @NonNull String newPerm, @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg, @UserIdInt int userId) { AppOpsManagerInternal appOpsManager = LocalServices.getService(AppOpsManagerInternal.class); String pkgName = pkg.packageName; if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { if (permissionToOp(newPerm) != null) { int mostLenientSourceMode = MODE_ERRORED; int flags = 0; // Find most lenient source permission state. int numSourcePerms = sourcePerms.size(); for (int i = 0; i < numSourcePerms; i++) { String sourcePerm = sourcePerms.valueAt(i); if (ps.hasRuntimePermission(sourcePerm, userId)) { int sourceOp = permissionToOpCode(sourcePerm); if (sourceOp != OP_NONE) { int mode = appOpsManager.checkOperationUnchecked(sourceOp, getUid(userId, getAppId(pkg.applicationInfo.uid)), pkgName); if (mode == MODE_FOREGROUND || mode == MODE_ERRORED) { Log.wtf(TAG, "split permission" + sourcePerm + " has app-op state " + AppOpsManager.MODE_NAMES[mode]); continue; } // Leniency order: allowed < ignored < default if (mode < mostLenientSourceMode) { mostLenientSourceMode = mode; flags = ps.getPermissionFlags(sourcePerm, userId); } else if (mode == mostLenientSourceMode) { flags |= ps.getPermissionFlags(sourcePerm, userId); } } } } if (mostLenientSourceMode != MODE_ERRORED) { if (DEBUG_PERMISSIONS) { Slog.i(TAG, newPerm + " inherits app-ops state " + mostLenientSourceMode + " from " + sourcePerms + " for " + pkgName); } setAppOpMode(newPerm, pkg, userId, mostLenientSourceMode); // Add permission flags ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags); } } } else { boolean isGranted = false; int flags = 0; Loading Loading @@ -1523,7 +1423,6 @@ public class PermissionManagerService { // Add permission flags ps.updatePermissionFlags(mSettings.getPermission(newPerm), userId, flags, flags); } } /** * Set the state of a implicit permission that is seen for the first time. Loading Loading @@ -1632,48 +1531,6 @@ 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); // 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; Loading
services/core/java/com/android/server/policy/PermissionPolicyService.java +71 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManagerInternal.PackageListObserver; import android.content.pm.PackageParser; import android.content.pm.PermissionInfo; import android.os.Build; import android.os.Process; import android.os.UserHandle; import android.permission.PermissionControllerManager; Loading Loading @@ -234,6 +235,7 @@ public final class PermissionPolicyService extends SystemService { * @see #syncRestrictedOps */ private final @NonNull ArrayList<OpToRestrict> mOpsToRestrict = new ArrayList<>(); /** * All ops that need to be unrestricted * Loading @@ -241,6 +243,13 @@ public final class PermissionPolicyService extends SystemService { */ private final @NonNull ArrayList<OpToUnrestrict> mOpsToUnrestrict = new ArrayList<>(); /** * All foreground permissions * * @see #syncOpsOfFgPermissions() */ private final @NonNull ArrayList<FgPermission> mFgPermOps = new ArrayList<>(); PermissionToOpSynchroniser(@NonNull Context context) { mContext = context; mPackageManager = context.getPackageManager(); Loading Loading @@ -339,11 +348,42 @@ public final class PermissionPolicyService extends SystemService { } } /** * Set app ops that belong to restricted permissions. * * <p>This processed ops previously added by {@link #addOpIfRestricted} */ private void syncOpsOfFgPermissions() { int numFgPermOps = mFgPermOps.size(); for (int i = 0; i < numFgPermOps; i++) { FgPermission perm = mFgPermOps.get(i); if (mPackageManager.checkPermission(perm.fgPermissionName, perm.packageName) == PackageManager.PERMISSION_GRANTED) { if (mPackageManager.checkPermission(perm.bgPermissionName, perm.packageName) == PackageManager.PERMISSION_GRANTED) { mAppOpsManager.setUidMode( AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid, AppOpsManager.MODE_ALLOWED); } else { mAppOpsManager.setUidMode( AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid, AppOpsManager.MODE_FOREGROUND); } } else { mAppOpsManager.setUidMode( AppOpsManager.permissionToOpCode(perm.fgPermissionName), perm.uid, AppOpsManager.MODE_IGNORED); } } } /** * Synchronize all previously {@link #addPackage added} packages. */ void syncPackages() { syncRestrictedOps(); syncOpsOfFgPermissions(); } /** Loading Loading @@ -380,6 +420,21 @@ public final class PermissionPolicyService extends SystemService { } } private void addOpIfFgPermissions(@NonNull PermissionInfo permissionInfo, @NonNull PackageInfo pkg) { if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) { // Pre-M apps do not store their fg/bg state in the permissions return; } if (permissionInfo.backgroundPermission == null) { return; } mFgPermOps.add(new FgPermission(pkg.applicationInfo.uid, pkg.packageName, permissionInfo.name, permissionInfo.backgroundPermission)); } /** * Add a package for {@link #syncPackages() processing} later. * Loading Loading @@ -415,6 +470,7 @@ public final class PermissionPolicyService extends SystemService { } addOpIfRestricted(permissionInfo, pkg); addOpIfFgPermissions(permissionInfo, pkg); } } Loading Loading @@ -451,5 +507,20 @@ public final class PermissionPolicyService extends SystemService { this.code = code; } } private class FgPermission { final int uid; final @NonNull String packageName; final @NonNull String fgPermissionName; final @NonNull String bgPermissionName; private FgPermission(int uid, @NonNull String packageName, @NonNull String fgPermissionName, @NonNull String bgPermissionName) { this.uid = uid; this.packageName = packageName; this.fgPermissionName = fgPermissionName; this.bgPermissionName = bgPermissionName; } } } }