Support preload of org.apache.http.legacy.jar

This library is still referenced by most (~70%) of the most commonly
used Android apps, and preloading yields modest improvements to both
app startup latency and memory, particularly for lower-end devices.

Add support for preloading the library behind a new flag:
  com.android.internal.os.enable_apache_http_legacy_preload

Bug: 241474956
Test: m + ART benchmark service
Test: atest FrameworksCoreTests:android.app.ApplicationLoadersTest
Flag: com.android.internal.os.enable_apache_http_legacy_preload
Change-Id: Iff97a0a78d9b4c12da963d252574a0a9bd8dd87d
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 85323c3..f8308e4 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -80,6 +80,7 @@
         "com.android.input.flags-aconfig-java",
         "com.android.internal.compat.flags-aconfig-java",
         "com.android.internal.foldables.flags-aconfig-java",
+        "com.android.internal.os.flags-aconfig-java",
         "com.android.internal.pm.pkg.component.flags-aconfig-java",
         "com.android.media.flags.bettertogether-aconfig-java",
         "com.android.media.flags.editing-aconfig-java",
@@ -361,6 +362,19 @@
     host_supported: true,
 }
 
+// OS Internal
+aconfig_declarations {
+    name: "com.android.internal.os.flags-aconfig",
+    package: "com.android.internal.os",
+    srcs: ["core/java/com/android/internal/os/flags.aconfig"],
+}
+
+java_aconfig_library {
+    name: "com.android.internal.os.flags-aconfig-java",
+    aconfig_declarations: "com.android.internal.os.flags-aconfig",
+    defaults: ["framework-minus-apex-aconfig-java-defaults"],
+}
+
 // VirtualDeviceManager
 cc_aconfig_library {
     name: "android.companion.virtualdevice.flags-aconfig-cc",
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 5297006..b9cc457 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -397,6 +397,14 @@
                 null /*declaringPackage*/, null /*dependentPackages*/, null /*dependencies*/,
                 false /*isNative*/));
 
+        if (Flags.enableApacheHttpLegacyPreload()) {
+            libs.add(new SharedLibraryInfo(
+                    "/system/framework/org.apache.http.legacy.jar", null /*packageName*/,
+                    null /*codePaths*/, null /*name*/, 0 /*version*/,
+                    SharedLibraryInfo.TYPE_BUILTIN, null /*declaringPackage*/,
+                    null /*dependentPackages*/, null /*dependencies*/, false /*isNative*/));
+        }
+
         // WindowManager Extensions is an optional shared library that is required for WindowManager
         // Jetpack to fully function. Since it is a widely used library, preload it to improve apps
         // startup performance.
diff --git a/core/java/com/android/internal/os/flags.aconfig b/core/java/com/android/internal/os/flags.aconfig
new file mode 100644
index 0000000..4c2bbd4
--- /dev/null
+++ b/core/java/com/android/internal/os/flags.aconfig
@@ -0,0 +1,10 @@
+package: "com.android.internal.os"
+
+flag {
+    name: "enable_apache_http_legacy_preload"
+    namespace: "system_performance"
+    description: "Enables zygote preload of non-BCP org.apache.http.legacy.jar library."
+    # Fixed read-only is required as the flag is read during zygote init.
+    is_fixed_read_only: true
+    bug: "241474956"
+}
\ No newline at end of file
diff --git a/core/tests/coretests/src/android/app/ApplicationLoadersTest.java b/core/tests/coretests/src/android/app/ApplicationLoadersTest.java
index 3cb62b9..565e21d 100644
--- a/core/tests/coretests/src/android/app/ApplicationLoadersTest.java
+++ b/core/tests/coretests/src/android/app/ApplicationLoadersTest.java
@@ -40,6 +40,8 @@
     private static final String LIB_A = "/system/framework/android.hidl.base-V1.0-java.jar";
     // a library installed onto the device which only depends on A
     private static final String LIB_DEP_A = "/system/framework/android.hidl.manager-V1.0-java.jar";
+    // a commonly used, non-BCP, app-facing library installed onto the device
+    private static final String LIB_APACHE_HTTP = "/system/framework/org.apache.http.legacy.jar";
 
     private static SharedLibraryInfo createLib(String zip) {
         return new SharedLibraryInfo(
@@ -137,4 +139,15 @@
 
         loaders.createAndCacheNonBootclasspathSystemClassLoaders(Lists.newArrayList(libB, libA));
     }
+
+    @Test
+    public void testCacheApacheHttpLegacy() {
+        ApplicationLoaders loaders = new ApplicationLoaders();
+        SharedLibraryInfo libApacheHttp = createLib(LIB_APACHE_HTTP);
+
+        loaders.createAndCacheNonBootclasspathSystemClassLoaders(Lists.newArrayList(libApacheHttp));
+
+        assertNotNull(loaders.getCachedNonBootclasspathSystemLib(
+                LIB_APACHE_HTTP, null, null, null));
+    }
 }