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

Commit ec09ad29 authored by Jiakai Zhang's avatar Jiakai Zhang
Browse files

Remove DexManager.

DexManager used to manage secondary dex use, which is now managed by ART
Service, so there is nothing for it to manage anymore.

This CL inlines some of its code, moves some to DexOptHelper, and
renames the rest to InstallScenarioHelper.

Bug: 258223472
Test: atest FrameworksServicesTests FrameworksMockingServicesTests
Test: Presubmit
Flag: EXEMPT cleanup
Change-Id: Ief7e3044980c32095a3a7b727fe854d076b3b1a0
parent 7faa0e66
Loading
Loading
Loading
Loading
+50 −39
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;
import android.util.Slog;
import android.util.jar.StrictJarFile;

import com.android.internal.logging.MetricsLogger;
import com.android.internal.util.FrameworkStatsLog;
@@ -75,7 +76,7 @@ import com.android.server.art.model.ArtFlags;
import com.android.server.art.model.DexoptParams;
import com.android.server.art.model.DexoptResult;
import com.android.server.pinner.PinnerService;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.dex.InstallScenarioHelper;
import com.android.server.pm.dex.DexoptOptions;
import com.android.server.pm.local.PackageManagerLocalImpl;
import com.android.server.pm.pkg.AndroidPackage;
@@ -83,6 +84,7 @@ import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;

import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
@@ -91,6 +93,7 @@ import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
@@ -98,6 +101,7 @@ import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.function.Predicate;
import java.util.zip.ZipEntry;

