From d42a15c4fd7107af23ecb2a6d796d5e991f5cc0c Mon Sep 17 00:00:00 2001 From: Jeff Boek Date: Mon, 18 Mar 2019 13:30:25 -0700 Subject: [PATCH 1/7] For #960 - Adds metrics to measure if Fenix is the default browser --- app/metrics.yaml | 20 +++++++++++++++++++ .../components/metrics/GleanMetricsService.kt | 6 ++++++ 2 files changed, 26 insertions(+) create mode 100644 app/metrics.yaml diff --git a/app/metrics.yaml b/app/metrics.yaml new file mode 100644 index 000000000000..ae7d23e73c26 --- /dev/null +++ b/app/metrics.yaml @@ -0,0 +1,20 @@ +# This file defines the metrics that are recorded by glean telemetry. They are +# automatically converted to Kotlin code at build time using the `glean_parser` +# PyPI package. + +$schema: moz://mozilla.org/schemas/glean/metrics/1-0-0 + +metrics: + default_browser: + type: boolean + description: > + Is Fenix the default browser? + send_in_pings: + - metrics + bugs: + - 123456789 + data_reviews: + - N/A + notification_emails: + - telemetry-client-dev@mozilla.com + expires: never \ No newline at end of file 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 bc0996560577..6b6c8a1fba00 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 @@ -5,13 +5,19 @@ package org.mozilla.fenix.components.metrics import android.content.Context import mozilla.components.service.glean.Glean +import mozilla.components.support.utils.Browsers import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.utils.Settings +import org.mozilla.fenix.debug.GleanMetrics.Metrics class GleanMetricsService(private val context: Context) : MetricsService { override fun start() { Glean.initialize(context) Glean.setUploadEnabled(IsGleanEnabled) + + Metrics.apply { + defaultBrowser.set(Browsers.all(context).isDefaultBrowser) + } } override fun track(event: Event) { } From 836e214527916a136e1b2aa4eef76bad43c66aa4 Mon Sep 17 00:00:00 2001 From: Jeff Boek Date: Mon, 18 Mar 2019 14:32:03 -0700 Subject: [PATCH 2/7] For #968 - Adds telemetry for app entry point --- app/metrics.yaml | 15 +++++++++++++++ .../main/java/org/mozilla/fenix/HomeActivity.kt | 12 ++++++++++-- .../components/metrics/GleanMetricsService.kt | 15 +++++++++++++-- .../mozilla/fenix/components/metrics/Metrics.kt | 12 ++++++++++-- .../mozilla/fenix/customtabs/CustomTabActivity.kt | 4 +++- 5 files changed, 51 insertions(+), 7 deletions(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index ae7d23e73c26..2c974162bf54 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -4,6 +4,21 @@ $schema: moz://mozilla.org/schemas/glean/metrics/1-0-0 +events: + app_opened: + type: event + description: > + A User opened the app + extra_keys: + source: "The source from which the app was opened" + bugs: + - 123456789 + data_reviews: + - N/A + notification_emails: + - telemetry-client-dev@mozilla.com + expires: never + metrics: default_browser: type: boolean diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 7287aee733af..933104a26ca8 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -32,6 +32,8 @@ import org.mozilla.fenix.settings.SettingsFragmentDirections @SuppressWarnings("TooManyFunctions") open class HomeActivity : AppCompatActivity() { + open val isCustomTab = false + val themeManager = DefaultThemeManager().also { it.onThemeChange = { theme -> setTheme(theme) @@ -60,16 +62,22 @@ open class HomeActivity : AppCompatActivity() { setSupportActionBar(navigationToolbar) NavigationUI.setupWithNavController(navigationToolbar, navHost.navController, appBarConfiguration) + val safeIntent = intent?.let { SafeIntent(it) } + + if (safeIntent?.isLauncherIntent == true) { + val source = if (isCustomTab) Event.OpenedAppSource.CUSTOM_TAB else Event.OpenedAppSource.APP_ICON + components.analytics.metrics.track(Event.OpenedApp(source)) + } + handleOpenedFromExternalSourceIfNecessary(intent) } - + override fun onResume() { super.onResume() // There is no session, or it has timed out; we should pop everything to home if (components.core.sessionStorage.current() == null) { navHost.navController.popBackStack(R.id.homeFragment, false) } - components.analytics.metrics.track(Event.OpenedApp) } override fun onNewIntent(intent: Intent?) { 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 6b6c8a1fba00..80210a1e8f67 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 @@ -4,11 +4,13 @@ package org.mozilla.fenix.components.metrics import android.content.Context +import mozilla.components.service.glean.EventMetricType import mozilla.components.service.glean.Glean import mozilla.components.support.utils.Browsers import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.utils.Settings import org.mozilla.fenix.debug.GleanMetrics.Metrics +import org.mozilla.fenix.debug.GleanMetrics.Events class GleanMetricsService(private val context: Context) : MetricsService { override fun start() { @@ -20,9 +22,18 @@ class GleanMetricsService(private val context: Context) : MetricsService { } } - override fun track(event: Event) { } + private fun mapEventToGlean(event: Event): EventMetricType? = when(event) { + is Event.OpenedApp -> Events.appOpened + else -> null + } + + override fun track(event: Event) { + mapEventToGlean(event)?.record(event.extras) + } - override fun shouldTrack(event: Event): Boolean = Settings.getInstance(context).isTelemetryEnabled + override fun shouldTrack(event: Event): Boolean { + return Settings.getInstance(context).isTelemetryEnabled + } companion object { private const val IsGleanEnabled = BuildConfig.TELEMETRY diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt index 710983f18479..915cba6f9046 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt @@ -9,7 +9,15 @@ sealed class Event { object AddBookmark : Event() object RemoveBookmark : Event() object OpenedBookmark : Event() - object OpenedApp : Event() + + enum class OpenedAppSource { + APP_ICON, CUSTOM_TAB + } + data class OpenedApp(val source: OpenedAppSource) : Event() { + override val extras: Map? + get() = hashMapOf("source" to source.name) + } + object OpenedAppFirstRun : Event() object InteractWithSearchURLArea : Event() object SavedLoginandPassword : Event() @@ -38,7 +46,7 @@ sealed class Event { object OpenedPocketStory : Event() object DarkModeEnabled : Event() - val extras: Map? + open val extras: Map? get() = null } diff --git a/app/src/main/java/org/mozilla/fenix/customtabs/CustomTabActivity.kt b/app/src/main/java/org/mozilla/fenix/customtabs/CustomTabActivity.kt index d42a1c4f21a5..5132bf319274 100644 --- a/app/src/main/java/org/mozilla/fenix/customtabs/CustomTabActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/customtabs/CustomTabActivity.kt @@ -6,4 +6,6 @@ package org.mozilla.fenix.customtabs import org.mozilla.fenix.HomeActivity -class CustomTabActivity : HomeActivity() +class CustomTabActivity : HomeActivity() { + override val isCustomTab = true +} From 75dd80f036396bbc8fc4ab44a230244e8c627fe9 Mon Sep 17 00:00:00 2001 From: Jeff Boek Date: Mon, 18 Mar 2019 14:54:36 -0700 Subject: [PATCH 3/7] For #959 - Adds telemetry for when the search bar is tapped --- app/metrics.yaml | 15 ++++++++++++++- .../main/java/org/mozilla/fenix/HomeActivity.kt | 2 +- .../org/mozilla/fenix/browser/BrowserFragment.kt | 16 +++++++++++----- .../components/metrics/GleanMetricsService.kt | 16 +++++++++------- .../components/metrics/LeanplumMetricsService.kt | 11 ++++++++--- .../mozilla/fenix/components/metrics/Metrics.kt | 14 ++++++++++---- .../java/org/mozilla/fenix/home/HomeFragment.kt | 3 +++ 7 files changed, 56 insertions(+), 21 deletions(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index 2c974162bf54..df33885957cf 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -8,7 +8,7 @@ events: app_opened: type: event description: > - A User opened the app + A user opened the app extra_keys: source: "The source from which the app was opened" bugs: @@ -18,6 +18,19 @@ events: notification_emails: - telemetry-client-dev@mozilla.com expires: never + search_bar_tapped: + type: event + description: > + A user tapped the search bar + extra_keys: + source: "The source from which the search bar was tapped" + bugs: + - 123456789 + data_reviews: + - N/A + notification_emails: + - telemetry-client-dev@mozilla.com + expires: never metrics: default_browser: diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 933104a26ca8..bcca742e504e 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -65,7 +65,7 @@ open class HomeActivity : AppCompatActivity() { val safeIntent = intent?.let { SafeIntent(it) } if (safeIntent?.isLauncherIntent == true) { - val source = if (isCustomTab) Event.OpenedAppSource.CUSTOM_TAB else Event.OpenedAppSource.APP_ICON + val source = if (isCustomTab) Event.OpenedApp.Source.CUSTOM_TAB else Event.OpenedApp.Source.APP_ICON components.analytics.metrics.track(Event.OpenedApp(source)) } diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt index a21398933eab..bfdd020763ca 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -42,6 +42,7 @@ import org.mozilla.fenix.IntentReceiverActivity import org.mozilla.fenix.utils.ItsNotBrokenSnack import org.mozilla.fenix.R import org.mozilla.fenix.components.FindInPageIntegration +import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.toolbar.SearchAction import org.mozilla.fenix.components.toolbar.SearchState import org.mozilla.fenix.components.toolbar.ToolbarComponent @@ -242,11 +243,16 @@ class BrowserFragment : Fragment(), BackHandler { getAutoDisposeObservable() .subscribe { when (it) { - is SearchAction.ToolbarTapped -> Navigation.findNavController(toolbarComponent.getView()) - .navigate( - BrowserFragmentDirections.actionBrowserFragmentToSearchFragment( - requireComponents.core.sessionManager.selectedSession?.id) - ) + is SearchAction.ToolbarTapped -> { + Navigation + .findNavController(toolbarComponent.getView()) + .navigate( + BrowserFragmentDirections.actionBrowserFragmentToSearchFragment( + requireComponents.core.sessionManager.selectedSession?.id) + ) + + requireComponents.analytics.metrics.track(Event.SearchBarTapped(Event.SearchBarTapped.Source.BROWSER)) + } is SearchAction.ToolbarMenuItemTapped -> handleToolbarItemInteraction(it) } } 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 80210a1e8f67..ab7e1f836795 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 @@ -12,6 +12,13 @@ import org.mozilla.fenix.utils.Settings import org.mozilla.fenix.debug.GleanMetrics.Metrics import org.mozilla.fenix.debug.GleanMetrics.Events +private val Event.metricType: EventMetricType? + get() = when(this) { + is Event.OpenedApp -> Events.appOpened + is Event.SearchBarTapped -> Events.searchBarTapped + else -> null + } + class GleanMetricsService(private val context: Context) : MetricsService { override fun start() { Glean.initialize(context) @@ -22,17 +29,12 @@ class GleanMetricsService(private val context: Context) : MetricsService { } } - private fun mapEventToGlean(event: Event): EventMetricType? = when(event) { - is Event.OpenedApp -> Events.appOpened - else -> null - } - override fun track(event: Event) { - mapEventToGlean(event)?.record(event.extras) + event.metricType?.record(event.extras) } override fun shouldTrack(event: Event): Boolean { - return Settings.getInstance(context).isTelemetryEnabled + return Settings.getInstance(context).isTelemetryEnabled && event.metricType != null } companion object { diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/LeanplumMetricsService.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/LeanplumMetricsService.kt index 9e6cb48c5409..5e520f1242f0 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/LeanplumMetricsService.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/LeanplumMetricsService.kt @@ -11,7 +11,7 @@ import com.leanplum.annotations.Parser import org.mozilla.fenix.BuildConfig import org.mozilla.fenix.utils.Settings -private val Event.name: String +private val Event.name: String? get() = when (this) { is Event.AddBookmark -> "E_Add_Bookmark" is Event.RemoveBookmark -> "E_Remove_Bookmark" @@ -44,6 +44,9 @@ private val Event.name: String is Event.UserDownloadedSend -> "E_User_Downloaded_Send" is Event.OpenedPocketStory -> "E_Opened_Pocket_Story" is Event.DarkModeEnabled -> "E_Dark_Mode_Enabled" + + // Do not track these events in Leanplum + is Event.SearchBarTapped -> "" } class LeanplumMetricsService(private val application: Application) : MetricsService { @@ -84,12 +87,14 @@ class LeanplumMetricsService(private val application: Application) : MetricsServ } override fun track(event: Event) { - Leanplum.track(event.name, event.extras) + event.name?.also { + Leanplum.track(it, event.extras) + } } override fun shouldTrack(event: Event): Boolean { return Settings.getInstance(application).isTelemetryEnabled && - token.type != Token.Type.Invalid + token.type != Token.Type.Invalid && !event.name.isNullOrEmpty() } companion object { diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt index 915cba6f9046..1582bfa8d0ef 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt @@ -10,10 +10,9 @@ sealed class Event { object RemoveBookmark : Event() object OpenedBookmark : Event() - enum class OpenedAppSource { - APP_ICON, CUSTOM_TAB - } - data class OpenedApp(val source: OpenedAppSource) : Event() { + + data class OpenedApp(val source: Source) : Event() { + enum class Source { APP_ICON, CUSTOM_TAB } override val extras: Map? get() = hashMapOf("source" to source.name) } @@ -46,6 +45,13 @@ sealed class Event { object OpenedPocketStory : Event() object DarkModeEnabled : Event() + // Interaction Events + data class SearchBarTapped(val source: Source) : Event() { + enum class Source { HOME, BROWSER } + override val extras: Map? + get() = mapOf("source" to source.name) + } + open val extras: Map? get() = null } diff --git a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt index 78426bb071f6..721ba813497b 100644 --- a/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/home/HomeFragment.kt @@ -35,6 +35,7 @@ import org.mozilla.fenix.DefaultThemeManager import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.utils.ItsNotBrokenSnack import org.mozilla.fenix.R +import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.ext.archive import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.home.sessions.ArchivedSession @@ -134,6 +135,8 @@ class HomeFragment : Fragment(), CoroutineScope { view.toolbar.setOnClickListener { val directions = HomeFragmentDirections.actionHomeFragmentToSearchFragment(null) Navigation.findNavController(it).navigate(directions) + + requireComponents.analytics.metrics.track(Event.SearchBarTapped(Event.SearchBarTapped.Source.HOME)) } // There is currently an issue with visibility changes in ConstraintLayout 2.0.0-alpha3 From 7787507597bc5b5bf09059243180695692194e63 Mon Sep 17 00:00:00 2001 From: Jeff Boek Date: Mon, 18 Mar 2019 16:09:27 -0700 Subject: [PATCH 4/7] For #959 - Adds search related telemetry --- app/metrics.yaml | 26 +++++++ .../components/metrics/GleanMetricsService.kt | 2 + .../metrics/LeanplumMetricsService.kt | 70 ++++++++++--------- .../fenix/components/metrics/Metrics.kt | 10 +++ .../mozilla/fenix/search/SearchFragment.kt | 12 ++++ 5 files changed, 86 insertions(+), 34 deletions(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index df33885957cf..e37db893479d 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -31,6 +31,32 @@ events: notification_emails: - telemetry-client-dev@mozilla.com expires: never + entered_url: + type: event + description: > + A user entered a url + extra_keys: + autocomplete: "The url was filled by the autocomplete" + bugs: + - 123456789 + data_reviews: + - N/A + notification_emails: + - telemetry-client-dev@mozilla.com + expires: never + performed_search: + type: event + description: > + A user performed a search + extra_keys: + search_suggestion: "The search was initiated from a search suggestion" + bugs: + - 123456789 + data_reviews: + - N/A + notification_emails: + - telemetry-client-dev@mozilla.com + expires: never metrics: default_browser: 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 ab7e1f836795..770a8e281a18 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 @@ -16,6 +16,8 @@ private val Event.metricType: EventMetricType? get() = when(this) { is Event.OpenedApp -> Events.appOpened is Event.SearchBarTapped -> Events.searchBarTapped + is Event.EnteredUrl -> Events.enteredUrl + is Event.PerformedSearch -> Events.performedSearch else -> null } diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/LeanplumMetricsService.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/LeanplumMetricsService.kt index 5e520f1242f0..3d0bcccbcebc 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/LeanplumMetricsService.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/LeanplumMetricsService.kt @@ -13,41 +13,43 @@ import org.mozilla.fenix.utils.Settings private val Event.name: String? get() = when (this) { - is Event.AddBookmark -> "E_Add_Bookmark" - is Event.RemoveBookmark -> "E_Remove_Bookmark" - is Event.OpenedBookmark -> "E_Opened_Bookmark" - is Event.OpenedApp -> "E_Opened_App" - is Event.OpenedAppFirstRun -> "E_Opened_App_FirstRun" - is Event.InteractWithSearchURLArea -> "E_Interact_With_Search_URL_Area" - is Event.SavedLoginandPassword -> "E_Saved_Login_and_Password" - is Event.FXANewSignup -> "E_FXA_New_Signup" - is Event.UserSignedInToFxA -> "E_User_Signed_In_To_FxA" - is Event.UserDownloadedFocus -> "E_User_Downloaded_Focus" - is Event.UserDownloadedLockbox -> "E_User_Downloaded_Lockbox" - is Event.UserDownloadedFennec -> "E_User_Downloaded_Fennec" - is Event.TrackingProtectionSettingsChanged -> "E_Tracking_Protection_Settings_Changed" - is Event.FXASyncedNewDevice -> "E_FXA_Synced_New_Device" - is Event.DismissedOnboarding -> "E_Dismissed_Onboarding" - is Event.Uninstall -> "E_Uninstall" - is Event.OpenNewNormalTab -> "E_Open_New_Normal_Tab" - is Event.OpenNewPrivateTab -> "E_Open_New_Private_Tab" - is Event.ShareStarted -> "E_Share_Started" - is Event.ShareCanceled -> "E_Share_Canceled" - is Event.ShareCompleted -> "E_Share_Completed" - is Event.ClosePrivateTabs -> "E_Close_Private_Tabs" - is Event.ClearedPrivateData -> "E_Cleared_Private_Data" - is Event.OpenedLoginManager -> "E_Opened_Login_Manager" - is Event.OpenedMailtoLink -> "E_Opened_Mailto_Link" - is Event.DownloadMediaSavedImage -> "E_Download_Media_Saved_Image" - is Event.UserUsedReaderView -> "E_User_Used_Reader_View" - is Event.UserDownloadedPocket -> "E_User_Downloaded_Pocket" - is Event.UserDownloadedSend -> "E_User_Downloaded_Send" - is Event.OpenedPocketStory -> "E_Opened_Pocket_Story" - is Event.DarkModeEnabled -> "E_Dark_Mode_Enabled" + is Event.AddBookmark -> "E_Add_Bookmark" + is Event.RemoveBookmark -> "E_Remove_Bookmark" + is Event.OpenedBookmark -> "E_Opened_Bookmark" + is Event.OpenedApp -> "E_Opened_App" + is Event.OpenedAppFirstRun -> "E_Opened_App_FirstRun" + is Event.InteractWithSearchURLArea -> "E_Interact_With_Search_URL_Area" + is Event.SavedLoginandPassword -> "E_Saved_Login_and_Password" + is Event.FXANewSignup -> "E_FXA_New_Signup" + is Event.UserSignedInToFxA -> "E_User_Signed_In_To_FxA" + is Event.UserDownloadedFocus -> "E_User_Downloaded_Focus" + is Event.UserDownloadedLockbox -> "E_User_Downloaded_Lockbox" + is Event.UserDownloadedFennec -> "E_User_Downloaded_Fennec" + is Event.TrackingProtectionSettingsChanged -> "E_Tracking_Protection_Settings_Changed" + is Event.FXASyncedNewDevice -> "E_FXA_Synced_New_Device" + is Event.DismissedOnboarding -> "E_Dismissed_Onboarding" + is Event.Uninstall -> "E_Uninstall" + is Event.OpenNewNormalTab -> "E_Open_New_Normal_Tab" + is Event.OpenNewPrivateTab -> "E_Open_New_Private_Tab" + is Event.ShareStarted -> "E_Share_Started" + is Event.ShareCanceled -> "E_Share_Canceled" + is Event.ShareCompleted -> "E_Share_Completed" + is Event.ClosePrivateTabs -> "E_Close_Private_Tabs" + is Event.ClearedPrivateData -> "E_Cleared_Private_Data" + is Event.OpenedLoginManager -> "E_Opened_Login_Manager" + is Event.OpenedMailtoLink -> "E_Opened_Mailto_Link" + is Event.DownloadMediaSavedImage -> "E_Download_Media_Saved_Image" + is Event.UserUsedReaderView -> "E_User_Used_Reader_View" + is Event.UserDownloadedPocket -> "E_User_Downloaded_Pocket" + is Event.UserDownloadedSend -> "E_User_Downloaded_Send" + is Event.OpenedPocketStory -> "E_Opened_Pocket_Story" + is Event.DarkModeEnabled -> "E_Dark_Mode_Enabled" - // Do not track these events in Leanplum - is Event.SearchBarTapped -> "" -} + // Do not track these events in Leanplum + is Event.SearchBarTapped -> "" + is Event.EnteredUrl -> "" + is Event.PerformedSearch -> "" + } class LeanplumMetricsService(private val application: Application) : MetricsService { data class Token(val id: String, val token: String) { diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt index 1582bfa8d0ef..deb995f1f497 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt @@ -52,6 +52,16 @@ sealed class Event { get() = mapOf("source" to source.name) } + data class EnteredUrl(val autoCompleted: Boolean) : Event() { + override val extras: Map? + get() = mapOf("autocomplete" to autoCompleted.toString()) + } + + data class PerformedSearch(val fromSearchSuggestion: Boolean) : Event() { + override val extras: Map? + get() = mapOf("search_suggestion" to fromSearchSuggestion.toString()) + } + open val extras: Map? get() = null } diff --git a/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt b/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt index 0f1ab640982e..9a25a9118a73 100644 --- a/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/search/SearchFragment.kt @@ -14,10 +14,12 @@ import androidx.fragment.app.Fragment import kotlinx.android.synthetic.main.fragment_search.view.* import mozilla.components.feature.search.SearchUseCases import mozilla.components.feature.session.SessionUseCases +import mozilla.components.support.ktx.kotlin.isUrl import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.utils.ItsNotBrokenSnack import org.mozilla.fenix.R +import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.components.toolbar.SearchAction import org.mozilla.fenix.components.toolbar.SearchState import org.mozilla.fenix.components.toolbar.ToolbarComponent @@ -92,6 +94,14 @@ class SearchFragment : Fragment() { if (it.url.isNotBlank()) { (activity as HomeActivity).openToBrowserAndLoad(it.url, it.session, BrowserDirection.FromSearch) + + val event = if (it.url.isUrl()) { + Event.EnteredUrl(false) + } else { + Event.PerformedSearch(false) + } + + requireComponents.analytics.metrics.track(event) } } is SearchAction.TextChanged -> { @@ -109,11 +119,13 @@ class SearchFragment : Fragment() { is AwesomeBarAction.URLTapped -> { getSessionUseCase(requireContext(), sessionId == null).invoke(it.url) (activity as HomeActivity).openToBrowser(sessionId, BrowserDirection.FromSearch) + requireComponents.analytics.metrics.track(Event.EnteredUrl(false)) } is AwesomeBarAction.SearchTermsTapped -> { getSearchUseCase(requireContext(), sessionId == null) .invoke(it.searchTerms, it.engine) (activity as HomeActivity).openToBrowser(sessionId, BrowserDirection.FromSearch) + requireComponents.analytics.metrics.track(Event.PerformedSearch(true)) } } } From 5190e80723284859ba33f008d3257dc97d240764 Mon Sep 17 00:00:00 2001 From: Jeff Boek Date: Mon, 18 Mar 2019 20:49:17 -0700 Subject: [PATCH 5/7] For #986 - Adds support for opening Fenix with a link to telemetry --- .../main/java/org/mozilla/fenix/HomeActivity.kt | 17 +++++++++++------ .../mozilla/fenix/browser/BrowserFragment.kt | 4 +++- .../components/metrics/GleanMetricsService.kt | 2 +- .../mozilla/fenix/components/metrics/Metrics.kt | 3 +-- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index bcca742e504e..9d2489b0bba2 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -62,12 +62,17 @@ open class HomeActivity : AppCompatActivity() { setSupportActionBar(navigationToolbar) NavigationUI.setupWithNavController(navigationToolbar, navHost.navController, appBarConfiguration) - val safeIntent = intent?.let { SafeIntent(it) } - - if (safeIntent?.isLauncherIntent == true) { - val source = if (isCustomTab) Event.OpenedApp.Source.CUSTOM_TAB else Event.OpenedApp.Source.APP_ICON - components.analytics.metrics.track(Event.OpenedApp(source)) - } + intent + ?.let { SafeIntent(it) } + ?.let { + when { + isCustomTab -> Event.OpenedApp.Source.CUSTOM_TAB + it.isLauncherIntent -> Event.OpenedApp.Source.APP_ICON + it.action == Intent.ACTION_VIEW -> Event.OpenedApp.Source.LINK + else -> null + } + } + ?.also { components.analytics.metrics.track(Event.OpenedApp(it)) } handleOpenedFromExternalSourceIfNecessary(intent) } diff --git a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt index bfdd020763ca..e4d66646dc04 100644 --- a/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt +++ b/app/src/main/java/org/mozilla/fenix/browser/BrowserFragment.kt @@ -251,7 +251,9 @@ class BrowserFragment : Fragment(), BackHandler { requireComponents.core.sessionManager.selectedSession?.id) ) - requireComponents.analytics.metrics.track(Event.SearchBarTapped(Event.SearchBarTapped.Source.BROWSER)) + requireComponents.analytics.metrics.track( + Event.SearchBarTapped(Event.SearchBarTapped.Source.BROWSER) + ) } is SearchAction.ToolbarMenuItemTapped -> handleToolbarItemInteraction(it) } 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 770a8e281a18..e57afbfef162 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 @@ -13,7 +13,7 @@ import org.mozilla.fenix.debug.GleanMetrics.Metrics import org.mozilla.fenix.debug.GleanMetrics.Events private val Event.metricType: EventMetricType? - get() = when(this) { + get() = when (this) { is Event.OpenedApp -> Events.appOpened is Event.SearchBarTapped -> Events.searchBarTapped is Event.EnteredUrl -> Events.enteredUrl diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt index deb995f1f497..84d2b3193f28 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/Metrics.kt @@ -10,9 +10,8 @@ sealed class Event { object RemoveBookmark : Event() object OpenedBookmark : Event() - data class OpenedApp(val source: Source) : Event() { - enum class Source { APP_ICON, CUSTOM_TAB } + enum class Source { APP_ICON, LINK, CUSTOM_TAB } override val extras: Map? get() = hashMapOf("source" to source.name) } From 6cf4e72372a2ed0d1b1c61ecba1ef0445af82549 Mon Sep 17 00:00:00 2001 From: Jeff Boek Date: Tue, 19 Mar 2019 14:58:49 -0700 Subject: [PATCH 6/7] Documents new telemetry events --- app/metrics.yaml | 20 ++++++++++---------- docs/telemetry.md | 22 ++++++++++++++++++---- 2 files changed, 28 insertions(+), 14 deletions(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index e37db893479d..50acb00db1b3 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -12,9 +12,9 @@ events: extra_keys: source: "The source from which the app was opened" bugs: - - 123456789 + - 968 data_reviews: - - N/A + - https://github.com/mozilla-mobile/fenix/pull/1067#issuecomment-474598673 notification_emails: - telemetry-client-dev@mozilla.com expires: never @@ -25,9 +25,9 @@ events: extra_keys: source: "The source from which the search bar was tapped" bugs: - - 123456789 + - 959 data_reviews: - - N/A + - https://github.com/mozilla-mobile/fenix/pull/1067#issuecomment-474598673 notification_emails: - telemetry-client-dev@mozilla.com expires: never @@ -38,9 +38,9 @@ events: extra_keys: autocomplete: "The url was filled by the autocomplete" bugs: - - 123456789 + - 959 data_reviews: - - N/A + - https://github.com/mozilla-mobile/fenix/pull/1067#issuecomment-474598673 notification_emails: - telemetry-client-dev@mozilla.com expires: never @@ -51,9 +51,9 @@ events: extra_keys: search_suggestion: "The search was initiated from a search suggestion" bugs: - - 123456789 + - 959 data_reviews: - - N/A + - https://github.com/mozilla-mobile/fenix/pull/1067#issuecomment-474598673 notification_emails: - telemetry-client-dev@mozilla.com expires: never @@ -66,9 +66,9 @@ metrics: send_in_pings: - metrics bugs: - - 123456789 + - 960 data_reviews: - - N/A + - https://github.com/mozilla-mobile/fenix/pull/1067#issuecomment-474598673 notification_emails: - telemetry-client-dev@mozilla.com expires: never \ No newline at end of file diff --git a/docs/telemetry.md b/docs/telemetry.md index 8f06202eaa39..152d8eed8517 100644 --- a/docs/telemetry.md +++ b/docs/telemetry.md @@ -4,10 +4,24 @@ Fenix uses Mozilla's telemetry service (Glean) and LeanPlum to measure feature p ## Baseline ping -Fenix creates and tries to send a "baseline" ping when the app goes to the background. This baseline ping is defined by the [Glean](https://github.com/mozilla-mobile/android-components/tree/master/components/service/glean) component and [documented in the Android Components repository](https://github.com/mozilla-mobile/android-components/blob/master/components/service/glean/docs/baseline.md). +Fenix creates and tries to send a "baseline" ping when the app goes to the background. This baseline ping is defined by the [Glean](https://github.com/mozilla-mobile/android-components/tree/master/components/service/glean) component and [documented in the Android Components repository](https://github.com/mozilla-mobile/android-components/blob/master/components/service/glean/docs/pings/baseline.md). + +## Metrics ping + +Fenix creates and tries to send a "baseline" ping. It is defined inside the [`metrics.yaml`](https://github.com/mozilla-mobile/fenix/blob/master/app/metrics.yaml) file. This ping includes things like wether or not Fenix is currently the default browser. ## Events -| Event | Glean Key | Leanplum Key | extras | -|-----------|-----------|--------------|--------| -| OpenedApp | | E_Opened_App | | \ No newline at end of file +Fenix sends event pings that allows us to measure feature performance. + +| Event | Glean Key | Leanplum Key | extras | +|-----------------|-------------------|--------------|-----------------------| +| OpenedApp | app_opened | E_Opened_App | source* | +| SearchBarTapped | search_bar_tapped | | source** | +| EnteredUrl | entered_url | | autocomplete*** | +| PerformedSearch | performed_search | | search_suggestion**** | + +* `source`: The method used to open Fenix (For exmaple: `app_icon` or `link`) +** `source`: The view the user was on when they initiated the search (For example: `Home` or `Browser`) +*** `autocomplete`: A boolean that tells us wether the URL was autofilled by an Autocomplete suggestion +**** `search_suggestion`: A boolean that tells us wether or not the search term was suggested by the Awesomebar \ No newline at end of file From 2de49bd7c49f56bf66d7bf7d805a07cd383f3c49 Mon Sep 17 00:00:00 2001 From: Jeff Boek Date: Thu, 21 Mar 2019 23:05:28 -0700 Subject: [PATCH 7/7] Addresses metrics nits --- app/metrics.yaml | 29 +++++++++++-------- .../java/org/mozilla/fenix/HomeActivity.kt | 2 +- .../components/metrics/GleanMetricsService.kt | 29 ++++++++++++++----- docs/telemetry.md | 22 ++++++-------- 4 files changed, 49 insertions(+), 33 deletions(-) diff --git a/app/metrics.yaml b/app/metrics.yaml index 50acb00db1b3..97b04b3740f9 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -1,6 +1,7 @@ -# This file defines the metrics that are recorded by glean telemetry. They are -# automatically converted to Kotlin code at build time using the `glean_parser` -# PyPI package. +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + $schema: moz://mozilla.org/schemas/glean/metrics/1-0-0 @@ -10,53 +11,57 @@ events: description: > A user opened the app extra_keys: - source: "The source from which the app was opened" + source: + description: "The method used to open Fenix. Possible values are: `app_icon`, `custom_tab` or `link`" bugs: - 968 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/1067#issuecomment-474598673 notification_emails: - telemetry-client-dev@mozilla.com - expires: never + expires: "2020-03-01" search_bar_tapped: type: event description: > A user tapped the search bar extra_keys: - source: "The source from which the search bar was tapped" + source: + description: "The view the user was on when they initiated the search (For example: `Home` or `Browser`)" bugs: - 959 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/1067#issuecomment-474598673 notification_emails: - telemetry-client-dev@mozilla.com - expires: never + expires: "2020-03-01" entered_url: type: event description: > A user entered a url extra_keys: - autocomplete: "The url was filled by the autocomplete" + autocomplete: + description: "A boolean that tells us whether the URL was autofilled by an Autocomplete suggestion" bugs: - 959 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/1067#issuecomment-474598673 notification_emails: - telemetry-client-dev@mozilla.com - expires: never + expires: "2020-03-01" performed_search: type: event description: > A user performed a search extra_keys: - search_suggestion: "The search was initiated from a search suggestion" + search_suggestion: + description: "A boolean that tells us whether or not the search term was suggested by the Awesomebar" bugs: - 959 data_reviews: - https://github.com/mozilla-mobile/fenix/pull/1067#issuecomment-474598673 notification_emails: - telemetry-client-dev@mozilla.com - expires: never + expires: "2020-03-01" metrics: default_browser: @@ -71,4 +76,4 @@ metrics: - https://github.com/mozilla-mobile/fenix/pull/1067#issuecomment-474598673 notification_emails: - telemetry-client-dev@mozilla.com - expires: never \ No newline at end of file + expires: "2020-03-01" \ No newline at end of file diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 9d2489b0bba2..1506a3aa3d5c 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -76,7 +76,7 @@ open class HomeActivity : AppCompatActivity() { handleOpenedFromExternalSourceIfNecessary(intent) } - + override fun onResume() { super.onResume() // There is no session, or it has timed out; we should pop everything to home 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 e57afbfef162..81190eb27e36 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 @@ -12,12 +12,27 @@ import org.mozilla.fenix.utils.Settings import org.mozilla.fenix.debug.GleanMetrics.Metrics import org.mozilla.fenix.debug.GleanMetrics.Events -private val Event.metricType: EventMetricType? +private class EventWrapper>( + private val event: EventMetricType, + private val keyMapper: ((String) -> T)? = null +) { + fun track(event: Event) { + val extras = if (keyMapper != null) { + event.extras?.mapKeys { keyMapper.invoke(it.key) } + } else { + null + } + + this.event.record(extras) + } +} + +private val Event.wrapper get() = when (this) { - is Event.OpenedApp -> Events.appOpened - is Event.SearchBarTapped -> Events.searchBarTapped - is Event.EnteredUrl -> Events.enteredUrl - is Event.PerformedSearch -> Events.performedSearch + is Event.OpenedApp -> EventWrapper(Events.appOpened) { Events.appOpenedKeys.valueOf(it) } + is Event.SearchBarTapped -> EventWrapper(Events.searchBarTapped) { Events.searchBarTappedKeys.valueOf(it) } + is Event.EnteredUrl -> EventWrapper(Events.enteredUrl) { Events.enteredUrlKeys.valueOf(it) } + is Event.PerformedSearch -> EventWrapper(Events.performedSearch) { Events.performedSearchKeys.valueOf(it) } else -> null } @@ -32,11 +47,11 @@ class GleanMetricsService(private val context: Context) : MetricsService { } override fun track(event: Event) { - event.metricType?.record(event.extras) + event.wrapper?.track(event) } override fun shouldTrack(event: Event): Boolean { - return Settings.getInstance(context).isTelemetryEnabled && event.metricType != null + return Settings.getInstance(context).isTelemetryEnabled && event.wrapper != null } companion object { diff --git a/docs/telemetry.md b/docs/telemetry.md index 152d8eed8517..121cb95ed771 100644 --- a/docs/telemetry.md +++ b/docs/telemetry.md @@ -12,16 +12,12 @@ Fenix creates and tries to send a "baseline" ping. It is defined inside the [`me ## Events -Fenix sends event pings that allows us to measure feature performance. - -| Event | Glean Key | Leanplum Key | extras | -|-----------------|-------------------|--------------|-----------------------| -| OpenedApp | app_opened | E_Opened_App | source* | -| SearchBarTapped | search_bar_tapped | | source** | -| EnteredUrl | entered_url | | autocomplete*** | -| PerformedSearch | performed_search | | search_suggestion**** | - -* `source`: The method used to open Fenix (For exmaple: `app_icon` or `link`) -** `source`: The view the user was on when they initiated the search (For example: `Home` or `Browser`) -*** `autocomplete`: A boolean that tells us wether the URL was autofilled by an Autocomplete suggestion -**** `search_suggestion`: A boolean that tells us wether or not the search term was suggested by the Awesomebar \ No newline at end of file +Fenix sends event pings that allows us to measure feature performance. These are defined inside the [`metrics.yaml`](https://github.com/mozilla-mobile/fenix/blob/master/app/metrics.yaml) file. + +## Leanplum Events + +| Event | Leanplum Key | extras | +|-----------------|---------------|-----------------------| +| OpenedApp | E_Opened_App | source* | + +* `source`: The method used to open Fenix (For exmaple: `app_icon`, `custom_tab` or `link`) \ No newline at end of file