diff --git a/app/metrics.yaml b/app/metrics.yaml index 0719f3573..b5bb901cc 100644 --- a/app/metrics.yaml +++ b/app/metrics.yaml @@ -1795,6 +1795,19 @@ preferences: notification_emails: - android-probes@mozilla.com expires: "2022-02-01" + search_term_groups_enabled: + type: boolean + description: | + Is search term group in tabs tray on? + bugs: + - https://github.com/mozilla-mobile/fenix/issues/22057 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/22058 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: "2022-11-01" search.default_engine: code: @@ -6002,3 +6015,52 @@ credit_cards: notification_emails: - android-probes@mozilla.com expires: "2022-09-01" + +search_terms: + number_of_search_term_group: + type: event + description: | + Number of search term group when tabs tray is opened. + extra_keys: + count: + description: | + The number of tabs per search group + bugs: + - https://github.com/mozilla-mobile/fenix/issues/22057 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/22058 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: "2022-11-01" + average_tabs_per_group: + type: event + description: | + Number of search term tabs per group when tabs tray is opened. + extra_keys: + count: + description: | + The average number of tabs per search group + bugs: + - https://github.com/mozilla-mobile/fenix/issues/22057 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/22058 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: "2022-11-01" + jump_back_in_group_tapped: + type: event + description: | + User tapped on the jump back in search term group. + bugs: + - https://github.com/mozilla-mobile/fenix/issues/22057 + data_reviews: + - https://github.com/mozilla-mobile/fenix/pull/22058 + data_sensitivity: + - interaction + notification_emails: + - android-probes@mozilla.com + expires: "2022-11-01" diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt index 9af8f941b..04d9d4f04 100644 --- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt +++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt @@ -669,6 +669,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider { voiceSearchEnabled.set(settings.shouldShowVoiceSearch) openLinksInAppEnabled.set(settings.openLinksInExternalApp) signedInSync.set(settings.signedInFxaAccount) + searchTermGroupsEnabled.set(settings.searchTermTabGroupsAreEnabled) val syncedItems = SyncEnginesStorage(applicationContext).getStatus().entries.filter { it.value diff --git a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt index f11cdee93..7d9848c7c 100644 --- a/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt +++ b/app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt @@ -24,6 +24,7 @@ import org.mozilla.fenix.GleanMetrics.Pocket import org.mozilla.fenix.GleanMetrics.Preferences import org.mozilla.fenix.GleanMetrics.ProgressiveWebApp import org.mozilla.fenix.GleanMetrics.SearchShortcuts +import org.mozilla.fenix.GleanMetrics.SearchTerms import org.mozilla.fenix.GleanMetrics.TabsTray import org.mozilla.fenix.GleanMetrics.ToolbarSettings import org.mozilla.fenix.GleanMetrics.TopSites @@ -663,6 +664,18 @@ sealed class Event { get() = mapOf(Events.tabViewChangedKeys.type to type.toString().lowercase(Locale.ROOT)) } + data class SearchTermGroupCount(val count: Int) : Event() { + override val extras: Map + get() = hashMapOf(SearchTerms.numberOfSearchTermGroupKeys.count to count.toString()) + } + + data class AverageTabsPerSearchTermGroup(val averageSize: Double) : Event() { + override val extras: Map + get() = hashMapOf(SearchTerms.averageTabsPerGroupKeys.count to averageSize.toString()) + } + + object JumpBackInGroupTapped : Event() + sealed class Search internal open val extras: Map<*, String>? 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 b70418f53..387fd2a1a 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 @@ -44,6 +44,7 @@ import org.mozilla.fenix.GleanMetrics.RecentBookmarks import org.mozilla.fenix.GleanMetrics.RecentSearches import org.mozilla.fenix.GleanMetrics.RecentTabs import org.mozilla.fenix.GleanMetrics.SearchShortcuts +import org.mozilla.fenix.GleanMetrics.SearchTerms import org.mozilla.fenix.GleanMetrics.SearchWidget import org.mozilla.fenix.GleanMetrics.SetDefaultNewtabExperiment import org.mozilla.fenix.GleanMetrics.SetDefaultSettingExperiment @@ -868,6 +869,17 @@ private val Event.wrapper: EventWrapper<*>? is Event.CreditCardManagementCardTapped -> EventWrapper( { CreditCards.managementCardTapped.record(it) } ) + is Event.SearchTermGroupCount -> EventWrapper( + { SearchTerms.numberOfSearchTermGroup.record(it) }, + { SearchTerms.numberOfSearchTermGroupKeys.valueOf(it) } + ) + is Event.AverageTabsPerSearchTermGroup -> EventWrapper( + { SearchTerms.averageTabsPerGroup.record(it) }, + { SearchTerms.averageTabsPerGroupKeys.valueOf(it) } + ) + is Event.JumpBackInGroupTapped -> EventWrapper( + { SearchTerms.jumpBackInGroupTapped.record(it) } + ) // Don't record other events in Glean: is Event.AddBookmark -> null diff --git a/app/src/main/java/org/mozilla/fenix/home/recenttabs/controller/RecentTabController.kt b/app/src/main/java/org/mozilla/fenix/home/recenttabs/controller/RecentTabController.kt index 4fccfeacd..964837570 100644 --- a/app/src/main/java/org/mozilla/fenix/home/recenttabs/controller/RecentTabController.kt +++ b/app/src/main/java/org/mozilla/fenix/home/recenttabs/controller/RecentTabController.kt @@ -69,6 +69,7 @@ class DefaultRecentTabsController( override fun handleRecentSearchGroupClicked(tabId: String) { selectTabUseCase.invoke(tabId) + metrics.track(Event.JumpBackInGroupTapped) navController.navigate(HomeFragmentDirections.actionGlobalTabsTrayFragment()) } diff --git a/app/src/main/java/org/mozilla/fenix/tabstray/browser/TabSorter.kt b/app/src/main/java/org/mozilla/fenix/tabstray/browser/TabSorter.kt index 172129a98..5ffc90e7b 100644 --- a/app/src/main/java/org/mozilla/fenix/tabstray/browser/TabSorter.kt +++ b/app/src/main/java/org/mozilla/fenix/tabstray/browser/TabSorter.kt @@ -62,6 +62,12 @@ class TabSorter( if (settings.inactiveTabsAreEnabled) { metrics.track(Event.TabsTrayHasInactiveTabs(inactiveTabs.size)) } + + if (groups.isNotEmpty()) { + val averageTabsPerGroup = groups.map { it.tabs.size }.average() + metrics.track(Event.AverageTabsPerSearchTermGroup(averageTabsPerGroup)) + } + metrics.track(Event.SearchTermGroupCount(groups.size)) } } } diff --git a/app/src/main/res/layout/recent_bookmarks_header.xml b/app/src/main/res/layout/recent_bookmarks_header.xml index 0c97c2285..92657a243 100644 --- a/app/src/main/res/layout/recent_bookmarks_header.xml +++ b/app/src/main/res/layout/recent_bookmarks_header.xml @@ -23,7 +23,7 @@ android:paddingTop="1dp" app:layout_constraintStart_toStartOf="parent" app:layout_constraintEnd_toStartOf="@id/showAllBookmarksButton" - app:layout_constraintTop_toTopOf="parent" /> + app:layout_constraintBottom_toBottomOf="parent" /> (), Preferences.syncItems.testGetValue()) assertEquals("fixed_top", Preferences.toolbarPositionSetting.testGetValue()) assertEquals("standard", Preferences.enhancedTrackingProtection.testGetValue()) diff --git a/app/src/test/java/org/mozilla/fenix/components/metrics/MetricControllerTest.kt b/app/src/test/java/org/mozilla/fenix/components/metrics/MetricControllerTest.kt index 8c2e5cf15..a03f7a014 100644 --- a/app/src/test/java/org/mozilla/fenix/components/metrics/MetricControllerTest.kt +++ b/app/src/test/java/org/mozilla/fenix/components/metrics/MetricControllerTest.kt @@ -510,4 +510,27 @@ class MetricControllerTest { assertEquals(message, expectedEvent, controller.factToEvent(fact)) } } + + @Test + fun `search term group events should be sent to enabled service`() { + val controller = ReleaseMetricController( + listOf(dataService1), + isDataTelemetryEnabled = { true }, + isMarketingDataTelemetryEnabled = { true }, + mockk() + ) + every { dataService1.shouldTrack(Event.SearchTermGroupCount(5)) } returns true + every { dataService1.shouldTrack(Event.AverageTabsPerSearchTermGroup(2.5)) } returns true + every { dataService1.shouldTrack(Event.JumpBackInGroupTapped) } returns true + + controller.start(MetricServiceType.Data) + + controller.track(Event.SearchTermGroupCount(5)) + controller.track(Event.AverageTabsPerSearchTermGroup(2.5)) + controller.track(Event.JumpBackInGroupTapped) + + verify { dataService1.track(Event.SearchTermGroupCount(5)) } + verify { dataService1.track(Event.AverageTabsPerSearchTermGroup(2.5)) } + verify { dataService1.track(Event.JumpBackInGroupTapped) } + } }