Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 84daedcd authored by Jaekyun Seok's avatar Jaekyun Seok Committed by android-build-merger
Browse files

Merge "Apply static RRO when parsing Android manifest of a target package"...

Merge "Apply static RRO when parsing Android manifest of a target package" into oc-dev am: dc326a88
am: 1a4bcd04

Change-Id: I342faf8a6486f3b6dfdf42047e90ae11671b58e5
parents ee155060 1a4bcd04
Loading
Loading
Loading
Loading
+35 −3
Original line number Diff line number Diff line
@@ -547,6 +547,8 @@ public class PackageParser {
     */
    public interface Callback {
        boolean hasFeature(String feature);
        String[] getOverlayPaths(String targetPackageName, String targetPath);
        String[] getOverlayApks(String targetPackageName);
    }

    /**
@@ -563,6 +565,14 @@ 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;
        }
    }

    /**
@@ -1054,7 +1064,19 @@ public class PackageParser {

        try {
            final byte[] bytes = IoUtils.readFileAsByteArray(cacheFile.getAbsolutePath());
            return fromCacheEntry(bytes);
            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;
        } catch (Exception e) {
            Slog.w(TAG, "Error reading package cache: ", e);

@@ -1238,7 +1260,7 @@ public class PackageParser {
            parser = assets.openXmlResourceParser(cookie, ANDROID_MANIFEST_FILENAME);

            final String[] outError = new String[1];
            final Package pkg = parseBaseApk(res, parser, flags, outError);
            final Package pkg = parseBaseApk(apkPath, res, parser, flags, outError);
            if (pkg == null) {
                throw new PackageParserException(mParseError,
                        apkPath + " (at " + parser.getPositionDescription() + "): " + outError[0]);
@@ -1938,6 +1960,7 @@ 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
@@ -1947,7 +1970,7 @@ public class PackageParser {
     * @throws XmlPullParserException
     * @throws IOException
     */
    private Package parseBaseApk(Resources res, XmlResourceParser parser, int flags,
    private Package parseBaseApk(String apkPath, Resources res, XmlResourceParser parser, int flags,
            String[] outError) throws XmlPullParserException, IOException {
        final String splitName;
        final String pkgName;
@@ -1967,6 +1990,15 @@ 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,
+117 −3
Original line number Diff line number Diff line
@@ -739,11 +739,122 @@ public class PackageManagerService extends IPackageManager.Stub
    @GuardedBy("mPackages")
    final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>();
    final PackageParser.Callback mPackageParserCallback = new PackageParser.Callback() {
        @Override public boolean hasFeature(String feature) {
    class PackageParserCallback implements PackageParser.Callback {
        @Override public final boolean hasFeature(String feature) {
            return PackageManagerService.this.hasSystemFeature(feature, 0);
        }
        final List<PackageParser.Package> getStaticOverlayPackagesLocked(
                Collection<PackageParser.Package> allPackages, String targetPackageName) {
            List<PackageParser.Package> overlayPackages = null;
            for (PackageParser.Package p : allPackages) {
                if (targetPackageName.equals(p.mOverlayTarget) && p.mIsStaticOverlay) {
                    if (overlayPackages == null) {
                        overlayPackages = new ArrayList<PackageParser.Package>();
                    }
                    overlayPackages.add(p);
                }
            }
            if (overlayPackages != null) {
                Comparator<PackageParser.Package> cmp = new Comparator<PackageParser.Package>() {
                    public int compare(PackageParser.Package p1, PackageParser.Package p2) {
                        return p1.mOverlayPriority - p2.mOverlayPriority;
                    }
                };
                Collections.sort(overlayPackages, cmp);
            }
            return overlayPackages;
        }
        final String[] getStaticOverlayPathsLocked(Collection<PackageParser.Package> allPackages,
                String targetPackageName, String targetPath) {
            if ("android".equals(targetPackageName)) {
                // Static RROs targeting to "android", ie framework-res.apk, are already applied by
                // native AssetManager.
                return null;
            }
            List<PackageParser.Package> overlayPackages =
                    getStaticOverlayPackagesLocked(allPackages, targetPackageName);
            if (overlayPackages == null || overlayPackages.isEmpty()) {
                return null;
            }
            List<String> overlayPathList = null;
            for (PackageParser.Package overlayPackage : overlayPackages) {
                if (targetPath == null) {
                    if (overlayPathList == null) {
                        overlayPathList = new ArrayList<String>();
                    }
                    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<String>();
                    }
                    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) {
            synchronized (mPackages) {
                return getStaticOverlayPathsLocked(
                        mPackages.values(), targetPackageName, 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<PackageParser.Package> mOverlayPackages = null;
        void findStaticOverlayPackages() {
            synchronized (mPackages) {
                for (PackageParser.Package p : mPackages.values()) {
                    if (p.mIsStaticOverlay) {
                        if (mOverlayPackages == null) {
                            mOverlayPackages = new ArrayList<PackageParser.Package>();
                        }
                        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.
            // Moreover holding mPackages on each parsing thread causes dead-lock.
            return mOverlayPackages == null ? null :
                    getStaticOverlayPathsLocked(mOverlayPackages, targetPackageName, targetPath);
        }
    }
    final PackageParser.Callback mPackageParserCallback = new PackageParserCallback();
    final ParallelPackageParserCallback mParallelPackageParserCallback =
            new ParallelPackageParserCallback();
    public static final class SharedLibraryEntry {
        public final String path;
@@ -2453,6 +2564,8 @@ public class PackageManagerService extends IPackageManager.Stub
                    | PackageParser.PARSE_IS_SYSTEM_DIR
                    | PackageParser.PARSE_TRUSTED_OVERLAY, scanFlags | SCAN_TRUSTED_OVERLAY, 0);
            mParallelPackageParserCallback.findStaticOverlayPackages();
            // Find base frameworks (resource packages without code).
            scanDirTracedLI(frameworkDir, mDefParseFlags
                    | PackageParser.PARSE_IS_SYSTEM
@@ -7856,7 +7969,8 @@ public class PackageManagerService extends IPackageManager.Stub
                    + " flags=0x" + Integer.toHexString(parseFlags));
        }
        ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir, mPackageParserCallback);
                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
                mParallelPackageParserCallback);
        // Submit files for parsing in parallel
        int fileCount = 0;