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

Commit ea6e9c69 authored by Winson Chiu's avatar Winson Chiu
Browse files

Remove ParsingPackageRead

This was only really in effect for one signatures utility, but makes the
interface hierarchy much more confusing, so this removes it and just readjusts
the utility to take in different types.

Test: atest AppsFilterImplTest
Test: atest PackageManagerTests
Test: atest PackageParserTest
Test: atest PackageParserLegacyCoreTest
Test: atest PackageParsingDeferErrorTest
Test: atest AppIntegrityManagerServiceImplTest
Test: atest GtsAppIntegrityManagerTests
Test: atest CtsAppIntegrityDeviceTestCases

Change-Id: I59c0a7ed2237b2c094fe8088f853ca0ddc80ee97
parent dc151ad1
Loading
Loading
Loading
Loading
+40 −56
Original line number Diff line number Diff line
@@ -44,7 +44,6 @@ import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
import android.content.pm.Signature;
import android.content.pm.SigningDetails;
import android.content.pm.SigningInfo;
import android.content.pm.parsing.result.ParseResult;
import android.content.pm.parsing.result.ParseTypeImpl;
import android.net.Uri;
@@ -52,23 +51,21 @@ import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.UserHandle;
import android.provider.Settings;
import android.util.Pair;
import android.util.Slog;
import android.util.apk.SourceStampVerificationResult;
import android.util.apk.SourceStampVerifier;

import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.LocalServices;
import com.android.server.integrity.engine.RuleEvaluationEngine;
import com.android.server.integrity.model.IntegrityCheckResult;
import com.android.server.integrity.model.RuleMetadata;
import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.PackageParser2;
import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.pkg.PackageUserStateInternal;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;

