Merge "Refactor dexopt related code to DexOptHelper" into main
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index a10bae9..3abf3a5 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -16,7 +16,10 @@
 
 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.incremental.IncrementalManager.isIncrementalPath;
 
 import static com.android.server.LocalManagerRegistry.ManagerNotFoundException;
 import static com.android.server.pm.ApexManager.ActiveApexInfo;
@@ -27,6 +30,8 @@
 import static com.android.server.pm.PackageManagerService.REASON_BOOT_AFTER_OTA;
 import static com.android.server.pm.PackageManagerService.REASON_CMDLINE;
 import static com.android.server.pm.PackageManagerService.REASON_FIRST_BOOT;
+import static com.android.server.pm.PackageManagerService.SCAN_AS_APEX;
+import static com.android.server.pm.PackageManagerService.SCAN_AS_INSTANT_APP;
 import static com.android.server.pm.PackageManagerService.STUB_SUFFIX;
 import static com.android.server.pm.PackageManagerService.TAG;
 import static com.android.server.pm.PackageManagerServiceCompilerMapping.getCompilerFilterForReason;
@@ -45,6 +50,8 @@
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
+import android.content.pm.Flags;
+import android.content.pm.PackageManager;
 import android.content.pm.ResolveInfo;
 import android.content.pm.SharedLibraryInfo;
 import android.content.pm.dex.ArtManager;
@@ -54,6 +61,7 @@
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
+import android.provider.Settings.Global;
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
@@ -1091,4 +1099,73 @@
                         + " has unsupported status " + status);
         }
     }
+
+    /**
+     * Returns DexoptOptions by the given InstallRequest.
+     */
+    static DexoptOptions getDexoptOptionsByInstallRequest(InstallRequest installRequest,
+            DexManager dexManager) {
+        final PackageSetting ps = installRequest.getScannedPackageSetting();
+        final String packageName = ps.getPackageName();
+        final boolean isBackupOrRestore =
+                installRequest.getInstallReason() == INSTALL_REASON_DEVICE_RESTORE
+                        || installRequest.getInstallReason() == INSTALL_REASON_DEVICE_SETUP;
+        final int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE
+                | DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES
+                | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE
+                | (isBackupOrRestore ? DexoptOptions.DEXOPT_FOR_RESTORE : 0);
+        // Compute the compilation reason from the installation scenario.
+        final int compilationReason =
+                dexManager.getCompilationReasonForInstallScenario(
+                        installRequest.getInstallScenario());
+        return new DexoptOptions(packageName, compilationReason, dexoptFlags);
+    }
+
+    /**
+     * Use ArtService to perform dexopt by the given InstallRequest.
+     */
+    static DexoptResult dexoptPackageUsingArtService(InstallRequest installRequest,
+            DexoptOptions dexoptOptions) {
+        final PackageSetting ps = installRequest.getScannedPackageSetting();
+        final String packageName = ps.getPackageName();
+
+        PackageManagerLocal packageManagerLocal =
+                LocalManagerRegistry.getManager(PackageManagerLocal.class);
+        try (PackageManagerLocal.FilteredSnapshot snapshot =
+                     packageManagerLocal.withFilteredSnapshot()) {
+            boolean ignoreDexoptProfile =
+                    (installRequest.getInstallFlags()
+                            & PackageManager.INSTALL_IGNORE_DEXOPT_PROFILE)
+                            != 0;
+            /*@DexoptFlags*/ int extraFlags =
+                    ignoreDexoptProfile && Flags.useArtServiceV2()
+                            ? ArtFlags.FLAG_IGNORE_PROFILE
+                            : 0;
+            DexoptParams params = dexoptOptions.convertToDexoptParams(extraFlags);
+            DexoptResult dexOptResult = getArtManagerLocal().dexoptPackage(
+                    snapshot, packageName, params);
+
+            return dexOptResult;
+        }
+    }
+
+    /**
+     * Returns whether to perform dexopt by the given InstallRequest.
+     */
+    static boolean shouldPerformDexopt(InstallRequest installRequest, DexoptOptions dexoptOptions,
+            Context context) {
+        final boolean isApex = ((installRequest.getScanFlags() & SCAN_AS_APEX) != 0);
+        final boolean instantApp = ((installRequest.getScanFlags() & SCAN_AS_INSTANT_APP) != 0);
+        final PackageSetting ps = installRequest.getScannedPackageSetting();
+        final AndroidPackage pkg = ps.getPkg();
+        final boolean onIncremental = isIncrementalPath(ps.getPathString());
+
+        return (!instantApp || Global.getInt(context.getContentResolver(),
+                Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
+                && pkg != null
+                && !pkg.isDebuggable()
+                && (!onIncremental)
+                && dexoptOptions.isCompilationEnabled()
+                && !isApex;
+    }
 }
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 0a6f6d4..62c26b6 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -32,8 +32,6 @@
 import static android.content.pm.PackageManager.INSTALL_FAILED_TEST_ONLY;
 import static android.content.pm.PackageManager.INSTALL_FAILED_UID_CHANGED;
 import static android.content.pm.PackageManager.INSTALL_FAILED_UPDATE_INCOMPATIBLE;
-import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_RESTORE;
-import static android.content.pm.PackageManager.INSTALL_REASON_DEVICE_SETUP;
 import static android.content.pm.PackageManager.INSTALL_STAGED;
 import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
 import static android.content.pm.PackageManager.UNINSTALL_REASON_UNKNOWN;
@@ -170,10 +168,7 @@
 import com.android.internal.util.ArrayUtils;
 import com.android.internal.util.CollectionUtils;
 import com.android.server.EventLogTags;
-import com.android.server.LocalManagerRegistry;
 import com.android.server.SystemConfig;
-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.criticalevents.CriticalEventLog;
 import com.android.server.pm.Installer.LegacyDexoptDisabledException;
@@ -2464,8 +2459,6 @@
         final ArraySet<IncrementalStorage> incrementalStorages = new ArraySet<>();
         for (ReconciledPackage reconciledPkg : reconciledPackages) {
             final InstallRequest installRequest = reconciledPkg.mInstallRequest;
-            final boolean instantApp = ((installRequest.getScanFlags() & SCAN_AS_INSTANT_APP) != 0);
-            final boolean isApex = ((installRequest.getScanFlags() & SCAN_AS_APEX) != 0);
             final PackageSetting ps = installRequest.getScannedPackageSetting();
             final String packageName = ps.getPackageName();
             final String codePath = ps.getPathString();
@@ -2507,28 +2500,14 @@
                 }
             }
 
