summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/pm/PackageManagerService.java
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@android.com>2014-02-11 13:34:46 -0800
committerAndroid Git Automerger <android-git-automerger@android.com>2014-02-11 13:34:46 -0800
commit4ad93639d210297764db3ffcd870ff38464943de (patch)
treeba794933d10f7716326b59672dc96775dae310c3 /services/java/com/android/server/pm/PackageManagerService.java
parent0cd115e1cebf4c090e7c36a65d4a5b7d1c363c21 (diff)
parent67754d93c4bfb2da1831b1dd2b40c12a838b1028 (diff)
downloadframeworks_base-4ad93639d210297764db3ffcd870ff38464943de.zip
frameworks_base-4ad93639d210297764db3ffcd870ff38464943de.tar.gz
frameworks_base-4ad93639d210297764db3ffcd870ff38464943de.tar.bz2
am 67754d93: Merge "Runtime resource overlay, iteration 2"
* commit '67754d93c4bfb2da1831b1dd2b40c12a838b1028': Runtime resource overlay, iteration 2
Diffstat (limited to 'services/java/com/android/server/pm/PackageManagerService.java')
-rwxr-xr-xservices/java/com/android/server/pm/PackageManagerService.java99
1 files changed, 98 insertions, 1 deletions
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 7ea1fce..74a66d6 100755
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -217,6 +217,7 @@ public class PackageManagerService extends IPackageManager.Stub {
static final int SCAN_UPDATE_TIME = 1<<6;
static final int SCAN_DEFER_DEX = 1<<7;
static final int SCAN_BOOTING = 1<<8;
+ static final int SCAN_TRUSTED_OVERLAY = 1<<9;
static final int REMOVE_CHATTY = 1<<16;
@@ -257,8 +258,13 @@ public class PackageManagerService extends IPackageManager.Stub {
private static final String LIB_DIR_NAME = "lib";
+ private static final String VENDOR_OVERLAY_DIR = "/vendor/overlay";
+
static final String mTempContainerPrefix = "smdl2tmp";
+ private static final String IDMAP_PREFIX = "/data/resource-cache/";
+ private static final String IDMAP_SUFFIX = "@idmap";
+
final HandlerThread mHandlerThread = new HandlerThread("PackageManager",
Process.THREAD_PRIORITY_BACKGROUND);
final PackageHandler mHandler;
@@ -296,6 +302,9 @@ public class PackageManagerService extends IPackageManager.Stub {
// This is the object monitoring the system app dir.
final FileObserver mVendorInstallObserver;
+ // This is the object monitoring the vendor overlay package dir.
+ final FileObserver mVendorOverlayInstallObserver;
+
// This is the object monitoring mAppInstallDir.
final FileObserver mAppInstallObserver;
@@ -343,6 +352,10 @@ public class PackageManagerService extends IPackageManager.Stub {
final HashMap<String, PackageParser.Package> mPackages =
new HashMap<String, PackageParser.Package>();
+ // Tracks available target package names -> overlay package paths.
+ final HashMap<String, HashMap<String, PackageParser.Package>> mOverlays =
+ new HashMap<String, HashMap<String, PackageParser.Package>>();
+
final Settings mSettings;
boolean mRestoredSettings;
@@ -1273,6 +1286,17 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
+ // Collect vendor overlay packages.
+ // (Do this before scanning any apps.)
+ // For security and version matching reason, only consider
+ // overlay packages if they reside in VENDOR_OVERLAY_DIR.
+ File vendorOverlayDir = new File(VENDOR_OVERLAY_DIR);
+ mVendorOverlayInstallObserver = new AppDirObserver(
+ vendorOverlayDir.getPath(), OBSERVER_EVENTS, true, false);
+ mVendorOverlayInstallObserver.startWatching();
+ scanDirLI(vendorOverlayDir, PackageParser.PARSE_IS_SYSTEM
+ | PackageParser.PARSE_IS_SYSTEM_DIR, scanMode | SCAN_TRUSTED_OVERLAY, 0);
+
// Find base frameworks (resource packages without code).
mFrameworkInstallObserver = new AppDirObserver(
frameworkDir.getPath(), OBSERVER_EVENTS, true, false);
@@ -3475,6 +3499,56 @@ public class PackageManagerService extends IPackageManager.Stub {
return finalList;
}
+ private void createIdmapsForPackageLI(PackageParser.Package pkg) {
+ HashMap<String, PackageParser.Package> overlays = mOverlays.get(pkg.packageName);
+ if (overlays == null) {
+ Slog.w(TAG, "Unable to create idmap for " + pkg.packageName + ": no overlay packages");
+ return;
+ }
+ for (PackageParser.Package opkg : overlays.values()) {
+ // Not much to do if idmap fails: we already logged the error
+ // and we certainly don't want to abort installation of pkg simply
+ // because an overlay didn't fit properly. For these reasons,
+ // ignore the return value of createIdmapForPackagePairLI.
+ createIdmapForPackagePairLI(pkg, opkg);
+ }
+ }
+
+ private boolean createIdmapForPackagePairLI(PackageParser.Package pkg,
+ PackageParser.Package opkg) {
+ if (!opkg.mTrustedOverlay) {
+ Slog.w(TAG, "Skipping target and overlay pair " + pkg.mScanPath + " and " +
+ opkg.mScanPath + ": overlay not trusted");
+ return false;
+ }
+ HashMap<String, PackageParser.Package> overlaySet = mOverlays.get(pkg.packageName);
+ if (overlaySet == null) {
+ Slog.e(TAG, "was about to create idmap for " + pkg.mScanPath + " and " +
+ opkg.mScanPath + " but target package has no known overlays");
+ return false;
+ }
+ final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
+ if (mInstaller.idmap(pkg.mScanPath, opkg.mScanPath, sharedGid) != 0) {
+ Slog.e(TAG, "Failed to generate idmap for " + pkg.mScanPath + " and " + opkg.mScanPath);
+ return false;
+ }
+ PackageParser.Package[] overlayArray =
+ overlaySet.values().toArray(new PackageParser.Package[0]);
+ Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
+ public int compare(PackageParser.Package p1, PackageParser.Package p2) {
+ return p1.mOverlayPriority - p2.mOverlayPriority;
+ }
+ };
+ Arrays.sort(overlayArray, cmp);
+
+ pkg.applicationInfo.resourceDirs = new String[overlayArray.length];
+ int i = 0;
+ for (PackageParser.Package p : overlayArray) {
+ pkg.applicationInfo.resourceDirs[i++] = p.applicationInfo.sourceDir;
+ }
+ return true;
+ }
+
private void scanDirLI(File dir, int flags, int scanMode, long currentTime) {
String[] files = dir.list();
if (files == null) {
@@ -3572,7 +3646,7 @@ public class PackageManagerService extends IPackageManager.Stub {
pp.setSeparateProcesses(mSeparateProcesses);
pp.setOnlyCoreApps(mOnlyCore);
final PackageParser.Package pkg = pp.parsePackage(scanFile,
- scanPath, mMetrics, parseFlags);
+ scanPath, mMetrics, parseFlags, (scanMode & SCAN_TRUSTED_OVERLAY) != 0);
if (pkg == null) {
mLastScanError = pp.getParseError();
@@ -5081,6 +5155,29 @@ public class PackageManagerService extends IPackageManager.Stub {
}
pkgSetting.setTimeStamp(scanFileTime);
+
+ // Create idmap files for pairs of (packages, overlay packages).
+ // Note: "android", ie framework-res.apk, is handled by native layers.
+ if (pkg.mOverlayTarget != null) {
+ // This is an overlay package.
+ if (pkg.mOverlayTarget != null && !pkg.mOverlayTarget.equals("android")) {
+ if (!mOverlays.containsKey(pkg.mOverlayTarget)) {
+ mOverlays.put(pkg.mOverlayTarget,
+ new HashMap<String, PackageParser.Package>());
+ }
+ HashMap<String, PackageParser.Package> map = mOverlays.get(pkg.mOverlayTarget);
+ map.put(pkg.packageName, pkg);
+ PackageParser.Package orig = mPackages.get(pkg.mOverlayTarget);
+ if (orig != null && !createIdmapForPackagePairLI(orig, pkg)) {
+ mLastScanError = PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
+ return null;
+ }
+ }
+ } else if (mOverlays.containsKey(pkg.packageName) &&
+ !pkg.packageName.equals("android")) {
+ // This is a regular package, with one or more known overlay packages.
+ createIdmapsForPackageLI(pkg);
+ }
}
return pkg;