/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.content.pm.parsing;

import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
import static android.content.pm.PackageManager.FEATURE_WATCH;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
import static android.os.Build.VERSION_CODES.DONUT;
import static android.os.Build.VERSION_CODES.O;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;

import android.annotation.AnyRes;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.StyleableRes;
import android.app.ActivityThread;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.FeatureGroupInfo;
import android.content.pm.FeatureInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.PackageParserException;
import android.content.pm.PackageParser.SigningDetails;
import android.content.pm.Signature;
import android.content.pm.parsing.component.ComponentParseUtils;
import android.content.pm.parsing.component.ParsedActivity;
import android.content.pm.parsing.component.ParsedActivityUtils;
import android.content.pm.parsing.component.ParsedAttribution;
import android.content.pm.parsing.component.ParsedAttributionUtils;
import android.content.pm.parsing.component.ParsedInstrumentation;
import android.content.pm.parsing.component.ParsedInstrumentationUtils;
import android.content.pm.parsing.component.ParsedIntentInfo;
import android.content.pm.parsing.component.ParsedIntentInfoUtils;
import android.content.pm.parsing.component.ParsedMainComponent;
import android.content.pm.parsing.component.ParsedPermission;
import android.content.pm.parsing.component.ParsedPermissionGroup;
import android.content.pm.parsing.component.ParsedPermissionUtils;
import android.content.pm.parsing.component.ParsedProcess;
import android.content.pm.parsing.component.ParsedProcessUtils;
import android.content.pm.parsing.component.ParsedProvider;
import android.content.pm.parsing.component.ParsedProviderUtils;
import android.content.pm.parsing.component.ParsedService;
import android.content.pm.parsing.component.ParsedServiceUtils;
import android.content.pm.parsing.result.ParseInput;
import android.content.pm.parsing.result.ParseResult;
import android.content.pm.permission.SplitPermissionInfoParcelable;
import android.content.pm.split.DefaultSplitAssetLoader;
import android.content.pm.split.SplitAssetDependencyLoader;
import android.content.pm.split.SplitAssetLoader;
import android.content.res.ApkAssets;
import android.content.res.AssetManager;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.FileUtils;
import android.os.RemoteException;
import android.os.SystemProperties;
import android.os.Trace;
import android.os.ext.SdkExtensions;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
import android.util.TypedValue;
import android.util.apk.ApkSignatureVerifier;

import com.android.internal.R;
import com.android.internal.os.ClassLoaderFactory;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.XmlUtils;

import libcore.io.IoUtils;
import libcore.util.EmptyArray;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;

import java.io.File;
import java.io.IOException;
import java.security.PublicKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;

/**
 * TODO(b/135203078): Differentiate between parse_ methods and some add_ method for whether it
 * mutates the passed-in component or not. Or consolidate so all parse_ methods mutate.
 *
 * @hide
 */
public class ParsingPackageUtils {

    public static final String TAG = ParsingUtils.TAG;

    private boolean mOnlyCoreApps;
    private String[] mSeparateProcesses;
    private DisplayMetrics mDisplayMetrics;
    private Callback mCallback;

    public ParsingPackageUtils(boolean onlyCoreApps, String[] separateProcesses,
            DisplayMetrics displayMetrics, @NonNull Callback callback) {
        mOnlyCoreApps = onlyCoreApps;
        mSeparateProcesses = separateProcesses;
        mDisplayMetrics = displayMetrics;
        mCallback = callback;
    }

    /**
     * Parse the package at the given location. Automatically detects if the
     * package is a monolithic style (single APK file) or cluster style
     * (directory of APKs).
     * <p>
     * This performs sanity checking on cluster style packages, such as
     * requiring identical package name and version codes, a single base APK,
     * and unique split names.
     * <p>
     * Note that this <em>does not</em> perform signature verification; that
     * must be done separately in {@link #collectCertificates(ParsingPackageRead, boolean)}.
     *
     * If {@code useCaches} is true, the package parser might return a cached
     * result from a previous parse of the same {@code packageFile} with the same
     * {@code flags}. Note that this method does not check whether {@code packageFile}
     * has changed since the last parse, it's up to callers to do so.
     *
     * @see PackageParser#parsePackageLite(File, int)
     */
    public ParseResult<ParsingPackage> parsePackage(ParseInput input, File packageFile,
            int flags)
            throws PackageParserException {
        if (packageFile.isDirectory()) {
            return parseClusterPackage(input, packageFile, flags);
        } else {
            return parseMonolithicPackage(input, packageFile, flags);
        }
    }

    /**
     * Parse all APKs contained in the given directory, treating them as a
     * single package. This also performs sanity checking, such as requiring
     * identical package name and version codes, a single base APK, and unique
     * split names.
     * <p>
     * Note that this <em>does not</em> perform signature verification; that
     * must be done separately in {@link #collectCertificates(ParsingPackageRead, boolean)}.
     */
    private ParseResult<ParsingPackage> parseClusterPackage(ParseInput input, File packageDir,
            int flags) throws PackageParserException {
        final PackageParser.PackageLite lite = ApkLiteParseUtils.parseClusterPackageLite(packageDir,
                0);
        if (mOnlyCoreApps && !lite.coreApp) {
            return input.error("Not a coreApp: " + packageDir);
        }

        // Build the split dependency tree.
        SparseArray<int[]> splitDependencies = null;
        final SplitAssetLoader assetLoader;
        if (lite.isolatedSplits && !ArrayUtils.isEmpty(lite.splitNames)) {
            try {
                splitDependencies = SplitAssetDependencyLoader.createDependenciesFromPackage(lite);
                assetLoader = new SplitAssetDependencyLoader(lite, splitDependencies, flags);
            } catch (SplitAssetDependencyLoader.IllegalDependencyException e) {
                return input.error(INSTALL_PARSE_FAILED_BAD_MANIFEST, e.getMessage());
            }
        } else {
            assetLoader = new DefaultSplitAssetLoader(lite, flags);
        }

        try {
            final AssetManager assets = assetLoader.getBaseAssetManager();
            final File baseApk = new File(lite.baseCodePath);
            ParseResult<ParsingPackage> result = parseBaseApk(input, baseApk,
                    lite.codePath, assets, flags);
            // TODO(b/135203078): Pass original error up?
            if (result.isError()) {
                return input.error(INSTALL_PARSE_FAILED_NOT_APK,
                        "Failed to parse base APK: " + baseApk);
            }

            ParsingPackage pkg = result.getResult();
            if (!ArrayUtils.isEmpty(lite.splitNames)) {
                pkg.asSplit(
                        lite.splitNames,
                        lite.splitCodePaths,
                        lite.splitRevisionCodes,
                        splitDependencies
                );
                final int num = lite.splitNames.length;

                for (int i = 0; i < num; i++) {
                    final AssetManager splitAssets = assetLoader.getSplitAssetManager(i);
                    parseSplitApk(input, pkg, i, splitAssets, flags);
                }
            }

            pkg.setUse32BitAbi(lite.use32bitAbi);
            return input.success(pkg);
        } finally {
            IoUtils.closeQuietly(assetLoader);
        }
    }

    /**
     * Parse the given APK file, treating it as as a single monolithic package.
     * <p>
     * Note that this <em>does not</em> perform signature verification; that
     * must be done separately in {@link #collectCertificates(ParsingPackageRead, boolean)}.
     */
    private ParseResult<ParsingPackage> parseMonolithicPackage(ParseInput input, File apkFile,
            int flags) throws PackageParserException {
        final PackageParser.PackageLite lite = ApkLiteParseUtils.parseMonolithicPackageLite(apkFile,
                flags);
        if (mOnlyCoreApps && !lite.coreApp) {
            return input.error("Not a coreApp: " + apkFile);
        }

        final SplitAssetLoader assetLoader = new DefaultSplitAssetLoader(lite, flags);
        try {
            ParseResult<ParsingPackage> result = parseBaseApk(input,
                    apkFile,
                    apkFile.getCanonicalPath(),
                    assetLoader.getBaseAssetManager(), flags);
            if (result.isError()) {
                return input.error(result);
            }

            return input.success(result.getResult()
                    .setUse32BitAbi(lite.use32bitAbi));
        } catch (IOException e) {
            return input.error(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
                    "Failed to get path: " + apkFile, e);
        } finally {
            IoUtils.closeQuietly(assetLoader);
        }
    }

    private ParseResult<ParsingPackage> parseBaseApk(ParseInput input, File apkFile,
            String codePath, AssetManager assets, int flags) {
        final String apkPath = apkFile.getAbsolutePath();

        String volumeUuid = null;
        if (apkPath.startsWith(PackageParser.MNT_EXPAND)) {
            final int end = apkPath.indexOf('/', PackageParser.MNT_EXPAND.length());
            volumeUuid = apkPath.substring(PackageParser.MNT_EXPAND.length(), end);
        }

        if (PackageParser.DEBUG_JAR) Slog.d(TAG, "Scanning base APK: " + apkPath);

        final int cookie = assets.findCookieForPath(apkPath);
        if (cookie == 0) {
            return input.error(INSTALL_PARSE_FAILED_BAD_MANIFEST,
                    "Failed adding asset path: " + apkPath);
        }

        try (XmlResourceParser parser = assets.openXmlResourceParser(cookie,
                PackageParser.ANDROID_MANIFEST_FILENAME)) {
            final Resources res = new Resources(assets, mDisplayMetrics, null);

            ParseResult<ParsingPackage> result = parseBaseApk(input, apkPath, codePath, res,
                    parser, flags);
            if (result.isError()) {
                return input.error(result.getErrorCode(),
                        apkPath + " (at " + parser.getPositionDescription() + "): "
                                + result.getErrorMessage());
            }

            ParsingPackage pkg = result.getResult();
            ApkAssets apkAssets = assets.getApkAssets()[0];
            if (apkAssets.definesOverlayable()) {
                SparseArray<String> packageNames = assets.getAssignedPackageIdentifiers();
                int size = packageNames.size();
                for (int index = 0; index < size; index++) {
                    String packageName = packageNames.get(index);
                    Map<String, String> overlayableToActor = assets.getOverlayableMap(packageName);
                    if (overlayableToActor != null && !overlayableToActor.isEmpty()) {
                        for (String overlayable : overlayableToActor.keySet()) {
                            pkg.addOverlayable(overlayable, overlayableToActor.get(overlayable));
                        }
                    }
                }
            }

            pkg.setVolumeUuid(volumeUuid)
                    .setSigningDetails(SigningDetails.UNKNOWN);

            return input.success(pkg);
        } catch (Exception e) {
            return input.error(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
                    "Failed to read manifest from " + apkPath, e);
        }
    }

    private ParseResult<ParsingPackage> parseSplitApk(ParseInput input,
            ParsingPackage pkg, int splitIndex, AssetManager assets, int flags) {
        final String apkPath = pkg.getSplitCodePaths()[splitIndex];

        if (PackageParser.DEBUG_JAR) Slog.d(TAG, "Scanning split APK: " + apkPath);

        // This must always succeed, as the path has been added to the AssetManager before.
        final int cookie = assets.findCookieForPath(apkPath);
        if (cookie == 0) {
            return input.error(INSTALL_PARSE_FAILED_BAD_MANIFEST,
                    "Failed adding asset path: " + apkPath);
        }
        try (XmlResourceParser parser = assets.openXmlResourceParser(cookie,
                PackageParser.ANDROID_MANIFEST_FILENAME)) {
            Resources res = new Resources(assets, mDisplayMetrics, null);
            ParseResult<ParsingPackage> parseResult = parseSplitApk(input, pkg, res,
                    parser, flags, splitIndex);
            if (parseResult.isError()) {
                return input.error(parseResult.getErrorCode(),
                        apkPath + " (at " + parser.getPositionDescription() + "): "
                                + parseResult.getErrorMessage());
            }

            return parseResult;
        } catch (Exception e) {
            return input.error(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
                    "Failed to read manifest from " + apkPath, e);
        }
    }

