am 9e398eb5: am 81f3a85a: Merge "Fix issue #22940169: "pm grant" can no longer grant permissions..." into mnc-dev

* commit '9e398eb51497dbcd2347cb1315933fa4e7cfcd9e':
  Fix issue #22940169: "pm grant" can no longer grant permissions...
This commit is contained in:
Dianne Hackborn
2015-08-14 17:21:46 +00:00
committed by Android Git Automerger
4 changed files with 82 additions and 28 deletions

View File

@ -88,4 +88,10 @@ final class BasePermission {
return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
== PermissionInfo.PROTECTION_DANGEROUS; == PermissionInfo.PROTECTION_DANGEROUS;
} }
public boolean isDevelopment() {
return (protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
== PermissionInfo.PROTECTION_SIGNATURE
&& (protectionLevel & PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0;
}
} }

View File

@ -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) { BasePermission bp) {
int index = pkg.requestedPermissions.indexOf(bp.name); int index = pkg.requestedPermissions.indexOf(bp.name);
if (index == -1) { if (index == -1) {
throw new SecurityException("Package " + pkg.packageName throw new SecurityException("Package " + pkg.packageName
+ " has not requested permission " + bp.name); + " has not requested permission " + bp.name);
} }
if (!bp.isRuntime()) { if (!bp.isRuntime() && !bp.isDevelopment()) {
throw new SecurityException("Permission " + bp.name throw new SecurityException("Permission " + bp.name
+ " is not a changeable permission type"); + " is not a changeable permission type");
} }
@ -3473,7 +3473,7 @@ public class PackageManagerService extends IPackageManager.Stub {
throw new IllegalArgumentException("Unknown permission: " + name); throw new IllegalArgumentException("Unknown permission: " + name);
} }
enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
uid = UserHandle.getUid(userId, pkg.applicationInfo.uid); uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
sb = (SettingBase) pkg.mExtras; sb = (SettingBase) pkg.mExtras;
@ -3489,6 +3489,16 @@ public class PackageManagerService extends IPackageManager.Stub {
+ name + " for package: " + packageName); + 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); final int result = permissionsState.grantRuntimePermission(bp, userId);
switch (result) { switch (result) {
case PermissionsState.PERMISSION_OPERATION_FAILURE: { case PermissionsState.PERMISSION_OPERATION_FAILURE: {
@ -3557,7 +3567,7 @@ public class PackageManagerService extends IPackageManager.Stub {
throw new IllegalArgumentException("Unknown permission: " + name); throw new IllegalArgumentException("Unknown permission: " + name);
} }
enforceDeclaredAsUsedAndRuntimePermission(pkg, bp); enforceDeclaredAsUsedAndRuntimeOrDevelopmentPermission(pkg, bp);
SettingBase sb = (SettingBase) pkg.mExtras; SettingBase sb = (SettingBase) pkg.mExtras;
if (sb == null) { if (sb == null) {
@ -3572,6 +3582,16 @@ public class PackageManagerService extends IPackageManager.Stub {
+ name + " for package: " + packageName); + 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) == if (permissionsState.revokeRuntimePermission(bp, userId) ==
PermissionsState.PERMISSION_OPERATION_FAILURE) { PermissionsState.PERMISSION_OPERATION_FAILURE) {
return; return;
@ -3799,21 +3819,6 @@ public class PackageManagerService extends IPackageManager.Stub {
return (flags & PackageManager.FLAG_PERMISSION_USER_SET) != 0; 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 @Override
public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) { public void addOnPermissionsChangeListener(IOnPermissionsChangeListener listener) {
mContext.enforceCallingOrSelfPermission( mContext.enforceCallingOrSelfPermission(
@ -14764,6 +14769,7 @@ public class PackageManagerService extends IPackageManager.Stub {
pw.println(" version: print database version info"); pw.println(" version: print database version info");
pw.println(" write: write current settings now"); pw.println(" write: write current settings now");
pw.println(" installs: details about install sessions"); pw.println(" installs: details about install sessions");
pw.println(" check-permission <permission> <package> [<user>]: does pkg hold perm?");
pw.println(" <package.name>: info about given package"); pw.println(" <package.name>: info about given package");
return; return;
} else if ("--checkin".equals(opt)) { } 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 // When dumping a single package, we always dump all of its
// filter information since the amount of data will be reasonable. // filter information since the amount of data will be reasonable.
dumpState.setOptionEnabled(DumpState.OPTION_SHOW_FILTERS); 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)) { } else if ("l".equals(cmd) || "libraries".equals(cmd)) {
dumpState.setDump(DumpState.DUMP_LIBS); dumpState.setDump(DumpState.DUMP_LIBS);
} else if ("f".equals(cmd) || "features".equals(cmd)) { } else if ("f".equals(cmd) || "features".equals(cmd)) {

View File

@ -3952,7 +3952,7 @@ final class Settings {
void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag, void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag,
ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf, ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf,
Date date, List<UserInfo> users) { Date date, List<UserInfo> users, boolean dumpAll) {
if (checkinTag != null) { if (checkinTag != null) {
pw.print(checkinTag); pw.print(checkinTag);
pw.print(","); 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<String> perms = ps.pkg.requestedPermissions;
pw.print(prefix); pw.println(" requested permissions:");
for (int i=0; i<perms.size(); i++) {
String perm = perms.get(i);
if (permissionNames != null
&& !permissionNames.contains(perm)) {
continue;
}
pw.print(prefix); pw.print(" "); pw.println(perm);
}
}
if (ps.sharedUser == null || permissionNames != null || dumpAll) {
PermissionsState permissionsState = ps.getPermissionsState(); PermissionsState permissionsState = ps.getPermissionsState();
dumpInstallPermissionsLPr(pw, prefix + " ", permissionNames, permissionsState); dumpInstallPermissionsLPr(pw, prefix + " ", permissionNames, permissionsState);
} }
@ -4190,7 +4204,7 @@ final class Settings {
PermissionsState permissionsState = ps.getPermissionsState(); PermissionsState permissionsState = ps.getPermissionsState();
dumpGidsLPr(pw, prefix + " ", permissionsState.computeGids(user.id)); dumpGidsLPr(pw, prefix + " ", permissionsState.computeGids(user.id));
dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissionsState dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissionsState
.getRuntimePermissionStates(user.id)); .getRuntimePermissionStates(user.id), dumpAll);
} }
if (permissionNames == null) { if (permissionNames == null) {
@ -4238,11 +4252,12 @@ final class Settings {
pw.println("Packages:"); pw.println("Packages:");
printedSomething = true; printedSomething = true;
} }
dumpPackageLPr(pw, " ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users); dumpPackageLPr(pw, " ", checkin ? "pkg" : null, permissionNames, ps, sdf, date, users,
packageName != null);
} }
printedSomething = false; printedSomething = false;
if (!checkin && mRenamedPackages.size() > 0 && permissionNames == null) { if (mRenamedPackages.size() > 0 && permissionNames == null) {
for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) { for (final Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
if (packageName != null && !packageName.equals(e.getKey()) if (packageName != null && !packageName.equals(e.getKey())
&& !packageName.equals(e.getValue())) { && !packageName.equals(e.getValue())) {
@ -4279,7 +4294,7 @@ final class Settings {
printedSomething = true; printedSomething = true;
} }
dumpPackageLPr(pw, " ", checkin ? "dis" : null, permissionNames, ps, sdf, date, 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()) { if (!ArrayUtils.isEmpty(gids) || !permissions.isEmpty()) {
pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": "); pw.print(prefix); pw.print("User "); pw.print(userId); pw.println(": ");
dumpGidsLPr(pw, prefix + " ", gids); dumpGidsLPr(pw, prefix + " ", gids);
dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissions); dumpRuntimePermissionsLPr(pw, prefix + " ", permissionNames, permissions,
packageName != null);
} }
} }
} else { } else {
@ -4410,8 +4426,8 @@ final class Settings {
} }
void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames, void dumpRuntimePermissionsLPr(PrintWriter pw, String prefix, ArraySet<String> permissionNames,
List<PermissionState> permissionStates) { List<PermissionState> permissionStates, boolean dumpAll) {
if (!permissionStates.isEmpty()) { if (!permissionStates.isEmpty() || dumpAll) {
pw.print(prefix); pw.println("runtime permissions:"); pw.print(prefix); pw.println("runtime permissions:");
for (PermissionState permissionState : permissionStates) { for (PermissionState permissionState : permissionStates) {
if (permissionNames != null if (permissionNames != null

View File

@ -2,6 +2,7 @@
package="com.android.test.voiceinteraction"> package="com.android.test.voiceinteraction">
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" /> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" />
<uses-permission android:name="android.permission.READ_LOGS" />
<application> <application>
<activity android:name="VoiceInteractionMain" android:label="Voice Interaction" <activity android:name="VoiceInteractionMain" android:label="Voice Interaction"