diff --git a/services/core/java/com/android/server/pm/BasePermission.java b/services/core/java/com/android/server/pm/BasePermission.java index 18407c9279b54..52d09287c3475 100644 --- a/services/core/java/com/android/server/pm/BasePermission.java +++ b/services/core/java/com/android/server/pm/BasePermission.java @@ -88,4 +88,10 @@ final class BasePermission { return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) == PermissionInfo.PROTECTION_DANGEROUS; } + + public boolean isDevelopment() { + return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) + == PermissionInfo.PROTECTION_SIGNATURE + && (protectionLevel & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0; + } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 8bab34f36c3af..656e35bec3df0 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -3432,14 +3432,14 @@ public class PackageManagerService extends IPackageManager.Stub { } } - private static void enforceDeclaredAsUsedAndRuntimePermission(PackageParser.Package pkg, + private static void enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(PackageParser.Package pkg, BasePermission bp) { int index = pkg.requestedPermissions.indexOf(bp.name); if (index == -1) { throw new SecurityException("Package " + pkg.packageName + " has not requested permission " + bp.name); } - if (!bp.isRuntime()) { + if (!bp.isRuntime() && !bp.isDevelopment()) { throw new SecurityException("Permission " + bp.name + " is not a changeable permission type"); } @@ -3473,7 +3473,7 @@ public class PackageManagerService extends IPackageManager.Stub { throw new IllegalArgumentException("Unknown permission: " + name); } - enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); + enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); sb = (SettingBase) pkg.mExtras; @@ -3489,6 +3489,16 @@ public class PackageManagerService extends IPackageManager.Stub { + name + " for package: " + packageName); } + if (bp.isDevelopment()) { + // Development permissions must be handled specially, since they are not + // normal runtime permissions. For now they apply to all users. + if (permissionsState.grantInstallPermission(bp) != + PermissionsState.PERMISSION_OPERATION_FAILURE) { + scheduleWriteSettingsLocked(); + } + return; + } + final int result = permissionsState.grantRuntimePermission(bp, userId); switch (result) { case PermissionsState.PERMISSION_OPERATION_FAILURE: { @@ -3557,7 +3567,7 @@ public class PackageManagerService extends IPackageManager.Stub { throw new IllegalArgumentException("Unknown permission: " + name); } - enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); + enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp); SettingBase sb = (SettingBase) pkg.mExtras; if (sb == null) { @@ -3572,6 +3582,16 @@ public class PackageManagerService extends IPackageManager.Stub { + name + " for package: " + packageName); } + if (bp.isDevelopment()) { + // Development permissions must be handled specially, since they are not + // normal runtime permissions. For now they apply to all users. + if (permissionsState.revokeInstallPermission(bp) != + PermissionsState.PERMISSION_OPERATION_FAILURE) { + scheduleWriteSettingsLocked(); + } + return; + } + if (permissionsState.revokeRuntimePermission(bp, userId) == PermissionsState.PERMISSION_OPERATION_FAILURE) { return; @@ -3799,21 +3819,6 @@ public class PackageManagerService extends IPackageManager.Stub { return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; } - void grantInstallPermissionLPw(String permission, PackageParser.Package pkg) { - BasePermission bp = mSettings.mPermissions.get(permission); - if (bp == null) { - throw new SecurityException("Missing " + permission + " permission"); - } - - SettingBase sb = (SettingBase) pkg.mExtras; - PermissionsState permissionsState = sb.getPermissionsState(); - - if (permissionsState.grantInstallPermission(bp) != - PermissionsState.PERMISSION_OPERATION_FAILURE) { - scheduleWriteSettingsLocked(); - } - } - @Override public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { mContext.enforceCallingOrSelfPermission( @@ -14764,6 +14769,7 @@ public class PackageManagerService extends IPackageManager.Stub { pw.println(" version: print database version info"); pw.println(" write: write current settings now"); pw.println(" installs: details about install sessions"); + pw.println(" check-permission []: does pkg hold perm?"); pw.println(" : info about given package"); return; } else if ("--checkin".equals(opt)) { @@ -14785,6 +14791,31 @@ public class PackageManagerService extends IPackageManager.Stub { // When dumping a single package, we always dump all of its // filter information since the amount of data will be reasonable. dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); + } else if ("check-permission".equals(cmd)) { + if (opti >= args.length) { + pw.println("Error: check-permission missing permission argument"); + return; + } + String perm = args[opti]; + opti++; + if (opti >= args.length) { + pw.println("Error: check-permission missing package argument"); + return; + } + String pkg = args[opti]; + opti++; + int user = UserHandle.getUserId(Binder.getCallingUid()); + if (opti < args.length) { + try { + user = Integer.parseInt(args[opti]); + } catch (NumberFormatException e) { + pw.println("Error: check-permission user argument is not a number: " + + args[opti]); + return; + } + } + pw.println(checkPermission(perm, pkg, user)); + return; } else if ("l".equals(cmd) || "libraries".equals(cmd)) { dumpState.setDump(DumpState.DUMP_LIBS); } else if ("f".equals(cmd) || "features".equals(cmd)) { diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java index 2b6ed45eeb737..943e649425c87 100644 --- a/services/core/java/com/android/server/pm/Settings.java +++ b/services/core/java/com/android/server/pm/Settings.java @@ -3952,7 +3952,7 @@ final class Settings { void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, ArraySet permissionNames, PackageSetting ps, SimpleDateFormat sdf, - Date date, List users) { + Date date, List users, boolean dumpAll) { if (checkinTag != null) { pw.print(checkinTag); pw.print(","); @@ -4163,7 +4163,21 @@ final class Settings { } } - if (ps.sharedUser == null || permissionNames != null) { + if ((permissionNames != null || dumpAll) && ps.pkg.requestedPermissions != null + && ps.pkg.requestedPermissions.size() > 0) { + final ArrayList perms = ps.pkg.requestedPermissions; + pw.print(prefix); pw.println(" requested permissions:"); + for (int i=0; i 0 && permissionNames == null) { + if (mRenamedPackages.size() > 0 && permissionNames == null) { for (final Map.Entry e : mRenamedPackages.entrySet()) { if (packageName != null && !packageName.equals(e.getKey()) && !packageName.equals(e.getValue())) { @@ -4279,7 +4294,7 @@ final class Settings { printedSomething = true; } dumpPackageLPr(pw, " ", checkin ? "dis" : null, permissionNames, ps, sdf, date, - users); + users, packageName != null); } } } @@ -4364,7 +4379,8 @@ final class Settings { if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) { pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": "); dumpGidsLPr(pw, prefix + " ", gids); - dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissions); + dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissions, + packageName != null); } } } else { @@ -4410,8 +4426,8 @@ final class Settings { } void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet permissionNames, - List permissionStates) { - if (!permissionStates.isEmpty()) { + List permissionStates, boolean dumpAll) { + if (!permissionStates.isEmpty() || dumpAll) { pw.print(prefix); pw.println("runtime permissions:"); for (PermissionState permissionState : permissionStates) { if (permissionNames != null diff --git a/tests/VoiceInteraction/AndroidManifest.xml b/tests/VoiceInteraction/AndroidManifest.xml index 36d5d984ba42f..fe17c6e186014 100644 --- a/tests/VoiceInteraction/AndroidManifest.xml +++ b/tests/VoiceInteraction/AndroidManifest.xml @@ -2,6 +2,7 @@ package="com.android.test.voiceinteraction"> +