Align the boot dexopt pass in the legacy code with ART Service.

A preparation to call into ART Service for that in a later CL.

- Add new compilation reason boot-after-mainline-update.

- Set the reason before doing anything else. This bit will be in the
  ART Service code path as well.

- Remove the dexopt_system_ui_on_boot device config property, because
  ART Service won't support it.

- The selection and priority of the packages in OTA upgrade dexopt are
  still different for now.

Test: atest CtsCompilationTestCases
Bug: 251903639
Bug: 265685704
Change-Id: Ie3c000918a0024f768972f9c8c171cd6f0e029f5
diff --git a/services/core/java/com/android/server/pm/DexOptHelper.java b/services/core/java/com/android/server/pm/DexOptHelper.java
index adb5084..5dd6fe7 100644
--- a/services/core/java/com/android/server/pm/DexOptHelper.java
+++ b/services/core/java/com/android/server/pm/DexOptHelper.java
@@ -23,6 +23,7 @@
 import static com.android.server.pm.InstructionSets.getAppDexInstructionSets;
 import static com.android.server.pm.PackageManagerService.DEBUG_DEXOPT;
 import static com.android.server.pm.PackageManagerService.PLATFORM_PACKAGE_NAME;
+import static com.android.server.pm.PackageManagerService.REASON_BOOT_AFTER_MAINLINE_UPDATE;
 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;
@@ -36,10 +37,8 @@
 
 import static dalvik.system.DexFile.isProfileGuidedCompilerFilter;
 
-import android.Manifest;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
 import android.app.AppGlobals;
 import android.content.Context;
 import android.content.Intent;
@@ -52,7 +51,6 @@
 import android.os.SystemProperties;
 import android.os.Trace;
 import android.os.UserHandle;
-import android.provider.DeviceConfig;
 import android.text.TextUtils;
 import android.util.ArraySet;
 import android.util.Log;
@@ -262,7 +260,7 @@
      * Checks if system UI package (typically "com.android.systemui") needs to be re-compiled, and
      * compiles it if needed.
      */
-    private void checkAndDexOptSystemUi() throws LegacyDexoptDisabledException {
+    private void checkAndDexOptSystemUi(int reason) throws LegacyDexoptDisabledException {
         Installer.checkLegacyDexoptDisabled();
         Computer snapshot = mPm.snapshotComputer();
         String sysUiPackageName =
@@ -273,10 +271,6 @@
             return;
         }
 
-        // It could also be after mainline update, but we're not introducing a new reason just for
-        // this special case.
-        int reason = REASON_BOOT_AFTER_OTA;
-
         String defaultCompilerFilter = getCompilerFilterForReason(reason);
         String targetCompilerFilter =
                 SystemProperties.get("dalvik.vm.systemuicompilerfilter", defaultCompilerFilter);
@@ -319,27 +313,30 @@
                 compilerFilter, null /* splitName */, dexoptFlags));
     }
 
