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

Commit 3498ce79 authored by Jiakai Zhang's avatar Jiakai Zhang
Browse files

[pm] Use APIs for ART managed install files.

Bug: 377474232
Test: atest CtsPackageManagerTestCases
Change-Id: I0589b9ccf31128e4df56fad411c136a047564c9d
parent 02d89958
Loading
Loading
Loading
Loading
+74 −16
Original line number Diff line number Diff line
@@ -61,6 +61,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;
@@ -186,6 +187,7 @@ import com.android.internal.util.Preconditions;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.LocalServices;
import com.android.server.art.ArtManagedInstallFileHelper;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.pkg.AndroidPackage;
@@ -848,7 +850,11 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            if (file.getName().endsWith(REMOVE_MARKER_EXTENSION)) return false;
            if (file.getName().endsWith(V4Signature.EXT)) return false;
            if (isAppMetadata(file)) return false;
            if (com.android.art.flags.Flags.artServiceV3()) {
                if (ArtManagedInstallFileHelper.isArtManaged(file.getPath())) return false;
            } else {
                if (DexMetadataHelper.isDexMetadataFile(file)) return false;
            }
            if (VerityUtils.isFsveritySignatureFile(file)) return false;
            if (ApkChecksums.isDigestOrDigestSignatureFile(file)) return false;
            return true;
@@ -872,6 +878,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            return true;
        }
    };
    private static final FileFilter sArtManagedFilter = new FileFilter() {
        @Override
        public boolean accept(File file) {
            return !file.isDirectory() && com.android.art.flags.Flags.artServiceV3()
                    && ArtManagedInstallFileHelper.isArtManaged(file.getPath());
        }
    };

    static boolean isDataLoaderInstallation(SessionParams params) {
        return params.dataLoaderParams != null;
@@ -1585,6 +1598,19 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        return filterFiles(stageDir, names, sAddedApkFilter);
    }

    @GuardedBy("mLock")
    private List<String> getArtManagedFilePathsLocked() {
        String[] names = getNamesLocked();
        ArrayList<String> result = new ArrayList<>(names.length);
        for (String name : names) {
            File file = new File(stageDir, name);
            if (sArtManagedFilter.accept(file)) {
                result.add(file.getPath());
            }
        }
        return result;
    }

    @GuardedBy("mLock")
    private void enableFsVerityToAddedApksWithIdsig() throws PackageManagerException {
        try {
@@ -3377,7 +3403,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        }

        final File targetFile = new File(stageDir, targetName);
        resolveAndStageFileLocked(addedFile, targetFile, null);
        resolveAndStageFileLocked(addedFile, targetFile, null, List.of() /* artManagedFilePaths */);
        mResolvedBaseFile = targetFile;

        // Populate package name of the apex session
@@ -3470,6 +3496,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                    TextUtils.formatSimple("Session: %d. No packages staged in %s", sessionId,
                          stageDir.getAbsolutePath()));
        }
        final List<String> artManagedFilePaths = getArtManagedFilePathsLocked();

        // Verify that all staged packages are internally consistent
        final ArraySet<String> stagedSplits = new ArraySet<>();
@@ -3526,7 +3553,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            final File targetFile = new File(stageDir, targetName);
            if (!isArchivedInstallation()) {
                final File sourceFile = new File(apk.getPath());
                resolveAndStageFileLocked(sourceFile, targetFile, apk.getSplitName());
                resolveAndStageFileLocked(
                        sourceFile, targetFile, apk.getSplitName(), artManagedFilePaths);
            }

            // Base is coming from session
