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

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

Merge "Remove legacy dexopt code from Package Manager." into main

parents 3d7b8f0c 6d255d41
Loading
Loading
Loading
Loading
+0 −19
Original line number Diff line number Diff line
@@ -598,25 +598,6 @@ interface IPackageManager {
     oneway void registerDexModule(in String packageName, in String dexModulePath,
             in boolean isSharedModule, IDexModuleRegisterCallback callback);

    /**
     * Ask the package manager to perform a dex-opt with the given compiler filter.
     *
     * Note: exposed only for the shell command to allow moving packages explicitly to a
     *       definite state.
     */
    boolean performDexOptMode(String packageName, boolean checkProfiles,
            String targetCompilerFilter, boolean force, boolean bootComplete, String splitName);

    /**
     * Ask the package manager to perform a dex-opt with the given compiler filter on the
     * secondary dex files belonging to the given package.
     *
     * Note: exposed only for the shell command to allow moving packages explicitly to a
     *       definite state.
     */
    boolean performDexOptSecondary(String packageName,
            String targetCompilerFilter, boolean force);

    @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
    int getMoveStatus(int moveId);

+1 −117
Original line number Diff line number Diff line
@@ -23,27 +23,18 @@ import android.content.pm.parsing.ApkLiteParseUtils;
import android.content.pm.parsing.PackageLite;
import android.content.pm.parsing.result.ParseInput;
import android.content.pm.parsing.result.ParseResult;
import android.os.SystemProperties;
import android.util.ArrayMap;
import android.util.JsonReader;
import android.util.Log;
import android.util.jar.StrictJarFile;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.security.VerityUtils;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;

/**
 * Helper class used to compute and validate the location of dex metadata files.
@@ -54,34 +45,16 @@ public class DexMetadataHelper {
    public static final String TAG = "DexMetadataHelper";
    /** $> adb shell 'setprop log.tag.DexMetadataHelper VERBOSE' */
    public static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
    /** $> adb shell 'setprop pm.dexopt.dm.require_manifest true' */
    private static final String PROPERTY_DM_JSON_MANIFEST_REQUIRED =
            "pm.dexopt.dm.require_manifest";
    /** $> adb shell 'setprop pm.dexopt.dm.require_fsverity true' */
    private static final String PROPERTY_DM_FSVERITY_REQUIRED = "pm.dexopt.dm.require_fsverity";

    private static final String DEX_METADATA_FILE_EXTENSION = ".dm";

    private DexMetadataHelper() {}

    /** Return true if the given file is a dex metadata file. */
    public static boolean isDexMetadataFile(File file) {
        return isDexMetadataPath(file.getName());
    }

    /** Return true if the given path is a dex metadata path. */
    private static boolean isDexMetadataPath(String path) {
        return path.endsWith(DEX_METADATA_FILE_EXTENSION);
    }

    /**
     * Returns whether fs-verity is required to install a dex metadata
     */
    public static boolean isFsVerityRequired() {
        return VerityUtils.isFsVeritySupported()
                && SystemProperties.getBoolean(PROPERTY_DM_FSVERITY_REQUIRED, false);
    }

    /**
     * Return the size (in bytes) of all dex metadata files associated with the given package.
     */
@@ -94,20 +67,6 @@ public class DexMetadataHelper {
        return sizeBytes;
    }

    /**
     * Search for the dex metadata file associated with the given target file.
     * If it exists, the method returns the dex metadata file; otherwise it returns null.
     *
     * Note that this performs a loose matching suitable to be used in the InstallerSession logic.
     * i.e. the method will attempt to match the {@code dmFile} regardless of {@code targetFile}
     * extension (e.g. 'foo.dm' will match 'foo' or 'foo.apk').
     */
    public static File findDexMetadataForFile(File targetFile) {
        String dexMetadataPath = buildDexMetadataPathForFile(targetFile);
        File dexMetadataFile = new File(dexMetadataPath);
        return dexMetadataFile.exists() ? dexMetadataFile : null;
    }

    /**
     * Return the dex metadata files for the given package as a map
     * [code path -> dex metadata path].
@@ -180,13 +139,6 @@ public class DexMetadataHelper {
     */
    public static ParseResult validateDexMetadataFile(ParseInput input, String dmaPath,
            String packageName, long versionCode) {
        return validateDexMetadataFile(input, dmaPath, packageName, versionCode,
               SystemProperties.getBoolean(PROPERTY_DM_JSON_MANIFEST_REQUIRED, false));
    }

    @VisibleForTesting
    public static ParseResult validateDexMetadataFile(ParseInput input, String dmaPath,
            String packageName, long versionCode, boolean requireManifest) {
        StrictJarFile jarFile = null;

        if (DEBUG) {
@@ -196,8 +148,7 @@ public class DexMetadataHelper {

        try {
            jarFile = new StrictJarFile(dmaPath, false, false);
            return validateDexMetadataManifest(input, dmaPath, jarFile, packageName, versionCode,
                    requireManifest);
            return input.success(null);
        } catch (IOException e) {
            return input.error(INSTALL_FAILED_BAD_DEX_METADATA, "Error opening " + dmaPath, e);
        } finally {
@@ -210,73 +161,6 @@ public class DexMetadataHelper {
        }
    }

    /** Ensure that packageName and versionCode match the manifest.json in the .dm file */
    private static ParseResult validateDexMetadataManifest(ParseInput input, String dmaPath,
            StrictJarFile jarFile, String packageName, long versionCode, boolean requireManifest)
            throws IOException {
        if (!requireManifest) {
            if (DEBUG) {
                Log.v(TAG, "validateDexMetadataManifest: " + dmaPath
                        + " manifest.json check skipped");
            }
            return input.success(null);
        }

        ZipEntry zipEntry = jarFile.findEntry("manifest.json");
        if (zipEntry == null) {
            return input.error(INSTALL_FAILED_BAD_DEX_METADATA,
                    "Missing manifest.json in " + dmaPath);
        }
        InputStream inputStream = jarFile.getInputStream(zipEntry);

        JsonReader reader;
        try {
          reader = new JsonReader(new InputStreamReader(inputStream, "UTF-8"));
        } catch (UnsupportedEncodingException e) {
            return input.error(INSTALL_FAILED_BAD_DEX_METADATA,
                    "Error opening manifest.json in " + dmaPath, e);
        }
        String jsonPackageName = null;
        long jsonVersionCode = -1;

        reader.beginObject();
        while (reader.hasNext()) {
            String name = reader.nextName();
            if (name.equals("packageName")) {
                jsonPackageName = reader.nextString();
            } else if (name.equals("versionCode")) {
                jsonVersionCode = reader.nextLong();
            } else {
                reader.skipValue();
            }
        }
        reader.endObject();

        if (jsonPackageName == null || jsonVersionCode == -1) {
            return input.error(INSTALL_FAILED_BAD_DEX_METADATA,
                    "manifest.json in " + dmaPath
                    + " is missing 'packageName' and/or 'versionCode'");
        }

        if (!jsonPackageName.equals(packageName)) {
            return input.error(INSTALL_FAILED_BAD_DEX_METADATA,
                    "manifest.json in " + dmaPath + " has invalid packageName: " + jsonPackageName
                    + ", expected: " + packageName);
        }

        if (versionCode != jsonVersionCode) {
            return input.error(INSTALL_FAILED_BAD_DEX_METADATA,
                    "manifest.json in " + dmaPath + " has invalid versionCode: " + jsonVersionCode
                    + ", expected: " + versionCode);
        }

        if (DEBUG) {
            Log.v(TAG, "validateDexMetadataManifest: " + dmaPath + ", " + packageName +
                    ", " + versionCode + ": successful");
        }
        return input.success(null);
    }

    /**
     * Validates that all dex metadata paths in the given list have a matching apk.
     * (for any foo.dm there should be either a 'foo' of a 'foo.apk' file).
+0 −1
Original line number Diff line number Diff line
@@ -607,7 +607,6 @@ public class AppDataHelper {
            } catch (Installer.InstallerException e) {
                Slog.w(TAG, String.valueOf(e));
            }
            mPm.getDexManager().notifyPackageDataDestroyed(packageName, userId);
            mPm.getDynamicCodeLogger().notifyPackageDataDestroyed(packageName, userId);
        }
    }
+0 −3
Original line number Diff line number Diff line
@@ -637,9 +637,6 @@ public interface Computer extends PackageDataSnapshot {
    @NonNull
    String[] getSharedUserPackagesForPackage(@NonNull String packageName, @UserIdInt int userId);

    @NonNull
    Set<String> getUnusedPackages(long downgradeTimeThresholdMillis);

    @Nullable
    CharSequence getHarmfulAppWarning(@NonNull String packageName, @UserIdInt int userId);

+0 −32
Original line number Diff line number Diff line
@@ -140,8 +140,6 @@ import com.android.internal.util.Preconditions;
import com.android.modules.utils.TypedXmlSerializer;
import com.android.server.LocalManagerRegistry;
import com.android.server.ondeviceintelligence.OnDeviceIntelligenceManagerLocal;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.dex.PackageDexUsage;
import com.android.server.pm.parsing.PackageInfoUtils;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
@@ -419,8 +417,6 @@ public class ComputerEngine implements Computer {
    private final InstantAppResolverConnection mInstantAppResolverConnection;
    private final DefaultAppProvider mDefaultAppProvider;
    private final DomainVerificationManagerInternal mDomainVerificationManager;
    private final PackageDexOptimizer mPackageDexOptimizer;
    private final DexManager mDexManager;
    private final CompilerStats mCompilerStats;
    private final PackageManagerInternal.ExternalSourcesPolicy mExternalSourcesPolicy;
    private final CrossProfileIntentResolverEngine mCrossProfileIntentResolverEngine;
@@ -471,8 +467,6 @@ public class ComputerEngine implements Computer {
        mInstantAppResolverConnection = args.service.mInstantAppResolverConnection;
        mDefaultAppProvider = args.service.getDefaultAppProvider();
        mDomainVerificationManager = args.service.mDomainVerificationManager;
        mPackageDexOptimizer = args.service.mPackageDexOptimizer;
        mDexManager = args.service.getDexManager();
        mCompilerStats = args.service.mCompilerStats;
        mExternalSourcesPolicy = args.service.mExternalSourcesPolicy;
        mCrossProfileIntentResolverEngine = new CrossProfileIntentResolverEngine(
@@ -5689,32 +5683,6 @@ public class ComputerEngine implements Computer {
        return res != null ? res : EmptyArray.STRING;
    }


    @NonNull
    @Override
    public Set<String> getUnusedPackages(long downgradeTimeThresholdMillis) {
        Set<String> unusedPackages = new ArraySet<>();
        long currentTimeInMillis = System.currentTimeMillis();
        final ArrayMap<String, ? extends PackageStateInternal> packageStates =
                mSettings.getPackages();
        for (int index = 0; index < packageStates.size(); index++) {
            final PackageStateInternal packageState = packageStates.valueAt(index);
            if (packageState.getPkg() == null) {
                continue;
            }
            PackageDexUsage.PackageUseInfo packageUseInfo =
                    mDexManager.getPackageUseInfoOrDefault(packageState.getPackageName());
            if (PackageManagerServiceUtils.isUnusedSinceTimeInMillis(
                    PackageStateUtils.getEarliestFirstInstallTime(packageState.getUserStates()),
                    currentTimeInMillis, downgradeTimeThresholdMillis, packageUseInfo,
                    packageState.getTransientState().getLatestPackageUseTimeInMills(),
                    packageState.getTransientState().getLatestForegroundPackageUseTimeInMills())) {
                unusedPackages.add(packageState.getPackageName());
            }
        }
        return unusedPackages;
    }

    @Nullable
    @Override
    public CharSequence getHarmfulAppWarning(@NonNull String packageName, @UserIdInt int userId) {
Loading