import java.io.ByteArrayInputStream;
@@ -297,8 +294,9 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {

            String packageName = intent.getStringExtra(EXTRA_PACKAGE_NAME);

            PackageInfo packageInfo = getPackageArchiveInfo(intent.getData());
            if (packageInfo == null) {
            Pair<SigningDetails, Bundle> packageSigningAndMetadata =
                    getPackageSigningAndMetadata(intent.getData());
            if (packageSigningAndMetadata == null) {
                Slog.w(TAG, "Cannot parse package " + packageName);
                // We can't parse the package.
                mPackageManagerInternal.setIntegrityVerificationResult(
@@ -306,8 +304,9 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
                return;
            }

            List<String> appCertificates = getCertificateFingerprint(packageInfo);
            List<String> appCertificateLineage = getCertificateLineage(packageInfo);
            var signingDetails = packageSigningAndMetadata.first;
            List<String> appCertificates = getCertificateFingerprint(packageName, signingDetails);
            List<String> appCertificateLineage = getCertificateLineage(packageName, signingDetails);
            List<String> installerCertificates =
                    getInstallerCertificateFingerprint(installerPackageName);

@@ -320,7 +319,10 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
            builder.setInstallerName(getPackageNameNormalized(installerPackageName));
            builder.setInstallerCertificates(installerCertificates);
            builder.setIsPreInstalled(isSystemApp(packageName));
            builder.setAllowedInstallersAndCert(getAllowedInstallers(packageInfo));

            Map<String, String> allowedInstallers =
                    getAllowedInstallers(packageSigningAndMetadata.second);
            builder.setAllowedInstallersAndCert(allowedInstallers);
            extractSourceStamp(intent.getData(), builder);

            AppInstallMetadata appInstallMetadata = builder.build();
@@ -331,7 +333,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
                        "To be verified: "
                                + appInstallMetadata
                                + " installers "
                                + getAllowedInstallers(packageInfo));
                                + allowedInstallers);
            }
            IntegrityCheckResult result = mEvaluationEngine.evaluate(appInstallMetadata);
            if (!result.getMatchedRules().isEmpty() || DEBUG_INTEGRITY_COMPONENT) {
@@ -443,38 +445,37 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
        if (installer.equals(ADB_INSTALLER) || installer.equals(UNKNOWN_INSTALLER)) {
            return Collections.emptyList();
        }
        try {
            PackageInfo installerInfo =
                    mContext.getPackageManager()
                            .getPackageInfo(installer, PackageManager.GET_SIGNING_CERTIFICATES);
            return getCertificateFingerprint(installerInfo);
        } catch (PackageManager.NameNotFoundException e) {
        var installerPkg = mPackageManagerInternal.getPackage(installer);
        if (installerPkg == null) {
            Slog.w(TAG, "Installer package " + installer + " not found.");
            return Collections.emptyList();
        }
        return getCertificateFingerprint(installerPkg.getPackageName(),
                installerPkg.getSigningDetails());
    }

    private List<String> getCertificateFingerprint(@NonNull PackageInfo packageInfo) {
    private List<String> getCertificateFingerprint(@NonNull String packageName,
            @NonNull SigningDetails signingDetails) {
        ArrayList<String> certificateFingerprints = new ArrayList();
        for (Signature signature : getSignatures(packageInfo)) {
        for (Signature signature : getSignatures(packageName, signingDetails)) {
            certificateFingerprints.add(getFingerprint(signature));
        }
        return certificateFingerprints;
    }

    private List<String> getCertificateLineage(@NonNull PackageInfo packageInfo) {
    private List<String> getCertificateLineage(@NonNull String packageName,
            @NonNull SigningDetails signingDetails) {
        ArrayList<String> certificateLineage = new ArrayList();
        for (Signature signature : getSignatureLineage(packageInfo)) {
        for (Signature signature : getSignatureLineage(packageName, signingDetails)) {
            certificateLineage.add(getFingerprint(signature));
        }
        return certificateLineage;
    }

    /** Get the allowed installers and their associated certificate hashes from <meta-data> tag. */
    private Map<String, String> getAllowedInstallers(@NonNull PackageInfo packageInfo) {
    private Map<String, String> getAllowedInstallers(@Nullable Bundle metaData) {
        Map<String, String> packageCertMap = new HashMap<>();
        if (packageInfo.applicationInfo != null && packageInfo.applicationInfo.metaData != null) {
            Bundle metaData = packageInfo.applicationInfo.metaData;
        if (metaData != null) {
            String allowedInstallers = metaData.getString(ALLOWED_INSTALLERS_METADATA_NAME);
            if (allowedInstallers != null) {
                // parse the metadata for certs.
@@ -540,32 +541,25 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
        }
    }

    private static Signature[] getSignatures(@NonNull PackageInfo packageInfo) {
        SigningInfo signingInfo = packageInfo.signingInfo;

        if (signingInfo == null || signingInfo.getApkContentsSigners().length < 1) {
            throw new IllegalArgumentException("Package signature not found in " + packageInfo);
    private static Signature[] getSignatures(@NonNull String packageName,
            @NonNull SigningDetails signingDetails) {
        Signature[] signatures = signingDetails.getSignatures();
        if (signatures == null || signatures.length < 1) {
            throw new IllegalArgumentException("Package signature not found in " + packageName);
        }

        // We are only interested in evaluating the active signatures.
        return signingInfo.getApkContentsSigners();
    }

    private static Signature[] getSignatureLineage(@NonNull PackageInfo packageInfo) {
        // Obtain the signing info of the package.
        SigningInfo signingInfo = packageInfo.signingInfo;
        if (signingInfo == null) {
            throw new IllegalArgumentException(
                    "Package signature not found in " + packageInfo);
        return signatures;
    }

    private static Signature[] getSignatureLineage(@NonNull String packageName,
            @NonNull SigningDetails signingDetails) {
        // Obtain the active signatures of the package.
        Signature[] signatureLineage = getSignatures(packageInfo);
        Signature[] signatureLineage = getSignatures(packageName, signingDetails);

        var pastSignatures = signingDetails.getPastSigningCertificates();
        // Obtain the past signatures of the package.
        if (!signingInfo.hasMultipleSigners() && signingInfo.hasPastSigningCertificates()) {
            Signature[] pastSignatures = signingInfo.getSigningCertificateHistory();

        if (signatureLineage.length == 1 && !ArrayUtils.isEmpty(pastSignatures)) {
            // Merge the signatures and return.
            Signature[] allSignatures =
                    new Signature[signatureLineage.length + pastSignatures.length];
@@ -614,15 +608,15 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
        }
    }

    private PackageInfo getPackageArchiveInfo(Uri dataUri) {
    @Nullable
    private Pair<SigningDetails, Bundle> getPackageSigningAndMetadata(Uri dataUri) {
        File installationPath = getInstallationPath(dataUri);
        if (installationPath == null) {
            throw new IllegalArgumentException("Installation path is null, package not found");
        }

        try (PackageParser2 parser = mParserSupplier.get()) {
            ParsedPackage pkg = parser.parsePackage(installationPath, 0, false);
            int flags = PackageManager.GET_SIGNING_CERTIFICATES | PackageManager.GET_META_DATA;
            var pkg = parser.parsePackage(installationPath, 0, false);
            // APK signatures is already verified elsewhere in PackageManager. We do not need to
            // verify it again since it could cause a timeout for large APKs.
            final ParseTypeImpl input = ParseTypeImpl.forDefaultParsing();
@@ -632,17 +626,7 @@ public class AppIntegrityManagerServiceImpl extends IAppIntegrityManager.Stub {
                Slog.w(TAG, result.getErrorMessage(), result.getException());
                return null;
            }
            pkg.setSigningDetails(result.getResult());
            return PackageInfoUtils.generate(
                    pkg,
                    null,
                    flags,
                    0,
                    0,
                    null,
                    PackageUserStateInternal.DEFAULT,
                    UserHandle.getCallingUserId(),
                    null);
            return Pair.create(result.getResult(), pkg.getMetaData());
        } catch (Exception e) {
            Slog.w(TAG, "Exception reading " + dataUri, e);
            return null;
+3 −4
Original line number Diff line number Diff line
@@ -75,7 +75,6 @@ import com.android.server.pm.pkg.component.ParsedProcess;
import com.android.server.pm.pkg.component.ParsedProvider;
import com.android.server.pm.pkg.component.ParsedService;
import com.android.server.pm.pkg.component.ParsedUsesPermission;
import com.android.server.pm.pkg.parsing.ParsingPackageRead;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
import com.android.server.pm.pkg.parsing.ParsingUtils;

@@ -142,7 +141,7 @@ public class PackageInfoUtils {
        PackageInfo info = new PackageInfo();
        info.packageName = pkg.getPackageName();
        info.splitNames = pkg.getSplitNames();
        ParsingPackageUtils.fillVersionCodes(pkg, info);
        AndroidPackageUtils.fillVersionCodes(pkg, info);
        info.baseRevisionCode = pkg.getBaseRevisionCode();
        info.splitRevisionCodes = pkg.getSplitRevisionCodes();
        info.versionName = pkg.getVersionName();
@@ -462,7 +461,7 @@ public class PackageInfoUtils {
        }

        // Make shallow copy so we can store the metadata/libraries safely
        ApplicationInfo info = ParsingPackageUtils.toAppInfoWithoutState(pkg);
        ApplicationInfo info = AndroidPackageUtils.toAppInfoWithoutState(pkg);

        updateApplicationInfo(info, flags, state);

@@ -1100,7 +1099,7 @@ public class PackageInfoUtils {
    }

    @NonNull
    public static File getDataDir(ParsingPackageRead pkg, int userId) {
    public static File getDataDir(AndroidPackage pkg, int userId) {
        if ("android".equals(pkg.getPackageName())) {
            return Environment.getDataSystemDirectory();
        }
+1141 −4

File changed.

Preview size limit exceeded, changes collapsed.

+16 −11
Original line number Diff line number Diff line
@@ -19,16 +19,11 @@ package com.android.server.pm.parsing.pkg;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.VersionedPackage;
import android.content.pm.dex.DexMetadataHelper;
import com.android.server.pm.pkg.parsing.ParsingPackageRead;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
import com.android.server.pm.pkg.component.ParsedActivity;
import com.android.server.pm.pkg.component.ParsedInstrumentation;
import com.android.server.pm.pkg.component.ParsedProvider;
import com.android.server.pm.pkg.component.ParsedService;
import android.content.pm.parsing.result.ParseResult;
import android.content.pm.parsing.result.ParseTypeImpl;
import android.os.incremental.IncrementalManager;
@@ -38,7 +33,13 @@ import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.util.ArrayUtils;
import com.android.server.SystemConfig;
import com.android.server.pm.PackageManagerException;
import com.android.server.pm.pkg.AndroidPackageApi;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.pkg.component.ParsedActivity;
import com.android.server.pm.pkg.component.ParsedInstrumentation;
import com.android.server.pm.pkg.component.ParsedProvider;
import com.android.server.pm.pkg.component.ParsedService;
import com.android.server.pm.pkg.parsing.ParsingPackageHidden;

import java.io.IOException;
import java.util.ArrayList;
@@ -259,11 +260,6 @@ public class AndroidPackageUtils {
        return ApplicationInfo.HIDDEN_API_ENFORCEMENT_ENABLED;
    }

    public static int getIcon(ParsingPackageRead pkg) {
        return (ParsingPackageUtils.sUseRoundIcon && pkg.getRoundIconRes() != 0)
                ? pkg.getRoundIconRes() : pkg.getIconRes();
    }

    /**
     * Returns false iff the provided flags include the {@link PackageManager#MATCH_SYSTEM_ONLY}
     * flag and the provided package is not a system package. Otherwise returns {@code true}.
@@ -338,4 +334,13 @@ public class AndroidPackageUtils {

        return pkg.getManifestPackageName();
    }

    public static void fillVersionCodes(@NonNull AndroidPackage pkg, @NonNull PackageInfo info) {
        info.versionCode = ((ParsingPackageHidden) pkg).getVersionCode();
        info.versionCodeMajor = ((ParsingPackageHidden) pkg).getVersionCodeMajor();
    }

    public static ApplicationInfo toAppInfoWithoutState(AndroidPackageApi pkg) {
        return ((ParsingPackageHidden) pkg).toAppInfoWithoutState();
    }
}
+1 −8
Original line number Diff line number Diff line
@@ -82,7 +82,6 @@ import com.android.server.pm.pkg.component.ParsedUsesPermission;
import com.android.server.pm.pkg.component.ParsedUsesPermissionImpl;
import com.android.server.pm.pkg.parsing.ParsingPackage;
import com.android.server.pm.pkg.parsing.ParsingPackageHidden;
import com.android.server.pm.pkg.parsing.ParsingPackageRead;
import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
import com.android.server.pm.pkg.parsing.ParsingUtils;

@@ -370,7 +369,7 @@ public class PackageImpl implements ParsedPackage, AndroidPackage,
    @DataClass.ParcelWith(ForInternedString.class)
    private String zygotePreloadName;
    /**
     * @see ParsingPackageRead#getResizeableActivity()
     * @see AndroidPackage#getResizeableActivity()
     */
    @Nullable
    @DataClass.ParcelWith(Parcelling.BuiltIn.ForBoolean.class)
@@ -1182,9 +1181,6 @@ public class PackageImpl implements ParsedPackage, AndroidPackage,
        return requiresSmallestWidthDp;
    }

    /**
     * @see ParsingPackageRead#getResizeableActivity()
     */
    @Nullable
    @Override
    public Boolean getResizeableActivity() {
@@ -2191,9 +2187,6 @@ public class PackageImpl implements ParsedPackage, AndroidPackage,
        return this;
    }

    /**
     * @see ParsingPackageRead#getResizeableActivity()
     */
    @Override
    public PackageImpl setResizeableActivity(@Nullable Boolean value) {
        resizeableActivity = value;
Loading