commit bd837e0ebcbe262053516e35f43da359e0d7b7c3
parent 1f301699e06a655e43be19615e628ac95912a2a7
Author: t-p-white <towhite@mozilla.com>
Date: Wed, 8 Oct 2025 15:53:17 +0000
Bug 1991520 - Add usage telemetry to enable measurement of privacy related settings. r=android-reviewers,gmalekpour
- DNS over HTTP preference
- HTTPS-only preference
- Global privacy control preference
Differential Revision: https://phabricator.services.mozilla.com/D267766
Diffstat:
3 files changed, 98 insertions(+), 4 deletions(-)
diff --git a/mobile/android/fenix/app/metrics.yaml b/mobile/android/fenix/app/metrics.yaml
@@ -4330,6 +4330,64 @@ preferences:
tags:
- Settings
- Performance
+ https_only_mode:
+ type: string
+ lifetime: application
+ description: |
+ Measures user retention of the HTTPS-Only setting at start-up.
+ Example values include: "DISABLED", "ENABLED_PRIVATE_ONLY", "ENABLED".
+ send_in_pings:
+ - metrics
+ bugs:
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1991520
+ data_reviews:
+ - https://phabricator.services.mozilla.com/D267766
+ data_sensitivity:
+ - interaction
+ notification_emails:
+ - android-probes@mozilla.com
+ expires: never
+ metadata:
+ tags:
+ - Settings
+ doh_protection_level:
+ type: string
+ lifetime: application
+ description: |
+ Measures user retention of the DNS over HTTPS (DoH) setting at start-up.
+ Example values include: "Default", "Increased", "Max", "Off".
+ send_in_pings:
+ - metrics
+ bugs:
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1991520
+ data_reviews:
+ - https://phabricator.services.mozilla.com/D267766
+ data_sensitivity:
+ - interaction
+ notification_emails:
+ - android-probes@mozilla.com
+ expires: never
+ metadata:
+ tags:
+ - Settings
+ global_privacy_control_enabled:
+ type: boolean
+ lifetime: application
+ description: Measures user retention of the Global Privacy Control (GPC) setting at start-up.
+ send_in_pings:
+ - metrics
+ notification_emails:
+ - android-probes@mozilla.com
+ bugs:
+ - https://bugzilla.mozilla.org/show_bug.cgi?id=1991520
+ data_reviews:
+ - https://phabricator.services.mozilla.com/D267766
+ expires: never
+ data_sensitivity:
+ - interaction
+ metadata:
+ tags:
+ - Settings
search.default_engine:
code:
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
@@ -109,6 +109,8 @@ import org.mozilla.fenix.perf.runBlockingIncrement
import org.mozilla.fenix.push.PushFxaIntegration
import org.mozilla.fenix.push.WebPushEngineIntegration
import org.mozilla.fenix.session.VisibilityLifecycleCallback
+import org.mozilla.fenix.settings.doh.DefaultDohSettingsProvider
+import org.mozilla.fenix.settings.doh.DohSettingsProvider
import org.mozilla.fenix.utils.Settings
import org.mozilla.fenix.utils.isLargeScreenSize
import org.mozilla.fenix.wallpapers.Wallpaper
@@ -756,10 +758,14 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
internal fun setStartupMetrics(
browserStore: BrowserStore,
settings: Settings,
+ dohSettingsProvider: DohSettingsProvider = DefaultDohSettingsProvider(
+ components.core.engine,
+ settings,
+ ),
browsersCache: BrowsersCache = BrowsersCache,
mozillaProductDetector: MozillaProductDetector = MozillaProductDetector,
) {
- setPreferenceMetrics(settings)
+ setPreferenceMetrics(settings, dohSettingsProvider)
with(Metrics) {
// Set this early to guarantee it's in every ping from here on.
distributionId.set(components.distributionIdManager.getDistributionId())
@@ -909,6 +915,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
@Suppress("ComplexMethod")
private fun setPreferenceMetrics(
settings: Settings,
+ dohSettingsProvider: DohSettingsProvider,
) {
with(Preferences) {
searchSuggestionsEnabled.set(settings.shouldShowSearchSuggestions)
@@ -980,6 +987,9 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
)
inactiveTabsEnabled.set(settings.inactiveTabsAreEnabled)
+ dohProtectionLevel.set(dohSettingsProvider.getSelectedProtectionLevel().toString())
+ httpsOnlyMode.set(settings.getHttpsOnlyMode().toString())
+ globalPrivacyControlEnabled.set(settings.shouldEnableGlobalPrivacyControl)
}
reportHomeScreenMetrics(settings)
}
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
@@ -14,6 +14,7 @@ import io.mockk.mockk
import io.mockk.spyk
import io.mockk.verify
import mozilla.components.browser.state.store.BrowserStore
+import mozilla.components.concept.engine.Engine.HttpsOnlyMode
import mozilla.components.concept.engine.webextension.DisabledFlags
import mozilla.components.concept.engine.webextension.Metadata
import mozilla.components.concept.engine.webextension.WebExtension
@@ -43,6 +44,8 @@ import org.mozilla.fenix.distributions.DistributionProviderChecker
import org.mozilla.fenix.distributions.DistributionSettings
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.helpers.FenixGleanTestRule
+import org.mozilla.fenix.settings.doh.DohSettingsProvider
+import org.mozilla.fenix.settings.doh.ProtectionLevel
import org.mozilla.fenix.utils.Settings
import org.robolectric.RobolectricTestRunner
import org.robolectric.Shadows.shadowOf
@@ -161,6 +164,7 @@ class FenixApplicationTest {
val expectedAppName = "org.mozilla.fenix"
val expectedAppInstallSource = "org.mozilla.install.source"
val settings = spyk(Settings(testContext))
+ val dohSettingsProvider = mockk<DohSettingsProvider>()
val application = spyk(application)
val packageManager: PackageManager = mockk()
@@ -218,6 +222,9 @@ class FenixApplicationTest {
every { settings.inactiveTabsAreEnabled } returns true
every { settings.isIsolatedProcessEnabled } returns true
every { application.isDeviceRamAboveThreshold } returns true
+ every { dohSettingsProvider.getSelectedProtectionLevel() } returns ProtectionLevel.Max
+ every { settings.getHttpsOnlyMode() } returns HttpsOnlyMode.ENABLED_PRIVATE_ONLY
+ every { settings.shouldEnableGlobalPrivacyControl } returns true
assertTrue(settings.contileContextId.isNotEmpty())
assertNotNull(TopSites.contextId.testGetValue())
@@ -226,6 +233,7 @@ class FenixApplicationTest {
application.setStartupMetrics(
browserStore = browserStore,
settings = settings,
+ dohSettingsProvider,
browsersCache = browsersCache,
mozillaProductDetector = mozillaProductDetector,
)
@@ -271,6 +279,9 @@ class FenixApplicationTest {
assertEquals(true, Metrics.defaultWallpaper.testGetValue())
assertEquals(true, Metrics.ramMoreThanThreshold.testGetValue())
assertEquals(7L, Metrics.deviceTotalRam.testGetValue())
+ assertEquals("Max", Preferences.dohProtectionLevel.testGetValue())
+ assertEquals("ENABLED_PRIVATE_ONLY", Preferences.httpsOnlyMode.testGetValue())
+ assertEquals(true, Preferences.globalPrivacyControlEnabled.testGetValue())
val contextId = TopSites.contextId.testGetValue()!!.toString()
@@ -283,7 +294,12 @@ class FenixApplicationTest {
assertNull(SearchDefaultEngine.name.testGetValue())
assertNull(SearchDefaultEngine.searchUrl.testGetValue())
- application.setStartupMetrics(browserStore, settings, browsersCache, mozillaProductDetector)
+ application.setStartupMetrics(
+ browserStore = browserStore,
+ settings = settings,
+ browsersCache = browsersCache,
+ mozillaProductDetector = mozillaProductDetector,
+ )
assertEquals(contextId, TopSites.contextId.testGetValue()!!.toString())
assertEquals(contextId, settings.contileContextId)
@@ -298,7 +314,12 @@ class FenixApplicationTest {
every { blockCookiesSelectionInCustomTrackingProtection } returns "Test"
}
- application.setStartupMetrics(browserStore, settings, browsersCache, mozillaProductDetector)
+ application.setStartupMetrics(
+ browserStore = browserStore,
+ settings = settings,
+ browsersCache = browsersCache,
+ mozillaProductDetector = mozillaProductDetector,
+ )
assertEquals("Test", Preferences.etpCustomCookiesSelection.testGetValue())
}
@@ -315,7 +336,12 @@ class FenixApplicationTest {
shadowOf(packageManager)
.setInstallSourceInfo(testContext.packageName, "initiating.package", "installing.package")
- application.setStartupMetrics(browserStore, settings, browsersCache, mozillaProductDetector)
+ application.setStartupMetrics(
+ browserStore = browserStore,
+ settings = settings,
+ browsersCache = browsersCache,
+ mozillaProductDetector = mozillaProductDetector,
+ )
assertEquals("Test", Preferences.etpCustomCookiesSelection.testGetValue())
}