CustomLocale.apk所需要的权限"android.permission.CHANGE_CONFIGURATION"自Android 4.2,4.2.2起系统定义为android:protectionLevel=“signature|system|development”,这就需要在已root的android设置上运行命令:
adb shell pm dump com.xx.xxx | grep permission
adb shell pm grant application_package android.permission.CHANGE_CONFIGURATION
下面具体说说pm grant的调用路径。
Pm.java
View Codepublic void run(String[] args) {
boolean validCommand = false;
if (args.length < 1) {
showUsage();
return;
}
…
if (“grant”.equals(op)) {
runGrantRevokePermission(true);
return;
}
…
private void runGrantRevokePermission(boolean grant) {
String pkg = nextArg();
if (pkg == null) {
System.err.println(“Error: no package specified”);
showUsage();
return;
}
String perm = nextArg();
if (perm == null) {
System.err.println(“Error: no permission specified”);
showUsage();
return;
}
try {
if (grant) {
mPm.grantPermission(pkg, perm);
} else {
mPm.revokePermission(pkg, perm);
}
} catch (RemoteException e) {
System.err.println(e.toString());
System.err.println(PM_NOT_RUNNING_ERR);
} catch (IllegalArgumentException e) {
System.err.println("Bad argument: " + e.toString());
showUsage();
} catch (SecurityException e) {
System.err.println("Operation not allowed: " + e.toString());
}
}
PackageManagerService.java
View Codepublic class PackageManagerService extends IPackageManager.Stub {
…
public void grantPermission(String packageName, String permissionName) {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.GRANT_REVOKE_PERMISSIONS, null);
synchronized (mPackages) {
final PackageParser.Package pkg = mPackages.get(packageName);
if (pkg == null) {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
final BasePermission bp = mSettings.mPermissions.get(permissionName);
if (bp == null) {
throw new IllegalArgumentException("Unknown permission: " + permissionName);
}
checkGrantRevokePermissions(pkg, bp);
final PackageSetting ps = (PackageSetting) pkg.mExtras;
if (ps == null) {
return;
}
final GrantedPermissions gp = (ps.sharedUser != null) ? ps.sharedUser : ps;
if (gp.gr