-            // Compute the compilation reason from the installation scenario.
-            final int compilationReason =
-                    mDexManager.getCompilationReasonForInstallScenario(
-                            installRequest.getInstallScenario());
-
             // 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.
-            final boolean isBackupOrRestore =
-                    installRequest.getInstallReason() == INSTALL_REASON_DEVICE_RESTORE
-                            || installRequest.getInstallReason() == INSTALL_REASON_DEVICE_SETUP;
-
-            final int dexoptFlags = DexoptOptions.DEXOPT_BOOT_COMPLETE
-                    | DexoptOptions.DEXOPT_CHECK_FOR_PROFILES_UPDATES
-                    | DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE
-                    | (isBackupOrRestore ? DexoptOptions.DEXOPT_FOR_RESTORE : 0);
-            DexoptOptions dexoptOptions =
-                    new DexoptOptions(packageName, compilationReason, dexoptFlags);
-
+            DexoptOptions dexoptOptions = DexOptHelper.getDexoptOptionsByInstallRequest(
+                    installRequest, mDexManager);
             // Check whether we need to dexopt the app.
             //
             // NOTE: it is IMPORTANT to call dexopt:
@@ -2555,16 +2534,9 @@
             //
             // TODO(b/174695087): instantApp and onIncremental should be removed and their install
             //       path moved to SCENARIO_FAST.
-            final boolean performDexopt =
-                    (!instantApp || android.provider.Settings.Global.getInt(
-                            mContext.getContentResolver(),
-                            android.provider.Settings.Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
-                            && pkg != null
-                            && !pkg.isDebuggable()
-                            && (!onIncremental)
-                            && dexoptOptions.isCompilationEnabled()
-                            && !isApex;
 
+            final boolean performDexopt = DexOptHelper.shouldPerformDexopt(installRequest,
+                    dexoptOptions, mContext);
             if (performDexopt) {
                 Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dexopt");
 
@@ -2579,23 +2551,9 @@
                 realPkgSetting.getPkgState().setUpdatedSystemApp(isUpdatedSystemApp);
 
                 if (useArtService()) {
-                    PackageManagerLocal packageManagerLocal =
-                            LocalManagerRegistry.getManager(PackageManagerLocal.class);
-                    try (PackageManagerLocal.FilteredSnapshot snapshot =
-                                    packageManagerLocal.withFilteredSnapshot()) {
-                        boolean ignoreDexoptProfile =
-                                (installRequest.getInstallFlags()
-                                        & PackageManager.INSTALL_IGNORE_DEXOPT_PROFILE)
-                                != 0;
-                        /*@DexoptFlags*/ int extraFlags =
-                                ignoreDexoptProfile && Flags.useArtServiceV2()
-                                ? ArtFlags.FLAG_IGNORE_PROFILE
-                                : 0;
-                        DexoptParams params = dexoptOptions.convertToDexoptParams(extraFlags);
-                        DexoptResult dexOptResult = DexOptHelper.getArtManagerLocal().dexoptPackage(
-                                snapshot, packageName, params);
-                        installRequest.onDexoptFinished(dexOptResult);
-                    }
+                    DexoptResult dexOptResult = DexOptHelper.dexoptPackageUsingArtService(
+                            installRequest, dexoptOptions);
+                    installRequest.onDexoptFinished(dexOptResult);
                 } else {
                     try {
                         mPackageDexOptimizer.performDexOpt(pkg, realPkgSetting,