/**
 * Helper class for dex optimization operations in PackageManagerService.
@@ -113,6 +117,7 @@ public final class DexOptHelper {
    private static boolean sArtManagerLocalIsInitialized = false;

    private final PackageManagerService mPm;
    private final InstallScenarioHelper mInstallScenarioHelper;

    // Start time for the boot dexopt in performPackageDexOptUpgradeIfNeeded when ART Service is
    // used, to make it available to the onDexoptDone callback.
@@ -125,6 +130,7 @@ public final class DexOptHelper {

    DexOptHelper(PackageManagerService pm) {
        mPm = pm;
        mInstallScenarioHelper = new InstallScenarioHelper(mPm.mContext);
    }

    /**
@@ -396,8 +402,7 @@ public final class DexOptHelper {
    }

    /** Returns DexoptOptions by the given InstallRequest. */
    private static DexoptOptions getDexoptOptionsByInstallRequest(
            InstallRequest installRequest, DexManager dexManager) {
    private DexoptOptions getDexoptOptionsByInstallRequest(InstallRequest installRequest) {
        final PackageSetting ps = installRequest.getScannedPackageSetting();
        final String packageName = ps.getPackageName();
        final boolean isBackupOrRestore =
@@ -409,7 +414,7 @@ public final class DexOptHelper {
                | (isBackupOrRestore ? DexoptOptions.DEXOPT_FOR_RESTORE : 0);
        // Compute the compilation reason from the installation scenario.
        final int compilationReason =
                dexManager.getCompilationReasonForInstallScenario(
                mInstallScenarioHelper.getCompilationReasonForInstallScenario(
                        installRequest.getInstallScenario());
        final AndroidPackage pkg = ps.getPkg();
        var options = new DexoptOptions(packageName, compilationReason, dexoptFlags);
@@ -421,39 +426,8 @@ public final class DexOptHelper {
        return options;
    }

    /** Perform dexopt if needed for the installation */
    static void performDexoptIfNeeded(
            InstallRequest installRequest,
            DexManager dexManager,
            PackageManagerTracedLock.RawLock installLock) {
        if (!shouldCallArtService(installRequest)) {
            return;
        }

        // dexopt can take long, and ArtService doesn't require installd, so we release the lock
        // here and re-acquire the lock after dexopt is finished.
        if (installLock != null) {
            installLock.unlock();
        }
        try {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
            DexoptOptions dexoptOptions =
                    getDexoptOptionsByInstallRequest(installRequest, dexManager);
            // Don't fail application installs if the dexopt step fails.
            DexoptResult dexOptResult =
                    DexOptHelper.dexoptPackageUsingArtService(installRequest, dexoptOptions);
            installRequest.onDexoptFinished(dexOptResult);
        } finally {
            Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
            if (installLock != null) {
                installLock.lock();
            }
        }
    }

    /** Same as above, but runs asynchronously. */
    static CompletableFuture<Void> performDexoptIfNeededAsync(
            InstallRequest installRequest, DexManager dexManager) {
    /** Perform dexopt asynchronously if needed for the installation. */
    CompletableFuture<Void> performDexoptIfNeededAsync(InstallRequest installRequest) {
        if (!shouldCallArtService(installRequest)) {
            return CompletableFuture.completedFuture(null);
        }
@@ -463,8 +437,7 @@ public final class DexOptHelper {
                            try {
                                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
                                DexoptOptions dexoptOptions =
                                        getDexoptOptionsByInstallRequest(
                                                installRequest, dexManager);
                                        getDexoptOptionsByInstallRequest(installRequest);
                                // Don't fail application installs if the dexopt step fails.
                                // TODO(b/393076925): Make this async in ART Service.
                                DexoptResult dexOptResult =
@@ -543,6 +516,44 @@ public final class DexOptHelper {
        return !instantApp && pkg != null && !isApex && performDexOptForRollback;
    }

    /**
     * Returns true if the archive located at {@code fileName} has uncompressed dex file that can be
     * directly mapped.
     */
    public static boolean checkUncompressedDexInApk(String fileName) {
        StrictJarFile jarFile = null;
        try {
            jarFile = new StrictJarFile(fileName,
                    false /*verify*/, false /*signatureSchemeRollbackProtectionsEnforced*/);
            Iterator<ZipEntry> it = jarFile.iterator();
            boolean allCorrect = true;
            while (it.hasNext()) {
                ZipEntry entry = it.next();
                if (entry.getName().endsWith(".dex")) {
                    if (entry.getMethod() != ZipEntry.STORED) {
                        allCorrect = false;
                        Slog.w(TAG, "APK " + fileName + " has compressed dex code " +
                                entry.getName());
                    } else if ((entry.getDataOffset() & 0x3) != 0) {
                        allCorrect = false;
                        Slog.w(TAG, "APK " + fileName + " has unaligned dex code " +
                                entry.getName());
                    }
                }
            }
            return allCorrect;
        } catch (IOException ignore) {
            Slog.wtf(TAG, "Error when parsing APK " + fileName);
            return false;
        } finally {
            try {
                if (jarFile != null) {
                    jarFile.close();
                }
            } catch (IOException ignore) {}
        }
    }

    private static class StagedApexObserver extends IStagedApexObserver.Stub {
        private final @NonNull ArtManagerLocal mArtManager;

+1 −4
Original line number Diff line number Diff line
@@ -175,7 +175,6 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;
import com.android.server.EventLogTags;
import com.android.server.criticalevents.CriticalEventLog;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.parsing.PackageCacher;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.permission.Permission;
@@ -222,7 +221,6 @@ final class InstallPackageHelper {
    private final DeletePackageHelper mDeletePackageHelper;
    private final IncrementalManager mIncrementalManager;
    private final ApexManager mApexManager;
    private final DexManager mDexManager;
    private final Context mContext;
    private final PackageAbiHelper mPackageAbiHelper;
    private final SharedLibrariesImpl mSharedLibraries;
@@ -251,7 +249,6 @@ final class InstallPackageHelper {
        mDeletePackageHelper = deletePackageHelper;
        mIncrementalManager = pm.mInjector.getIncrementalManager();
        mApexManager = pm.mInjector.getApexManager();
        mDexManager = pm.mInjector.getDexManager();
        mContext = pm.mInjector.getContext();
        mPackageAbiHelper = pm.mInjector.getAbiHelper();
        mSharedLibraries = pm.mInjector.getSharedLibrariesImpl();
@@ -1223,7 +1220,7 @@ final class InstallPackageHelper {
            request.setKeepArtProfile(true);

            CompletableFuture<Void> future =
                    DexOptHelper.performDexoptIfNeededAsync(request, mDexManager);
                    mPm.getDexOptHelper().performDexoptIfNeededAsync(request);
            completableFutures.add(future);
            request.onWaitDexoptStarted();
        }
+1 −2
Original line number Diff line number Diff line
@@ -219,7 +219,6 @@ 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;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.pm.verify.developer.DeveloperVerificationStatusInternal;
@@ -4592,7 +4591,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
        if (packageLite.isUseEmbeddedDex()) {
            for (File file : mResolvedStagedFiles) {
                if (file.getName().endsWith(".apk")
                        && !DexManager.auditUncompressedDexInApk(file.getPath())) {
                        && !DexOptHelper.checkUncompressedDexInApk(file.getPath())) {
                    throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
                            "Some dex are not uncompressed and aligned correctly for "
                            + mPackageName);
+0 −2
Original line number Diff line number Diff line
@@ -55,7 +55,6 @@ import android.util.SparseArray;

import com.android.internal.pm.pkg.component.ParsedMainComponent;
import com.android.internal.util.ArrayUtils;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageStateInternal;
@@ -93,7 +92,6 @@ abstract class PackageManagerInternalBase extends PackageManagerInternal {
    @NonNull protected abstract UserNeedsBadgingCache getUserNeedsBadging();
    @NonNull protected abstract InstantAppRegistry getInstantAppRegistry();
    @NonNull protected abstract ApexManager getApexManager();
    @NonNull protected abstract DexManager getDexManager();

    @Override
    public final Computer snapshot() {
+2 −21
Original line number Diff line number Diff line
@@ -223,7 +223,6 @@ import com.android.server.crashrecovery.CrashRecoveryAdaptor;
import com.android.server.pm.Installer.InstallerException;
import com.android.server.pm.Settings.VersionInfo;
import com.android.server.pm.dex.ArtManagerService;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.dex.DynamicCodeLogger;
import com.android.server.pm.local.PackageManagerLocalImpl;
import com.android.server.pm.parsing.PackageCacher;
@@ -824,9 +823,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
    final PackageInstallerService mInstallerService;
    final ArtManagerService mArtManagerService;

    // DexManager handles the usage of dex files (e.g. secondary files, whether or not a package
    // is used by other apps).
    private final DexManager mDexManager;
    private final DynamicCodeLogger mDynamicCodeLogger;

    private final AtomicInteger mNextMoveId = new AtomicInteger();
@@ -1728,7 +1724,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
                        i.getLocalService(PackageManagerInternal.class)),
                (i, pm) -> (PlatformCompat) ServiceManager.getService("platform_compat"),
                (i, pm) -> SystemConfig.getInstance(),
                (i, pm) -> new DexManager(i.getContext()),
                (i, pm) -> new DynamicCodeLogger(i.getInstaller()),
                (i, pm) -> new ArtManagerService(i.getContext(), i.getInstaller(),
                        i.getInstallLock()),
@@ -1910,7 +1905,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        mDefParseFlags = testParams.defParseFlags;
        mDefaultAppProvider = testParams.defaultAppProvider;
        mLegacyPermissionManager = testParams.legacyPermissionManagerInternal;
        mDexManager = testParams.dexManager;
        mDynamicCodeLogger = testParams.dynamicCodeLogger;
        mFactoryTest = testParams.factoryTest;
        mIncrementalManager = testParams.incrementalManager;
@@ -2127,7 +2121,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
            mSeparateProcesses = null;
        }

        mDexManager = injector.getDexManager();
        mDynamicCodeLogger = injector.getDynamicCodeLogger();
        mArtManagerService = injector.getArtManagerService();
        mMoveCallbacks = new MovePackageHelper.MoveCallbacks(FgThread.get().getLooper());
@@ -3092,10 +3085,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
        }
    }

    /*package*/ DexManager getDexManager() {
        return mDexManager;
    }

    /*package*/ DexOptHelper getDexOptHelper() {
        return mDexOptHelper;
    }
@@ -5856,14 +5845,12 @@ public class PackageManagerService implements PackageSender, TestUtilityService
            Slog.i(TAG,
                    "Ignored unsupported registerDexModule call for " + dexModulePath + " in "
                            + packageName);
            DexManager.RegisterDexModuleResult result = new DexManager.RegisterDexModuleResult(
                    false, "registerDexModule call not supported since Android U");

            if (callback != null) {
                mHandler.post(() -> {
                    try {
                        callback.onDexModuleRegistered(dexModulePath, result.success,
                                result.message);
                        callback.onDexModuleRegistered(dexModulePath, false,
                                "registerDexModule call not supported since Android U");
                    } catch (RemoteException e) {
                        Slog.w(PackageManagerService.TAG,
                                "Failed to callback after module registration " + dexModulePath, e);
@@ -6915,12 +6902,6 @@ public class PackageManagerService implements PackageSender, TestUtilityService
            return mApexManager;
        }

        @NonNull
        @Override
        protected DexManager getDexManager() {
            return mDexManager;
        }

        @NonNull
        @Override
        public DynamicCodeLogger getDynamicCodeLogger() {
Loading