    /**
     * Parse the manifest of a <em>base APK</em>. When adding new features you
     * 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
     * @return Parsed package or null on error.
     */
    private ParseResult<ParsingPackage> parseBaseApk(ParseInput input, String apkPath,
            String codePath, Resources res, XmlResourceParser parser, int flags)
            throws XmlPullParserException, IOException {
        final String splitName;
        final String pkgName;

        try {
            Pair<String, String> packageSplit = PackageParser.parsePackageSplitNames(parser,
                    parser);
            pkgName = packageSplit.first;
            splitName = packageSplit.second;

            if (!TextUtils.isEmpty(splitName)) {
                return input.error(
                        PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
                        "Expected base APK, but found split " + splitName
                );
            }
        } catch (PackageParserException e) {
            return input.error(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME);
        }

        TypedArray manifestArray = res.obtainAttributes(parser, R.styleable.AndroidManifest);
        try {
            boolean isCoreApp = parser.getAttributeBooleanValue(null, "coreApp", false);

            ParsingPackage pkg = mCallback.startParsingPackage(pkgName, apkPath, codePath,
                    manifestArray, isCoreApp);

            ParseResult<ParsingPackage> result = parseBaseApkTags(input, pkg, manifestArray,
                    res, parser, flags);
            if (result.isError()) {
                return result;
            }

            return input.success(pkg);
        } finally {
            manifestArray.recycle();
        }
    }

    /**
     * Parse the manifest of a <em>split APK</em>.
     * <p>
     * Note that split APKs have many more restrictions on what they're capable
     * of doing, so many valid features of a base APK have been carefully
     * omitted here.
     *
     * @param pkg builder to fill
     * @return false on failure
     */
    private ParseResult<ParsingPackage> parseSplitApk(ParseInput input, ParsingPackage pkg,
            Resources res, XmlResourceParser parser, int flags, int splitIndex)
            throws XmlPullParserException, IOException, PackageParserException {
        AttributeSet attrs = parser;

        // We parsed manifest tag earlier; just skip past it
        PackageParser.parsePackageSplitNames(parser, attrs);

        int type;

        boolean foundApp = false;

        int outerDepth = parser.getDepth();
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
            if (outerDepth + 1 < parser.getDepth() || type != XmlPullParser.START_TAG) {
                continue;
            }

            final ParseResult result;
            String tagName = parser.getName();
            if (PackageParser.TAG_APPLICATION.equals(tagName)) {
                if (foundApp) {
                    if (PackageParser.RIGID_PARSER) {
                        result = input.error("<manifest> has more than one <application>");
                    } else {
                        Slog.w(TAG, "<manifest> has more than one <application>");
                        result = input.success(null);
                    }
                } else {
                    foundApp = true;
                    result = parseSplitApplication(input, pkg, res, parser, flags, splitIndex);
                }
            } else {
                result = ParsingUtils.unknownTag("<manifest>", pkg, parser, input);
            }

            if (result.isError()) {
                return input.error(result);
            }
        }

        if (!foundApp) {
            return input.error(
                    PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY,
                    "<manifest> does not contain an <application>"
            );
        }

