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

Commit 48004fb0 authored by Rhed Jao's avatar Rhed Jao Committed by Android (Google) Code Review
Browse files

Merge "Fix an IllegalStateException in the OverlayConfigParser"

parents b3dbf417 b62f02cb
Loading
Loading
Loading
Loading
+33 −2
Original line number Diff line number Diff line
@@ -108,6 +108,16 @@ public class ApkLite {
    private final boolean mOverlayIsStatic;
    /** Indicate the priority of this overlay package */
    private final int mOverlayPriority;
    /**
     * A comma separated list of system property names to control whether the overlay should be
     * excluded based on the system property condition.
     */
    private final @Nullable String mRequiredSystemPropertyName;
    /**
     * A comma separated list of system property values to control whether the overlay should be
     * excluded based on the system property condition.
     */
    private final @Nullable String mRequiredSystemPropertyValue;

    /**
     * Indicate the policy to deal with user data when rollback is committed
@@ -125,6 +135,7 @@ public class ApkLite {
            boolean debuggable, boolean profileableByShell, boolean multiArch, boolean use32bitAbi,
            boolean useEmbeddedDex, boolean extractNativeLibs, boolean isolatedSplits,
            String targetPackageName, boolean overlayIsStatic, int overlayPriority,
            String requiredSystemPropertyName, String requiredSystemPropertyValue,
            int minSdkVersion, int targetSdkVersion, int rollbackDataPolicy,
            Set<String> requiredSplitTypes, Set<String> splitTypes) {
        mPath = path;
@@ -153,6 +164,8 @@ public class ApkLite {
        mTargetPackageName = targetPackageName;
        mOverlayIsStatic = overlayIsStatic;
        mOverlayPriority = overlayPriority;
        mRequiredSystemPropertyName = requiredSystemPropertyName;
        mRequiredSystemPropertyValue = requiredSystemPropertyValue;
        mMinSdkVersion = minSdkVersion;
        mTargetSdkVersion = targetSdkVersion;
        mRollbackDataPolicy = rollbackDataPolicy;
@@ -418,6 +431,24 @@ public class ApkLite {
        return mOverlayPriority;
    }

    /**
     * A comma separated list of system property names to control whether the overlay should be
     * excluded based on the system property condition.
     */
    @DataClass.Generated.Member
    public @Nullable String getRequiredSystemPropertyName() {
        return mRequiredSystemPropertyName;
    }

    /**
     * A comma separated list of system property values to control whether the overlay should be
     * excluded based on the system property condition.
     */
    @DataClass.Generated.Member
    public @Nullable String getRequiredSystemPropertyValue() {
        return mRequiredSystemPropertyValue;
    }

    /**
     * Indicate the policy to deal with user data when rollback is committed
     *
@@ -431,10 +462,10 @@ public class ApkLite {
    }

    @DataClass.Generated(
            time = 1628562554893L,
            time = 1631763761543L,
            codegenVersion = "1.0.23",
            sourceFile = "frameworks/base/core/java/android/content/pm/parsing/ApkLite.java",
            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mRevisionCode\nprivate final  int mInstallLocation\nprivate final  int mMinSdkVersion\nprivate final  int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final  boolean mFeatureSplit\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mProfileableByShell\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final  boolean mOverlayIsStatic\nprivate final  int mOverlayPriority\nprivate final  int mRollbackDataPolicy\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
            inputSignatures = "private final @android.annotation.NonNull java.lang.String mPackageName\nprivate final @android.annotation.NonNull java.lang.String mPath\nprivate final @android.annotation.Nullable java.lang.String mSplitName\nprivate final @android.annotation.Nullable java.lang.String mUsesSplitName\nprivate final @android.annotation.Nullable java.lang.String mConfigForSplit\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mRequiredSplitTypes\nprivate final @android.annotation.Nullable java.util.Set<java.lang.String> mSplitTypes\nprivate final  int mVersionCodeMajor\nprivate final  int mVersionCode\nprivate final  int mRevisionCode\nprivate final  int mInstallLocation\nprivate final  int mMinSdkVersion\nprivate final  int mTargetSdkVersion\nprivate final @android.annotation.NonNull android.content.pm.VerifierInfo[] mVerifiers\nprivate final @android.annotation.NonNull android.content.pm.SigningDetails mSigningDetails\nprivate final  boolean mFeatureSplit\nprivate final  boolean mIsolatedSplits\nprivate final  boolean mSplitRequired\nprivate final  boolean mCoreApp\nprivate final  boolean mDebuggable\nprivate final  boolean mProfileableByShell\nprivate final  boolean mMultiArch\nprivate final  boolean mUse32bitAbi\nprivate final  boolean mExtractNativeLibs\nprivate final  boolean mUseEmbeddedDex\nprivate final @android.annotation.Nullable java.lang.String mTargetPackageName\nprivate final  boolean mOverlayIsStatic\nprivate final  int mOverlayPriority\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyName\nprivate final @android.annotation.Nullable java.lang.String mRequiredSystemPropertyValue\nprivate final  int mRollbackDataPolicy\npublic  long getLongVersionCode()\nprivate  boolean hasAnyRequiredSplitTypes()\nclass ApkLite extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genConstDefs=false)")
    @Deprecated
    private void __metadata() {}

+12 −10
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package android.content.pm.parsing;

import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
import static android.content.pm.parsing.ParsingPackageUtils.PARSE_IGNORE_OVERLAY_REQUIRED_SYSTEM_PROPERTY;
import static android.content.pm.parsing.ParsingPackageUtils.checkRequiredSystemProperties;
import static android.content.pm.parsing.ParsingPackageUtils.parsePublicKey;
import static android.content.pm.parsing.ParsingPackageUtils.validateName;
@@ -332,7 +333,7 @@ public class ApkLiteParseUtils {
                signingDetails = SigningDetails.UNKNOWN;
            }

            return parseApkLite(input, apkPath, parser, signingDetails);
            return parseApkLite(input, apkPath, parser, signingDetails, flags);
        } catch (XmlPullParserException | IOException | RuntimeException e) {
            Slog.w(TAG, "Failed to parse " + apkPath, e);
            return input.error(PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
@@ -350,7 +351,7 @@ public class ApkLiteParseUtils {
    }

    private static ParseResult<ApkLite> parseApkLite(ParseInput input, String codePath,
            XmlResourceParser parser, SigningDetails signingDetails)
            XmlResourceParser parser, SigningDetails signingDetails, int flags)
            throws IOException, XmlPullParserException {
        ParseResult<Pair<String, String>> result = parsePackageSplitNames(input, parser);
        if (result.isError()) {
@@ -522,14 +523,14 @@ public class ApkLiteParseUtils {
        }

        // Check to see if overlay should be excluded based on system property condition
        if (!checkRequiredSystemProperties(requiredSystemPropertyName,
                requiredSystemPropertyValue)) {
            Slog.i(TAG, "Skipping target and overlay pair " + targetPackage + " and "
        if ((flags & PARSE_IGNORE_OVERLAY_REQUIRED_SYSTEM_PROPERTY) == 0
                && !checkRequiredSystemProperties(
                        requiredSystemPropertyName, requiredSystemPropertyValue)) {
            String message = "Skipping target and overlay pair " + targetPackage + " and "
                    + codePath + ": overlay ignored due to required system property: "
                    + requiredSystemPropertyName + " with value: " + requiredSystemPropertyValue);
            targetPackage = null;
            overlayIsStatic = false;
            overlayPriority = 0;
                    + requiredSystemPropertyName + " with value: " + requiredSystemPropertyValue;
            Slog.i(TAG, message);
            return input.skip(message);
        }

        return input.success(
@@ -538,7 +539,8 @@ public class ApkLiteParseUtils {
                        versionCodeMajor, revisionCode, installLocation, verifiers, signingDetails,
                        coreApp, debuggable, profilableByShell, multiArch, use32bitAbi,
                        useEmbeddedDex, extractNativeLibs, isolatedSplits, targetPackage,
                        overlayIsStatic, overlayPriority, minSdkVersion, targetSdkVersion,
                        overlayIsStatic, overlayPriority, requiredSystemPropertyName,
                        requiredSystemPropertyValue, minSdkVersion, targetSdkVersion,
                        rollbackDataPolicy, requiredSplitTypes.first, requiredSplitTypes.second));
    }

+6 −0
Original line number Diff line number Diff line
@@ -217,6 +217,11 @@ public class ParsingPackageUtils {
    public static final int PARSE_IS_SYSTEM_DIR = 1 << 4;
    public static final int PARSE_COLLECT_CERTIFICATES = 1 << 5;
    public static final int PARSE_ENFORCE_CODE = 1 << 6;
    /**
     * This flag is applied in the ApkLiteParser. Used by OverlayConfigParser to ignore the
     * checks of required system property within the overlay tag.
     */
    public static final int PARSE_IGNORE_OVERLAY_REQUIRED_SYSTEM_PROPERTY = 1 << 7;
    public static final int PARSE_CHATTY = 1 << 31;

    @IntDef(flag = true, prefix = { "PARSE_" }, value = {
@@ -227,6 +232,7 @@ public class ParsingPackageUtils {
            PARSE_IGNORE_PROCESSES,
            PARSE_IS_SYSTEM_DIR,
            PARSE_MUST_BE_APK,
            PARSE_IGNORE_OVERLAY_REQUIRED_SYSTEM_PROPERTY,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface ParseFlags {}
+12 −12
Original line number Diff line number Diff line
@@ -35,6 +35,8 @@ import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.function.Supplier;

@@ -116,14 +118,16 @@ public class OverlayConfig {
        }

        boolean foundConfigFile = false;
        ArrayList<ParsedOverlayInfo> packageManagerOverlayInfos = null;
        final Map<String, ParsedOverlayInfo> packageManagerOverlayInfos =
                packageProvider == null ? null : getOverlayPackageInfos(packageProvider);

        final ArrayList<ParsedConfiguration> overlays = new ArrayList<>();
        for (int i = 0, n = partitions.size(); i < n; i++) {
            final OverlayPartition partition = partitions.get(i);
            final OverlayScanner scanner = (scannerFactory == null) ? null : scannerFactory.get();
            final ArrayList<ParsedConfiguration> partitionOverlays =
                    OverlayConfigParser.getConfigurations(partition, scanner);
                    OverlayConfigParser.getConfigurations(partition, scanner,
                            packageManagerOverlayInfos);
            if (partitionOverlays != null) {
                foundConfigFile = true;
                overlays.addAll(partitionOverlays);
@@ -138,12 +142,8 @@ public class OverlayConfig {
            if (scannerFactory != null) {
                partitionOverlayInfos = new ArrayList<>(scanner.getAllParsedInfos());
            } else {
                if (packageManagerOverlayInfos == null) {
                    packageManagerOverlayInfos = getOverlayPackageInfos(packageProvider);
                }

                // Filter out overlays not present in the partition.
                partitionOverlayInfos = new ArrayList<>(packageManagerOverlayInfos);
                partitionOverlayInfos = new ArrayList<>(packageManagerOverlayInfos.values());
                for (int j = partitionOverlayInfos.size() - 1; j >= 0; j--) {
                    if (!partition.containsFile(partitionOverlayInfos.get(j).path)) {
                        partitionOverlayInfos.remove(j);
@@ -289,14 +289,14 @@ public class OverlayConfig {
    }

    @NonNull
    private static ArrayList<ParsedOverlayInfo> getOverlayPackageInfos(
    private static Map<String, ParsedOverlayInfo> getOverlayPackageInfos(
            @NonNull PackageProvider packageManager) {
        final ArrayList<ParsedOverlayInfo> overlays = new ArrayList<>();
        final HashMap<String, ParsedOverlayInfo> overlays = new HashMap<>();
        packageManager.forEachPackage((ParsingPackageRead p, Boolean isSystem) -> {
            if (p.getOverlayTarget() != null && isSystem) {
                overlays.add(new ParsedOverlayInfo(p.getPackageName(), p.getOverlayTarget(),
                        p.getTargetSdkVersion(), p.isOverlayIsStatic(), p.getOverlayPriority(),
                        new File(p.getBaseApkPath())));
                overlays.put(p.getPackageName(), new ParsedOverlayInfo(p.getPackageName(),
                        p.getOverlayTarget(), p.getTargetSdkVersion(), p.isOverlayIsStatic(),
                        p.getOverlayPriority(), new File(p.getBaseApkPath())));
            }
        });
        return overlays;
+36 −9
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.util.Log;
import android.util.Xml;

import com.android.internal.content.om.OverlayScanner.ParsedOverlayInfo;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;

import libcore.io.IoUtils;
@@ -40,6 +41,7 @@ import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Map;

/**
 * Responsible for parsing configurations of Runtime Resource Overlays that control mutability,
@@ -192,7 +194,8 @@ final class OverlayConfigParser {
     */
    @Nullable
    static ArrayList<ParsedConfiguration> getConfigurations(
            @NonNull OverlayPartition partition, @Nullable OverlayScanner scanner) {
            @NonNull OverlayPartition partition, @Nullable OverlayScanner scanner,
            @Nullable Map<String, ParsedOverlayInfo> packageManagerOverlayInfos) {
        if (partition.getOverlayFolder() == null) {
            return null;
        }
@@ -207,11 +210,12 @@ final class OverlayConfigParser {
        }

        final ParsingContext parsingContext = new ParsingContext(partition);
        readConfigFile(configFile, scanner, parsingContext);
        readConfigFile(configFile, scanner, packageManagerOverlayInfos, parsingContext);
        return parsingContext.mOrderedConfigurations;
    }

    private static void readConfigFile(@NonNull File configFile, @Nullable OverlayScanner scanner,
            @Nullable Map<String, ParsedOverlayInfo> packageManagerOverlayInfos,
            @NonNull ParsingContext parsingContext) {
        FileReader configReader;
        try {
@@ -231,10 +235,12 @@ final class OverlayConfigParser {
                final String name = parser.getName();
                switch (name) {
                    case "merge":
                        parseMerge(configFile, parser, scanner, parsingContext);
                        parseMerge(configFile, parser, scanner, packageManagerOverlayInfos,
                                parsingContext);
                        break;
                    case "overlay":
                        parseOverlay(configFile, parser, scanner, parsingContext);
                        parseOverlay(configFile, parser, scanner, packageManagerOverlayInfos,
                                parsingContext);
                        break;
                    default:
                        Log.w(TAG, String.format("Tag %s is unknown in %s at %s",
@@ -258,7 +264,9 @@ final class OverlayConfigParser {
     * configuration files.
     */
    private static void parseMerge(@NonNull File configFile, @NonNull XmlPullParser parser,
            @Nullable OverlayScanner scanner, @NonNull ParsingContext parsingContext) {
            @Nullable OverlayScanner scanner,
            @Nullable Map<String, ParsedOverlayInfo> packageManagerOverlayInfos,
            @NonNull ParsingContext parsingContext) {
        final String path = parser.getAttributeValue(null, "path");
        if (path == null) {
            throw new IllegalStateException(String.format("<merge> without path in %s at %s"
@@ -304,7 +312,7 @@ final class OverlayConfigParser {
                            parser.getPositionDescription()));
        }

        readConfigFile(includedConfigFile, scanner, parsingContext);
        readConfigFile(includedConfigFile, scanner, packageManagerOverlayInfos, parsingContext);
        parsingContext.mMergeDepth--;
    }

@@ -330,7 +338,12 @@ final class OverlayConfigParser {
     * order of non-configured overlays when enabled by the OverlayManagerService is undefined.
     */
    private static void parseOverlay(@NonNull File configFile, @NonNull XmlPullParser parser,
            @Nullable OverlayScanner scanner, @NonNull ParsingContext parsingContext) {
            @Nullable OverlayScanner scanner,
            @Nullable Map<String, ParsedOverlayInfo> packageManagerOverlayInfos,
            @NonNull ParsingContext parsingContext) {
        Preconditions.checkArgument((scanner == null) != (packageManagerOverlayInfos == null),
                "scanner and packageManagerOverlayInfos cannot be both null or both non-null");

        final String packageName = parser.getAttributeValue(null, "package");
        if (packageName == null) {
            throw new IllegalStateException(String.format("\"<overlay> without package in %s at %s",
@@ -338,16 +351,30 @@ final class OverlayConfigParser {
        }

        // Ensure the overlay being configured is present in the partition during zygote
        // initialization.
        // initialization, unless the package is an excluded overlay package.
        ParsedOverlayInfo info = null;
        if (scanner != null) {
            info = scanner.getParsedInfo(packageName);
            if (info == null|| !parsingContext.mPartition.containsOverlay(info.path)) {
            if (info == null
                    && scanner.isExcludedOverlayPackage(packageName, parsingContext.mPartition)) {
                Log.d(TAG, "overlay " + packageName + " in partition "
                        + parsingContext.mPartition.getOverlayFolder() + " is ignored.");
                return;
            } else if (info == null || !parsingContext.mPartition.containsOverlay(info.path)) {
                throw new IllegalStateException(
                        String.format("overlay %s not present in partition %s in %s at %s",
                                packageName, parsingContext.mPartition.getOverlayFolder(),
                                configFile, parser.getPositionDescription()));
            }
        } else {
            // Zygote shall have crashed itself, if there's an overlay apk not present in the
            // partition. For the overlay package not found in the package manager, we can assume
            // that it's an excluded overlay package.
            if (packageManagerOverlayInfos.get(packageName) == null) {
                Log.d(TAG, "overlay " + packageName + " in partition "
                        + parsingContext.mPartition.getOverlayFolder() + " is ignored.");
                return;
            }
        }

        if (parsingContext.mConfiguredOverlays.contains(packageName)) {
Loading