-    @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
+    /**
+     * Called during startup to do any boot time dexopting. This can occasionally be time consuming
+     * (30+ seconds) and the function will block until it is complete.
+     */
     public void performPackageDexOptUpgradeIfNeeded() throws LegacyDexoptDisabledException {
         PackageManagerServiceUtils.enforceSystemOrRoot(
                 "Only the system can request package update");
 
-        // The default is "true".
-        if (!"false".equals(DeviceConfig.getProperty("runtime", "dexopt_system_ui_on_boot"))) {
-            // System UI is important to user experience, so we check it after a mainline update or
-            // an OTA. It may need to be re-compiled in these cases.
-            if (hasBcpApexesChanged() || mPm.isDeviceUpgrading()) {
-                checkAndDexOptSystemUi();
-            }
+        int reason;
+        if (mPm.isFirstBoot()) {
+            reason = REASON_FIRST_BOOT; // First boot or factory reset.
+        } else if (mPm.isDeviceUpgrading()) {
+            reason = REASON_BOOT_AFTER_OTA;
+        } else if (hasBcpApexesChanged()) {
+            reason = REASON_BOOT_AFTER_MAINLINE_UPDATE;
+        } else {
+            return;
         }
 
-        // We need to re-extract after an OTA.
-        boolean causeUpgrade = mPm.isDeviceUpgrading();
+        // System UI is important to user experience, so we check it after a mainline update
+        // or an OTA. It may need to be re-compiled in these cases.
+        checkAndDexOptSystemUi(reason);
 
-        // First boot or factory reset.
-        boolean causeFirstBoot = mPm.isFirstBoot();
-
-        if (!causeUpgrade && !causeFirstBoot) {
+        if (reason != REASON_BOOT_AFTER_OTA && reason != REASON_FIRST_BOOT) {
             return;
         }
 
@@ -348,9 +345,7 @@
                 getPackagesForDexopt(snapshot.getPackageStates().values(), mPm);
 
         final long startTime = System.nanoTime();
-        final int[] stats = performDexOptUpgrade(pkgSettings,
-                causeFirstBoot ? REASON_FIRST_BOOT : REASON_BOOT_AFTER_OTA,
-                false /* bootComplete */);
+        final int[] stats = performDexOptUpgrade(pkgSettings, reason, false /* bootComplete */);
 
         final int elapsedTimeSeconds =
                 (int) TimeUnit.NANOSECONDS.toSeconds(System.nanoTime() - startTime);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 82fc912..0cd4988 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -552,6 +552,7 @@
     private static final int REQUIRED_VERIFIERS_MAX_COUNT = 2;
 
     // Compilation reasons.
+    // TODO(b/260124949): Clean this up with the legacy dexopt code.
     public static final int REASON_FIRST_BOOT = 0;
     public static final int REASON_BOOT_AFTER_OTA = 1;
     public static final int REASON_POST_BOOT = 2;
@@ -565,7 +566,8 @@
     public static final int REASON_AB_OTA = 10;
     public static final int REASON_INACTIVE_PACKAGE_DOWNGRADE = 11;
     public static final int REASON_CMDLINE = 12;
-    public static final int REASON_SHARED = 13;
+    public static final int REASON_BOOT_AFTER_MAINLINE_UPDATE = 13;
+    public static final int REASON_SHARED = 14;
 
     public static final int REASON_LAST = REASON_SHARED;
 
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
index 7c1f054..e2ddba5 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceCompilerMapping.java
@@ -41,6 +41,7 @@
         "ab-ota",
         "inactive",
         "cmdline",
+        "boot-after-mainline-update",
         // "shared" must be the last entry
         "shared"
     };
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index b5b6347..b4cedfb 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -620,6 +620,7 @@
     private static final int TRON_COMPILATION_REASON_CMDLINE = 22;
     private static final int TRON_COMPILATION_REASON_PREBUILT = 23;
     private static final int TRON_COMPILATION_REASON_VDEX = 24;
+    private static final int TRON_COMPILATION_REASON_BOOT_AFTER_MAINLINE_UPDATE = 25;
 
     // The annotation to add as a suffix to the compilation reason when dexopt was
     // performed with dex metadata.
@@ -634,6 +635,8 @@
             case "error" : return TRON_COMPILATION_REASON_ERROR;
             case "first-boot" : return TRON_COMPILATION_REASON_FIRST_BOOT;
             case "boot-after-ota": return TRON_COMPILATION_REASON_BOOT_AFTER_OTA;
+            case "boot-after-mainline-update":
+                return TRON_COMPILATION_REASON_BOOT_AFTER_MAINLINE_UPDATE;
             case "post-boot" : return TRON_COMPILATION_REASON_POST_BOOT;
             case "install" : return TRON_COMPILATION_REASON_INSTALL;
             case "bg-dexopt" : return TRON_COMPILATION_REASON_BG_DEXOPT;