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

Commit 61d23430 authored by TYM Tsai's avatar TYM Tsai
Browse files

Code refactoring: Move dexopt code to DexOptHelper

Move dexopt code to DexOptHelper, and set up the updated system
app flag in scanInstallPackages.

Bug: 321139675
Flag: EXEMPT code refactoring
Test: atest CtsPackageManagerTestCases
Test: atest CtsInstallHostTestCases
Change-Id: Ia9bf9454b4a43cbe815afdc80f29ab9d7e9efdeb
parent 52db2456
Loading
Loading
Loading
Loading
+73 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.pm;
import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_RESTORE;
import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP;
import static android.os.Trace.TRACE_TAG_DALVIK;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static android.os.incremental.IncrementalManager.isIncrementalPath;

import static com.android.server.LocalManagerRegistry.ManagerNotFoundException;
@@ -738,6 +739,78 @@ public final class DexOptHelper {
        return options;
    }

    /**
     * Perform dexopt if needed for the installation
     */
    static void performDexoptIfNeeded(InstallRequest installRequest, DexManager dexManager,
            Context context, PackageManagerTracedLock.RawLock installLock) {

        // Construct the DexoptOptions early to see if we should skip running dexopt.
        //
        // Do not run PackageDexOptimizer through the local performDexOpt
        // method because `pkg` may not be in `mPackages` yet.
        //
        // Also, don't fail application installs if the dexopt step fails.
        DexoptOptions dexoptOptions = getDexoptOptionsByInstallRequest(installRequest, dexManager);
        // Check whether we need to dexopt the app.
        //
        // NOTE: it is IMPORTANT to call dexopt:
        //   - after doRename which will sync the package data from AndroidPackage and
        //     its corresponding ApplicationInfo.
        //   - after installNewPackageLIF or replacePackageLIF which will update result with the
        //     uid of the application (pkg.applicationInfo.uid).
        //     This update happens in place!
        //
        // We only need to dexopt if the package meets ALL of the following conditions:
        //   1) it is not an instant app or if it is then dexopt is enabled via gservices.
        //   2) it is not debuggable.
        //   3) it is not on Incremental File System.
        //
        // Note that we do not dexopt instant apps by default. dexopt can take some time to
        // complete, so we skip this step during installation. Instead, we'll take extra time
        // the first time the instant app starts. It's preferred to do it this way to provide
        // continuous progress to the useur instead of mysteriously blocking somewhere in the
        // middle of running an instant app. The default behaviour can be overridden
        // via gservices.
        //
        // Furthermore, dexopt may be skipped, depending on the install scenario and current
        // state of the device.
        //
        // TODO(b/174695087): instantApp and onIncremental should be removed and their install
        //       path moved to SCENARIO_FAST.

        final boolean performDexopt = DexOptHelper.shouldPerformDexopt(installRequest,
                dexoptOptions, context);
        if (performDexopt) {
            // 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");

                // This mirrors logic from commitReconciledScanResultLocked, where the library
                // files needed for dexopt are assigned.
                PackageSetting realPkgSetting = installRequest.getRealPackageSetting();
                // Unfortunately, the updated system app flag is only tracked on this
                // PackageSetting
                boolean isUpdatedSystemApp =
                        installRequest.getScannedPackageSetting().isUpdatedSystemApp();
                realPkgSetting.getPkgState().setUpdatedSystemApp(isUpdatedSystemApp);

                DexoptResult dexOptResult = DexOptHelper.dexoptPackageUsingArtService(
                        installRequest, dexoptOptions);
                installRequest.onDexoptFinished(dexOptResult);
            } finally {
                Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                if (installLock != null) {
                    installLock.lock();
                }
            }
        }
    }

    /**
     * Use ArtService to perform dexopt by the given InstallRequest.
     */
+2 −66
Original line number Diff line number Diff line
@@ -172,11 +172,9 @@ import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;
import com.android.server.EventLogTags;
import com.android.server.SystemConfig;
import com.android.server.art.model.DexoptResult;
import com.android.server.criticalevents.CriticalEventLog;
import com.android.server.pm.dex.ArtManagerService;
import com.android.server.pm.dex.DexManager;
import com.android.server.pm.dex.DexoptOptions;
import com.android.server.pm.parsing.PackageCacher;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.permission.Permission;
@@ -2633,70 +2631,8 @@ final class InstallPackageHelper {
                        pkg.getBaseApkPath(), pkg.getSplitCodePaths());
            }

            // Construct the DexoptOptions early to see if we should skip running dexopt.
            //
            // Do not run PackageDexOptimizer through the local performDexOpt
            // method because `pkg` may not be in `mPackages` yet.
            //
            // Also, don't fail application installs if the dexopt step fails.
            DexoptOptions dexoptOptions = DexOptHelper.getDexoptOptionsByInstallRequest(
                    installRequest, mDexManager);
            // Check whether we need to dexopt the app.
            //
            // NOTE: it is IMPORTANT to call dexopt:
            //   - after doRename which will sync the package data from AndroidPackage and
            //     its corresponding ApplicationInfo.
            //   - after installNewPackageLIF or replacePackageLIF which will update result with the
            //     uid of the application (pkg.applicationInfo.uid).
            //     This update happens in place!
            //
            // We only need to dexopt if the package meets ALL of the following conditions:
            //   1) it is not an instant app or if it is then dexopt is enabled via gservices.
            //   2) it is not debuggable.
            //   3) it is not on Incremental File System.
            //
            // Note that we do not dexopt instant apps by default. dexopt can take some time to
            // complete, so we skip this step during installation. Instead, we'll take extra time
            // the first time the instant app starts. It's preferred to do it this way to provide
            // continuous progress to the useur instead of mysteriously blocking somewhere in the
            // middle of running an instant app. The default behaviour can be overridden
            // via gservices.
            //
            // Furthermore, dexopt may be skipped, depending on the install scenario and current
            // state of the device.
            //
            // TODO(b/174695087): instantApp and onIncremental should be removed and their install
            //       path moved to SCENARIO_FAST.

            final boolean performDexopt = DexOptHelper.shouldPerformDexopt(installRequest,
                    dexoptOptions, mContext);
            if (performDexopt) {
                // 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.
                PackageManagerTracedLock.RawLock installLock = mPm.mInstallLock.getRawLock();
                installLock.unlock();
                try {
                    Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");

                    // This mirrors logic from commitReconciledScanResultLocked, where the library
                    // files needed for dexopt are assigned.
                    PackageSetting realPkgSetting = installRequest.getRealPackageSetting();

                    // Unfortunately, the updated system app flag is only tracked on this
                    // PackageSetting
                    boolean isUpdatedSystemApp =
                            installRequest.getScannedPackageSetting().isUpdatedSystemApp();

                    realPkgSetting.getPkgState().setUpdatedSystemApp(isUpdatedSystemApp);

                    DexoptResult dexOptResult = DexOptHelper.dexoptPackageUsingArtService(
                            installRequest, dexoptOptions);
                    installRequest.onDexoptFinished(dexOptResult);
                    Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
                } finally {
                    installLock.lock();
                }
            }
            DexOptHelper.performDexoptIfNeeded(installRequest, mDexManager, mContext,
                    mPm.mInstallLock.getRawLock());
        }
        PackageManagerServiceUtils.waitForNativeBinariesExtractionForIncremental(
                incrementalStorages);