

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());
}
}


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.grantedPermissions.add(permissionName)) {
if (ps.haveGids) {
gp.gids = appendInts(gp.gids, bp.gids);
}
mSettings.writeLPr();
}
}
}
...



View Codefinal class Settings {
...
private final File mSettingsFilename;
...
Settings(Context context, File dataDir) {
mContext = context;
mSystemDir = new File(dataDir, "system");
mSystemDir.mkdirs();
FileUtils.setPermissions(mSystemDir.toString(),
FileUtils.S_IRWXU|FileUtils.S_IRWXG
|FileUtils.S_IROTH|FileUtils.S_IXOTH,
-1, -1);
mSettingsFilename = new File(mSystemDir, "packages.xml");
mBackupSettingsFilename = new File(mSystemDir, "packages-backup.xml");
mPackageListFilename = new File(mSystemDir, "packages.list");
FileUtils.setPermissions(mPackageListFilename, 0660, SYSTEM_UID, PACKAGE_INFO_GID);
// Deprecated: Needed for migration
mStoppedPackagesFilename = new File(mSystemDir, "packages-stopped.xml");
mBackupStoppedPackagesFilename = new File(mSystemDir, "packages-stopped-backup.xml");
}
...
void writeLPr() {
//Debug.startMethodTracing("/data/system/packageprof", 8 * 1024 * 1024);
// Keep the old settings around until we know the new ones have
// been successfully written.
if (mSettingsFilename.exists()) {
// Presence of backup settings file indicates that we failed
// to persist settings earlier. So preserve the older
// backup for future reference since the current settings
// might have been corrupted.
if (!mBackupSettingsFilename.exists()) {
if (!mSettingsFilename.renameTo(mBackupSettingsFilename)) {
Log.wtf(PackageManagerService.TAG, "Unable to backup package manager settings, "
+ " current changes will be lost at reboot");
return;
}
} else {
mSettingsFilename.delete();
Slog.w(PackageManagerService.TAG, "Preserving older settings backup");
}
}
mPastSignatures.clear();
try {
FileOutputStream fstr = new FileOutputStream(mSettingsFilename);
BufferedOutputStream str = new BufferedOutputStream(fstr);
//XmlSerializer serializer = XmlUtils.serializerInstance();
XmlSerializer serializer = new FastXmlSerializer();
serializer.setOutput(str, "utf-8");
serializer.startDocument(null, true);
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startTag(null, "packages");
serializer.startTag(null, "last-platform-version");
serializer.attribute(null, "internal", Integer.toString(mInternalSdkPlatform));
serializer.attribute(null, "external", Integer.toString(mExternalSdkPlatform));
serializer.endTag(null, "last-platform-version");
if (mVerifierDeviceIdentity != null) {
serializer.startTag(null, "verifier");
serializer.attribute(null, "device", mVerifierDeviceIdentity.toString());
serializer.endTag(null, "verifier");
}
if (mReadExternalStorageEnforced != null) {
serializer.startTag(null, TAG_READ_EXTERNAL_STORAGE);
serializer.attribute(
null, ATTR_ENFORCEMENT, mReadExternalStorageEnforced ? "1" : "0");
serializer.endTag(null, TAG_READ_EXTERNAL_STORAGE);
}
serializer.startTag(null, "permission-trees");
for (BasePermission bp : mPermissionTrees.values()) {
writePermissionLPr(serializer, bp);
}
serializer.endTag(null, "permission-trees");
serializer.startTag(null, "permissions");
for (BasePermission bp : mPermissions.values()) {
writePermissionLPr(serializer, bp);
}
serializer.endTag(null, "permissions");
for (final PackageSetting pkg : mPackages.values()) {
writePackageLPr(serializer, pkg);
}
for (final PackageSetting pkg : mDisabledSysPackages.values()) {
writeDisabledSysPackageLPr(serializer, pkg);
}
for (final SharedUserSetting usr : mSharedUsers.values()) {
serializer.startTag(null, "shared-user");
serializer.attribute(null, ATTR_NAME, usr.name);
serializer.attribute(null, "userId",
Integer.toString(usr.userId));
usr.signatures.writeXml(serializer, "sigs", mPastSignatures);
serializer.startTag(null, "perms");
for (String name : usr.grantedPermissions) {
serializer.startTag(null, TAG_ITEM);
serializer.attribute(null, ATTR_NAME, name);
serializer.endTag(null, TAG_ITEM);
}
serializer.endTag(null, "perms");
serializer.endTag(null, "shared-user");
}
if (mPackagesToBeCleaned.size() > 0) {
for (PackageCleanItem item : mPackagesToBeCleaned) {
final String userStr = Integer.toString(item.userId);
serializer.startTag(null, "cleaning-package");
serializer.attribute(null, ATTR_NAME, item.packageName);
serializer.attribute(null, ATTR_CODE, item.andCode ? "true" : "false");
serializer.attribute(null, ATTR_USER, userStr);
serializer.endTag(null, "cleaning-package");
}
}
if (mRenamedPackages.size() > 0) {
for (Map.Entry<String, String> e : mRenamedPackages.entrySet()) {
serializer.startTag(null, "renamed-package");
serializer.attribute(null, "new", e.getKey());
serializer.attribute(null, "old", e.getValue());
serializer.endTag(null, "renamed-package");
}
}
mKeySetManager.writeKeySetManagerLPr(serializer);
serializer.endTag(null, "packages");
serializer.endDocument();
str.flush();
FileUtils.sync(fstr);
str.close();
// New settings successfully written, old ones are no longer
// needed.
mBackupSettingsFilename.delete();
FileUtils.setPermissions(mSettingsFilename.toString(),
FileUtils.S_IRUSR|FileUtils.S_IWUSR
|FileUtils.S_IRGRP|FileUtils.S_IWGRP,
-1, -1);
// Write package list file now, use a JournaledFile.
File tempFile = new File(mPackageListFilename.getAbsolutePath() + ".tmp");
JournaledFile journal = new JournaledFile(mPackageListFilename, tempFile);
final File writeTarget = journal.chooseForWrite();
fstr = new FileOutputStream(writeTarget);
str = new BufferedOutputStream(fstr);
try {
FileUtils.setPermissions(fstr.getFD(), 0660, SYSTEM_UID, PACKAGE_INFO_GID);
StringBuilder sb = new StringBuilder();
for (final PackageSetting pkg : mPackages.values()) {
if (pkg.pkg == null || pkg.pkg.applicationInfo == null) {
Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
continue;
}
final ApplicationInfo ai = pkg.pkg.applicationInfo;
final String dataPath = ai.dataDir;
final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
final int[] gids = pkg.getGids();
// Avoid any application that has a space in its path.
if (dataPath.indexOf("") >= 0)
continue;
// we store on each line the following information for now:
//
// pkgName - package name
// userId - application-specific user id
// debugFlag - 0 or 1 if the package is debuggable.
// dataPath - path to package‘s data path
// seinfo - seinfo label for the app (assigned at install time)
// gids - supplementary gids this app launches with
//
// NOTE: We prefer not to expose all ApplicationInfo flags for now.
//
// DO NOT MODIFY THIS FORMAT UNLESS YOU CAN ALSO MODIFY ITS USERS
// FROM NATIVE CODE. AT THE MOMENT, LOOK AT THE FOLLOWING SOURCES:
// system/core/run-as/run-as.c
// system/core/sdcard/sdcard.c
//
sb.setLength(0);
sb.append(ai.packageName);
sb.append("");
sb.append((int)ai.uid);
sb.append(isDebug ? " 1 " : " 0 ");
sb.append(dataPath);
sb.append("");
sb.append(ai.seinfo);
sb.append("");
if (gids != null && gids.length > 0) {
sb.append(gids[0]);
for (int i = 1; i < gids.length; i++) {
sb.append(",");
sb.append(gids[i]);
}
} else {
sb.append("none");
}
sb.append("\n");
str.write(sb.toString().getBytes());
}
str.flush();
FileUtils.sync(fstr);
str.close();
journal.commit();
} catch (Exception e) {
Log.wtf(TAG, "Failed to write packages.list", e);
IoUtils.closeQuietly(str);
journal.rollback();
}
writeAllUsersPackageRestrictionsLPr();
return;
} catch(XmlPullParserException e) {
Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
+ "current changes will be lost at reboot", e);
} catch(java.io.IOException e) {
Log.wtf(PackageManagerService.TAG, "Unable to write package manager settings, "
+ "current changes will be lost at reboot", e);
}
// Clean up partially written files
if (mSettingsFilename.exists()) {
if (!mSettingsFilename.delete()) {
Log.wtf(PackageManagerService.TAG, "Failed to clean up mangled file: "
+ mSettingsFilename);
}
}
//Debug.stopMethodTracing();
}
...
