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

Commit d9314af4 authored by Jiakai Zhang's avatar Jiakai Zhang Committed by Android (Google) Code Review
Browse files

Merge "Use ART-managed install files validation API." into main

parents 230a57f9 819e67ce
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -1541,7 +1541,9 @@ final class InstallPackageHelper {
            if (request.getPackageLite() == null || !request.isArchived()) {
                // TODO: pass packageLite from install request instead of reparsing the package
                parsedPackage = pp.parsePackage(tmpPackageFile, parseFlags, false);
                if (!com.android.art.flags.Flags.artManagedInstallFilesValidationApi()) {
                    AndroidPackageUtils.validatePackageDexMetadata(parsedPackage);
                }
                archivedPackage = null;
            } else {
                // Archived install mode, no APK.
+4 −2
Original line number Diff line number Diff line
@@ -160,8 +160,7 @@ final class InstallRequest {
    @NonNull
    private int[] mUpdateBroadcastInstantUserIds = EMPTY_INT_ARRAY;

    @NonNull
    private final ArrayList<String> mWarnings = new ArrayList<>();
    @NonNull private final ArrayList<String> mWarnings;

    @Nullable
    private DomainSet mPreVerifiedDomains;
@@ -198,6 +197,7 @@ final class InstallRequest {
        mDependencyInstallerEnabled = params.mDependencyInstallerEnabled;
        mMissingSharedLibraryCount = params.mMissingSharedLibraryCount;
        mDeveloperVerificationStatus = params.mDeveloperVerificationStatus;
        mWarnings = new ArrayList<>(params.mWarnings);
    }

    // Install existing package as user
@@ -220,6 +220,7 @@ final class InstallRequest {
        mDependencyInstallerEnabled = false;
        mMissingSharedLibraryCount = 0;
        mDeveloperVerificationStatus = null;
        mWarnings = new ArrayList<>();
    }

    // addForInit
@@ -245,6 +246,7 @@ final class InstallRequest {
        mDependencyInstallerEnabled = false;
        mMissingSharedLibraryCount = 0;
        mDeveloperVerificationStatus = null;
        mWarnings = new ArrayList<>();
    }

    @Nullable
+5 −1
Original line number Diff line number Diff line
@@ -108,6 +108,7 @@ class InstallingSession {
    final boolean mDependencyInstallerEnabled;
    final int mMissingSharedLibraryCount;
    @Nullable final DeveloperVerificationStatusInternal mDeveloperVerificationStatus;
    final List<String> mWarnings;

    // For move install
    InstallingSession(OriginInfo originInfo, MoveInfo moveInfo, IPackageInstallObserver2 observer,
@@ -146,6 +147,7 @@ class InstallingSession {
        mDependencyInstallerEnabled = false;
        mMissingSharedLibraryCount = 0;
        mDeveloperVerificationStatus = null;
        mWarnings = new ArrayList<>();
    }

    InstallingSession(int sessionId, File stagedDir, IPackageInstallObserver2 observer,
@@ -154,7 +156,8 @@ class InstallingSession {
            PackageLite packageLite, DomainSet preVerifiedDomains, PackageManagerService pm,
            boolean hasAppMetadatafile, boolean dependencyInstallerEnabled,
            int missingSharedLibraryCount,
            DeveloperVerificationStatusInternal developerVerificationStatus) {
            DeveloperVerificationStatusInternal developerVerificationStatus,
            List<String> warnings) {
        mPm = pm;
        mUser = user;
        mOriginInfo = OriginInfo.fromStagedFile(stagedDir);
@@ -188,6 +191,7 @@ class InstallingSession {
        mDependencyInstallerEnabled = dependencyInstallerEnabled;
        mMissingSharedLibraryCount = missingSharedLibraryCount;
        mDeveloperVerificationStatus = developerVerificationStatus;
        mWarnings = new ArrayList<>(warnings);
    }

    @Override
+51 −2
Original line number Diff line number Diff line
@@ -79,6 +79,7 @@ import static com.android.server.pm.PackageManagerShellCommandDataLoader.Metadat

import android.Manifest;
import android.annotation.AnyThread;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -216,6 +217,7 @@ import com.android.server.IoThread;
import com.android.server.LocalServices;
import com.android.server.Watchdog;
import com.android.server.art.ArtManagedInstallFileHelper;
import com.android.server.art.model.ValidationResult;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.pkg.AndroidPackage;
@@ -237,6 +239,7 @@ import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.security.cert.Certificate;
@@ -927,6 +930,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    @UnarchivalStatus
    private int mUnarchivalStatus = UNARCHIVAL_STATUS_UNSET;

    @GuardedBy("mLock") private final List<String> mWarnings = new ArrayList<>();

    private static final FileFilter sAddedApkFilter = new FileFilter() {
        @Override
        public boolean accept(File file) {
@@ -3999,7 +4004,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            return new InstallingSession(sessionId, stageDir, localObserver, params, mInstallSource,
                    user, mSigningDetails, mInstallerUid, mPackageLite, mPreVerifiedDomains, mPm,
                    mHasAppMetadataFile, mDependencyInstallerEnabled.get(),
                    mMissingSharedLibraryCount.get(), mDeveloperVerificationStatusInternal);
                    mMissingSharedLibraryCount.get(), mDeveloperVerificationStatusInternal,
                    mWarnings);
        }
    }

@@ -4199,6 +4205,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        mResolvedBaseFile = null;
        mResolvedStagedFiles.clear();
        mResolvedInheritedFiles.clear();
        mWarnings.clear();

        final PackageInfo pkgInfo = mPm.snapshotComputer().getPackageInfo(
                params.appPackageName, PackageManager.GET_SIGNATURES
@@ -4309,7 +4316,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            CollectionUtils.addAll(stagedSplitTypes, apk.getSplitTypes());
        }

        if (com.android.art.flags.Flags.artManagedInstallFilesValidationApi()) {
            validateArtManagedInstallFiles(artManagedFilePaths);
        } else {
            verifySdmSignatures(artManagedFilePaths, mSigningDetails);
        }

        if (removeSplitList.size() > 0) {
            if (pkgInfo == null) {
@@ -4907,6 +4918,44 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        return true;
    }

    @FlaggedApi(com.android.art.flags.Flags.FLAG_ART_MANAGED_INSTALL_FILES_VALIDATION_API)
    private void validateArtManagedInstallFiles(List<String> artManagedFilePaths)
            throws PackageManagerException {
        for (ValidationResult result :
                ArtManagedInstallFileHelper.validateFiles(artManagedFilePaths)) {
            switch (result.getCode()) {
                case ValidationResult.RESULT_ACCEPTED -> {
                }
                case ValidationResult.RESULT_UNRECOGNIZED -> {
                    Slog.wtf(TAG,
                            "Unrecognized ART-managed install file path '" + result.getPath()
                                    + "'");
                }
                case ValidationResult.RESULT_SHOULD_DELETE_AND_CONTINUE -> {
                    try {
                        Files.delete(Paths.get(result.getPath()));
                    } catch (IOException e) {
                        throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR,
                                "Failed to delete '" + result.getPath() + "': " + e.getMessage());
                    }
                    mWarnings.add(result.getMessage());
                    mResolvedStagedFiles.removeIf(
                            f -> f.getAbsolutePath().equals(result.getPath()));
                    artManagedFilePaths.remove(result.getPath());
                }
                case ValidationResult.RESULT_SHOULD_FAIL -> {
                    throw new PackageManagerException(
                            INSTALL_FAILED_INVALID_APK, result.getMessage());
                }
                default -> {
                    Slog.wtf(TAG,
                            "ArtManagedInstallFileHelper.validateFiles returned unknown code "
                                    + result.getCode());
                }
            }
        }
    }

    /**
     * Verifies the signatures of SDM files.
     *
+1 −1
Original line number Diff line number Diff line
@@ -1482,7 +1482,7 @@ public class PackageManagerService implements PackageSender, TestUtilityService
                break;
            }
        }
        if (!request.getWarnings().isEmpty()) {
        if (!request.getWarnings().isEmpty() && extras != null) {
            extras.putStringArrayList(PackageInstaller.EXTRA_WARNINGS, request.getWarnings());
        }
        return extras;