diff --git a/app/metrics.yaml b/app/metrics.yaml index 31f524f7d..c1338788b 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -426,6 +426,20 @@ metrics: notification_emails: - fenix-core@mozilla.com expires: "2020-03-01" + total_uri_count: + type: string + lifetime: application + description: > + A counter of URIs visited by the user in the current session, including page reloads. This does not include background page requests and URIs from embedded pages or private browsing. + send_in_pings: + - metrics + bugs: + - https://github.com/mozilla-mobile/fenix/issue/4456 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/TODO + notification_emails: + - fenix-core@mozilla.com + expires: "2020-03-01" search.default_engine: diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt index 4c5ef885e..8ec7bbcd9 100644 --- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt +++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -64,6 +64,8 @@ open class FenixApplication : Application() { registerRxExceptionHandling() enableStrictMode() + applicationContext.settings().totalUriCount = 0 + if (!isMainProcess()) { // If this is not the main process then do not continue with the initialization here. Everything that // follows only needs to be done in our app's main process and should not be done in other processes like diff --git a/app/src/main/java/org/mozilla/fenix/browser/UriOpenedObserver.kt b/app/src/main/java/org/mozilla/fenix/browser/UriOpenedObserver.kt index d6ca725cf..f0602494b 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/UriOpenedObserver.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/UriOpenedObserver.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.browser +import android.content.Context import androidx.annotation.VisibleForTesting import androidx.fragment.app.FragmentActivity import androidx.lifecycle.LifecycleOwner @@ -13,14 +14,17 @@ import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.metrics.MetricController import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.metrics +import org.mozilla.fenix.ext.settings class UriOpenedObserver( + private val context: Context, private val owner: LifecycleOwner, private val sessionManager: SessionManager, private val metrics: MetricController ) : SessionManager.Observer { constructor(activity: FragmentActivity) : this( + activity, activity, activity.components.core.sessionManager, activity.metrics @@ -58,6 +62,7 @@ class UriOpenedObserver( } else if (urlLoading != null && !session.private && temporaryFix.shouldSendEvent(session.url)) { temporaryFix.eventSentFor = session.url metrics.track(Event.UriOpened) + context.settings().totalUriCount += 1 } } } diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt index 3c0f10f04..7d451bd72 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/GleanMetricsService.kt @@ -470,6 +470,7 @@ class GleanMetricsService(private val context: Context) : MetricsService { } mozillaProducts.set(MozillaProductDetector.getInstalledMozillaProducts(context)) adjustCampaign.set(context.settings().adjustCampaignId) + totalUriCount.set(context.settings().totalUriCount.toString()) } SearchDefaultEngine.apply { diff --git a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt index 254691817..38a792693 100644 --- a/app/src/main/java/org/mozilla/fenix/utils/Settings.kt +++ b/app/src/main/java/org/mozilla/fenix/utils/Settings.kt @@ -312,6 +312,11 @@ class Settings private constructor( default = 0 ) + var totalUriCount by longPreference( + appContext.getPreferenceKey(R.string.pref_key_total_uri), + default = 0 + ) + fun addSearchWidgetInstalled(count: Int) { val key = appContext.getPreferenceKey(R.string.pref_key_search_widget_installed) val newValue = preferences.getInt(key, 0) + count diff --git a/app/src/main/res/values/preference_keys.xml b/app/src/main/res/values/preference_keys.xml index c285081c0..9a49b11bd 100644 --- a/app/src/main/res/values/preference_keys.xml +++ b/app/src/main/res/values/preference_keys.xml @@ -113,4 +113,6 @@ pref_key_reader_mode_notification pref_key_adjust_campaign pref_key_testing_stage + + pref_key_total_uri diff --git a/app/src/test/java/org/mozilla/fenix/browser/UriOpenedObserverTest.kt b/app/src/test/java/org/mozilla/fenix/browser/UriOpenedObserverTest.kt index 5dee9558f..7e2bb8c73 100644 --- a/app/src/test/java/org/mozilla/fenix/browser/UriOpenedObserverTest.kt +++ b/app/src/test/java/org/mozilla/fenix/browser/UriOpenedObserverTest.kt @@ -4,6 +4,7 @@ package org.mozilla.fenix.browser +import android.content.Context import androidx.lifecycle.LifecycleOwner import io.mockk.every import io.mockk.mockk @@ -17,12 +18,14 @@ import org.mozilla.fenix.components.metrics.MetricController class UriOpenedObserverTest { + private lateinit var context: Context private lateinit var owner: LifecycleOwner private lateinit var sessionManager: SessionManager private lateinit var metrics: MetricController @Before fun setup() { + context = mockk(relaxed = true) owner = mockk(relaxed = true) sessionManager = mockk(relaxed = true) metrics = mockk(relaxed = true) @@ -30,13 +33,13 @@ class UriOpenedObserverTest { @Test fun `registers self as observer`() { - val observer = UriOpenedObserver(owner, sessionManager, metrics) + val observer = UriOpenedObserver(context, owner, sessionManager, metrics) verify { sessionManager.register(observer, owner) } } @Test fun `registers single session observer`() { - val observer = UriOpenedObserver(owner, sessionManager, metrics) + val observer = UriOpenedObserver(context, owner, sessionManager, metrics) val session: Session = mockk(relaxed = true) observer.onSessionAdded(session) @@ -48,7 +51,7 @@ class UriOpenedObserverTest { @Test fun `tracks that a url was loaded`() { - val observer = UriOpenedObserver(owner, sessionManager, metrics).singleSessionObserver + val observer = UriOpenedObserver(context, owner, sessionManager, metrics).singleSessionObserver val session: Session = mockk(relaxed = true) every { session.url } returns "https://mozilla.com" diff --git a/docs/metrics.md b/docs/metrics.md index c8697b49f..94d135d92 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -161,6 +161,7 @@ The following metrics are added to the ping: | metrics.default_moz_browser |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |The name of the default browser on device if and only if it's a Mozilla owned product |[1](https://github.com/mozilla-mobile/fenix/pull/1953/), [2](https://github.com/mozilla-mobile/fenix/pull/5216)||2020-03-01 | | metrics.mozilla_products |[string_list](https://mozilla.github.io/glean/book/user/metrics/string_list.html) |A list of all the Mozilla products installed on device. We currently scan for: Firefox, Firefox Beta, Firefox Aurora, Firefox Nightly, Firefox Fdroid, Firefox Lite, Reference Browser, Reference Browser Debug, Fenix, Focus, and Lockwise. |[1](https://github.com/mozilla-mobile/fenix/pull/1953/), [2](https://github.com/mozilla-mobile/fenix/pull/5216)||2020-03-01 | | metrics.search_count |[labeled_counter](https://mozilla.github.io/glean/book/user/metrics/labeled_counters.html) |The labels for this counter are `.`. If the search engine is bundled with Fenix `search-engine-name` will be the name of the search engine. If it's a custom search engine (defined: https://github.com/mozilla-mobile/fenix/issues/1607) the value will be `custom`. `source` will either be `action` or `suggestion` |[1](https://github.com/mozilla-mobile/fenix/pull/1677), [2](https://github.com/mozilla-mobile/fenix/pull/5216)||2020-03-01 | +| metrics.total_uri_count |[counter](https://mozilla.github.io/glean/book/user/metrics/counter.html) |A counter of URIs visited by the user in the current session, including page reloads. This does not include background page requests and URIs from embedded pages or private browsing. |[1](https://github.com/mozilla-mobile/fenix/pull/TODO)||2020-03-01 | | search.default_engine.code |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |If the search engine is pre-loaded with Fenix this value will be the search engine identifier. If it's a custom search engine (defined: https://github.com/mozilla-mobile/fenix/issues/1607) the value will be "custom" |[1](https://github.com/mozilla-mobile/fenix/pull/1606), [2](https://github.com/mozilla-mobile/fenix/pull/5216)||2020-03-01 | | search.default_engine.name |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |If the search engine is pre-loaded with Fenix this value will be the search engine name. If it's a custom search engine (defined: https://github.com/mozilla-mobile/fenix/issues/1607) the value will be "custom" |[1](https://github.com/mozilla-mobile/fenix/pull/1606), [2](https://github.com/mozilla-mobile/fenix/pull/5216)||2020-03-01 | | search.default_engine.submission_url |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |If the search engine is pre-loaded with Fenix this value will be he base URL we use to build the search query for the search engine. For example: https://mysearchengine.com/?query=%s. If it's a custom search engine (defined: https://github.com/mozilla-mobile/fenix/issues/1607) the value will be "custom" |[1](https://github.com/mozilla-mobile/fenix/pull/1606), [2](https://github.com/mozilla-mobile/fenix/pull/5216)||2020-03-01 |