        return input.success(pkg);
    }

    /**
     * Parse the {@code application} XML tree at the current parse location in a
     * <em>split APK</em> manifest.
     * <p>
     * Note that split APKs have many more restrictions on what they're capable
     * of doing, so many valid features of a base APK have been carefully
     * omitted here.
     */
    private ParseResult<ParsingPackage> parseSplitApplication(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser, int flags, int splitIndex)
            throws XmlPullParserException, IOException {
        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestApplication);
        try {
            pkg.setSplitHasCode(splitIndex, sa.getBoolean(
                    R.styleable.AndroidManifestApplication_hasCode, true));

            final String classLoaderName = sa.getString(
                    R.styleable.AndroidManifestApplication_classLoader);
            if (classLoaderName == null || ClassLoaderFactory.isValidClassLoaderName(
                    classLoaderName)) {
                pkg.setSplitClassLoaderName(splitIndex, classLoaderName);
            } else {
                return input.error("Invalid class loader name: " + classLoaderName);
            }
        } finally {
            sa.recycle();
        }
        final int depth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG
                || parser.getDepth() > depth)) {
            if (type != XmlPullParser.START_TAG) {
                continue;
            }

            ParsedMainComponent mainComponent = null;

            final ParseResult result;
            String tagName = parser.getName();
            boolean isActivity = false;
            switch (tagName) {
                case "activity":
                    isActivity = true;
                    // fall-through
                case "receiver":
                    ParseResult<ParsedActivity> activityResult =
                            ParsedActivityUtils.parseActivityOrReceiver(mSeparateProcesses, pkg,
                                    res,
                                    parser, flags, PackageParser.sUseRoundIcon, input);
                    if (activityResult.isSuccess()) {
                        ParsedActivity activity = activityResult.getResult();
                        if (isActivity) {
                            pkg.addActivity(activity);
                        } else {
                            pkg.addReceiver(activity);
                        }
                        mainComponent = activity;
                    }
                    result = activityResult;
                    break;
                case "service":
                    ParseResult<ParsedService> serviceResult = ParsedServiceUtils.parseService(
                            mSeparateProcesses, pkg, res, parser, flags,
                            PackageParser.sUseRoundIcon, input);
                    if (serviceResult.isSuccess()) {
                        ParsedService service = serviceResult.getResult();
                        pkg.addService(service);
                        mainComponent = service;
                    }
                    result = serviceResult;
                    break;
                case "provider":
                    ParseResult<ParsedProvider> providerResult =
                            ParsedProviderUtils.parseProvider(mSeparateProcesses, pkg, res, parser,
                                    flags, PackageParser.sUseRoundIcon, input);
                    if (providerResult.isSuccess()) {
                        ParsedProvider provider = providerResult.getResult();
                        pkg.addProvider(provider);
                        mainComponent = provider;
                    }
                    result = providerResult;
                    break;
                case "activity-alias":
                    activityResult = ParsedActivityUtils.parseActivityAlias(pkg, res, parser,
                            PackageParser.sUseRoundIcon, input);
                    if (activityResult.isSuccess()) {
                        ParsedActivity activity = activityResult.getResult();
                        pkg.addActivity(activity);
                        mainComponent = activity;
                    }

                    result = activityResult;
                    break;
                default:
                    result = parseSplitBaseAppChildTags(input, tagName, pkg, res, parser);
                    break;
            }

            if (result.isError()) {
                return input.error(result);
            }

            if (mainComponent != null && mainComponent.getSplitName() == null) {
                // If the loaded component did not specify a split, inherit the split name
                // based on the split it is defined in.
                // This is used to later load the correct split when starting this
                // component.
                mainComponent.setSplitName(pkg.getSplitNames()[splitIndex]);
            }
        }

        return input.success(pkg);
    }

    /**
     * For parsing non-MainComponents. Main ones have an order and some special handling which is
     * done directly in {@link #parseSplitApplication(ParseInput, ParsingPackage, Resources,
     * XmlResourceParser, int, int)}.
     */
    private ParseResult parseSplitBaseAppChildTags(ParseInput input, String tag, ParsingPackage pkg,
            Resources res, XmlResourceParser parser) throws IOException, XmlPullParserException {
        switch (tag) {
            case "meta-data":
                // note: application meta-data is stored off to the side, so it can
                // remain null in the primary copy (we like to avoid extra copies because
                // it can be large)
                ParseResult<Bundle> metaDataResult = parseMetaData(pkg, res, parser,
                        pkg.getMetaData(), input);
                if (metaDataResult.isSuccess()) {
                    pkg.setMetaData(metaDataResult.getResult());
                }
                return metaDataResult;
            case "uses-static-library":
                return parseUsesStaticLibrary(input, pkg, res, parser);
            case "uses-library":
                return parseUsesLibrary(input, pkg, res, parser);
            case "uses-package":
                // Dependencies for app installers; we don't currently try to
                // enforce this.
                return input.success(null);
            default:
                return ParsingUtils.unknownTag("<application>", pkg, parser, input);
        }
    }

    private ParseResult<ParsingPackage> parseBaseApkTags(ParseInput input, ParsingPackage pkg,
            TypedArray sa, Resources res, XmlResourceParser parser, int flags)
            throws XmlPullParserException, IOException {
        ParseResult<ParsingPackage> sharedUserResult = parseSharedUser(input, pkg, sa);
        if (sharedUserResult.isError()) {
            return sharedUserResult;
        }

        pkg.setInstallLocation(anInt(PackageParser.PARSE_DEFAULT_INSTALL_LOCATION,
                R.styleable.AndroidManifest_installLocation, sa))
                .setTargetSandboxVersion(anInt(PackageParser.PARSE_DEFAULT_TARGET_SANDBOX,
                        R.styleable.AndroidManifest_targetSandboxVersion, sa))
                /* Set the global "on SD card" flag */
                .setExternalStorage((flags & PackageParser.PARSE_EXTERNAL_STORAGE) != 0)
                .setIsolatedSplitLoading(
                        bool(false, R.styleable.AndroidManifest_isolatedSplits, sa));

        boolean foundApp = false;
        final int depth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG
                || parser.getDepth() > depth)) {
            if (type != XmlPullParser.START_TAG) {
                continue;
            }

            String tagName = parser.getName();
            final ParseResult result;

            // TODO(b/135203078): Convert to instance methods to share variables
            // <application> has special logic, so it's handled outside the general method
            if (PackageParser.TAG_APPLICATION.equals(tagName)) {
                if (foundApp) {
                    if (PackageParser.RIGID_PARSER) {
                        result = input.error("<manifest> has more than one <application>");
                    } else {
                        Slog.w(TAG, "<manifest> has more than one <application>");
                        result = input.success(null);
                    }
                } else {
                    foundApp = true;
                    result = parseBaseApplication(input, pkg, res, parser, flags);
                }
            } else {
                result = parseBaseApkTag(tagName, input, pkg, res, parser, flags);
            }

            if (result.isError()) {
                return input.error(result);
            }
        }

        if (!foundApp && ArrayUtils.size(pkg.getInstrumentations()) == 0) {
            return input.error(
                    PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY,
                    "<manifest> does not contain an <application> or <instrumentation>"
            );
        }

        if (!ParsedAttribution.isCombinationValid(pkg.getAttributions())) {
            return input.error(
                    INSTALL_PARSE_FAILED_BAD_MANIFEST,
                    "Combination <feature> tags are not valid"
            );
        }

        convertNewPermissions(pkg);

        convertSplitPermissions(pkg);

        // At this point we can check if an application is not supporting densities and hence
        // cannot be windowed / resized. Note that an SDK version of 0 is common for
        // pre-Doughnut applications.
        if (pkg.getTargetSdkVersion() < DONUT
                || (!pkg.isSupportsSmallScreens()
                && !pkg.isSupportsNormalScreens()
                && !pkg.isSupportsLargeScreens()
                && !pkg.isSupportsExtraLargeScreens()
                && !pkg.isResizeable()
                && !pkg.isAnyDensity())) {
            adjustPackageToBeUnresizeableAndUnpipable(pkg);
        }

        return input.success(pkg);
    }

    private ParseResult parseBaseApkTag(String tag, ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser, int flags)
            throws IOException, XmlPullParserException {
        switch (tag) {
            case PackageParser.TAG_OVERLAY:
                return parseOverlay(input, pkg, res, parser);
            case PackageParser.TAG_KEY_SETS:
                return parseKeySets(input, pkg, res, parser);
            case "feature": // TODO moltmann: Remove
            case PackageParser.TAG_ATTRIBUTION:
                return parseAttribution(input, pkg, res, parser);
            case PackageParser.TAG_PERMISSION_GROUP:
                return parsePermissionGroup(input, pkg, res, parser);
            case PackageParser.TAG_PERMISSION:
                return parsePermission(input, pkg, res, parser);
            case PackageParser.TAG_PERMISSION_TREE:
                return parsePermissionTree(input, pkg, res, parser);
            case PackageParser.TAG_USES_PERMISSION:
            case PackageParser.TAG_USES_PERMISSION_SDK_M:
            case PackageParser.TAG_USES_PERMISSION_SDK_23:
                return parseUsesPermission(input, pkg, res, parser);
            case PackageParser.TAG_USES_CONFIGURATION:
                return parseUsesConfiguration(input, pkg, res, parser);
            case PackageParser.TAG_USES_FEATURE:
                return parseUsesFeature(input, pkg, res, parser);
            case PackageParser.TAG_FEATURE_GROUP:
                return parseFeatureGroup(input, pkg, res, parser);
            case PackageParser.TAG_USES_SDK:
                return parseUsesSdk(input, pkg, res, parser);
            case PackageParser.TAG_SUPPORT_SCREENS:
                return parseSupportScreens(input, pkg, res, parser);
            case PackageParser.TAG_PROTECTED_BROADCAST:
                return parseProtectedBroadcast(input, pkg, res, parser);
            case PackageParser.TAG_INSTRUMENTATION:
                return parseInstrumentation(input, pkg, res, parser);
            case PackageParser.TAG_ORIGINAL_PACKAGE:
                return parseOriginalPackage(input, pkg, res, parser);
            case PackageParser.TAG_ADOPT_PERMISSIONS:
                return parseAdoptPermissions(input, pkg, res, parser);
            case PackageParser.TAG_USES_GL_TEXTURE:
            case PackageParser.TAG_COMPATIBLE_SCREENS:
            case PackageParser.TAG_SUPPORTS_INPUT:
            case PackageParser.TAG_EAT_COMMENT:
                // Just skip this tag
                XmlUtils.skipCurrentTag(parser);
                return input.success(pkg);
            case PackageParser.TAG_RESTRICT_UPDATE:
                return parseRestrictUpdateHash(flags, input, pkg, res, parser);
            case PackageParser.TAG_QUERIES:
                return parseQueries(input, pkg, res, parser);
            default:
                return ParsingUtils.unknownTag("<manifest>", pkg, parser, input);
        }
    }

    private static ParseResult<ParsingPackage> parseSharedUser(ParseInput input,
            ParsingPackage pkg, TypedArray sa) {
        String str = nonConfigString(0, R.styleable.AndroidManifest_sharedUserId, sa);
        if (TextUtils.isEmpty(str)) {
            return input.success(pkg);
        }

        ParseResult nameResult = validateName(input, str, true, true);
        if (nameResult.isError()) {
            if ("android".equals(pkg.getPackageName())) {
                nameResult.ignoreError();
            } else {
                return input.error(PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID,
                        "<manifest> specifies bad sharedUserId name \"" + str + "\": "
                                + nameResult.getErrorMessage());
            }
        }

        return input.success(pkg
                .setSharedUserId(str.intern())
                .setSharedUserLabel(resId(R.styleable.AndroidManifest_sharedUserLabel, sa)));
    }

    private static ParseResult<ParsingPackage> parseKeySets(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser)
            throws XmlPullParserException, IOException {
        // we've encountered the 'key-sets' tag
        // all the keys and keysets that we want must be defined here
        // so we're going to iterate over the parser and pull out the things we want
        int outerDepth = parser.getDepth();
        int currentKeySetDepth = -1;
        int type;
        String currentKeySet = null;
        ArrayMap<String, PublicKey> publicKeys = new ArrayMap<>();
        ArraySet<String> upgradeKeySets = new ArraySet<>();
        ArrayMap<String, ArraySet<String>> definedKeySets = new ArrayMap<>();
        ArraySet<String> improperKeySets = new ArraySet<>();
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
            if (type == XmlPullParser.END_TAG) {
                if (parser.getDepth() == currentKeySetDepth) {
                    currentKeySet = null;
                    currentKeySetDepth = -1;
                }
                continue;
            }
            String tagName = parser.getName();
            switch (tagName) {
                case "key-set": {
                    if (currentKeySet != null) {
                        return input.error("Improperly nested 'key-set' tag at "
                                + parser.getPositionDescription());
                    }
                    TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestKeySet);
                    try {
                        final String keysetName = sa.getNonResourceString(
                                R.styleable.AndroidManifestKeySet_name);
                        definedKeySets.put(keysetName, new ArraySet<>());
                        currentKeySet = keysetName;
                        currentKeySetDepth = parser.getDepth();
                    } finally {
                        sa.recycle();
                    }
                } break;
                case "public-key": {
                    if (currentKeySet == null) {
                        return input.error("Improperly nested 'key-set' tag at "
                                + parser.getPositionDescription());
                    }
                    TypedArray sa = res.obtainAttributes(parser,
                            R.styleable.AndroidManifestPublicKey);
                    try {
                        final String publicKeyName = nonResString(
                                R.styleable.AndroidManifestPublicKey_name, sa);
                        final String encodedKey = nonResString(
                                R.styleable.AndroidManifestPublicKey_value, sa);
                        if (encodedKey == null && publicKeys.get(publicKeyName) == null) {
                            return input.error("'public-key' " + publicKeyName
                                    + " must define a public-key value on first use at "
                                    + parser.getPositionDescription());
                        } else if (encodedKey != null) {
                            PublicKey currentKey = PackageParser.parsePublicKey(encodedKey);
                            if (currentKey == null) {
                                Slog.w(TAG, "No recognized valid key in 'public-key' tag at "
                                        + parser.getPositionDescription() + " key-set "
                                        + currentKeySet
                                        + " will not be added to the package's defined key-sets.");
                                improperKeySets.add(currentKeySet);
                                XmlUtils.skipCurrentTag(parser);
                                continue;
                            }
                            if (publicKeys.get(publicKeyName) == null
                                    || publicKeys.get(publicKeyName).equals(currentKey)) {

                                /* public-key first definition, or matches old definition */
                                publicKeys.put(publicKeyName, currentKey);
                            } else {
                                return input.error("Value of 'public-key' " + publicKeyName
                                        + " conflicts with previously defined value at "
                                        + parser.getPositionDescription());
                            }
                        }
                        definedKeySets.get(currentKeySet).add(publicKeyName);
                        XmlUtils.skipCurrentTag(parser);
                    } finally {
                        sa.recycle();
                    }
                } break;
                case "upgrade-key-set": {
                    TypedArray sa = res.obtainAttributes(parser,
                            R.styleable.AndroidManifestUpgradeKeySet);
                    try {
                        String name = sa.getNonResourceString(
                                R.styleable.AndroidManifestUpgradeKeySet_name);
                        upgradeKeySets.add(name);
                        XmlUtils.skipCurrentTag(parser);
                    } finally {
                        sa.recycle();
                    }
                } break;
                default:
                    ParseResult result = ParsingUtils.unknownTag("<key-sets>", pkg, parser,
                            input);
                    if (result.isError()) {
                        return input.error(result);
                    }
                    break;
            }
        }
        String packageName = pkg.getPackageName();
        Set<String> publicKeyNames = publicKeys.keySet();
        if (publicKeyNames.removeAll(definedKeySets.keySet())) {
            return input.error("Package" + packageName
                    + " AndroidManifest.xml 'key-set' and 'public-key' names must be distinct.");
        }

        for (ArrayMap.Entry<String, ArraySet<String>> e : definedKeySets.entrySet()) {
            final String keySetName = e.getKey();
            if (e.getValue().size() == 0) {
                Slog.w(TAG, "Package" + packageName + " AndroidManifest.xml "
                        + "'key-set' " + keySetName + " has no valid associated 'public-key'."
                        + " Not including in package's defined key-sets.");
                continue;
            } else if (improperKeySets.contains(keySetName)) {
                Slog.w(TAG, "Package" + packageName + " AndroidManifest.xml "
                        + "'key-set' " + keySetName + " contained improper 'public-key'"
                        + " tags. Not including in package's defined key-sets.");
                continue;
            }

            for (String s : e.getValue()) {
                pkg.addKeySet(keySetName, publicKeys.get(s));
            }
        }
        if (pkg.getKeySetMapping().keySet().containsAll(upgradeKeySets)) {
            pkg.setUpgradeKeySets(upgradeKeySets);
        } else {
            return input.error("Package" + packageName
                    + " AndroidManifest.xml does not define all 'upgrade-key-set's .");
        }

        return input.success(pkg);
    }

    private static ParseResult<ParsingPackage> parseAttribution(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser)
            throws IOException, XmlPullParserException {
        ParseResult<ParsedAttribution> result = ParsedAttributionUtils.parseAttribution(res,
                parser, input);
        if (result.isError()) {
            return input.error(result);
        }
        return input.success(pkg.addAttribution(result.getResult()));
    }

    private static ParseResult<ParsingPackage> parsePermissionGroup(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser)
            throws XmlPullParserException, IOException {
        ParseResult<ParsedPermissionGroup> result = ParsedPermissionUtils.parsePermissionGroup(
                pkg, res, parser, PackageParser.sUseRoundIcon, input);
        if (result.isError()) {
            return input.error(result);
        }
        return input.success(pkg.addPermissionGroup(result.getResult()));
    }

    private static ParseResult<ParsingPackage> parsePermission(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser)
            throws XmlPullParserException, IOException {
        ParseResult<ParsedPermission> result = ParsedPermissionUtils.parsePermission(
                pkg, res, parser, PackageParser.sUseRoundIcon, input);
        if (result.isError()) {
            return input.error(result);
        }
        return input.success(pkg.addPermission(result.getResult()));
    }

    private static ParseResult<ParsingPackage> parsePermissionTree(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser)
            throws XmlPullParserException, IOException {
        ParseResult<ParsedPermission> result = ParsedPermissionUtils.parsePermissionTree(
                pkg, res, parser, PackageParser.sUseRoundIcon, input);
        if (result.isError()) {
            return input.error(result);
        }
        return input.success(pkg.addPermission(result.getResult()));
    }

    private ParseResult<ParsingPackage> parseUsesPermission(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser)
            throws IOException, XmlPullParserException {
        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesPermission);
        try {
            // Note: don't allow this value to be a reference to a resource
            // that may change.
            String name = sa.getNonResourceString(
                    R.styleable.AndroidManifestUsesPermission_name);

            int maxSdkVersion = 0;
            TypedValue val = sa.peekValue(
                    R.styleable.AndroidManifestUsesPermission_maxSdkVersion);
            if (val != null) {
                if (val.type >= TypedValue.TYPE_FIRST_INT && val.type <= TypedValue.TYPE_LAST_INT) {
                    maxSdkVersion = val.data;
                }
            }

            final String requiredFeature = sa.getNonConfigurationString(
                    R.styleable.AndroidManifestUsesPermission_requiredFeature, 0);

            final String requiredNotfeature = sa.getNonConfigurationString(
                    R.styleable.AndroidManifestUsesPermission_requiredNotFeature,
                    0);

            XmlUtils.skipCurrentTag(parser);

            // Can only succeed from here on out
            ParseResult<ParsingPackage> success = input.success(pkg);

            if (name == null) {
                return success;
            }

            if ((maxSdkVersion != 0) && (maxSdkVersion < Build.VERSION.RESOURCES_SDK_INT)) {
                return success;
            }

            // Only allow requesting this permission if the platform supports the given feature.
            if (requiredFeature != null && mCallback != null && !mCallback.hasFeature(
                    requiredFeature)) {
                return success;
            }

            // Only allow requesting this permission if the platform doesn't support the given
            // feature.
            if (requiredNotfeature != null && mCallback != null
                    && mCallback.hasFeature(requiredNotfeature)) {
                return success;
            }

            if (!pkg.getRequestedPermissions().contains(name)) {
                pkg.addRequestedPermission(name.intern());
            } else {
                Slog.w(TAG, "Ignoring duplicate uses-permissions/uses-permissions-sdk-m: "
                        + name + " in package: " + pkg.getPackageName() + " at: "
                        + parser.getPositionDescription());
            }

            return success;
        } finally {
            sa.recycle();
        }
    }

    private static ParseResult<ParsingPackage> parseUsesConfiguration(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser) {
        ConfigurationInfo cPref = new ConfigurationInfo();
        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesConfiguration);
        try {
            cPref.reqTouchScreen = sa.getInt(
                    R.styleable.AndroidManifestUsesConfiguration_reqTouchScreen,
                    Configuration.TOUCHSCREEN_UNDEFINED);
            cPref.reqKeyboardType = sa.getInt(
                    R.styleable.AndroidManifestUsesConfiguration_reqKeyboardType,
                    Configuration.KEYBOARD_UNDEFINED);
            if (sa.getBoolean(
                    R.styleable.AndroidManifestUsesConfiguration_reqHardKeyboard,
                    false)) {
                cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
            }
            cPref.reqNavigation = sa.getInt(
                    R.styleable.AndroidManifestUsesConfiguration_reqNavigation,
                    Configuration.NAVIGATION_UNDEFINED);
            if (sa.getBoolean(
                    R.styleable.AndroidManifestUsesConfiguration_reqFiveWayNav,
                    false)) {
                cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
            }
            pkg.addConfigPreference(cPref);
            return input.success(pkg);
        } finally {
            sa.recycle();
        }
    }

    private static ParseResult<ParsingPackage> parseUsesFeature(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser) {
        FeatureInfo fi = parseFeatureInfo(res, parser);
        pkg.addReqFeature(fi);

        if (fi.name == null) {
            ConfigurationInfo cPref = new ConfigurationInfo();
            cPref.reqGlEsVersion = fi.reqGlEsVersion;
            pkg.addConfigPreference(cPref);
        }

        return input.success(pkg);
    }

    private static FeatureInfo parseFeatureInfo(Resources res, AttributeSet attrs) {
        FeatureInfo fi = new FeatureInfo();
        TypedArray sa = res.obtainAttributes(attrs, R.styleable.AndroidManifestUsesFeature);
        try {
            // Note: don't allow this value to be a reference to a resource
            // that may change.
            fi.name = sa.getNonResourceString(R.styleable.AndroidManifestUsesFeature_name);
            fi.version = sa.getInt(R.styleable.AndroidManifestUsesFeature_version, 0);
            if (fi.name == null) {
                fi.reqGlEsVersion = sa.getInt(R.styleable.AndroidManifestUsesFeature_glEsVersion,
                        FeatureInfo.GL_ES_VERSION_UNDEFINED);
            }
            if (sa.getBoolean(R.styleable.AndroidManifestUsesFeature_required, true)) {
                fi.flags |= FeatureInfo.FLAG_REQUIRED;
            }
            return fi;
        } finally {
            sa.recycle();
        }
    }

    private static ParseResult<ParsingPackage> parseFeatureGroup(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser)
            throws IOException, XmlPullParserException {
        FeatureGroupInfo group = new FeatureGroupInfo();
        ArrayList<FeatureInfo> features = null;
        final int depth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG
                || parser.getDepth() > depth)) {
            if (type != XmlPullParser.START_TAG) {
                continue;
            }

            final String innerTagName = parser.getName();
            if (innerTagName.equals("uses-feature")) {
                FeatureInfo featureInfo = parseFeatureInfo(res, parser);
                // FeatureGroups are stricter and mandate that
                // any <uses-feature> declared are mandatory.
                featureInfo.flags |= FeatureInfo.FLAG_REQUIRED;
                features = ArrayUtils.add(features, featureInfo);
            } else {
                Slog.w(TAG,
                        "Unknown element under <feature-group>: " + innerTagName +
                                " at " + pkg.getBaseCodePath() + " " +
                                parser.getPositionDescription());
            }
        }

        if (features != null) {
            group.features = new FeatureInfo[features.size()];
            group.features = features.toArray(group.features);
        }

        pkg.addFeatureGroup(group);
        return input.success(pkg);
    }

    private static ParseResult<ParsingPackage> parseUsesSdk(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser)
            throws IOException, XmlPullParserException {
        if (PackageParser.SDK_VERSION > 0) {
            TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesSdk);
            try {
                int minVers = 1;
                String minCode = null;
                int targetVers = 0;
                String targetCode = null;

                TypedValue val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_minSdkVersion);
                if (val != null) {
                    if (val.type == TypedValue.TYPE_STRING && val.string != null) {
                        minCode = val.string.toString();
                    } else {
                        // If it's not a string, it's an integer.
                        minVers = val.data;
                    }
                }

                val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_targetSdkVersion);
                if (val != null) {
                    if (val.type == TypedValue.TYPE_STRING && val.string != null) {
                        targetCode = val.string.toString();
                        if (minCode == null) {
                            minCode = targetCode;
                        }
                    } else {
                        // If it's not a string, it's an integer.
                        targetVers = val.data;
                    }
                } else {
                    targetVers = minVers;
                    targetCode = minCode;
                }

                ParseResult<Integer> minSdkVersionResult = computeMinSdkVersion(minVers, minCode,
                        PackageParser.SDK_VERSION, PackageParser.SDK_CODENAMES, input);
                if (minSdkVersionResult.isError()) {
                    return input.error(minSdkVersionResult);
                }

                int minSdkVersion = minSdkVersionResult.getResult();

                ParseResult<Integer> targetSdkVersionResult = computeTargetSdkVersion(
                        targetVers, targetCode, PackageParser.SDK_CODENAMES, input);
                if (targetSdkVersionResult.isError()) {
                    return input.error(targetSdkVersionResult);
                }

                int targetSdkVersion = minSdkVersionResult.getResult();

                pkg.setMinSdkVersion(minSdkVersion)
                        .setTargetSdkVersion(targetSdkVersion);

                int type;
                final int innerDepth = parser.getDepth();
                while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                        && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
                    if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
                        continue;
                    }

                    final ParseResult result;
                    if (parser.getName().equals("extension-sdk")) {
                        result = parseExtensionSdk(input, pkg, res, parser);
                        XmlUtils.skipCurrentTag(parser);
                    } else {
                        result = ParsingUtils.unknownTag("<uses-sdk>", pkg, parser, input);
                    }

                    if (result.isError()) {
                        return input.error(result);
                    }
                }
            } finally {
                sa.recycle();
            }
        }
        return input.success(pkg);
    }

    private static ParseResult parseExtensionSdk(ParseInput input, ParsingPackage pkg,
            Resources res, XmlResourceParser parser) {
        int sdkVersion;
        int minVersion;
        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestExtensionSdk);
        try {
            sdkVersion = sa.getInt(R.styleable.AndroidManifestExtensionSdk_sdkVersion, -1);
            minVersion = sa.getInt(R.styleable.AndroidManifestExtensionSdk_minExtensionVersion, -1);
        } finally {
            sa.recycle();
        }

        if (sdkVersion < 0) {
            return input.error(
                    PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
                    "<extension-sdk> must specify an sdkVersion >= 0");
        }
        if (minVersion < 0) {
            return input.error(
                    PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
                    "<extension-sdk> must specify minExtensionVersion >= 0");
        }

        try {
            int version = SdkExtensions.getExtensionVersion(sdkVersion);
            if (version < minVersion) {
                return input.error(
                        PackageManager.INSTALL_FAILED_OLDER_SDK,
                        "Package requires " + sdkVersion + " extension version " + minVersion
                                + " which exceeds device version " + version);
            }
        } catch (RuntimeException e) {
            return input.error(
                    PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
                    "Specified sdkVersion " + sdkVersion + " is not valid");
        }
        return input.success(pkg);
    }

    /**
     * {@link ParseResult} version of
     * {@link PackageParser#computeMinSdkVersion(int, String, int, String[], String[])}
     */
    public static ParseResult<Integer> computeMinSdkVersion(@IntRange(from = 1) int minVers,
            @Nullable String minCode, @IntRange(from = 1) int platformSdkVersion,
            @NonNull String[] platformSdkCodenames, @NonNull ParseInput input) {
        // If it's a release SDK, make sure we meet the minimum SDK requirement.
        if (minCode == null) {
            if (minVers <= platformSdkVersion) {
                return input.success(minVers);
            }

            // We don't meet the minimum SDK requirement.
            return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK,
                    "Requires newer sdk version #" + minVers
                            + " (current version is #" + platformSdkVersion + ")");
        }

        // If it's a pre-release SDK and the codename matches this platform, we
        // definitely meet the minimum SDK requirement.
        if (matchTargetCode(platformSdkCodenames, minCode)) {
            return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT);
        }

        // Otherwise, we're looking at an incompatible pre-release SDK.
        if (platformSdkCodenames.length > 0) {
            return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK,
                    "Requires development platform " + minCode
                            + " (current platform is any of "
                            + Arrays.toString(platformSdkCodenames) + ")");
        } else {
            return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK,
                    "Requires development platform " + minCode
                            + " but this is a release platform.");
        }
    }

    /**
     * {@link ParseResult} version of
     * {@link PackageParser#computeTargetSdkVersion(int, String, String[], String[])}
     */
    public static ParseResult<Integer> computeTargetSdkVersion(@IntRange(from = 0) int targetVers,
            @Nullable String targetCode, @NonNull String[] platformSdkCodenames,
            @NonNull ParseInput input) {
        // If it's a release SDK, return the version number unmodified.
        if (targetCode == null) {
            return input.success(targetVers);
        }

        // If it's a pre-release SDK and the codename matches this platform, it
        // definitely targets this SDK.
        if (matchTargetCode(platformSdkCodenames, targetCode)) {
            return input.success(Build.VERSION_CODES.CUR_DEVELOPMENT);
        }

        // Otherwise, we're looking at an incompatible pre-release SDK.
        if (platformSdkCodenames.length > 0) {
            return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK,
                    "Requires development platform " + targetCode
                            + " (current platform is any of "
                            + Arrays.toString(platformSdkCodenames) + ")");
        } else {
            return input.error(PackageManager.INSTALL_FAILED_OLDER_SDK,
                    "Requires development platform " + targetCode
                            + " but this is a release platform.");
        }
    }

    /**
     * Matches a given {@code targetCode} against a set of release codeNames. Target codes can
     * either be of the form {@code [codename]}" (e.g {@code "Q"}) or of the form
     * {@code [codename].[fingerprint]} (e.g {@code "Q.cafebc561"}).
     */
    private static boolean matchTargetCode(@NonNull String[] codeNames,
            @NonNull String targetCode) {
        final String targetCodeName;
        final int targetCodeIdx = targetCode.indexOf('.');
        if (targetCodeIdx == -1) {
            targetCodeName = targetCode;
        } else {
            targetCodeName = targetCode.substring(0, targetCodeIdx);
        }
        return ArrayUtils.contains(codeNames, targetCodeName);
    }

    private static ParseResult<ParsingPackage> parseRestrictUpdateHash(int flags, ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser) {
        if ((flags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
            TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestRestrictUpdate);
            try {
                final String hash = sa.getNonConfigurationString(
                        R.styleable.AndroidManifestRestrictUpdate_hash,
                        0);

                if (hash != null) {
                    final int hashLength = hash.length();
                    final byte[] hashBytes = new byte[hashLength / 2];
                    for (int i = 0; i < hashLength; i += 2) {
                        hashBytes[i / 2] = (byte) ((Character.digit(hash.charAt(i), 16)
                                << 4)
                                + Character.digit(hash.charAt(i + 1), 16));
                    }
                    pkg.setRestrictUpdateHash(hashBytes);
                } else {
                    pkg.setRestrictUpdateHash(null);
                }
            } finally {
                sa.recycle();
            }
        }
        return input.success(pkg);
    }

    private static ParseResult<ParsingPackage> parseQueries(ParseInput input, ParsingPackage pkg,
            Resources res, XmlResourceParser parser) throws IOException, XmlPullParserException {
        final int depth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG
                || parser.getDepth() > depth)) {
            if (type != XmlPullParser.START_TAG) {
                continue;
            }
            if (parser.getName().equals("intent")) {
                ParseResult<ParsedIntentInfo> result = ParsedIntentInfoUtils.parseIntentInfo(null,
                        pkg, res, parser, true /*allowGlobs*/, true /*allowAutoVerify*/, input);
                if (result.isError()) {
                    return input.error(result);
                }

                ParsedIntentInfo intentInfo = result.getResult();

                Uri data = null;
                String dataType = null;
                String host = "";
                final int numActions = intentInfo.countActions();
                final int numSchemes = intentInfo.countDataSchemes();
                final int numTypes = intentInfo.countDataTypes();
                final int numHosts = intentInfo.getHosts().length;
                if ((numSchemes == 0 && numTypes == 0 && numActions == 0)) {
                    return input.error("intent tags must contain either an action or data.");
                }
                if (numActions > 1) {
                    return input.error("intent tag may have at most one action.");
                }
                if (numTypes > 1) {
                    return input.error("intent tag may have at most one data type.");
                }
                if (numSchemes > 1) {
                    return input.error("intent tag may have at most one data scheme.");
                }
                if (numHosts > 1) {
                    return input.error("intent tag may have at most one data host.");
                }
                Intent intent = new Intent();
                for (int i = 0, max = intentInfo.countCategories(); i < max; i++) {
                    intent.addCategory(intentInfo.getCategory(i));
                }
                if (numHosts == 1) {
                    host = intentInfo.getHosts()[0];
                }
                if (numSchemes == 1) {
                    data = new Uri.Builder()
                            .scheme(intentInfo.getDataScheme(0))
                            .authority(host)
                            .build();
                }
                if (numTypes == 1) {
                    dataType = intentInfo.getDataType(0);
                }
                intent.setDataAndType(data, dataType);
                if (numActions == 1) {
                    intent.setAction(intentInfo.getAction(0));
                }
                pkg.addQueriesIntent(intent);
            } else if (parser.getName().equals("package")) {
                final TypedArray sa = res.obtainAttributes(parser,
                        R.styleable.AndroidManifestQueriesPackage);
                final String packageName = sa.getString(
                        R.styleable.AndroidManifestQueriesPackage_name);
                if (TextUtils.isEmpty(packageName)) {
                    return input.error("Package name is missing from package tag.");
                }
                pkg.addQueriesPackage(packageName.intern());
            } else if (parser.getName().equals("provider")) {
                final TypedArray sa = res.obtainAttributes(parser,
                        R.styleable.AndroidManifestQueriesProvider);
                try {
                    final String authorities =
                            sa.getString(R.styleable.AndroidManifestQueriesProvider_authorities);
                    if (TextUtils.isEmpty(authorities)) {
                        return input.error(
                                PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
                                "Authority missing from provider tag."
                        );
                    }
                    StringTokenizer authoritiesTokenizer = new StringTokenizer(authorities, ";");
                    while (authoritiesTokenizer.hasMoreElements()) {
                        pkg.addQueriesProvider(authoritiesTokenizer.nextToken());
                    }
                } finally {
                    sa.recycle();
                }
            }
        }
        return input.success(pkg);
    }

    /**
     * Parse the {@code application} XML tree at the current parse location in a
     * <em>base APK</em> manifest.
     * <p>
     * When adding new features, carefully consider if they should also be
     * supported by split APKs.
     *
     * This method should avoid using a getter for fields set by this method. Prefer assigning
     * a local variable and using it. Otherwise there's an ordering problem which can be broken
     * if any code moves around.
     */
    private ParseResult<ParsingPackage> parseBaseApplication(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser, int flags)
            throws XmlPullParserException, IOException {
        final String pkgName = pkg.getPackageName();
        int targetSdk = pkg.getTargetSdkVersion();

        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestApplication);
        try {
            // TODO(b/135203078): Remove this and force unit tests to mock an empty manifest
            // This case can only happen in unit tests where we sometimes need to create fakes
            // of various package parser data structures.
            if (sa == null) {
                return input.error("<application> does not contain any attributes");
            }

            String name = sa.getNonConfigurationString(R.styleable.AndroidManifestApplication_name,
                    0);
            if (name != null) {
                String packageName = pkg.getPackageName();
                String outInfoName = ParsingUtils.buildClassName(packageName, name);
                if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(outInfoName)) {
                    return input.error("<application> invalid android:name");
                } else if (outInfoName == null) {
                    return input.error("Empty class name in package " + packageName);
                }

                pkg.setClassName(outInfoName);
            }

            TypedValue labelValue = sa.peekValue(R.styleable.AndroidManifestApplication_label);
            if (labelValue != null) {
                pkg.setLabelRes(labelValue.resourceId);
                if (labelValue.resourceId == 0) {
                    pkg.setNonLocalizedLabel(labelValue.coerceToString());
                }
            }

            parseBaseAppBasicFlags(pkg, sa);

            String manageSpaceActivity = nonConfigString(Configuration.NATIVE_CONFIG_VERSION,
                    R.styleable.AndroidManifestApplication_manageSpaceActivity, sa);
            if (manageSpaceActivity != null) {
                String manageSpaceActivityName = ParsingUtils.buildClassName(pkgName,
                        manageSpaceActivity);

                if (manageSpaceActivityName == null) {
                    return input.error("Empty class name in package " + pkgName);
                }

                pkg.setManageSpaceActivityName(manageSpaceActivityName);
            }

            if (pkg.isAllowBackup()) {
                // backupAgent, killAfterRestore, fullBackupContent, backupInForeground,
                // and restoreAnyVersion are only relevant if backup is possible for the
                // given application.
                String backupAgent = nonConfigString(Configuration.NATIVE_CONFIG_VERSION,
                        R.styleable.AndroidManifestApplication_backupAgent, sa);
                if (backupAgent != null) {
                    String backupAgentName = ParsingUtils.buildClassName(pkgName, backupAgent);
                    if (backupAgentName == null) {
                        return input.error("Empty class name in package " + pkgName);
                    }

                    if (PackageParser.DEBUG_BACKUP) {
                        Slog.v(TAG, "android:backupAgent = " + backupAgentName
                                + " from " + pkgName + "+" + backupAgent);
                    }

                    pkg.setBackupAgentName(backupAgentName)
                            .setKillAfterRestore(bool(true,
                                    R.styleable.AndroidManifestApplication_killAfterRestore, sa))
                            .setRestoreAnyVersion(bool(false,
                                    R.styleable.AndroidManifestApplication_restoreAnyVersion, sa))
                            .setFullBackupOnly(bool(false,
                                    R.styleable.AndroidManifestApplication_fullBackupOnly, sa))
                            .setBackupInForeground(bool(false,
                                    R.styleable.AndroidManifestApplication_backupInForeground, sa));
                }

                TypedValue v = sa.peekValue(
                        R.styleable.AndroidManifestApplication_fullBackupContent);
                int fullBackupContent = 0;

                if (v != null) {
                    fullBackupContent = v.resourceId;

                    if (v.resourceId == 0) {
                        if (PackageParser.DEBUG_BACKUP) {
                            Slog.v(TAG, "fullBackupContent specified as boolean=" +
                                    (v.data == 0 ? "false" : "true"));
                        }
                        // "false" => -1, "true" => 0
                        fullBackupContent = v.data == 0 ? -1 : 0;
                    }

                    pkg.setFullBackupContent(fullBackupContent);
                }
                if (PackageParser.DEBUG_BACKUP) {
                    Slog.v(TAG, "fullBackupContent=" + fullBackupContent + " for " + pkgName);
                }
            }

            if (sa.getBoolean(R.styleable.AndroidManifestApplication_persistent, false)) {
                // Check if persistence is based on a feature being present
                final String requiredFeature = sa.getNonResourceString(R.styleable
                        .AndroidManifestApplication_persistentWhenFeatureAvailable);
                pkg.setPersistent(requiredFeature == null || mCallback.hasFeature(requiredFeature));
            }

            // TODO(b/135203078): Should parsing code be responsible for this? Maybe move to a
            //  util or just have PackageImpl return true if either flag is set
            // Debuggable implies profileable
            pkg.setProfileableByShell(pkg.isProfileableByShell() || pkg.isDebuggable());

            if (sa.hasValueOrEmpty(R.styleable.AndroidManifestApplication_resizeableActivity)) {
                pkg.setResizeableActivity(sa.getBoolean(
                        R.styleable.AndroidManifestApplication_resizeableActivity, true));
            } else {
                pkg.setResizeableActivityViaSdkVersion(
                        targetSdk >= Build.VERSION_CODES.N);
            }

            String taskAffinity;
            if (targetSdk >= Build.VERSION_CODES.FROYO) {
                taskAffinity = sa.getNonConfigurationString(
                        R.styleable.AndroidManifestApplication_taskAffinity,
                        Configuration.NATIVE_CONFIG_VERSION);
            } else {
                // Some older apps have been seen to use a resource reference
                // here that on older builds was ignored (with a warning).  We
                // need to continue to do this for them so they don't break.
                taskAffinity = sa.getNonResourceString(
                        R.styleable.AndroidManifestApplication_taskAffinity);
            }

            ParseResult<String> taskAffinityResult = ComponentParseUtils.buildTaskAffinityName(
                    pkgName, pkgName, taskAffinity, input);
            if (taskAffinityResult.isError()) {
                return input.error(taskAffinityResult);
            }

            pkg.setTaskAffinity(taskAffinityResult.getResult());
            String factory = sa.getNonResourceString(
                    R.styleable.AndroidManifestApplication_appComponentFactory);
            if (factory != null) {
                String appComponentFactory = ParsingUtils.buildClassName(pkgName, factory);
                if (appComponentFactory == null) {
                    return input.error("Empty class name in package " + pkgName);
                }

                pkg.setAppComponentFactory(appComponentFactory);
            }

            CharSequence pname;
            if (targetSdk >= Build.VERSION_CODES.FROYO) {
                pname = sa.getNonConfigurationString(
                        R.styleable.AndroidManifestApplication_process,
                        Configuration.NATIVE_CONFIG_VERSION);
            } else {
                // Some older apps have been seen to use a resource reference
                // here that on older builds was ignored (with a warning).  We
                // need to continue to do this for them so they don't break.
                pname = sa.getNonResourceString(
                        R.styleable.AndroidManifestApplication_process);
            }
            ParseResult<String> processNameResult = ComponentParseUtils.buildProcessName(
                    pkgName, null, pname, flags, mSeparateProcesses, input);
            if (processNameResult.isError()) {
                return input.error(processNameResult);
            }

            String processName = processNameResult.getResult();
            pkg.setProcessName(processName);

            if (pkg.isCantSaveState()) {
                // A heavy-weight application can not be in a custom process.
                // We can do direct compare because we intern all strings.
                if (processName != null && !processName.equals(pkgName)) {
                    return input.error(
                            "cantSaveState applications can not use custom processes");
                }
            }

            String classLoaderName = pkg.getClassLoaderName();
            if (classLoaderName != null
                    && !ClassLoaderFactory.isValidClassLoaderName(classLoaderName)) {
                return input.error("Invalid class loader name: " + classLoaderName);
            }
        } finally {
            sa.recycle();
        }

        boolean hasActivityOrder = false;
        boolean hasReceiverOrder = false;
        boolean hasServiceOrder = false;
        final int depth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG
                || parser.getDepth() > depth)) {
            if (type != XmlPullParser.START_TAG) {
                continue;
            }

            final ParseResult result;
            String tagName = parser.getName();
            boolean isActivity = false;
            switch (tagName) {
                case "activity":
                    isActivity = true;
                    // fall-through
                case "receiver":
                    ParseResult<ParsedActivity> activityResult =
                            ParsedActivityUtils.parseActivityOrReceiver(mSeparateProcesses, pkg,
                                    res, parser, flags, PackageParser.sUseRoundIcon, input);

                    if (activityResult.isSuccess()) {
                        ParsedActivity activity = activityResult.getResult();
                        if (isActivity) {
                            hasActivityOrder |= (activity.getOrder() != 0);
                            pkg.addActivity(activity);
                        } else {
                            hasReceiverOrder |= (activity.getOrder() != 0);
                            pkg.addReceiver(activity);
                        }
                    }

                    result = activityResult;
                    break;
                case "service":
                    ParseResult<ParsedService> serviceResult =
                            ParsedServiceUtils.parseService(mSeparateProcesses, pkg, res, parser,
                                    flags, PackageParser.sUseRoundIcon, input);
                    if (serviceResult.isSuccess()) {
                        ParsedService service = serviceResult.getResult();
                        hasServiceOrder |= (service.getOrder() != 0);
                        pkg.addService(service);
                    }

                    result = serviceResult;
                    break;
                case "provider":
                    ParseResult<ParsedProvider> providerResult =
                            ParsedProviderUtils.parseProvider(mSeparateProcesses, pkg, res, parser,
                                    flags, PackageParser.sUseRoundIcon, input);
                    if (providerResult.isSuccess()) {
                        pkg.addProvider(providerResult.getResult());
                    }

                    result = providerResult;
                    break;
                case "activity-alias":
                    activityResult = ParsedActivityUtils.parseActivityAlias(pkg, res,
                            parser, PackageParser.sUseRoundIcon, input);
                    if (activityResult.isSuccess()) {
                        ParsedActivity activity = activityResult.getResult();
                        hasActivityOrder |= (activity.getOrder() != 0);
                        pkg.addActivity(activity);
                    }

                    result = activityResult;
                    break;
                default:
                    result = parseBaseAppChildTag(input, tagName, pkg, res, parser, flags);
                    break;
            }

            if (result.isError()) {
                return input.error(result);
            }
        }

        if (TextUtils.isEmpty(pkg.getStaticSharedLibName())) {
            // Add a hidden app detail activity to normal apps which forwards user to App Details
            // page.
            ParseResult<ParsedActivity> a = generateAppDetailsHiddenActivity(input, pkg);
            // Backwards-compat, assume success
            pkg.addActivity(a.getResult());
            a.ignoreError();
        }

        if (hasActivityOrder) {
            pkg.sortActivities();
        }
        if (hasReceiverOrder) {
            pkg.sortReceivers();
        }
        if (hasServiceOrder) {
            pkg.sortServices();
        }

        // Must be run after the entire {@link ApplicationInfo} has been fully processed and after
        // every activity info has had a chance to set it from its attributes.
        setMaxAspectRatio(pkg);
        setMinAspectRatio(pkg);

        pkg.setHasDomainUrls(hasDomainURLs(pkg));

        return input.success(pkg);
    }

    /**
     * Collection of single-line, no (or little) logic assignments. Separated for readability.
     *
     * Flags are separated by type and by default value. They are sorted alphabetically within each
     * section.
     */
    private void parseBaseAppBasicFlags(ParsingPackage pkg, TypedArray sa) {
        int targetSdk = pkg.getTargetSdkVersion();
        //@formatter:off
        // CHECKSTYLE:off
        pkg
                // Default true
                .setAllowBackup(bool(true, R.styleable.AndroidManifestApplication_allowBackup, sa))
                .setAllowClearUserData(bool(true, R.styleable.AndroidManifestApplication_allowClearUserData, sa))
                .setAllowClearUserDataOnFailedRestore(bool(true, R.styleable.AndroidManifestApplication_allowClearUserDataOnFailedRestore, sa))
                .setAllowNativeHeapPointerTagging(bool(true, R.styleable.AndroidManifestApplication_allowNativeHeapPointerTagging, sa))
                .setEnabled(bool(true, R.styleable.AndroidManifestApplication_enabled, sa))
                .setExtractNativeLibs(bool(true, R.styleable.AndroidManifestApplication_extractNativeLibs, sa))
                .setHasCode(bool(true, R.styleable.AndroidManifestApplication_hasCode, sa))
                // Default false
                .setAllowTaskReparenting(bool(false, R.styleable.AndroidManifestApplication_allowTaskReparenting, sa))
                .setCantSaveState(bool(false, R.styleable.AndroidManifestApplication_cantSaveState, sa))
                .setCrossProfile(bool(false, R.styleable.AndroidManifestApplication_crossProfile, sa))
                .setDebuggable(bool(false, R.styleable.AndroidManifestApplication_debuggable, sa))
                .setDefaultToDeviceProtectedStorage(bool(false, R.styleable.AndroidManifestApplication_defaultToDeviceProtectedStorage, sa))
                .setDirectBootAware(bool(false, R.styleable.AndroidManifestApplication_directBootAware, sa))
                .setForceQueryable(bool(false, R.styleable.AndroidManifestApplication_forceQueryable, sa))
                .setGame(bool(false, R.styleable.AndroidManifestApplication_isGame, sa))
                .setHasFragileUserData(bool(false, R.styleable.AndroidManifestApplication_hasFragileUserData, sa))
                .setLargeHeap(bool(false, R.styleable.AndroidManifestApplication_largeHeap, sa))
                .setMultiArch(bool(false, R.styleable.AndroidManifestApplication_multiArch, sa))
                .setPreserveLegacyExternalStorage(bool(false, R.styleable.AndroidManifestApplication_preserveLegacyExternalStorage, sa))
                .setRequiredForAllUsers(bool(false, R.styleable.AndroidManifestApplication_requiredForAllUsers, sa))
                .setSupportsRtl(bool(false, R.styleable.AndroidManifestApplication_supportsRtl, sa))
                .setTestOnly(bool(false, R.styleable.AndroidManifestApplication_testOnly, sa))
                .setUseEmbeddedDex(bool(false, R.styleable.AndroidManifestApplication_useEmbeddedDex, sa))
                .setUsesNonSdkApi(bool(false, R.styleable.AndroidManifestApplication_usesNonSdkApi, sa))
                .setVmSafeMode(bool(false, R.styleable.AndroidManifestApplication_vmSafeMode, sa))
                // targetSdkVersion gated
                .setAllowAudioPlaybackCapture(bool(targetSdk >= Build.VERSION_CODES.Q, R.styleable.AndroidManifestApplication_allowAudioPlaybackCapture, sa))
                .setBaseHardwareAccelerated(bool(targetSdk >= Build.VERSION_CODES.ICE_CREAM_SANDWICH, R.styleable.AndroidManifestApplication_hardwareAccelerated, sa))
                .setRequestLegacyExternalStorage(bool(targetSdk < Build.VERSION_CODES.Q, R.styleable.AndroidManifestApplication_requestLegacyExternalStorage, sa))
                .setUsesCleartextTraffic(bool(targetSdk < Build.VERSION_CODES.P, R.styleable.AndroidManifestApplication_usesCleartextTraffic, sa))
                // Ints Default 0
                .setUiOptions(anInt(R.styleable.AndroidManifestApplication_uiOptions, sa))
                // Ints
                .setCategory(anInt(ApplicationInfo.CATEGORY_UNDEFINED, R.styleable.AndroidManifestApplication_appCategory, sa))
                // Floats Default 0f
                .setMaxAspectRatio(aFloat(R.styleable.AndroidManifestApplication_maxAspectRatio, sa))
                .setMinAspectRatio(aFloat(R.styleable.AndroidManifestApplication_minAspectRatio, sa))
                // Resource ID
                .setBanner(resId(R.styleable.AndroidManifestApplication_banner, sa))
                .setDescriptionRes(resId(R.styleable.AndroidManifestApplication_description, sa))
                .setIconRes(resId(R.styleable.AndroidManifestApplication_icon, sa))
                .setLogo(resId(R.styleable.AndroidManifestApplication_logo, sa))
                .setNetworkSecurityConfigRes(resId(R.styleable.AndroidManifestApplication_networkSecurityConfig, sa))
                .setRoundIconRes(resId(R.styleable.AndroidManifestApplication_roundIcon, sa))
                .setTheme(resId(R.styleable.AndroidManifestApplication_theme, sa))
                // Strings
                .setClassLoaderName(string(R.styleable.AndroidManifestApplication_classLoader, sa))
                .setRequiredAccountType(string(R.styleable.AndroidManifestApplication_requiredAccountType, sa))
                .setRestrictedAccountType(string(R.styleable.AndroidManifestApplication_restrictedAccountType, sa))
                .setZygotePreloadName(string(R.styleable.AndroidManifestApplication_zygotePreloadName, sa))
                // Non-Config String
                .setPermission(nonConfigString(0, R.styleable.AndroidManifestApplication_permission, sa));
        // CHECKSTYLE:on
        //@formatter:on
    }

    /**
     * For parsing non-MainComponents. Main ones have an order and some special handling which is
     * done directly in {@link #parseBaseApplication(ParseInput, ParsingPackage, Resources,
     * XmlResourceParser, int)}.
     */
    private ParseResult parseBaseAppChildTag(ParseInput input, String tag, ParsingPackage pkg,
            Resources res, XmlResourceParser parser, int flags)
            throws IOException, XmlPullParserException {
        switch (tag) {
            case "meta-data":
                // TODO(b/135203078): I have no idea what this comment means
                // note: application meta-data is stored off to the side, so it can
                // remain null in the primary copy (we like to avoid extra copies because
                // it can be large)
                ParseResult<Bundle> metaDataResult = parseMetaData(pkg, res, parser,
                        pkg.getMetaData(), input);
                if (metaDataResult.isSuccess()) {
                    pkg.setMetaData(metaDataResult.getResult());
                }

                return metaDataResult;
            case "static-library":
                return parseStaticLibrary(pkg, res, parser, input);
            case "library":
                return parseLibrary(pkg, res, parser, input);
            case "uses-static-library":
                return parseUsesStaticLibrary(input, pkg, res, parser);
            case "uses-library":
                return parseUsesLibrary(input, pkg, res, parser);
            case "processes":
                return parseProcesses(input, pkg, res, parser, mSeparateProcesses, flags);
            case "uses-package":
                // Dependencies for app installers; we don't currently try to
                // enforce this.
                return input.success(null);
            case "profileable":
                return parseProfileable(input, pkg, res, parser);
            default:
                return ParsingUtils.unknownTag("<application>", pkg, parser, input);
        }
    }

    @NonNull
    private static ParseResult<ParsingPackage> parseStaticLibrary(
            ParsingPackage pkg, Resources res,
            XmlResourceParser parser, ParseInput input) {
        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestStaticLibrary);
        try {
            // Note: don't allow this value to be a reference to a resource
            // that may change.
            String lname = sa.getNonResourceString(
                    R.styleable.AndroidManifestStaticLibrary_name);
            final int version = sa.getInt(
                    R.styleable.AndroidManifestStaticLibrary_version, -1);
            final int versionMajor = sa.getInt(
                    R.styleable.AndroidManifestStaticLibrary_versionMajor,
                    0);

            // Since the app canot run without a static lib - fail if malformed
            if (lname == null || version < 0) {
                return input.error("Bad static-library declaration name: " + lname
                        + " version: " + version);
            } else if (pkg.getSharedUserId() != null) {
                return input.error(
                        PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID,
                        "sharedUserId not allowed in static shared library"
                );
            } else if (pkg.getStaticSharedLibName() != null) {
                return input.error("Multiple static-shared libs for package "
                        + pkg.getPackageName());
            }

            return input.success(pkg.setStaticSharedLibName(lname.intern())
                    .setStaticSharedLibVersion(
                            PackageInfo.composeLongVersionCode(versionMajor, version))
                    .setStaticSharedLibrary(true));
        } finally {
            sa.recycle();
        }
    }

    @NonNull
    private static ParseResult<ParsingPackage> parseLibrary(
            ParsingPackage pkg, Resources res,
            XmlResourceParser parser, ParseInput input) {
        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestLibrary);
        try {
            // Note: don't allow this value to be a reference to a resource
            // that may change.
            String lname = sa.getNonResourceString(R.styleable.AndroidManifestLibrary_name);

            if (lname != null) {
                lname = lname.intern();
                if (!ArrayUtils.contains(pkg.getLibraryNames(), lname)) {
                    pkg.addLibraryName(lname);
                }
            }
            return input.success(pkg);
        } finally {
            sa.recycle();
        }
    }

    @NonNull
    private static ParseResult<ParsingPackage> parseUsesStaticLibrary(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser)
            throws XmlPullParserException, IOException {
        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesStaticLibrary);
        try {
            // Note: don't allow this value to be a reference to a resource that may change.
            String lname = sa.getNonResourceString(
                    R.styleable.AndroidManifestUsesLibrary_name);
            final int version = sa.getInt(
                    R.styleable.AndroidManifestUsesStaticLibrary_version, -1);
            String certSha256Digest = sa.getNonResourceString(R.styleable
                    .AndroidManifestUsesStaticLibrary_certDigest);

            // Since an APK providing a static shared lib can only provide the lib - fail if
            // malformed
            if (lname == null || version < 0 || certSha256Digest == null) {
                return input.error("Bad uses-static-library declaration name: " + lname
                        + " version: " + version + " certDigest" + certSha256Digest);
            }

            // Can depend only on one version of the same library
            List<String> usesStaticLibraries = pkg.getUsesStaticLibraries();
            if (usesStaticLibraries.contains(lname)) {
                return input.error(
                        "Depending on multiple versions of static library " + lname);
            }

            lname = lname.intern();
            // We allow ":" delimiters in the SHA declaration as this is the format
            // emitted by the certtool making it easy for developers to copy/paste.
            certSha256Digest = certSha256Digest.replace(":", "").toLowerCase();

            // Fot apps targeting O-MR1 we require explicit enumeration of all certs.
            String[] additionalCertSha256Digests = EmptyArray.STRING;
            if (pkg.getTargetSdkVersion() >= Build.VERSION_CODES.O_MR1) {
                ParseResult<String[]> certResult = parseAdditionalCertificates(input, res, parser);
                if (certResult.isError()) {
                    return input.error(certResult);
                }
                additionalCertSha256Digests = certResult.getResult();
            }

            final String[] certSha256Digests = new String[additionalCertSha256Digests.length + 1];
            certSha256Digests[0] = certSha256Digest;
            System.arraycopy(additionalCertSha256Digests, 0, certSha256Digests,
                    1, additionalCertSha256Digests.length);

            return input.success(pkg.addUsesStaticLibrary(lname)
                    .addUsesStaticLibraryVersion(version)
                    .addUsesStaticLibraryCertDigests(certSha256Digests));
        } finally {
            sa.recycle();
        }
    }

    @NonNull
    private static ParseResult<ParsingPackage> parseUsesLibrary(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser) {
        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesLibrary);
        try {
            // Note: don't allow this value to be a reference to a resource
            // that may change.
            String lname = sa.getNonResourceString(R.styleable.AndroidManifestUsesLibrary_name);
            boolean req = sa.getBoolean(R.styleable.AndroidManifestUsesLibrary_required, true);

            if (lname != null) {
                lname = lname.intern();
                if (req) {
                    // Upgrade to treat as stronger constraint
                    pkg.addUsesLibrary(lname)
                            .removeUsesOptionalLibrary(lname);
                } else {
                    // Ignore if someone already defined as required
                    if (!ArrayUtils.contains(pkg.getUsesLibraries(), lname)) {
                        pkg.addUsesOptionalLibrary(lname);
                    }
                }
            }

            return input.success(pkg);
        } finally {
            sa.recycle();
        }
    }

    @NonNull
    private static ParseResult<ParsingPackage> parseProcesses(ParseInput input, ParsingPackage pkg,
            Resources res, XmlResourceParser parser, String[] separateProcesses, int flags)
            throws IOException, XmlPullParserException {
        ParseResult<ArrayMap<String, ParsedProcess>> result =
                ParsedProcessUtils.parseProcesses(separateProcesses, pkg, res, parser, flags,
                        input);
        if (result.isError()) {
            return input.error(result);
        }

        return input.success(pkg.setProcesses(result.getResult()));
    }

    @NonNull
    private static ParseResult<ParsingPackage> parseProfileable(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser) {
        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestProfileable);
        try {
            return input.success(pkg.setProfileableByShell(pkg.isProfileableByShell()
                    || bool(false, R.styleable.AndroidManifestProfileable_shell, sa)));
        } finally {
            sa.recycle();
        }
    }

    private static ParseResult<String[]> parseAdditionalCertificates(ParseInput input,
            Resources resources, XmlResourceParser parser)
            throws XmlPullParserException, IOException {
        String[] certSha256Digests = EmptyArray.STRING;
        final int depth = parser.getDepth();
        int type;
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
                && (type != XmlPullParser.END_TAG
                || parser.getDepth() > depth)) {
            if (type != XmlPullParser.START_TAG) {
                continue;
            }

            final String nodeName = parser.getName();
            if (nodeName.equals("additional-certificate")) {
                TypedArray sa = resources.obtainAttributes(parser,
                        R.styleable.AndroidManifestAdditionalCertificate);
                try {
                    String certSha256Digest = sa.getNonResourceString(
                            R.styleable.AndroidManifestAdditionalCertificate_certDigest);

                    if (TextUtils.isEmpty(certSha256Digest)) {
                        return input.error("Bad additional-certificate declaration with empty"
                                + " certDigest:" + certSha256Digest);
                    }


                    // We allow ":" delimiters in the SHA declaration as this is the format
                    // emitted by the certtool making it easy for developers to copy/paste.
                    certSha256Digest = certSha256Digest.replace(":", "").toLowerCase();
                    certSha256Digests = ArrayUtils.appendElement(String.class,
                            certSha256Digests, certSha256Digest);
                } finally {
                    sa.recycle();
                }
            }
        }

        return input.success(certSha256Digests);
    }

    /**
     * Generate activity object that forwards user to App Details page automatically.
     * This activity should be invisible to user and user should not know or see it.
     */
    @NonNull
    private static ParseResult<ParsedActivity> generateAppDetailsHiddenActivity(ParseInput input,
            ParsingPackage pkg) {
        String packageName = pkg.getPackageName();
        ParseResult<String> taskAffinityResult = ComponentParseUtils.buildTaskAffinityName(
                packageName, packageName, ":app_details", input);

        String taskAffinity;
        if (taskAffinityResult.isSuccess()) {
            taskAffinity = taskAffinityResult.getResult();
        } else {
            // Backwards-compat, do not fail
            taskAffinity = null;
            taskAffinityResult.ignoreError();
        }

        // Build custom App Details activity info instead of parsing it from xml
        return input.success(ParsedActivity.makeAppDetailsActivity(packageName,
                pkg.getProcessName(), pkg.getUiOptions(), taskAffinity,
                pkg.isBaseHardwareAccelerated()));
    }

    /**
     * Check if one of the IntentFilter as both actions DEFAULT / VIEW and a HTTP/HTTPS data URI
     */
    private static boolean hasDomainURLs(ParsingPackage pkg) {
        final List<ParsedActivity> activities = pkg.getActivities();
        final int activitiesSize = activities.size();
        for (int index = 0; index < activitiesSize; index++) {
            ParsedActivity activity = activities.get(index);
            List<ParsedIntentInfo> filters = activity.getIntents();
            final int filtersSize = filters.size();
            for (int filtersIndex = 0; filtersIndex < filtersSize; filtersIndex++) {
                ParsedIntentInfo aii = filters.get(filtersIndex);
                if (!aii.hasAction(Intent.ACTION_VIEW)) continue;
                if (!aii.hasAction(Intent.ACTION_DEFAULT)) continue;
                if (aii.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
                        aii.hasDataScheme(IntentFilter.SCHEME_HTTPS)) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * Sets the max aspect ratio of every child activity that doesn't already have an aspect
     * ratio set.
     */
    private static void setMaxAspectRatio(ParsingPackage pkg) {
        // Default to (1.86) 16.7:9 aspect ratio for pre-O apps and unset for O and greater.
        // NOTE: 16.7:9 was the max aspect ratio Android devices can support pre-O per the CDD.
        float maxAspectRatio = pkg.getTargetSdkVersion() < O
                ? PackageParser.DEFAULT_PRE_O_MAX_ASPECT_RATIO : 0;

        float packageMaxAspectRatio = pkg.getMaxAspectRatio();
        if (packageMaxAspectRatio != 0) {
            // Use the application max aspect ration as default if set.
            maxAspectRatio = packageMaxAspectRatio;
        } else {
            Bundle appMetaData = pkg.getMetaData();
            if (appMetaData != null && appMetaData.containsKey(
                    PackageParser.METADATA_MAX_ASPECT_RATIO)) {
                maxAspectRatio = appMetaData.getFloat(PackageParser.METADATA_MAX_ASPECT_RATIO,
                        maxAspectRatio);
            }
        }

        List<ParsedActivity> activities = pkg.getActivities();
        int activitiesSize = activities.size();
        for (int index = 0; index < activitiesSize; index++) {
            ParsedActivity activity = activities.get(index);
            // If the max aspect ratio for the activity has already been set, skip.
            if (activity.getMaxAspectRatio() != null) {
                continue;
            }

            // By default we prefer to use a values defined on the activity directly than values
            // defined on the application. We do not check the styled attributes on the activity
            // as it would have already been set when we processed the activity. We wait to
            // process the meta data here since this method is called at the end of processing
            // the application and all meta data is guaranteed.
            final float activityAspectRatio = activity.getMetaData() != null
                    ? activity.getMetaData().getFloat(PackageParser.METADATA_MAX_ASPECT_RATIO,
                    maxAspectRatio)
                    : maxAspectRatio;

            activity.setMaxAspectRatio(activity.getResizeMode(), activityAspectRatio);
        }
    }

    /**
     * Sets the min aspect ratio of every child activity that doesn't already have an aspect
     * ratio set.
     */
    private void setMinAspectRatio(ParsingPackage pkg) {
        final float minAspectRatio;
        float packageMinAspectRatio = pkg.getMinAspectRatio();
        if (packageMinAspectRatio != 0) {
            // Use the application max aspect ration as default if set.
            minAspectRatio = packageMinAspectRatio;
        } else {
            // Default to (1.33) 4:3 aspect ratio for pre-Q apps and unset for Q and greater.
            // NOTE: 4:3 was the min aspect ratio Android devices can support pre-Q per the CDD,
            // except for watches which always supported 1:1.
            minAspectRatio = pkg.getTargetSdkVersion() >= Build.VERSION_CODES.Q
                    ? 0
                    : (mCallback != null && mCallback.hasFeature(FEATURE_WATCH))
                            ? PackageParser.DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH
                            : PackageParser.DEFAULT_PRE_Q_MIN_ASPECT_RATIO;
        }

        List<ParsedActivity> activities = pkg.getActivities();
        int activitiesSize = activities.size();
        for (int index = 0; index < activitiesSize; index++) {
            ParsedActivity activity = activities.get(index);
            if (activity.getMinAspectRatio() == null) {
                activity.setMinAspectRatio(activity.getResizeMode(), minAspectRatio);
            }
        }
    }

    private static ParseResult<ParsingPackage> parseOverlay(ParseInput input, ParsingPackage pkg,
            Resources res, XmlResourceParser parser) {
        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestResourceOverlay);
        try {
            String target = sa.getString(R.styleable.AndroidManifestResourceOverlay_targetPackage);
            int priority = anInt(0, R.styleable.AndroidManifestResourceOverlay_priority, sa);

            if (target == null) {
                return input.error("<overlay> does not specify a target package");
            } else if (priority < 0 || priority > 9999) {
                return input.error("<overlay> priority must be between 0 and 9999");
            }

            // check to see if overlay should be excluded based on system property condition
            String propName = sa.getString(
                    R.styleable.AndroidManifestResourceOverlay_requiredSystemPropertyName);
            String propValue = sa.getString(
                    R.styleable.AndroidManifestResourceOverlay_requiredSystemPropertyValue);
            if (!checkOverlayRequiredSystemProperty(propName, propValue)) {
                Slog.i(TAG, "Skipping target and overlay pair " + target + " and "
                        + pkg.getBaseCodePath()
                        + ": overlay ignored due to required system property: "
                        + propName + " with value: " + propValue);
                return input.error("Skipping target and overlay pair " + target + " and "
                        + pkg.getBaseCodePath()
                        + ": overlay ignored due to required system property: "
                        + propName + " with value: " + propValue);
            }

            return input.success(pkg.setOverlay(true)
                    .setOverlayTarget(target)
                    .setOverlayPriority(priority)
                    .setOverlayTargetName(
                            sa.getString(R.styleable.AndroidManifestResourceOverlay_targetName))
                    .setOverlayCategory(
                            sa.getString(R.styleable.AndroidManifestResourceOverlay_category))
                    .setOverlayIsStatic(
                            bool(false, R.styleable.AndroidManifestResourceOverlay_isStatic, sa)));
        } finally {
            sa.recycle();
        }
    }

    private static ParseResult<ParsingPackage> parseProtectedBroadcast(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser) {
        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestProtectedBroadcast);
        try {
            // Note: don't allow this value to be a reference to a resource
            // that may change.
            String name = nonResString(R.styleable.AndroidManifestProtectedBroadcast_name, sa);
            if (name != null) {
                pkg.addProtectedBroadcast(name);
            }
            return input.success(pkg);
        } finally {
            sa.recycle();
        }
    }

    private static ParseResult<ParsingPackage> parseSupportScreens(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser) {
        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestSupportsScreens);
        try {
            int requiresSmallestWidthDp = anInt(0,
                    R.styleable.AndroidManifestSupportsScreens_requiresSmallestWidthDp, sa);
            int compatibleWidthLimitDp = anInt(0,
                    R.styleable.AndroidManifestSupportsScreens_compatibleWidthLimitDp, sa);
            int largestWidthLimitDp = anInt(0,
                    R.styleable.AndroidManifestSupportsScreens_largestWidthLimitDp, sa);

            // This is a trick to get a boolean and still able to detect
            // if a value was actually set.
            return input.success(pkg
                    .setSupportsSmallScreens(
                            anInt(1, R.styleable.AndroidManifestSupportsScreens_smallScreens, sa))
                    .setSupportsNormalScreens(
                            anInt(1, R.styleable.AndroidManifestSupportsScreens_normalScreens, sa))
                    .setSupportsLargeScreens(
                            anInt(1, R.styleable.AndroidManifestSupportsScreens_largeScreens, sa))
                    .setSupportsExtraLargeScreens(
                            anInt(1, R.styleable.AndroidManifestSupportsScreens_xlargeScreens, sa))
                    .setResizeable(
                            anInt(1, R.styleable.AndroidManifestSupportsScreens_resizeable, sa))
                    .setAnyDensity(
                            anInt(1, R.styleable.AndroidManifestSupportsScreens_anyDensity, sa))
                    .setRequiresSmallestWidthDp(requiresSmallestWidthDp)
                    .setCompatibleWidthLimitDp(compatibleWidthLimitDp)
                    .setLargestWidthLimitDp(largestWidthLimitDp));
        } finally {
            sa.recycle();
        }
    }

    private static ParseResult<ParsingPackage> parseInstrumentation(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser)
            throws XmlPullParserException, IOException {
        ParseResult<ParsedInstrumentation> result = ParsedInstrumentationUtils.parseInstrumentation(
                pkg, res, parser, PackageParser.sUseRoundIcon, input);
        if (result.isError()) {
            return input.error(result);
        }
        return input.success(pkg.addInstrumentation(result.getResult()));
    }

    private static ParseResult<ParsingPackage> parseOriginalPackage(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser) {
        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestOriginalPackage);
        try {
            String orig = sa.getNonConfigurationString(
                    R.styleable.AndroidManifestOriginalPackage_name,
                    0);
            if (!pkg.getPackageName().equals(orig)) {
                if (pkg.getOriginalPackages().isEmpty()) {
                    pkg.setRealPackage(pkg.getPackageName());
                }
                pkg.addOriginalPackage(orig);
            }
            return input.success(pkg);
        } finally {
            sa.recycle();
        }
    }

    private static ParseResult<ParsingPackage> parseAdoptPermissions(ParseInput input,
            ParsingPackage pkg, Resources res, XmlResourceParser parser) {
        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestOriginalPackage);
        try {
            String name = nonConfigString(0, R.styleable.AndroidManifestOriginalPackage_name, sa);
            if (name != null) {
                pkg.addAdoptPermission(name);
            }
            return input.success(pkg);
        } finally {
            sa.recycle();
        }
    }

    private static void convertNewPermissions(ParsingPackage pkg) {
        final int NP = PackageParser.NEW_PERMISSIONS.length;
        StringBuilder newPermsMsg = null;
        for (int ip = 0; ip < NP; ip++) {
            final PackageParser.NewPermissionInfo npi
                    = PackageParser.NEW_PERMISSIONS[ip];
            if (pkg.getTargetSdkVersion() >= npi.sdkVersion) {
                break;
            }
            if (!pkg.getRequestedPermissions().contains(npi.name)) {
                if (newPermsMsg == null) {
                    newPermsMsg = new StringBuilder(128);
                    newPermsMsg.append(pkg.getPackageName());
                    newPermsMsg.append(": compat added ");
                } else {
                    newPermsMsg.append(' ');
                }
                newPermsMsg.append(npi.name);
                pkg.addRequestedPermission(npi.name)
                        .addImplicitPermission(npi.name);
            }
        }
        if (newPermsMsg != null) {
            Slog.i(TAG, newPermsMsg.toString());
        }
    }

    private static void convertSplitPermissions(ParsingPackage pkg) {
        List<SplitPermissionInfoParcelable> splitPermissions;

        try {
            splitPermissions = ActivityThread.getPermissionManager().getSplitPermissions();
        } catch (RemoteException e) {
            throw e.rethrowFromSystemServer();
        }

        final int listSize = splitPermissions.size();
        for (int is = 0; is < listSize; is++) {
            final SplitPermissionInfoParcelable spi = splitPermissions.get(is);
            List<String> requestedPermissions = pkg.getRequestedPermissions();
            if (pkg.getTargetSdkVersion() >= spi.getTargetSdk()
                    || !requestedPermissions.contains(spi.getSplitPermission())) {
                continue;
            }
            final List<String> newPerms = spi.getNewPermissions();
            for (int in = 0; in < newPerms.size(); in++) {
                final String perm = newPerms.get(in);
                if (!requestedPermissions.contains(perm)) {
                    pkg.addRequestedPermission(perm)
                            .addImplicitPermission(perm);
                }
            }
        }
    }

    private static boolean checkOverlayRequiredSystemProperty(String propName, String propValue) {
        if (TextUtils.isEmpty(propName) || TextUtils.isEmpty(propValue)) {
            if (!TextUtils.isEmpty(propName) || !TextUtils.isEmpty(propValue)) {
                // malformed condition - incomplete
                Slog.w(TAG, "Disabling overlay - incomplete property :'" + propName
                        + "=" + propValue + "' - require both requiredSystemPropertyName"
                        + " AND requiredSystemPropertyValue to be specified.");
                return false;
            }
            // no valid condition set - so no exclusion criteria, overlay will be included.
            return true;
        }

        // check property value - make sure it is both set and equal to expected value
        final String currValue = SystemProperties.get(propName);
        return (currValue != null && currValue.equals(propValue));
    }

    /**
     * This is a pre-density application which will get scaled - instead of being pixel perfect.
     * This type of application is not resizable.
     *
     * @param pkg The package which needs to be marked as unresizable.
     */
    private static void adjustPackageToBeUnresizeableAndUnpipable(ParsingPackage pkg) {
        List<ParsedActivity> activities = pkg.getActivities();
        int activitiesSize = activities.size();
        for (int index = 0; index < activitiesSize; index++) {
            ParsedActivity activity = activities.get(index);
            activity.setResizeMode(RESIZE_MODE_UNRESIZEABLE)
                    .setFlags(activity.getFlags() & ~FLAG_SUPPORTS_PICTURE_IN_PICTURE);
        }
    }

    private static ParseResult validateName(ParseInput input, String name, boolean requireSeparator,
            boolean requireFilename) {
        final int N = name.length();
        boolean hasSep = false;
        boolean front = true;
        for (int i = 0; i < N; i++) {
            final char c = name.charAt(i);
            if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
                front = false;
                continue;
            }
            if (!front) {
                if ((c >= '0' && c <= '9') || c == '_') {
                    continue;
                }
            }
            if (c == '.') {
                hasSep = true;
                front = true;
                continue;
            }
            return input.error("bad character '" + c + "'");
        }
        if (requireFilename && !FileUtils.isValidExtFilename(name)) {
            return input.error("Invalid filename");
        }
        return hasSep || !requireSeparator
                ? input.success(null)
                : input.error("must have at least one '.' separator");
    }

    public static ParseResult<Bundle> parseMetaData(ParsingPackage pkg, Resources res,
            XmlResourceParser parser, Bundle data, ParseInput input) {
        TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestMetaData);
        try {
            if (data == null) {
                data = new Bundle();
            }

            String name = TextUtils.safeIntern(
                    nonConfigString(0, R.styleable.AndroidManifestMetaData_name, sa));
            if (name == null) {
                return input.error("<meta-data> requires an android:name attribute");
            }

            TypedValue v = sa.peekValue(R.styleable.AndroidManifestMetaData_resource);
            if (v != null && v.resourceId != 0) {
                //Slog.i(TAG, "Meta data ref " + name + ": " + v);
                data.putInt(name, v.resourceId);
            } else {
                v = sa.peekValue(R.styleable.AndroidManifestMetaData_value);
                //Slog.i(TAG, "Meta data " + name + ": " + v);
                if (v != null) {
                    if (v.type == TypedValue.TYPE_STRING) {
                        CharSequence cs = v.coerceToString();
                        data.putString(name, cs != null ? cs.toString() : null);
                    } else if (v.type == TypedValue.TYPE_INT_BOOLEAN) {
                        data.putBoolean(name, v.data != 0);
                    } else if (v.type >= TypedValue.TYPE_FIRST_INT
                            && v.type <= TypedValue.TYPE_LAST_INT) {
                        data.putInt(name, v.data);
                    } else if (v.type == TypedValue.TYPE_FLOAT) {
                        data.putFloat(name, v.getFloat());
                    } else {
                        if (!PackageParser.RIGID_PARSER) {
                            Slog.w(TAG,
                                    "<meta-data> only supports string, integer, float, color, "
                                            + "boolean, and resource reference types: "
                                            + parser.getName() + " at "
                                            + pkg.getBaseCodePath() + " "
                                            + parser.getPositionDescription());
                        } else {
                            return input.error("<meta-data> only supports string, integer, float, "
                                    + "color, boolean, and resource reference types");
                        }
                    }
                } else {
                    return input.error("<meta-data> requires an android:value "
                            + "or android:resource attribute");
                }
            }
            return input.success(data);
        } finally {
            sa.recycle();
        }
    }

    /**
     * Collect certificates from all the APKs described in the given package. Also asserts that
     * all APK contents are signed correctly and consistently.
     */
    public static SigningDetails collectCertificates(ParsingPackageRead pkg, boolean skipVerify)
            throws PackageParserException {
        SigningDetails signingDetails = SigningDetails.UNKNOWN;

        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
        try {
            signingDetails = collectCertificates(
                    pkg.getBaseCodePath(),
                    skipVerify,
                    pkg.isStaticSharedLibrary(),
                    signingDetails,
                    pkg.getTargetSdkVersion()
            );

            String[] splitCodePaths = pkg.getSplitCodePaths();
            if (!ArrayUtils.isEmpty(splitCodePaths)) {
                for (int i = 0; i < splitCodePaths.length; i++) {
                    signingDetails = collectCertificates(
                            splitCodePaths[i],
                            skipVerify,
                            pkg.isStaticSharedLibrary(),
                            signingDetails,
                            pkg.getTargetSdkVersion()
                    );
                }
            }
            return signingDetails;
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
        }
    }

    public static SigningDetails collectCertificates(String baseCodePath, boolean skipVerify,
            boolean isStaticSharedLibrary, @NonNull SigningDetails existingSigningDetails,
            int targetSdk) throws PackageParserException {
        int minSignatureScheme = ApkSignatureVerifier.getMinimumSignatureSchemeVersionForTargetSdk(
                targetSdk);
        if (isStaticSharedLibrary) {
            // must use v2 signing scheme
            minSignatureScheme = SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2;
        }
        SigningDetails verified;
        if (skipVerify) {
            // systemDir APKs are already trusted, save time by not verifying
            verified = ApkSignatureVerifier.unsafeGetCertsWithoutVerification(
                    baseCodePath, minSignatureScheme);
        } else {
            verified = ApkSignatureVerifier.verify(baseCodePath, minSignatureScheme);
        }

        // Verify that entries are signed consistently with the first pkg
        // we encountered. Note that for splits, certificates may have
        // already been populated during an earlier parse of a base APK.
        if (existingSigningDetails == SigningDetails.UNKNOWN) {
            return verified;
        } else {
            if (!Signature.areExactMatch(existingSigningDetails.signatures, verified.signatures)) {
                throw new PackageParserException(
                        INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
                        baseCodePath + " has mismatched certificates");
            }

            return existingSigningDetails;
        }
    }

    /*
     The following set of methods makes code easier to read by re-ordering the TypedArray methods.

     The first parameter is the default, which is the most important to understand for someone
     reading through the parsing code.

     That's followed by the attribute name, which is usually irrelevant during reading because
     it'll look like setSomeValue(true, R.styleable.ReallyLongParentName_SomeValueAttr... and
     the "setSomeValue" part is enough to communicate what the line does.

     Last comes the TypedArray, which is by far the least important since each try-with-resources
     should only have 1.
    */

    // Note there is no variant of bool without a defaultValue parameter, since explicit true/false
    // is important to specify when adding an attribute.
    private static boolean bool(boolean defaultValue, @StyleableRes int attribute, TypedArray sa) {
        return sa.getBoolean(attribute, defaultValue);
    }

    private static float aFloat(float defaultValue, @StyleableRes int attribute, TypedArray sa) {
        return sa.getFloat(attribute, defaultValue);
    }

    private static float aFloat(@StyleableRes int attribute, TypedArray sa) {
        return sa.getFloat(attribute, 0f);
    }

    private static int anInt(int defaultValue, @StyleableRes int attribute, TypedArray sa) {
        return sa.getInt(attribute, defaultValue);
    }

    private static int anInt(@StyleableRes int attribute, TypedArray sa) {
        return sa.getInt(attribute, 0);
    }

    @AnyRes
    private static int resId(@StyleableRes int attribute, TypedArray sa) {
        return sa.getResourceId(attribute, 0);
    }

    private static String string(@StyleableRes int attribute, TypedArray sa) {
        return sa.getString(attribute);
    }

    private static String nonConfigString(int allowedChangingConfigs, @StyleableRes int attribute,
            TypedArray sa) {
        return sa.getNonConfigurationString(attribute, allowedChangingConfigs);
    }

    private static String nonResString(@StyleableRes int index, TypedArray sa) {
        return sa.getNonResourceString(index);
    }

    /**
     * Callback interface for retrieving information that may be needed while parsing
     * a package.
     */
    public interface Callback {
        boolean hasFeature(String feature);

        ParsingPackage startParsingPackage(String packageName, String baseCodePath, String codePath,
                TypedArray manifestArray, boolean isCoreApp);
    }
}
