Preload HttpEngine into the Zygote via an API
In order to speed-up the initialization of HttpEngine, we plan to
preload HttpEngine and all of its components into the Zygote. Currently
the plan is to preload the Impl classes and the shared library but
the current implementation only preload a single impl.
The new API is protected behind a flag and should be gradually
rolled out to ensure that we don't mess with the system health
metrics by enrolling HttpEngine into the Zygote. It's important to
note that HttpEngine's other version (Cronet) is extensively used
by a lot of apps and this would be a net positive for the entire
ecosystem.
Unfortunately, using exported flags in this case is impossible because
ZygoteInit happens before the DeviceConfig has initialized which means
that we have to link the same flag twice, once into tethering and
another into platform. The consequence here is that calling
`HttpEngine.preload()` can lead to NoSuchMethodError even if the flag
condition is enabled. This is protected by catching the exception and
logging it.
Bug: 380349437
Change-Id: I00fb4f751f41ee9459c55e76d58690d7ca4f0b30
diff --git a/AconfigFlags.bp b/AconfigFlags.bp
index 9fc4fff..dae7e10 100644
--- a/AconfigFlags.bp
+++ b/AconfigFlags.bp
@@ -89,6 +89,7 @@
"com.android.media.flags.editing-aconfig-java",
"com.android.media.flags.performance-aconfig-java",
"com.android.media.flags.projection-aconfig-java",
+ "com.android.net.http.flags-aconfig-exported-java",
"com.android.net.thread.platform.flags-aconfig-java",
"com.android.ranging.flags.ranging-aconfig-java-export",
"com.android.server.contextualsearch.flags-java",
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index e402ddf..e60879e 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -19,6 +19,8 @@
import static android.system.OsConstants.S_IRWXG;
import static android.system.OsConstants.S_IRWXO;
+import static android.net.http.Flags.preloadHttpengineInZygote;
+
import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__SECONDARY_ZYGOTE_INIT_START;
import static com.android.internal.util.FrameworkStatsLog.BOOT_TIME_EVENT_ELAPSED_TIME__EVENT__ZYGOTE_INIT_START;
@@ -27,6 +29,7 @@
import android.content.pm.SharedLibraryInfo;
import android.content.res.Resources;
import android.os.Build;
+import android.net.http.HttpEngine;
import android.os.Environment;
import android.os.IInstalld;
import android.os.Process;
@@ -144,6 +147,23 @@
Trace.traceEnd(Trace.TRACE_TAG_DALVIK);
preloadSharedLibraries();
preloadTextResources();
+
+ // TODO: remove the try/catch and the flag read as soon as the flag is ramped and 25Q2
+ // starts building from source.
+ if (preloadHttpengineInZygote()) {
+ try {
+ HttpEngine.preload();
+ } catch (NoSuchMethodError e){
+ // The flag protecting this API is not an exported
+ // flag because ZygoteInit happens before the
+ // system service has initialized the flag which means
+ // that we can't query the real value of the flag
+ // from the tethering module. In order to avoid crashing
+ // in the case where we have (new zygote, old tethering).
+ // we catch the NoSuchMethodError and just log.
+ Log.d(TAG, "HttpEngine.preload() threw " + e);
+ }
+ }
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
WebViewFactory.prepareWebViewInZygote();