diff --git a/services/java/com/android/server/IntentResolver.java b/services/java/com/android/server/IntentResolver.java index 19b0a769bbc35..8ab65e927bb6f 100644 --- a/services/java/com/android/server/IntentResolver.java +++ b/services/java/com/android/server/IntentResolver.java @@ -91,38 +91,64 @@ public class IntentResolver { } } - void dumpMap(PrintWriter out, String prefix, Map> map) { + boolean dumpMap(PrintWriter out, String titlePrefix, String title, + String prefix, Map> map, String packageName) { String eprefix = prefix + " "; String fprefix = prefix + " "; + boolean printedSomething = false; for (Map.Entry> e : map.entrySet()) { - out.print(eprefix); out.print(e.getKey()); out.println(":"); ArrayList a = e.getValue(); final int N = a.size(); + boolean printedHeader = false; for (int i=0; i { @@ -286,6 +312,10 @@ public class IntentResolver { return true; } + protected String packageForFilter(F filter) { + return null; + } + protected R newResult(F filter, int match) { return (R)filter; } diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java index 55725bdab7632..87a744e69cac4 100644 --- a/services/java/com/android/server/PackageManagerService.java +++ b/services/java/com/android/server/PackageManagerService.java @@ -29,7 +29,6 @@ import org.xmlpull.v1.XmlSerializer; import android.app.ActivityManagerNative; import android.app.IActivityManager; -import android.app.admin.DevicePolicyManager; import android.app.admin.IDevicePolicyManager; import android.app.backup.IBackupManager; import android.content.ComponentName; @@ -79,14 +78,11 @@ import android.os.Environment; import android.os.FileObserver; import android.os.FileUtils; import android.os.Handler; -import android.os.StatFs; -import android.os.storage.StorageResultCode; import android.os.ParcelFileDescriptor; import android.os.Process; import android.os.ServiceManager; import android.os.SystemClock; import android.os.SystemProperties; -import android.provider.Settings; import android.security.SystemKeyStore; import android.util.*; import android.view.Display; @@ -122,6 +118,17 @@ import java.util.zip.ZipException; import java.util.zip.ZipFile; import java.util.zip.ZipOutputStream; +/** + * Keep track of all those .apks everywhere. + * + * This is very central to the platform's security; please run the unit + * tests whenever making modifications here: + * +mmm frameworks/base/tests/AndroidTests +adb install -r -f out/target/product/passion/data/app/AndroidTests.apk +adb shell am instrument -w -e class com.android.unit_tests.PackageManagerTests com.android.unit_tests/android.test.InstrumentationTestRunner + * + */ class PackageManagerService extends IPackageManager.Stub { private static final String TAG = "PackageManager"; private static final boolean DEBUG_SETTINGS = false; @@ -912,7 +919,7 @@ class PackageManagerService extends IPackageManager.Stub { + ((SystemClock.uptimeMillis()-startTime)/1000f) + " seconds"); - updatePermissionsLP(); + updatePermissionsLP(null, null, true, false); mSettings.writeLP(); @@ -1207,6 +1214,36 @@ class PackageManagerService extends IPackageManager.Stub { return cur; } + static int[] removeInt(int[] cur, int val) { + if (cur == null) { + return null; + } + final int N = cur.length; + for (int i=0; i 0) { + System.arraycopy(cur, 0, ret, 0, i); + } + if (i < (N-1)) { + System.arraycopy(cur, i, ret, i+1, N-i-1); + } + return ret; + } + } + return cur; + } + + static int[] removeInts(int[] cur, int[] rem) { + if (rem == null) return cur; + if (cur == null) return cur; + final int N = rem.length; + for (int i=0; i out = new ArrayList(10); for (BasePermission p : mSettings.mPermissions.values()) { if (group == null) { - if (p.perm.info.group == null) { - out.add(PackageParser.generatePermissionInfo(p.perm, flags)); + if (p.perm == null || p.perm.info.group == null) { + out.add(generatePermissionInfo(p, flags)); } } else { - if (group.equals(p.perm.info.group)) { + if (p.perm != null && group.equals(p.perm.info.group)) { out.add(PackageParser.generatePermissionInfo(p.perm, flags)); } } @@ -1600,6 +1650,7 @@ class PackageManagerService extends IPackageManager.Stub { "Not allowed to modify non-dynamic permission " + info.name); } + bp.protectionLevel = info.protectionLevel; bp.perm = new PackageParser.Permission(tree.perm.owner, new PermissionInfo(info)); bp.perm.info.packageName = tree.perm.info.packageName; @@ -3268,6 +3319,7 @@ class PackageManagerService extends IPackageManager.Stub { BasePermission tree = findPermissionTreeLP(p.info.name); if (tree == null || tree.sourcePackage.equals(p.info.packageName)) { + bp.packageSetting = pkgSetting; bp.perm = p; bp.uid = pkg.applicationInfo.uid; if ((parseFlags&PackageParser.PARSE_CHATTY) != 0) { @@ -3298,6 +3350,9 @@ class PackageManagerService extends IPackageManager.Stub { r.append("DUP:"); r.append(p.info.name); } + if (bp.perm == p) { + bp.protectionLevel = p.info.protectionLevel; + } } else { Slog.w(TAG, "Permission " + p.info.name + " from package " + p.info.packageName + " ignored: no group " @@ -3723,15 +3778,7 @@ class PackageManagerService extends IPackageManager.Stub { bp = mSettings.mPermissionTrees.get(p.info.name); } if (bp != null && bp.perm == p) { - if (bp.type != BasePermission.TYPE_BUILTIN) { - if (tree) { - mSettings.mPermissionTrees.remove(p.info.name); - } else { - mSettings.mPermissions.remove(p.info.name); - } - } else { - bp.perm = null; - } + bp.perm = null; if (chatty) { if (r == null) { r = new StringBuilder(256); @@ -3770,16 +3817,38 @@ class PackageManagerService extends IPackageManager.Stub { return name != null && name.endsWith(".apk"); } - private void updatePermissionsLP() { + private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) { + for (int i=pkgInfo.permissions.size()-1; i>=0; i--) { + if (pkgInfo.permissions.get(i).info.name.equals(perm)) { + return true; + } + } + return false; + } + + private void updatePermissionsLP(String changingPkg, + PackageParser.Package pkgInfo, boolean grantPermissions, boolean replace) { // Make sure there are no dangling permission trees. Iterator it = mSettings.mPermissionTrees .values().iterator(); while (it.hasNext()) { BasePermission bp = it.next(); - if (bp.perm == null) { + if (bp.packageSetting == null) { + // We may not yet have parsed the package, so just see if + // we still know about its settings. + bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); + } + if (bp.packageSetting == null) { Slog.w(TAG, "Removing dangling permission tree: " + bp.name + " from package " + bp.sourcePackage); it.remove(); + } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { + if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { + Slog.i(TAG, "Removing old permission tree: " + bp.name + + " from package " + bp.sourcePackage); + grantPermissions = true; + it.remove(); + } } } @@ -3792,9 +3861,10 @@ class PackageManagerService extends IPackageManager.Stub { if (DEBUG_SETTINGS) Log.v(TAG, "Dynamic permission: name=" + bp.name + " pkg=" + bp.sourcePackage + " info=" + bp.pendingInfo); - if (bp.perm == null && bp.pendingInfo != null) { + if (bp.packageSetting == null && bp.pendingInfo != null) { BasePermission tree = findPermissionTreeLP(bp.name); if (tree != null) { + bp.packageSetting = tree.packageSetting; bp.perm = new PackageParser.Permission(tree.perm.owner, new PermissionInfo(bp.pendingInfo)); bp.perm.info.packageName = tree.perm.info.packageName; @@ -3803,17 +3873,37 @@ class PackageManagerService extends IPackageManager.Stub { } } } - if (bp.perm == null) { + if (bp.packageSetting == null) { + // We may not yet have parsed the package, so just see if + // we still know about its settings. + bp.packageSetting = mSettings.mPackages.get(bp.sourcePackage); + } + if (bp.packageSetting == null) { Slog.w(TAG, "Removing dangling permission: " + bp.name + " from package " + bp.sourcePackage); it.remove(); + } else if (changingPkg != null && changingPkg.equals(bp.sourcePackage)) { + if (pkgInfo == null || !hasPermission(pkgInfo, bp.name)) { + Slog.i(TAG, "Removing old permission: " + bp.name + + " from package " + bp.sourcePackage); + grantPermissions = true; + it.remove(); + } } } // Now update the permissions for all packages, in particular // replace the granted permissions of the system packages. - for (PackageParser.Package pkg : mPackages.values()) { - grantPermissionsLP(pkg, false); + if (grantPermissions) { + for (PackageParser.Package pkg : mPackages.values()) { + if (pkg != pkgInfo) { + grantPermissionsLP(pkg, false); + } + } + } + + if (pkgInfo != null) { + grantPermissionsLP(pkgInfo, replace); } } @@ -3823,7 +3913,7 @@ class PackageManagerService extends IPackageManager.Stub { return; } final GrantedPermissions gp = ps.sharedUser != null ? ps.sharedUser : ps; - boolean addedPermission = false; + boolean changedPermission = false; if (replace) { ps.permissionsFixed = false; @@ -3841,26 +3931,26 @@ class PackageManagerService extends IPackageManager.Stub { for (int i=0; i(gp.grantedPermissions); } } - + private final class ActivityIntentResolver extends IntentResolver { public List queryIntent(Intent intent, String resolvedType, boolean defaultOnly) { @@ -4029,6 +4132,11 @@ class PackageManagerService extends IPackageManager.Stub { return true; } + @Override + protected String packageForFilter(PackageParser.ActivityIntentInfo info) { + return info.activity.owner.packageName; + } + @Override protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info, int match) { @@ -4069,7 +4177,9 @@ class PackageManagerService extends IPackageManager.Stub { out.print(prefix); out.print( Integer.toHexString(System.identityHashCode(filter.activity))); out.print(' '); - out.println(filter.activity.getComponentShortName()); + out.print(filter.activity.getComponentShortName()); + out.print(" filter "); + out.println(Integer.toHexString(System.identityHashCode(filter))); } // List filterEnabled(List resolveInfoList) { @@ -4179,6 +4289,11 @@ class PackageManagerService extends IPackageManager.Stub { return true; } + @Override + protected String packageForFilter(PackageParser.ServiceIntentInfo info) { + return info.service.owner.packageName; + } + @Override protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter, int match) { @@ -4220,7 +4335,9 @@ class PackageManagerService extends IPackageManager.Stub { out.print(prefix); out.print( Integer.toHexString(System.identityHashCode(filter.service))); out.print(' '); - out.println(filter.service.getComponentShortName()); + out.print(filter.service.getComponentShortName()); + out.print(" filter "); + out.println(Integer.toHexString(System.identityHashCode(filter))); } // List filterEnabled(List resolveInfoList) { @@ -4389,7 +4506,8 @@ class PackageManagerService extends IPackageManager.Stub { SCAN_MONITOR | SCAN_NO_PATHS); if (p != null) { synchronized (mPackages) { - grantPermissionsLP(p, false); + updatePermissionsLP(p.packageName, p, + p.permissions.size() > 0, false); } addedPackage = p.applicationInfo.packageName; addedUid = p.applicationInfo.uid; @@ -5410,7 +5528,8 @@ class PackageManagerService extends IPackageManager.Stub { parseFlags |= ~PackageManager.INSTALL_REPLACE_EXISTING; scanPackageLI(restoreFile, parseFlags, scanMode); synchronized (mPackages) { - grantPermissionsLP(deletedPackage, false); + updatePermissionsLP(deletedPackage.packageName, deletedPackage, + true, false); mSettings.writeLP(); } if (restoreRes.returnCode != PackageManager.INSTALL_SUCCEEDED) { @@ -5536,7 +5655,8 @@ class PackageManagerService extends IPackageManager.Stub { Log.d(TAG, "New package installed in " + newPackage.mPath); } synchronized (mPackages) { - grantPermissionsLP(newPackage, true); + updatePermissionsLP(newPackage.packageName, newPackage, + newPackage.permissions.size() > 0, true); res.name = pkgName; res.uid = newPackage.applicationInfo.uid; res.pkg = newPackage; @@ -5917,19 +6037,23 @@ class PackageManagerService extends IPackageManager.Stub { File dataDir = new File(pkg.applicationInfo.dataDir); dataDir.delete(); } - schedulePackageCleaning(packageName); - synchronized (mPackages) { - if (outInfo != null) { - outInfo.removedUid = mSettings.removePackageLP(packageName); - } - } } synchronized (mPackages) { - if ( (deletedPs != null) && (deletedPs.sharedUser != null)) { - // remove permissions associated with package - mSettings.updateSharedUserPermsLP(deletedPs, mGlobalGids); - } if (deletedPs != null) { + schedulePackageCleaning(packageName); + + if ((flags&PackageManager.DONT_DELETE_DATA) == 0) { + if (outInfo != null) { + outInfo.removedUid = mSettings.removePackageLP(packageName); + } + if (deletedPs != null) { + updatePermissionsLP(deletedPs.name, null, false, false); + if (deletedPs.sharedUser != null) { + // remove permissions associated with package + mSettings.updateSharedUserPermsLP(deletedPs, mGlobalGids); + } + } + } // remove from preferred activities. ArrayList removed = new ArrayList(); for (PreferredActivity pa : mSettings.mPreferredActivities.filterSet()) { @@ -6003,7 +6127,7 @@ class PackageManagerService extends IPackageManager.Stub { return false; } synchronized (mPackages) { - grantPermissionsLP(newPkg, true); + updatePermissionsLP(newPkg.packageName, newPkg, true, true); mSettings.writeLP(); } return true; @@ -6659,35 +6783,102 @@ class PackageManagerService extends IPackageManager.Stub { return; } + String packageName = null; + + int opti = 0; + while (opti < args.length) { + String opt = args[opti]; + if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') { + break; + } + opti++; + if ("-a".equals(opt)) { + // Right now we only know how to print all. + } else if ("-h".equals(opt)) { + pw.println("Package manager dump options:"); + pw.println(" [-h] [cmd] ..."); + pw.println(" cmd may be one of:"); + pw.println(" [package.name]: info about given package"); + return; + } else { + pw.println("Unknown argument: " + opt + "; use -h for help"); + } + } + + // Is the caller requesting to dump a particular piece of data? + if (opti < args.length) { + String cmd = args[opti]; + opti++; + // Is this a package name? + if ("android".equals(cmd) || cmd.contains(".")) { + packageName = cmd; + } + } + + boolean printedTitle = false; + synchronized (mPackages) { - pw.println("Activity Resolver Table:"); - mActivities.dump(pw, " "); - pw.println(" "); - pw.println("Receiver Resolver Table:"); - mReceivers.dump(pw, " "); - pw.println(" "); - pw.println("Service Resolver Table:"); - mServices.dump(pw, " "); - pw.println(" "); - pw.println("Preferred Activities:"); - mSettings.mPreferredActivities.dump(pw, " "); - pw.println(" "); - pw.println("Permissions:"); + if (mActivities.dump(pw, "Activity Resolver Table:", " ", packageName)) { + printedTitle = true; + } + if (mReceivers.dump(pw, printedTitle + ? "\nReceiver Resolver Table:" : "Receiver Resolver Table:", + " ", packageName)) { + printedTitle = true; + } + if (mServices.dump(pw, printedTitle + ? "\nService Resolver Table:" : "Service Resolver Table:", + " ", packageName)) { + printedTitle = true; + } + if (mSettings.mPreferredActivities.dump(pw, printedTitle + ? "\nPreferred Activities:" : "Preferred Activities:", + " ", packageName)) { + printedTitle = true; + } + boolean printedSomething = false; { for (BasePermission p : mSettings.mPermissions.values()) { + if (packageName != null && !packageName.equals(p.sourcePackage)) { + continue; + } + if (!printedSomething) { + if (printedTitle) pw.println(" "); + pw.println("Permissions:"); + printedSomething = true; + printedTitle = true; + } pw.print(" Permission ["); pw.print(p.name); pw.print("] ("); pw.print(Integer.toHexString(System.identityHashCode(p))); pw.println("):"); pw.print(" sourcePackage="); pw.println(p.sourcePackage); pw.print(" uid="); pw.print(p.uid); pw.print(" gids="); pw.print(arrayToString(p.gids)); - pw.print(" type="); pw.println(p.type); + pw.print(" type="); pw.print(p.type); + pw.print(" prot="); pw.println(p.protectionLevel); + if (p.packageSetting != null) { + pw.print(" packageSetting="); pw.println(p.packageSetting); + } + if (p.perm != null) { + pw.print(" perm="); pw.println(p.perm); + } } } - pw.println(" "); - pw.println("Packages:"); + printedSomething = false; + SharedUserSetting packageSharedUser = null; { for (PackageSetting ps : mSettings.mPackages.values()) { + if (packageName != null && !packageName.equals(ps.realName) + && !packageName.equals(ps.name)) { + continue; + } + if (!printedSomething) { + if (printedTitle) pw.println(" "); + pw.println("Packages:"); + printedSomething = true; + printedTitle = true; + } + packageSharedUser = ps.sharedUser; pw.print(" Package ["); pw.print(ps.realName != null ? ps.realName : ps.name); pw.print("] ("); @@ -6771,20 +6962,38 @@ class PackageManagerService extends IPackageManager.Stub { } } } + printedSomething = false; if (mSettings.mRenamedPackages.size() > 0) { - pw.println(" "); - pw.println("Renamed packages:"); for (HashMap.Entry e : mSettings.mRenamedPackages.entrySet()) { + if (packageName != null && !packageName.equals(e.getKey()) + && !packageName.equals(e.getValue())) { + continue; + } + if (!printedSomething) { + if (printedTitle) pw.println(" "); + pw.println("Renamed packages:"); + printedSomething = true; + printedTitle = true; + } pw.print(" "); pw.print(e.getKey()); pw.print(" -> "); pw.println(e.getValue()); } } + printedSomething = false; if (mSettings.mDisabledSysPackages.size() > 0) { - pw.println(" "); - pw.println("Hidden system packages:"); for (PackageSetting ps : mSettings.mDisabledSysPackages.values()) { - pw.print(" Package ["); + if (packageName != null && !packageName.equals(ps.realName) + && !packageName.equals(ps.name)) { + continue; + } + if (!printedSomething) { + if (printedTitle) pw.println(" "); + pw.println("Hidden system packages:"); + printedSomething = true; + printedTitle = true; + } + pw.print(" Package ["); pw.print(ps.realName != null ? ps.realName : ps.name); pw.print("] ("); pw.print(Integer.toHexString(System.identityHashCode(ps))); @@ -6798,10 +7007,18 @@ class PackageManagerService extends IPackageManager.Stub { pw.print(" resourcePath="); pw.println(ps.resourcePathString); } } - pw.println(" "); - pw.println("Shared Users:"); + printedSomething = false; { for (SharedUserSetting su : mSettings.mSharedUsers.values()) { + if (packageName != null && su != packageSharedUser) { + continue; + } + if (!printedSomething) { + if (printedTitle) pw.println(" "); + pw.println("Shared users:"); + printedSomething = true; + printedTitle = true; + } pw.print(" SharedUser ["); pw.print(su.name); pw.print("] ("); pw.print(Integer.toHexString(System.identityHashCode(su))); pw.println("):"); @@ -6818,29 +7035,40 @@ class PackageManagerService extends IPackageManager.Stub { } } - pw.println(" "); - pw.println("Settings parse messages:"); - pw.println(mSettings.mReadMessages.toString()); - - pw.println(" "); - pw.println("Package warning messages:"); - File fname = getSettingsProblemFile(); - FileInputStream in; - try { - in = new FileInputStream(fname); - int avail = in.available(); - byte[] data = new byte[avail]; - in.read(data); - pw.println(new String(data)); - } catch (FileNotFoundException e) { - } catch (IOException e) { + if (packageName == null) { + if (printedTitle) pw.println(" "); + printedTitle = true; + pw.println("Settings parse messages:"); + pw.println(mSettings.mReadMessages.toString()); + + pw.println(" "); + pw.println("Package warning messages:"); + File fname = getSettingsProblemFile(); + FileInputStream in; + try { + in = new FileInputStream(fname); + int avail = in.available(); + byte[] data = new byte[avail]; + in.read(data); + pw.println(new String(data)); + } catch (FileNotFoundException e) { + } catch (IOException e) { + } } } synchronized (mProviders) { - pw.println(" "); - pw.println("Registered ContentProviders:"); + boolean printedSomething = false; for (PackageParser.Provider p : mProviders.values()) { + if (packageName != null && !packageName.equals(p.info.packageName)) { + continue; + } + if (!printedSomething) { + if (printedTitle) pw.println(" "); + pw.println("Registered ContentProviders:"); + printedSomething = true; + printedTitle = true; + } pw.print(" ["); pw.print(p.info.authority); pw.print("]: "); pw.println(p.toString()); } @@ -6854,7 +7082,9 @@ class PackageManagerService extends IPackageManager.Stub { final String name; String sourcePackage; + PackageSettingBase packageSetting; final int type; + int protectionLevel; PackageParser.Permission perm; PermissionInfo pendingInfo; int uid; @@ -6864,6 +7094,14 @@ class PackageManagerService extends IPackageManager.Stub { name = _name; sourcePackage = _sourcePackage; type = _type; + // Default to most conservative protection level. + protectionLevel = PermissionInfo.PROTECTION_SIGNATURE; + } + + public String toString() { + return "BasePermission{" + + Integer.toHexString(System.identityHashCode(this)) + + " " + name + "}"; } } @@ -7496,6 +7734,10 @@ class PackageManagerService extends IPackageManager.Stub { private final IntentResolver mPreferredActivities = new IntentResolver() { @Override + protected String packageForFilter(PreferredActivity filter) { + return filter.mActivity.getPackageName(); + } + @Override protected void dumpFilter(PrintWriter out, String prefix, PreferredActivity filter) { out.print(prefix); out.print( @@ -7734,9 +7976,10 @@ class PackageManagerService extends IPackageManager.Stub { + " from pkg " + bp.sourcePackage + " to " + newPkg); bp.sourcePackage = newPkg; + bp.packageSetting = null; bp.perm = null; if (bp.pendingInfo != null) { - bp.sourcePackage = newPkg; + bp.pendingInfo.packageName = newPkg; } bp.uid = 0; bp.gids = null; @@ -8243,7 +8486,7 @@ class PackageManagerService extends IPackageManager.Stub { // be set. for (final String name : pkg.grantedPermissions) { BasePermission bp = mPermissions.get(name); - if ((bp != null) && (bp.perm != null) && (bp.perm.info != null)) { + if (bp != null) { // We only need to write signature or system permissions but this wont // match the semantics of grantedPermissions. So write all permissions. serializer.startTag(null, "item"); @@ -8337,6 +8580,11 @@ class PackageManagerService extends IPackageManager.Stub { serializer.startTag(null, "item"); serializer.attribute(null, "name", bp.name); serializer.attribute(null, "package", bp.sourcePackage); + if (bp.protectionLevel != + PermissionInfo.PROTECTION_NORMAL) { + serializer.attribute(null, "protection", + Integer.toString(bp.protectionLevel)); + } if (DEBUG_SETTINGS) Log.v(TAG, "Writing perm: name=" + bp.name + " type=" + bp.type); if (bp.type == BasePermission.TYPE_DYNAMIC) { @@ -8352,11 +8600,6 @@ class PackageManagerService extends IPackageManager.Stub { serializer.attribute(null, "label", pi.nonLocalizedLabel.toString()); } - if (pi.protectionLevel != - PermissionInfo.PROTECTION_NORMAL) { - serializer.attribute(null, "protection", - Integer.toString(pi.protectionLevel)); - } } } serializer.endTag(null, "item"); @@ -8558,6 +8801,8 @@ class PackageManagerService extends IPackageManager.Stub { dynamic ? BasePermission.TYPE_DYNAMIC : BasePermission.TYPE_NORMAL); + bp.protectionLevel = readInt(parser, null, "protection", + PermissionInfo.PROTECTION_NORMAL); if (dynamic) { PermissionInfo pi = new PermissionInfo(); pi.packageName = sourcePackage.intern(); @@ -8565,8 +8810,7 @@ class PackageManagerService extends IPackageManager.Stub { pi.icon = readInt(parser, null, "icon", 0); pi.nonLocalizedLabel = parser.getAttributeValue( null, "label"); - pi.protectionLevel = readInt(parser, null, "protection", - PermissionInfo.PROTECTION_NORMAL); + pi.protectionLevel = bp.protectionLevel; bp.pendingInfo = pi; } out.put(bp.name, bp); @@ -9322,10 +9566,6 @@ class PackageManagerService extends IPackageManager.Stub { // Scan the package if (scanPackageLI(pkg, parseFlags, SCAN_MONITOR) != null) { synchronized (mPackages) { - // Grant permissions - grantPermissionsLP(pkg, false); - // Persist settings - mSettings.writeLP(); retCode = PackageManager.INSTALL_SUCCEEDED; pkgList.add(pkg.packageName); // Post process args @@ -9344,6 +9584,10 @@ class PackageManagerService extends IPackageManager.Stub { } } } + synchronized (mPackages) { + // Persist settings + mSettings.writeLP(); + } // Send a broadcast to let everyone know we are done processing if (sendUpdateBroadcast) { sendResourcesChangedBroadcast(true, pkgList, uidArr); diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index a437d9582af5c..2ecebed86f248 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -9356,7 +9356,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen dumpAll = true; } else if ("-h".equals(opt)) { pw.println("Activity manager dump options:"); - pw.println(" [-a] [h- [cmd] ..."); + pw.println(" [-a] [-h] [cmd] ..."); pw.println(" cmd may be one of:"); pw.println(" activities: activity stack state"); pw.println(" broadcasts: broadcast state"); @@ -9756,7 +9756,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen pw.println(" "); pw.println("Receiver Resolver Table:"); - mReceiverResolver.dump(pw, " "); + mReceiverResolver.dump(pw, null, " ", null); needSep = true; } diff --git a/tests/AndroidTests/Android.mk b/tests/AndroidTests/Android.mk index 0d29c358afdeb..c22547feaf5bd 100644 --- a/tests/AndroidTests/Android.mk +++ b/tests/AndroidTests/Android.mk @@ -16,4 +16,6 @@ LOCAL_CERTIFICATE := platform include $(BUILD_PACKAGE) -include $(call all-makefiles-under,$(LOCAL_PATH)) +LOCAL_STORED_PATH:= $(LOCAL_PATH) +include $(call all-makefiles-under,$(LOCAL_STORED_PATH)) +include $(call all-makefiles-under,$(LOCAL_STORED_PATH)/apks) diff --git a/tests/AndroidTests/apks/install_decl_perm/Android.mk b/tests/AndroidTests/apks/install_decl_perm/Android.mk new file mode 100644 index 0000000000000..9dcf9a0f0a149 --- /dev/null +++ b/tests/AndroidTests/apks/install_decl_perm/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := AndroidTests_install_decl_perm + +include $(BUILD_PACKAGE) + diff --git a/tests/AndroidTests/apks/install_decl_perm/AndroidManifest.xml b/tests/AndroidTests/apks/install_decl_perm/AndroidManifest.xml new file mode 100644 index 0000000000000..43875007c89f8 --- /dev/null +++ b/tests/AndroidTests/apks/install_decl_perm/AndroidManifest.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/tests/AndroidTests/apks/install_decl_perm/res/values/strings.xml b/tests/AndroidTests/apks/install_decl_perm/res/values/strings.xml new file mode 100644 index 0000000000000..5564300690b20 --- /dev/null +++ b/tests/AndroidTests/apks/install_decl_perm/res/values/strings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/AndroidTests/apks/install_use_perm_good/Android.mk b/tests/AndroidTests/apks/install_use_perm_good/Android.mk new file mode 100644 index 0000000000000..a25a03c759644 --- /dev/null +++ b/tests/AndroidTests/apks/install_use_perm_good/Android.mk @@ -0,0 +1,11 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_MODULE_TAGS := tests + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_PACKAGE_NAME := AndroidTests_install_use_perm_good + +include $(BUILD_PACKAGE) + diff --git a/tests/AndroidTests/apks/install_use_perm_good/AndroidManifest.xml b/tests/AndroidTests/apks/install_use_perm_good/AndroidManifest.xml new file mode 100644 index 0000000000000..6dd3e7113d4da --- /dev/null +++ b/tests/AndroidTests/apks/install_use_perm_good/AndroidManifest.xml @@ -0,0 +1,10 @@ + + + + + + + + + diff --git a/tests/AndroidTests/apks/install_use_perm_good/res/values/strings.xml b/tests/AndroidTests/apks/install_use_perm_good/res/values/strings.xml new file mode 100644 index 0000000000000..5564300690b20 --- /dev/null +++ b/tests/AndroidTests/apks/install_use_perm_good/res/values/strings.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/tests/AndroidTests/res/raw/install_decl_perm b/tests/AndroidTests/res/raw/install_decl_perm new file mode 100644 index 0000000000000..6f223213e2416 Binary files /dev/null and b/tests/AndroidTests/res/raw/install_decl_perm differ diff --git a/tests/AndroidTests/res/raw/install_use_perm_good b/tests/AndroidTests/res/raw/install_use_perm_good new file mode 100644 index 0000000000000..d5216f89a47a0 Binary files /dev/null and b/tests/AndroidTests/res/raw/install_use_perm_good differ diff --git a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java index b988920e041d2..009c0f2d936be 100755 --- a/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java +++ b/tests/AndroidTests/src/com/android/unit_tests/PackageManagerTests.java @@ -45,6 +45,7 @@ import android.content.pm.PackageManager; import android.content.pm.PackageParser; import android.content.pm.PackageStats; import android.content.pm.IPackageManager; +import android.content.pm.PermissionInfo; import android.content.pm.PackageManager.NameNotFoundException; import android.content.res.Resources; import android.content.res.Resources.NotFoundException; @@ -372,6 +373,7 @@ public class PackageManagerTests extends AndroidTestCase { } return INSTALL_LOC_ERR; } + private void assertInstall(PackageParser.Package pkg, int flags, int expInstallLocation) { try { String pkgName = pkg.packageName; @@ -410,6 +412,7 @@ public class PackageManagerTests extends AndroidTestCase { failStr("failed with exception : " + e); } } + private void assertNotInstalled(String pkgName) { try { ApplicationInfo info = getPm().getApplicationInfo(pkgName, 0); @@ -434,6 +437,95 @@ public class PackageManagerTests extends AndroidTestCase { false, -1, PackageInfo.INSTALL_LOCATION_AUTO); } + static final String PERM_PACKAGE = "package"; + static final String PERM_DEFINED = "defined"; + static final String PERM_UNDEFINED = "undefined"; + static final String PERM_USED = "used"; + static final String PERM_NOTUSED = "notused"; + + private void assertPermissions(String[] cmds) { + final PackageManager pm = getPm(); + String pkg = null; + PackageInfo pkgInfo = null; + String mode = PERM_DEFINED; + int i = 0; + while (i < cmds.length) { + String cmd = cmds[i++]; + if (cmd == PERM_PACKAGE) { + pkg = cmds[i++]; + try { + pkgInfo = pm.getPackageInfo(pkg, + PackageManager.GET_PERMISSIONS + | PackageManager.GET_UNINSTALLED_PACKAGES); + } catch (NameNotFoundException e) { + pkgInfo = null; + } + } else if (cmd == PERM_DEFINED || cmd == PERM_UNDEFINED + || cmd == PERM_USED || cmd == PERM_NOTUSED) { + mode = cmds[i++]; + } else { + if (mode == PERM_DEFINED) { + try { + PermissionInfo pi = pm.getPermissionInfo(cmd, 0); + assertNotNull(pi); + assertEquals(pi.packageName, pkg); + assertEquals(pi.name, cmd); + assertNotNull(pkgInfo); + boolean found = false; + for (int j=0; j