Skip to content

Commit

Permalink
For mozilla-mobile#20507 - Inactive tabs telemetry
Browse files Browse the repository at this point in the history
Two new events are added:
- "inactive_tabs_expanded" for when the inactive tabs section is expanded
- "inactive_tabs_collapsed" for when the inactive tabs section is collapsed

For tracking when an inactive tab is opened / closed I've repurposed the
existing tabs tray telemetry (since the functionality uses the same code)
- tabs_tray.opened_existing_tab
- tabs_tray.closed_existing_tab
to support an extra "source" key indicating the feature from which a tab was
opened or closed. The current values for this new key are:
- "Tabs tray" for when a tab was opened/closed from tabs tray
- "Inactive tabs" for when a tab was openes/closed from the Inactive tabs
section of the tabs tray.
  • Loading branch information
Mugurell authored and pkirakosyan committed Aug 27, 2021
1 parent f0ce0a9 commit 748f654
Show file tree
Hide file tree
Showing 21 changed files with 265 additions and 56 deletions.
46 changes: 42 additions & 4 deletions app/metrics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2625,35 +2625,45 @@ tabs_tray:
opened_existing_tab:
type: event
description: |
A user opened an existing tab
A user opened an existing tab from a particular app feature.
extra_keys:
source:
description: |
From which app feature was an existing tab opened.
bugs:
- https://github.com/mozilla-mobile/fenix/issues/11273
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/12036
- https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068
- https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789
- https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041
- https://github.com/mozilla-mobile/fenix/pull/20508#issuecomment-902160532
data_sensitivity:
- interaction
notification_emails:
- [email protected]
expires: "2022-02-01"
expires: "2022-08-01"
closed_existing_tab:
type: event
description: |
A user closed an existing tab
A user closed an existing tab from a particular app feature.
extra_keys:
source:
description: |
From which app feature was an existing tab closed.
bugs:
- https://github.com/mozilla-mobile/fenix/issues/11273
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/12036
- https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068
- https://github.com/mozilla-mobile/fenix/pull/19924#issuecomment-861423789
- https://github.com/mozilla-mobile/fenix/pull/20517#pullrequestreview-718069041
- https://github.com/mozilla-mobile/fenix/pull/20508#issuecomment-902160532
data_sensitivity:
- interaction
notification_emails:
- [email protected]
expires: "2022-02-01"
expires: "2022-08-01"
private_mode_tapped:
type: event
description: |
Expand Down Expand Up @@ -2811,6 +2821,34 @@ tabs_tray:
notification_emails:
- [email protected]
expires: "2022-08-01"
inactive_tabs_expanded:
type: event
description: |
A user tapped the "Inactive tabs" header to expand
the group of inactive tabs.
bugs:
- https://github.com/mozilla-mobile/fenix/issues/20507
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/20508#issuecomment-901336677
data_sensitivity:
- interaction
notification_emails:
- [email protected]
expires: "2022-08-01"
inactive_tabs_collapsed:
type: event
description: |
A user tapped the "Inactive tabs" header to collapse
the group of inactive tabs.
bugs:
- https://github.com/mozilla-mobile/fenix/issues/20507
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/20508#issuecomment-901336677
data_sensitivity:
- interaction
notification_emails:
- [email protected]
expires: "2022-08-01"

