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

Commit d9439bf4 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Revert "Remove overlay logic from package manager and parser""

parents 35d7aade 08e4756f
Loading
Loading
Loading
Loading
+36 −3
Original line number Diff line number Diff line
@@ -591,6 +591,8 @@ public class PackageParser {
     */
    public interface Callback {
        boolean hasFeature(String feature);
        String[] getOverlayPaths(String targetPackageName, String targetPath);
        String[] getOverlayApks(String targetPackageName);
    }

    /**
@@ -607,6 +609,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;
        }
    }

    /**
@@ -1158,7 +1168,19 @@ public class PackageParser {
            }

            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 (Throwable e) {
            Slog.w(TAG, "Error reading package cache: ", e);

@@ -1332,7 +1354,7 @@ public class PackageParser {
            final Resources res = new Resources(assets, mMetrics, null);

            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]);
@@ -1889,6 +1911,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
@@ -1898,7 +1921,8 @@ public class PackageParser {
     * @throws XmlPullParserException
     * @throws IOException
     */
    private Package parseBaseApk(Resources res, XmlResourceParser parser, int flags,
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
    private Package parseBaseApk(String apkPath, Resources res, XmlResourceParser parser, int flags,
            String[] outError) throws XmlPullParserException, IOException {
        final String splitName;
        final String pkgName;
@@ -1918,6 +1942,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,
+118 −1
Original line number Diff line number Diff line
@@ -757,9 +757,124 @@ public class PackageManagerService extends IPackageManager.Stub
        @Override public final boolean hasFeature(String feature) {
            return PackageManagerService.this.hasSystemFeature(feature, 0);
        }
        final List<PackageParser.Package> getStaticOverlayPackages(
                Collection<PackageParser.Package> 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<PackageParser.Package> 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<PackageParser.Package> cmp =
                        Comparator.comparingInt(p -> p.mOverlayPriority);
                overlayPackages.sort(cmp);
            }
            return overlayPackages;
        }
        final String[] getStaticOverlayPaths(List<PackageParser.Package> overlayPackages,
                String targetPath) {
            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<>();
                    }
                    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<PackageParser.Package> 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<PackageParser.Package> 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<String, LongSparseArray<SharedLibraryInfo>> mSharedLibraries = new ArrayMap<>();
@@ -2464,6 +2579,8 @@ public class PackageManagerService extends IPackageManager.Stub
                    | SCAN_AS_ODM,
                    0);
            mParallelPackageParserCallback.findStaticOverlayPackages();
            // Find base frameworks (resource packages without code).
            scanDirTracedLI(frameworkDir,
                    mDefParseFlags
@@ -8686,7 +8803,7 @@ public class PackageManagerService extends IPackageManager.Stub
        }
        try (ParallelPackageParser parallelPackageParser = new ParallelPackageParser(
                mSeparateProcesses, mOnlyCore, mMetrics, mCacheDir,
                mPackageParserCallback)) {
                mParallelPackageParserCallback)) {
            // Submit files for parsing in parallel
            int fileCount = 0;
            for (File file : files) {