commit ae19f80fa81862494123ff178bcb62b6d24ee58b parent 17856cb36eb1a2048b471e35e5f5529ae2a48f4d Author: Olivia Hall <ohall@mozilla.com> Date: Mon, 20 Oct 2025 21:37:57 +0000 Bug 1989943 - Secret Setting to Enable App Zygote Process on Fenix r=kaya,android-reviewers,nalexander Patch adds: * A secret setting to Enable App Zygote Process on Fenix when SDK >= 29 * A Nimbus instrumentation to toggle the secret setting * Telemetry to register pref changes Differential Revision: https://phabricator.services.mozilla.com/D265600 Diffstat:
10 files changed, 50 insertions(+), 0 deletions(-)
diff --git a/mobile/android/fenix/app/metrics.yaml b/mobile/android/fenix/app/metrics.yaml @@ -4388,6 +4388,25 @@ preferences: metadata: tags: - Settings + app_zygote_isolated_content_processes_enabled: + type: boolean + lifetime: application + description: True when app Zygote preloading with isolated processes is enabled. + send_in_pings: + - metrics + bugs: + - https://bugzilla.mozilla.org/show_bug.cgi?id=1989943 + data_reviews: + - https://phabricator.services.mozilla.com/D265600 + data_sensitivity: + - technical + notification_emails: + - android-probes@mozilla.com + expires: never + metadata: + tags: + - Settings + - Performance search.default_engine: code: diff --git a/mobile/android/fenix/app/nimbus.fml.yaml b/mobile/android/fenix/app/nimbus.fml.yaml @@ -1023,6 +1023,11 @@ features: Whether or not to enable isolated content processes. type: Boolean default: false + app-zygote-preloading: + description: > + Whether or not to enable app Zygote preloaded isolated content processes. + type: Boolean + default: false custom-review-prompt: description: Feature that controls the Play store in-app custom review prompt. diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -907,6 +907,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider { openLinksInAppEnabled.set(settings.openLinksInExternalApp) signedInSync.set(settings.signedInFxaAccount) isolatedContentProcessesEnabled.set(settings.isIsolatedProcessEnabled) + appZygoteIsolatedContentProcessesEnabled.set(settings.isAppZygoteEnabled) val syncedItems = SyncEnginesStorage(applicationContext).getStatus().entries.filter { it.value diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/gecko/GeckoProvider.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/gecko/GeckoProvider.kt @@ -132,6 +132,7 @@ object GeckoProvider { FxNimbus.features.sameDocumentNavigationOverridesLoadType.value().forceDisableUri, ) .isolatedProcessEnabled(context.settings().isIsolatedProcessEnabled) + .appZygoteProcessEnabled(context.settings().isAppZygoteEnabled) .build() } } diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/settings/SecretSettingsFragment.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.settings +import android.os.Build import android.os.Bundle import androidx.core.content.edit import androidx.lifecycle.lifecycleScope @@ -366,6 +367,12 @@ class SecretSettingsFragment : PreferenceFragmentCompat() { isChecked = context.settings().isIsolatedProcessEnabled onPreferenceChangeListener = SharedPreferenceUpdater() } + + requirePreference<SwitchPreference>(R.string.pref_key_enable_app_zygote_process).apply { + isVisible = Config.channel.isNightlyOrDebug && Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q + isChecked = context.settings().isAppZygoteEnabled + onPreferenceChangeListener = SharedPreferenceUpdater() + } } override fun onPreferenceTreeClick(preference: Preference): Boolean { diff --git a/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/mobile/android/fenix/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -911,6 +911,15 @@ class Settings(private val appContext: Context) : PreferencesHolder { ) /** + * Indicates whether app Zygote preloading using isolated content processes are enabled or not. + */ + var isAppZygoteEnabled by lazyFeatureFlagPreference( + key = appContext.getPreferenceKey(R.string.pref_key_enable_app_zygote_process), + featureFlag = true, + default = { FxNimbus.features.isolatedContentProcesses.value().appZygotePreloading }, + ) + + /** * Indicates if the user should start on the home screen, based on the user's preferences. */ fun shouldStartOnHome(): Boolean { diff --git a/mobile/android/fenix/app/src/main/res/values/preference_keys.xml b/mobile/android/fenix/app/src/main/res/values/preference_keys.xml @@ -442,6 +442,7 @@ <string name="pref_key_enable_toolbar_customization">pref_key_enable_toolbar_customization</string> <string name="pref_key_enable_lna_blocking_enabled" translatable="false">pref_key_enable_lna_blocking_enabled</string> <string name="pref_key_enable_isolated_process" translatable="false">pref_key_enable_isolated_process</string> + <string name="pref_key_enable_app_zygote_process" translatable="false">pref_key_enable_app_zygote_process</string> <!-- Logins --> <string name="pref_key_enable_compose_logins" translatable="false">pref_key_enable_compose_logins</string> diff --git a/mobile/android/fenix/app/src/main/res/values/static_strings.xml b/mobile/android/fenix/app/src/main/res/values/static_strings.xml @@ -135,6 +135,7 @@ <!-- Label for enabling isolated content processes in secret settings. --> <string name="preferences_debug_settings_isolated_process" translatable="false">Enable Isolated Content Process (requires restart)</string> + <string name="preferences_debug_settings_app_zygote" translatable="false">Enable Isolated Processes with Zygote Preloading (requires restart)</string> <!-- A secret menu option in the tabs tray for making a tab inactive for testing. --> <string name="inactive_tabs_menu_item">Make inactive</string> diff --git a/mobile/android/fenix/app/src/main/res/xml/secret_settings_preferences.xml b/mobile/android/fenix/app/src/main/res/xml/secret_settings_preferences.xml @@ -125,6 +125,10 @@ android:key="@string/pref_key_enable_isolated_process" android:title="@string/preferences_debug_settings_isolated_process" app:iconSpaceReserved="false" /> + <SwitchPreference + android:key="@string/pref_key_enable_app_zygote_process" + android:title="@string/preferences_debug_settings_app_zygote" + app:iconSpaceReserved="false" /> <EditTextPreference android:key="@string/pref_key_custom_glean_server_url" android:title="@string/preferences_debug_settings_custom_glean_server_url" diff --git a/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/FenixApplicationTest.kt b/mobile/android/fenix/app/src/test/java/org/mozilla/fenix/FenixApplicationTest.kt @@ -181,6 +181,7 @@ class FenixApplicationTest { every { application.getDeviceTotalRAM() } returns 7L every { settings.inactiveTabsAreEnabled } returns true every { settings.isIsolatedProcessEnabled } returns true + every { settings.isAppZygoteEnabled } returns true every { application.isDeviceRamAboveThreshold } returns true every { dohSettingsProvider.getSelectedProtectionLevel() } returns ProtectionLevel.Max every { settings.getHttpsOnlyMode() } returns HttpsOnlyMode.ENABLED_PRIVATE_ONLY @@ -236,6 +237,7 @@ class FenixApplicationTest { assertEquals(listOf("switch", "touch exploration"), Preferences.accessibilityServices.testGetValue()) assertEquals(true, Preferences.inactiveTabsEnabled.testGetValue()) assertEquals(true, Preferences.isolatedContentProcessesEnabled.testGetValue()) + assertEquals(true, Preferences.appZygoteIsolatedContentProcessesEnabled.testGetValue()) assertEquals(true, Metrics.defaultWallpaper.testGetValue()) assertEquals(true, Metrics.ramMoreThanThreshold.testGetValue()) assertEquals(7L, Metrics.deviceTotalRam.testGetValue())