collections:
renamed:
Expand Down
11 changes: 9 additions & 2 deletions app/src/main/java/org/mozilla/fenix/components/metrics/Event.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import org.mozilla.fenix.GleanMetrics.Logins
import org.mozilla.fenix.GleanMetrics.Onboarding
import org.mozilla.fenix.GleanMetrics.ProgressiveWebApp
import org.mozilla.fenix.GleanMetrics.SearchShortcuts
import org.mozilla.fenix.GleanMetrics.TabsTray
import org.mozilla.fenix.GleanMetrics.Tip
import org.mozilla.fenix.GleanMetrics.ToolbarSettings
import org.mozilla.fenix.GleanMetrics.TopSites
Expand Down Expand Up @@ -175,8 +176,12 @@ sealed class Event {
// Tab tray
object TabsTrayOpened : Event()
object TabsTrayClosed : Event()
object OpenedExistingTab : Event()
object ClosedExistingTab : Event()
data class OpenedExistingTab(val source: String) : Event() {
override val extras = mapOf(TabsTray.openedExistingTabKeys.source to source)
}
data class ClosedExistingTab(val source: String) : Event() {
override val extras = mapOf(TabsTray.closedExistingTabKeys.source to source)
}
object TabsTrayPrivateModeTapped : Event()
object TabsTrayNormalModeTapped : Event()
object TabsTraySyncedModeTapped : Event()
Expand All @@ -187,6 +192,8 @@ sealed class Event {
object TabsTrayShareAllTabsPressed : Event()
object TabsTrayCloseAllTabsPressed : Event()
object TabsTrayRecentlyClosedPressed : Event()
object TabsTrayInactiveTabsExpanded : Event()
object TabsTrayInactiveTabsCollapsed : Event()

object ProgressiveWebAppOpenFromHomescreenTap : Event()
object ProgressiveWebAppInstallAsShortcut : Event()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -650,11 +650,13 @@ private val Event.wrapper: EventWrapper<*>?
is Event.TabsTrayClosed -> EventWrapper<NoExtraKeys>(
{ TabsTray.closed.record(it) }
)
is Event.OpenedExistingTab -> EventWrapper<NoExtraKeys>(
{ TabsTray.openedExistingTab.record(it) }
is Event.OpenedExistingTab -> EventWrapper(
{ TabsTray.openedExistingTab.record(it) },
{ TabsTray.openedExistingTabKeys.valueOf(it) }
)
is Event.ClosedExistingTab -> EventWrapper<NoExtraKeys>(
{ TabsTray.closedExistingTab.record(it) }
is Event.ClosedExistingTab -> EventWrapper(
{ TabsTray.closedExistingTab.record(it) },
{ TabsTray.closedExistingTabKeys.valueOf(it) }
)
is Event.TabsTrayPrivateModeTapped -> EventWrapper<NoExtraKeys>(
{ TabsTray.privateModeTapped.record(it) }
Expand Down Expand Up @@ -686,6 +688,12 @@ private val Event.wrapper: EventWrapper<*>?
is Event.TabsTrayRecentlyClosedPressed -> EventWrapper<NoExtraKeys>(
{ TabsTray.inactiveTabsRecentlyClosed.record(it) }
)
is Event.TabsTrayInactiveTabsExpanded -> EventWrapper<NoExtraKeys>(
{ TabsTray.inactiveTabsExpanded.record(it) }
)
is Event.TabsTrayInactiveTabsCollapsed -> EventWrapper<NoExtraKeys>(
{ TabsTray.inactiveTabsCollapsed.record(it) }
)
is Event.AutoPlaySettingVisited -> EventWrapper<NoExtraKeys>(
{ Autoplay.visitedSetting.record(it) }
)
Expand Down
10 changes: 7 additions & 3 deletions app/src/main/java/org/mozilla/fenix/tabstray/TrayPagerAdapter.kt
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ class TrayPagerAdapter(

private val normalAdapter by lazy {
ConcatAdapter(
BrowserTabsAdapter(context, browserInteractor, store),
InactiveTabsAdapter(context, browserInteractor)
BrowserTabsAdapter(context, browserInteractor, store, TABS_TRAY_FEATURE_NAME),
InactiveTabsAdapter(context, browserInteractor, INACTIVE_TABS_FEATURE_NAME)
)
}
private val privateAdapter by lazy { BrowserTabsAdapter(context, browserInteractor, store) }
private val privateAdapter by lazy { BrowserTabsAdapter(context, browserInteractor, store, TABS_TRAY_FEATURE_NAME) }
private val syncedTabsAdapter by lazy { SyncedTabsAdapter(TabClickDelegate(navInteractor)) }

override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AbstractPageViewHolder {
Expand Down Expand Up @@ -102,6 +102,10 @@ class TrayPagerAdapter(
companion object {
const val TRAY_TABS_COUNT = 3

// Telemetry keys for identifying from which app features the a was opened / closed.
const val TABS_TRAY_FEATURE_NAME = "Tabs tray"
const val INACTIVE_TABS_FEATURE_NAME = "Inactive tabs"

val POSITION_NORMAL_TABS = Page.NormalTabs.ordinal
val POSITION_PRIVATE_TABS = Page.PrivateTabs.ordinal
/* Gexsi begin: disable sync
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,19 +35,28 @@ import org.mozilla.fenix.ext.removeTouchDelegate
import org.mozilla.fenix.ext.showAndEnable
import org.mozilla.fenix.ext.toShortUrl
import org.mozilla.fenix.selection.SelectionHolder
import org.mozilla.fenix.selection.SelectionInteractor
import org.mozilla.fenix.tabstray.TabsTrayState
import org.mozilla.fenix.tabstray.TabsTrayStore
import org.mozilla.fenix.tabstray.ext.isSelect

/**
* A RecyclerView ViewHolder implementation for "tab" items.
*
* @param itemView [View] that displays a "tab".
* @param imageLoader [ImageLoader] used to load tab thumbnails.
* @param trayStore [TabsTrayStore] containing the complete state of tabs tray and methods to update that.
* @param featureName [String] representing the name of the feature displaying tabs. Used in telemetry reporting.
* @param store [BrowserStore] containing the complete state of the browser and methods to update that.
* @param metrics [MetricController] used for handling telemetry events.
*/
@Suppress("LongParameterList")
abstract class AbstractBrowserTabViewHolder(
itemView: View,
private val imageLoader: ImageLoader,
private val trayStore: TabsTrayStore,
private val selectionHolder: SelectionHolder<Tab>?,
@VisibleForTesting
internal val featureName: String,
private val store: BrowserStore = itemView.context.components.core.store,
private val metrics: MetricController = itemView.context.components.analytics.metrics
) : TabViewHolder(itemView) {
Expand Down Expand Up @@ -91,7 +100,7 @@ abstract class AbstractBrowserTabViewHolder(
if (selectionHolder != null) {
setSelectionInteractor(tab, selectionHolder, browserTrayInteractor)
} else {
itemView.setOnClickListener { browserTrayInteractor.open(tab) }
itemView.setOnClickListener { browserTrayInteractor.open(tab, featureName) }
}

if (tab.thumbnail != null) {
Expand Down Expand Up @@ -202,12 +211,12 @@ abstract class AbstractBrowserTabViewHolder(
private fun setSelectionInteractor(
item: Tab,
holder: SelectionHolder<Tab>,
interactor: SelectionInteractor<Tab>
interactor: BrowserTrayInteractor
) {
itemView.setOnClickListener {
val selected = holder.selectedItems
when {
selected.isEmpty() && trayStore.state.mode.isSelect().not() -> interactor.open(item)
selected.isEmpty() && trayStore.state.mode.isSelect().not() -> interactor.open(item, featureName)
item in selected -> interactor.deselect(item)
else -> interactor.select(item)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,22 @@ import org.mozilla.fenix.tabstray.TabsTrayStore

/**
* A RecyclerView ViewHolder implementation for "tab" items with grid layout.
*
* @param imageLoader [ImageLoader] used to load tab thumbnails.
* @param browserTrayInteractor [BrowserTrayInteractor] handling tabs interactions in a tab tray.
* @param store [TabsTrayStore] containing the complete state of tabs tray and methods to update that.
* @param selectionHolder [SelectionHolder]<[Tab]> for helping with selecting any number of displayed [Tab]s.
* @param itemView [View] that displays a "tab".
* @param featureName [String] representing the name of the feature displaying tabs. Used in telemetry reporting.
*/
class BrowserTabGridViewHolder(
imageLoader: ImageLoader,
override val browserTrayInteractor: BrowserTrayInteractor,
store: TabsTrayStore,
selectionHolder: SelectionHolder<Tab>? = null,
itemView: View
) : AbstractBrowserTabViewHolder(itemView, imageLoader, store, selectionHolder) {
itemView: View,
featureName: String
) : AbstractBrowserTabViewHolder(itemView, imageLoader, store, selectionHolder, featureName) {

private val closeButton: AppCompatImageButton = itemView.findViewById(R.id.mozac_browser_tabstray_close)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,22 @@ import kotlin.math.max

/**
* A RecyclerView ViewHolder implementation for "tab" items with list layout.
*/
*
* @param imageLoader [ImageLoader] used to load tab thumbnails.
* @param browserTrayInteractor [BrowserTrayInteractor] handling tabs interactions in a tab tray.
* @param store [TabsTrayStore] containing the complete state of tabs tray and methods to update that.
* @param selectionHolder [SelectionHolder]<[Tab]> for helping with selecting any number of displayed [Tab]s.
* @param itemView [View] that displays a "tab".
* @param featureName [String] representing the name of the feature displaying tabs. Used in telemetry reporting.
*/
class BrowserTabListViewHolder(
imageLoader: ImageLoader,
override val browserTrayInteractor: BrowserTrayInteractor,
store: TabsTrayStore,
selectionHolder: SelectionHolder<Tab>? = null,
itemView: View
) : AbstractBrowserTabViewHolder(itemView, imageLoader, store, selectionHolder) {
itemView: View,
featureName: String
) : AbstractBrowserTabViewHolder(itemView, imageLoader, store, selectionHolder, featureName) {
override val thumbnailSize: Int
get() = max(
itemView.resources.getDimensionPixelSize(R.dimen.tab_tray_list_item_thumbnail_height),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import mozilla.components.concept.tabstray.TabsTray
import mozilla.components.support.base.observer.Observable
import mozilla.components.support.base.observer.ObserverRegistry
import org.mozilla.fenix.R
import org.mozilla.fenix.components.Components
import org.mozilla.fenix.databinding.TabTrayGridItemBinding
import org.mozilla.fenix.databinding.TabTrayItemBinding
import org.mozilla.fenix.ext.components
Expand All @@ -25,11 +26,18 @@ import org.mozilla.fenix.tabstray.TabsTrayStore

/**
* A [RecyclerView.Adapter] for browser tabs.
*
* @param context [Context] used for various platform interactions or accessing [Components]
* @param interactor [BrowserTrayInteractor] handling tabs interactions in a tab tray.
* @param store [TabsTrayStore] containing the complete state of tabs tray and methods to update that.
* @param featureName [String] representing the name of the feature displaying tabs. Used in telemetry reporting.
* @param delegate [Observable]<[TabsTray.Observer]> for observing tabs tray changes. Defaults to [ObserverRegistry].
*/
class BrowserTabsAdapter(
private val context: Context,
private val interactor: BrowserTrayInteractor,
private val store: TabsTrayStore,
private val featureName: String,
delegate: Observable<TabsTray.Observer> = ObserverRegistry()
) : TabsAdapter<AbstractBrowserTabViewHolder>(delegate) {

Expand Down Expand Up @@ -62,9 +70,9 @@ class BrowserTabsAdapter(

return when (viewType) {
ViewType.GRID.layoutRes ->
BrowserTabGridViewHolder(imageLoader, interactor, store, selectionHolder, view)
BrowserTabGridViewHolder(imageLoader, interactor, store, selectionHolder, view, featureName)
else ->
BrowserTabListViewHolder(imageLoader, interactor, store, selectionHolder, view)
BrowserTabListViewHolder(imageLoader, interactor, store, selectionHolder, view, featureName)
}
}

Expand All @@ -76,12 +84,12 @@ class BrowserTabsAdapter(
ViewType.GRID.layoutRes -> {
val gridBinding = TabTrayGridItemBinding.bind(holder.itemView)
selectedMaskView = gridBinding.checkboxInclude.selectedMask
gridBinding.mozacBrowserTabstrayClose.setOnClickListener { interactor.close(tab) }
gridBinding.mozacBrowserTabstrayClose.setOnClickListener { interactor.close(tab, featureName) }
}
ViewType.LIST.layoutRes -> {
val listBinding = TabTrayItemBinding.bind(holder.itemView)
selectedMaskView = listBinding.checkboxInclude.selectedMask
listBinding.mozacBrowserTabstrayClose.setOnClickListener { interactor.close(tab) }
listBinding.mozacBrowserTabstrayClose.setOnClickListener { interactor.close(tab, featureName) }
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,21 @@ import org.mozilla.fenix.tabstray.TabsTrayStore
*/
interface BrowserTrayInteractor : SelectionInteractor<Tab>, UserInteractionHandler {

/**
* Open a tab.
*
* @param tab [Tab] to open in browser.
* @param source app feature from which the [tab] was opened.
*/
fun open(tab: Tab, source: String? = null)

/**
* Close the tab.
*
* @param tab [Tab] to close.
* @param source app feature from which the [tab] was closed.
*/
fun close(tab: Tab)
fun close(tab: Tab, source: String? = null)

/**
* TabTray's Floating Action Button clicked.
Expand Down Expand Up @@ -65,14 +76,21 @@ class DefaultBrowserTrayInteractor(
* See [SelectionInteractor.open]
*/
override fun open(item: Tab) {
selectTabWrapper.invoke(item.id)
open(item, null)
}

/**
* See [BrowserTrayInteractor.open].
*/
override fun open(tab: Tab, source: String?) {
selectTabWrapper.invoke(tab.id, source)
}

/**
* See [BrowserTrayInteractor.close].
*/
override fun close(tab: Tab) {
removeTabWrapper.invoke(tab.id)
override fun close(tab: Tab, source: String?) {
removeTabWrapper.invoke(tab.id, source)
}

/**
Expand Down
Loading

0 comments on commit 748f654

Please sign in to comment.