Close #22172: Add Recent searches telemetry (#22369)

pull/415/head
Roger Yang 3 years ago committed by GitHub
parent 636606d71c
commit 7361c3a785
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -2635,6 +2635,25 @@ history:
- android-probes@mozilla.com - android-probes@mozilla.com
- erichards@mozilla.com - erichards@mozilla.com
expires: never expires: never
recent_searches_tapped:
type: event
description: |
User has tapped on a recent searches card in home.
extra_keys:
page_number:
description: |
The page number in the homescreen carousel that the recent searches
card was on.
bugs:
- https://github.com/mozilla-mobile/fenix/issues/22172
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/22173
data_sensitivity:
- interaction
notification_emails:
- android-probes@mozilla.com
expires: "2022-11-01"
reader_mode: reader_mode:
available: available:

@ -17,6 +17,7 @@ import org.mozilla.fenix.GleanMetrics.ContextMenu
import org.mozilla.fenix.GleanMetrics.CrashReporter import org.mozilla.fenix.GleanMetrics.CrashReporter
import org.mozilla.fenix.GleanMetrics.ErrorPage import org.mozilla.fenix.GleanMetrics.ErrorPage
import org.mozilla.fenix.GleanMetrics.Events import org.mozilla.fenix.GleanMetrics.Events
import org.mozilla.fenix.GleanMetrics.History
import org.mozilla.fenix.GleanMetrics.Logins import org.mozilla.fenix.GleanMetrics.Logins
import org.mozilla.fenix.GleanMetrics.Onboarding import org.mozilla.fenix.GleanMetrics.Onboarding
import org.mozilla.fenix.GleanMetrics.Pocket import org.mozilla.fenix.GleanMetrics.Pocket
@ -81,6 +82,9 @@ sealed class Event {
object HistoryOpenedInPrivateTabs : Event() object HistoryOpenedInPrivateTabs : Event()
object HistoryItemRemoved : Event() object HistoryItemRemoved : Event()
object HistoryAllItemsRemoved : Event() object HistoryAllItemsRemoved : Event()
data class HistoryRecentSearchesTapped(val source: String) : Event() {
override val extras = mapOf(History.recentSearchesTappedKeys.pageNumber to source)
}
object ReaderModeAvailable : Event() object ReaderModeAvailable : Event()
object ReaderModeOpened : Event() object ReaderModeOpened : Event()
object ReaderModeClosed : Event() object ReaderModeClosed : Event()

@ -315,6 +315,10 @@ private val Event.wrapper: EventWrapper<*>?
is Event.HistoryAllItemsRemoved -> EventWrapper<NoExtraKeys>( is Event.HistoryAllItemsRemoved -> EventWrapper<NoExtraKeys>(
{ History.removedAll.record(it) } { History.removedAll.record(it) }
) )
is Event.HistoryRecentSearchesTapped -> EventWrapper(
{ History.recentSearchesTapped.record(it) },
{ History.recentSearchesTappedKeys.valueOf(it) }
)
is Event.CollectionRenamed -> EventWrapper<NoExtraKeys>( is Event.CollectionRenamed -> EventWrapper<NoExtraKeys>(
{ Collections.renamed.record(it) } { Collections.renamed.record(it) }
) )

@ -10,6 +10,8 @@ import androidx.compose.ui.platform.ViewCompositionStrategy
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import mozilla.components.lib.state.ext.observeAsComposableState import mozilla.components.lib.state.ext.observeAsComposableState
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.historymetadata.interactor.HistoryMetadataInteractor import org.mozilla.fenix.historymetadata.interactor.HistoryMetadataInteractor
import org.mozilla.fenix.home.HomeFragmentStore import org.mozilla.fenix.home.HomeFragmentStore
import org.mozilla.fenix.theme.FirefoxTheme import org.mozilla.fenix.theme.FirefoxTheme
@ -20,13 +22,14 @@ import org.mozilla.fenix.utils.view.ViewHolder
* *
* @param composeView [ComposeView] which will be populated with Jetpack Compose UI content. * @param composeView [ComposeView] which will be populated with Jetpack Compose UI content.
* @param store [HomeFragmentStore] containing the list of history metadata groups to be displayed. * @param store [HomeFragmentStore] containing the list of history metadata groups to be displayed.
* @property interactor [HistoryMetadataInteractor] which will have delegated to all user * @property interactor [HistoryMetadataInteractor] which will have delegated to all user interactions.
* interactions. * @property metrics [MetricController] that handles telemetry events.
*/ */
class HistoryMetadataGroupViewHolder( class HistoryMetadataGroupViewHolder(
val composeView: ComposeView, val composeView: ComposeView,
private val store: HomeFragmentStore, private val store: HomeFragmentStore,
private val interactor: HistoryMetadataInteractor private val interactor: HistoryMetadataInteractor,
private val metrics: MetricController
) : ViewHolder(composeView) { ) : ViewHolder(composeView) {
init { init {
@ -50,7 +53,10 @@ class HistoryMetadataGroupViewHolder(
} }
) )
), ),
onRecentVisitClick = { interactor.onHistoryMetadataGroupClicked(it) } onRecentVisitClick = { historyMetadataGroup, pageNumber ->
metrics.track(Event.HistoryRecentSearchesTapped(pageNumber.toString()))
interactor.onHistoryMetadataGroupClicked(historyMetadataGroup)
}
) )
} }
} }