@@ -3687,7 +3715,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            // Inherit base if not overridden.
            if (mResolvedBaseFile == null) {
                mResolvedBaseFile = new File(appInfo.getBaseCodePath());
                inheritFileLocked(mResolvedBaseFile);
                inheritFileLocked(mResolvedBaseFile, artManagedFilePaths);
                // Collect the requiredSplitTypes from base
                CollectionUtils.addAll(requiredSplitTypes, existing.getBaseRequiredSplitTypes());
            } else if ((params.installFlags & PackageManager.INSTALL_DONT_KILL_APP) != 0) {
@@ -3706,7 +3734,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                    final boolean splitRemoved = removeSplitList.contains(splitName);
                    final boolean splitReplaced = stagedSplits.contains(splitName);
                    if (!splitReplaced && !splitRemoved) {
                        inheritFileLocked(splitFile);
                        inheritFileLocked(splitFile, artManagedFilePaths);
                        // Collect the requiredSplitTypes and staged splitTypes from splits
                        CollectionUtils.addAll(requiredSplitTypes,
                                existing.getRequiredSplitTypes()[i]);
@@ -3892,6 +3920,23 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                DexMetadataHelper.isFsVerityRequired());
    }

    @FlaggedApi(com.android.art.flags.Flags.FLAG_ART_SERVICE_V3)
    @GuardedBy("mLock")
    private void maybeStageArtManagedInstallFilesLocked(File origFile, File targetFile,
            List<String> artManagedFilePaths) throws PackageManagerException {
        for (String path : ArtManagedInstallFileHelper.filterPathsForApk(
                     artManagedFilePaths, origFile.getPath())) {
            File artManagedFile = new File(path);
            if (!FileUtils.isValidExtFilename(artManagedFile.getName())) {
                throw new PackageManagerException(
                        INSTALL_FAILED_INVALID_APK, "Invalid filename: " + artManagedFile);
            }
            File targetArtManagedFile = new File(
                    ArtManagedInstallFileHelper.getTargetPathForApk(path, targetFile.getPath()));
            stageFileLocked(artManagedFile, targetArtManagedFile);
        }
    }

    private IncrementalFileStorages getIncrementalFileStorages() {
        synchronized (mLock) {
            return mIncrementalFileStorages;
@@ -3989,8 +4034,8 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    }

    @GuardedBy("mLock")
    private void resolveAndStageFileLocked(File origFile, File targetFile, String splitName)
            throws PackageManagerException {
    private void resolveAndStageFileLocked(File origFile, File targetFile, String splitName,
            List<String> artManagedFilePaths) throws PackageManagerException {
        stageFileLocked(origFile, targetFile);

        // Stage APK's fs-verity signature if present.
@@ -4001,8 +4046,13 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
                && VerityUtils.isFsVeritySupported()) {
            maybeStageV4SignatureLocked(origFile, targetFile);
        }
        // Stage dex metadata (.dm) and corresponding fs-verity signature if present.
        // Stage ART managed install files (e.g., dex metadata (.dm)) and corresponding fs-verity
        // signature if present.
        if (com.android.art.flags.Flags.artServiceV3()) {
            maybeStageArtManagedInstallFilesLocked(origFile, targetFile, artManagedFilePaths);
        } else {
            maybeStageDexMetadataLocked(origFile, targetFile);
        }
        // Stage checksums (.digests) if present.
        maybeStageDigestsLocked(origFile, targetFile, splitName);
    }
@@ -4027,7 +4077,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
    }

    @GuardedBy("mLock")
    private void inheritFileLocked(File origFile) {
    private void inheritFileLocked(File origFile, List<String> artManagedFilePaths) {
        mResolvedInheritedFiles.add(origFile);

        maybeInheritFsveritySignatureLocked(origFile);
@@ -4035,13 +4085,21 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
            maybeInheritV4SignatureLocked(origFile);
        }

        // Inherit the dex metadata if present.
        final File dexMetadataFile =
                DexMetadataHelper.findDexMetadataForFile(origFile);
        // Inherit ART managed install files (e.g., dex metadata (.dm)) if present.
        if (com.android.art.flags.Flags.artServiceV3()) {
            for (String path : ArtManagedInstallFileHelper.filterPathsForApk(
                         artManagedFilePaths, origFile.getPath())) {
                File artManagedFile = new File(path);
                mResolvedInheritedFiles.add(artManagedFile);
                maybeInheritFsveritySignatureLocked(artManagedFile);
            }
        } else {
            final File dexMetadataFile = DexMetadataHelper.findDexMetadataForFile(origFile);
            if (dexMetadataFile != null) {
                mResolvedInheritedFiles.add(dexMetadataFile);
                maybeInheritFsveritySignatureLocked(dexMetadataFile);
            }
        }
        // Inherit the digests if present.
        final File digestsFile = ApkChecksums.findDigestsForFile(origFile);
        if (digestsFile != null) {