tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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:
Mmobile/android/fenix/app/metrics.yaml | 58++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mmobile/android/fenix/app/src/main/java/org/mozilla/fenix/FenixApplication.kt | 12+++++++++++-
Mmobile/android/fenix/app/src/test/java/org/mozilla/fenix/FenixApplicationTest.kt | 32+++++++++++++++++++++++++++++---
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()) }