@ -24,7 +24,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card import androidx.compose.material.Card
import androidx.compose.material.Divider import androidx.compose.material.Divider
@ -62,7 +62,7 @@ private const val VISITS_PER_COLUMN = 3
fun RecentlyVisited( fun RecentlyVisited(
recentVisits: List<HistoryMetadataGroup>, recentVisits: List<HistoryMetadataGroup>,
menuItems: List<RecentVisitMenuItem>, menuItems: List<RecentVisitMenuItem>,
onRecentVisitClick: (HistoryMetadataGroup) -> Unit = {} onRecentVisitClick: (HistoryMetadataGroup, Int) -> Unit = { _, _ -> }
) { ) {
Card( Card(
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
@ -76,7 +76,7 @@ fun RecentlyVisited(
) { ) {
val itemsList = recentVisits.chunked(VISITS_PER_COLUMN) val itemsList = recentVisits.chunked(VISITS_PER_COLUMN)
items(itemsList) { items -> itemsIndexed(itemsList) { pageIndex, items ->
Column( Column(
modifier = Modifier.fillMaxWidth() modifier = Modifier.fillMaxWidth()
) { ) {
@ -85,7 +85,8 @@ fun RecentlyVisited(
recentVisit = recentVisit, recentVisit = recentVisit,
menuItems = menuItems, menuItems = menuItems,
showDividerLine = index < items.size - 1, showDividerLine = index < items.size - 1,
onRecentVisitClick = onRecentVisitClick onRecentVisitClick = onRecentVisitClick,
pageNumber = pageIndex + 1
) )
} }
} }
@ -100,6 +101,7 @@ fun RecentlyVisited(
* @param recentVisit The [HistoryMetadataGroup] to display. * @param recentVisit The [HistoryMetadataGroup] to display.
* @param menuItems List of [RecentVisitMenuItem] to display in a recent visit dropdown menu. * @param menuItems List of [RecentVisitMenuItem] to display in a recent visit dropdown menu.
* @param onRecentVisitClick Invoked when the user clicks on a recent visit. * @param onRecentVisitClick Invoked when the user clicks on a recent visit.
* @param pageNumber which page is the item on.
*/ */
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
@ -107,14 +109,15 @@ private fun RecentVisitItem(
recentVisit: HistoryMetadataGroup, recentVisit: HistoryMetadataGroup,
menuItems: List<RecentVisitMenuItem>, menuItems: List<RecentVisitMenuItem>,
showDividerLine: Boolean, showDividerLine: Boolean,
onRecentVisitClick: (HistoryMetadataGroup) -> Unit = {} onRecentVisitClick: (HistoryMetadataGroup, Int) -> Unit = { _, _ -> },
pageNumber: Int
) { ) {
var menuExpanded by remember { mutableStateOf(false) } var menuExpanded by remember { mutableStateOf(false) }
Row( Row(
modifier = Modifier modifier = Modifier
.combinedClickable( .combinedClickable(
onClick = { onRecentVisitClick(recentVisit) }, onClick = { onRecentVisitClick(recentVisit, pageNumber) },
onLongClick = { menuExpanded = true } onLongClick = { menuExpanded = true }
) )
.size(268.dp, 56.dp), .size(268.dp, 56.dp),

@ -244,7 +244,8 @@ class SessionControlAdapter(
HistoryMetadataGroupViewHolder.LAYOUT_ID -> return HistoryMetadataGroupViewHolder( HistoryMetadataGroupViewHolder.LAYOUT_ID -> return HistoryMetadataGroupViewHolder(
composeView = ComposeView(parent.context), composeView = ComposeView(parent.context),
store = store, store = store,
interactor = interactor interactor = interactor,
metrics = components.analytics.metrics
) )
} }

@ -169,6 +169,13 @@ class GleanMetricsServiceTest {
assertFalse(History.openedItemsInPrivateTabs.testHasValue()) assertFalse(History.openedItemsInPrivateTabs.testHasValue())
gleanService.track(Event.HistoryOpenedInPrivateTabs) gleanService.track(Event.HistoryOpenedInPrivateTabs)
assertTrue(History.openedItemsInPrivateTabs.testHasValue()) assertTrue(History.openedItemsInPrivateTabs.testHasValue())
assertFalse(History.recentSearchesTapped.testHasValue())
gleanService.track(Event.HistoryRecentSearchesTapped("5"))
assertTrue(History.recentSearchesTapped.testHasValue())
val events = History.recentSearchesTapped.testGetValue()
assertEquals(1, events[0].extra!!.size)
assertEquals("5", events[0].extra!!["page_number"])
} }
@Test @Test

Loading…
Cancel
Save