Register the DexLoadReporter before creating the main class loader

We used to register the DexLoadReporter after the main class loader
was created. That was done to avoid superfluous reports of the app's
primary apks (since we already know about them).

However that also means that if the app would start as an isolated
process we would miss this signal in the DexManager.

Make sure we get signals for isolated processes by registering the
reporter before we create the main class loader.

Test: manual, using chrome and maps go
adb shell cmd package compile -m speed-profile com.android.chrome
adb shell am start -n \
com.google.android.apps.mapslite/com.google.maps.lite.twa.MapsLiteTwaLauncherActivity
adb shell dumpsys package dexopt
(confirm that chrome is used by an isolated process)
adb shell cmd package compile -m speed-profile com.android.chrome
(confirm that chrome is speed compiled - or verify, based on the device
setting)

Bug: 163018062
Change-Id: I5d683ae85b3973cc2011dd33b4cb14837b18005f
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 5d2370d..8e51cc1 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -886,6 +886,21 @@
 
         boolean registerAppInfoToArt = false;
         if (mDefaultClassLoader == null) {
+            // Setup the dex reporter to notify package manager
+            // of any relevant dex loads. The idle maintenance job will use the information
+            // reported to optimize the loaded dex files.
+            // Note that we only need one global reporter per app.
+            // Make sure we do this before creating the main app classloader for the first time
+            // so that we can capture the complete application startup.
+            //
+            // We should not do this in a zygote context (where mActivityThread will be null),
+            // thus we'll guard against it.
+            // Also, the system server reporter (SystemServerDexLoadReporter) is already registered
+            // when system server starts, so we don't need to do it here again.
+            if (mActivityThread != null && !ActivityThread.isSystem()) {
+                BaseDexClassLoader.setReporter(DexLoadReporter.getInstance());
+            }
+
             // Temporarily disable logging of disk reads on the Looper thread
             // as this is early and necessary.
             StrictMode.ThreadPolicy oldPolicy = allowThreadDiskReads();
@@ -985,14 +1000,6 @@
     }
 
     private void registerAppInfoToArt() {
-        // Setup the dex reporter to notify package manager
-        // of any relevant dex loads. The idle maintenance job will use the information
-        // reported to optimize the loaded dex files.
-        // Note that we only need one global reporter per app.
-        // Make sure we do this before invoking app code for the first time so that we
-        // can capture the complete application startup.
-        BaseDexClassLoader.setReporter(DexLoadReporter.getInstance());
-
         // Only set up profile support if the loaded apk has the same uid as the
         // current process.
         // Currently, we do not support profiling across different apps.