From c6778e5435f0bea1737fd987af3f4480ac3ab2d1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?M=C3=A5rten=20Kongstad?= Date: Thu, 6 Dec 2018 13:40:12 +0100 Subject: [PATCH] Remove overlay logic from package manager and parser Consolidate all knowledge about overlays to the overlay manager (except static RROs that target "android": these are handled from native code in order to be loaded as part of Zygote boot). This removes the ability to overlay AndroidManifest.xml. There are some use-cases where overlaying a manifest makes sense [e.g. changing an app's label or icon or what components should be enabled by default] but the opposite is also true [e.g. permissions]. Support for manifests can be introduced again gradually with these goals in mind: - should not happen during parsing [which represents the immutable truth as read from disk] - should happen during scanning [which applies mutable settings to a parsed package] - be limited in what can be modified Bug: 78808368 Test: builds, boots Change-Id: I12c16fce65b1e68876f0c9acd7e2a61405e64435 (cherry picked from commit 588784dc259c23782db6a6c93054056fca1dbd77) --- core/java/android/content/pm/PackageParser.java | 39 +------ .../android/server/pm/PackageManagerService.java | 119 +-------------------- 2 files changed, 4 insertions(+), 154 deletions(-) diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java index 2b23e7a2a633..270aea851791 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -591,8 +591,6 @@ public class PackageParser { */ public interface Callback { boolean hasFeature(String feature); - String[] getOverlayPaths(String targetPackageName, String targetPath); - String[] getOverlayApks(String targetPackageName); } /** @@ -609,14 +607,6 @@ public class PackageParser { @Override public boolean hasFeature(String feature) { return mPm.hasSystemFeature(feature); } - - @Override public String[] getOverlayPaths(String targetPackageName, String targetPath) { - return null; - } - - @Override public String[] getOverlayApks(String targetPackageName) { - return null; - } } /** @@ -1168,19 +1158,7 @@ public class PackageParser { } final byte[] bytes = IoUtils.readFileAsByteArray(cacheFile.getAbsolutePath()); - Package p = fromCacheEntry(bytes); - if (mCallback != null) { - String[] overlayApks = mCallback.getOverlayApks(p.packageName); - if (overlayApks != null && overlayApks.length > 0) { - for (String overlayApk : overlayApks) { - // If a static RRO is updated, return null. - if (!isCacheUpToDate(new File(overlayApk), cacheFile)) { - return null; - } - } - } - } - return p; + return fromCacheEntry(bytes); } catch (Throwable e) { Slog.w(TAG, "Error reading package cache: ", e); @@ -1354,7 +1332,7 @@ public class PackageParser { final Resources res = new Resources(assets, mMetrics, null); final String[] outError = new String[1]; - final Package pkg = parseBaseApk(apkPath, res, parser, flags, outError); + final Package pkg = parseBaseApk(res, parser, flags, outError); if (pkg == null) { throw new PackageParserException(mParseError, apkPath + " (at " + parser.getPositionDescription() + "): " + outError[0]); @@ -1911,7 +1889,6 @@ public class PackageParser { * need to consider whether they should be supported by split APKs and child * packages. * - * @param apkPath The package apk file path * @param res The resources from which to resolve values * @param parser The manifest parser * @param flags Flags how to parse @@ -1921,8 +1898,7 @@ public class PackageParser { * @throws XmlPullParserException * @throws IOException */ - @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023) - private Package parseBaseApk(String apkPath, Resources res, XmlResourceParser parser, int flags, + private Package parseBaseApk(Resources res, XmlResourceParser parser, int flags, String[] outError) throws XmlPullParserException, IOException { final String splitName; final String pkgName; @@ -1942,15 +1918,6 @@ public class PackageParser { return null; } - if (mCallback != null) { - String[] overlayPaths = mCallback.getOverlayPaths(pkgName, apkPath); - if (overlayPaths != null && overlayPaths.length > 0) { - for (String overlayPath : overlayPaths) { - res.getAssets().addOverlayPath(overlayPath); - } - } - } - final Package pkg = new Package(pkgName); TypedArray sa = res.obtainAttributes(parser, diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 898437ddae41..6c5abe49fe13 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -757,124 +757,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public final boolean hasFeature(String feature) { return PackageManagerService.this.hasSystemFeature(feature, 0); } - - final List getStaticOverlayPackages( - Collection allPackages, String targetPackageName) { - if ("android".equals(targetPackageName)) { - // Static RROs targeting to "android", ie framework-res.apk, are already applied by - // native AssetManager. - return null; - } - - List overlayPackages = null; - for (PackageParser.Package p : allPackages) { - if (targetPackageName.equals(p.mOverlayTarget) && p.mOverlayIsStatic) { - if (overlayPackages == null) { - overlayPackages = new ArrayList<>(); - } - overlayPackages.add(p); - } - } - if (overlayPackages != null) { - Comparator cmp = - Comparator.comparingInt(p -> p.mOverlayPriority); - overlayPackages.sort(cmp); - } - return overlayPackages; - } - - final String[] getStaticOverlayPaths(List overlayPackages, - String targetPath) { - if (overlayPackages == null || overlayPackages.isEmpty()) { - return null; - } - List overlayPathList = null; - for (PackageParser.Package overlayPackage : overlayPackages) { - if (targetPath == null) { - if (overlayPathList == null) { - overlayPathList = new ArrayList<>(); - } - overlayPathList.add(overlayPackage.baseCodePath); - continue; - } - - try { - // Creates idmaps for system to parse correctly the Android manifest of the - // target package. - // - // OverlayManagerService will update each of them with a correct gid from its - // target package app id. - mInstaller.idmap(targetPath, overlayPackage.baseCodePath, - UserHandle.getSharedAppGid( - UserHandle.getUserGid(UserHandle.USER_SYSTEM))); - if (overlayPathList == null) { - overlayPathList = new ArrayList<>(); - } - overlayPathList.add(overlayPackage.baseCodePath); - } catch (InstallerException e) { - Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " + - overlayPackage.baseCodePath); - } - } - return overlayPathList == null ? null : overlayPathList.toArray(new String[0]); - } - - String[] getStaticOverlayPaths(String targetPackageName, String targetPath) { - List overlayPackages; - synchronized (mInstallLock) { - synchronized (mPackages) { - overlayPackages = getStaticOverlayPackages( - mPackages.values(), targetPackageName); - } - // It is safe to keep overlayPackages without holding mPackages because static overlay - // packages can't be uninstalled or disabled. - return getStaticOverlayPaths(overlayPackages, targetPath); - } - } - - @Override public final String[] getOverlayApks(String targetPackageName) { - return getStaticOverlayPaths(targetPackageName, null); - } - - @Override public final String[] getOverlayPaths(String targetPackageName, - String targetPath) { - return getStaticOverlayPaths(targetPackageName, targetPath); - } - } - - class ParallelPackageParserCallback extends PackageParserCallback { - List mOverlayPackages = null; - - void findStaticOverlayPackages() { - synchronized (mPackages) { - for (PackageParser.Package p : mPackages.values()) { - if (p.mOverlayIsStatic) { - if (mOverlayPackages == null) { - mOverlayPackages = new ArrayList<>(); - } - mOverlayPackages.add(p); - } - } - } - } - - @Override - synchronized String[] getStaticOverlayPaths(String targetPackageName, String targetPath) { - // We can trust mOverlayPackages without holding mPackages because package uninstall - // can't happen while running parallel parsing. - // And we can call mInstaller inside getStaticOverlayPaths without holding mInstallLock - // because mInstallLock is held before running parallel parsing. - // Moreover holding mPackages or mInstallLock on each parsing thread causes dead-lock. - return mOverlayPackages == null ? null : - getStaticOverlayPaths( - getStaticOverlayPackages(mOverlayPackages, targetPackageName), - targetPath); - } } final PackageParser.Callback mPackageParserCallback = new PackageParserCallback(); - final ParallelPackageParserCallback mParallelPackageParserCallback = - new ParallelPackageParserCallback(); // Currently known shared libraries. final ArrayMap> mSharedLibraries = new ArrayMap<>(); @@ -2558,8 +2443,6 @@ public class PackageManagerService extends IPackageManager.Stub | SCAN_AS_ODM, 0); - mParallelPackageParserCallback.findStaticOverlayPackages(); - // Find base frameworks (resource packages without code). scanDirTracedLI(frameworkDir, mDefParseFlags @@ -8782,7 +8665,7 @@ public class PackageManagerService extends IPackageManager.Stub } try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser( mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, - mParallelPackageParserCallback)) { + mPackageParserCallback)) { // Submit files for parsing in parallel int fileCount = 0; for (File file : files) { -- 2.11.0