2019-03-12 21:09:04 +01:00
|
|
|
/* 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/. */
|
|
|
|
package org.mozilla.fenix.components.metrics
|
|
|
|
|
2019-04-03 01:29:26 +02:00
|
|
|
import mozilla.components.support.base.Component
|
|
|
|
import mozilla.components.support.base.facts.Fact
|
|
|
|
import mozilla.components.support.base.facts.FactProcessor
|
|
|
|
import mozilla.components.support.base.facts.Facts
|
2019-03-15 21:09:59 +01:00
|
|
|
import org.mozilla.fenix.BuildConfig
|
|
|
|
|
2019-03-12 21:09:04 +01:00
|
|
|
sealed class Event {
|
|
|
|
object AddBookmark : Event()
|
|
|
|
object RemoveBookmark : Event()
|
|
|
|
object OpenedBookmark : Event()
|
2019-03-18 22:32:03 +01:00
|
|
|
|
2019-03-18 22:54:36 +01:00
|
|
|
data class OpenedApp(val source: Source) : Event() {
|
2019-03-19 04:49:17 +01:00
|
|
|
enum class Source { APP_ICON, LINK, CUSTOM_TAB }
|
2019-03-18 22:32:03 +01:00
|
|
|
override val extras: Map<String, String>?
|
|
|
|
get() = hashMapOf("source" to source.name)
|
|
|
|
}
|
|
|
|
|
2019-03-12 21:09:04 +01:00
|
|
|
object OpenedAppFirstRun : Event()
|
|
|
|
object InteractWithSearchURLArea : Event()
|
|
|
|
object SavedLoginandPassword : Event()
|
|
|
|
object FXANewSignup : Event()
|
|
|
|
object UserSignedInToFxA : Event()
|
|
|
|
object UserDownloadedFocus : Event()
|
|
|
|
object UserDownloadedLockbox : Event()
|
|
|
|
object UserDownloadedFennec : Event()
|
|
|
|
object TrackingProtectionSettingsChanged : Event()
|
|
|
|
object FXASyncedNewDevice : Event()
|
|
|
|
object DismissedOnboarding : Event()
|
|
|
|
object Uninstall : Event()
|
|
|
|
object OpenNewNormalTab : Event()
|
|
|
|
object OpenNewPrivateTab : Event()
|
|
|
|
object ShareStarted : Event()
|
|
|
|
object ShareCanceled : Event()
|
|
|
|
object ShareCompleted : Event()
|
|
|
|
object ClosePrivateTabs : Event()
|
|
|
|
object ClearedPrivateData : Event()
|
|
|
|
object OpenedLoginManager : Event()
|
|
|
|
object OpenedMailtoLink : Event()
|
|
|
|
object DownloadMediaSavedImage : Event()
|
|
|
|
object UserUsedReaderView : Event()
|
|
|
|
object UserDownloadedPocket : Event()
|
|
|
|
object UserDownloadedSend : Event()
|
|
|
|
object OpenedPocketStory : Event()
|
|
|
|
object DarkModeEnabled : Event()
|
2019-03-26 22:45:23 +01:00
|
|
|
object SearchShortcutMenuOpened : Event()
|
|
|
|
object SearchShortcutMenuClosed : Event()
|
2019-03-12 21:09:04 +01:00
|
|
|
|
2019-03-18 22:54:36 +01:00
|
|
|
// Interaction Events
|
|
|
|
data class SearchBarTapped(val source: Source) : Event() {
|
|
|
|
enum class Source { HOME, BROWSER }
|
|
|
|
override val extras: Map<String, String>?
|
|
|
|
get() = mapOf("source" to source.name)
|
|
|
|
}
|
|
|
|
|
2019-03-19 00:09:27 +01:00
|
|
|
data class EnteredUrl(val autoCompleted: Boolean) : Event() {
|
|
|
|
override val extras: Map<String, String>?
|
|
|
|
get() = mapOf("autocomplete" to autoCompleted.toString())
|
|
|
|
}
|
|
|
|
|
2019-03-26 22:45:23 +01:00
|
|
|
data class PerformedSearch(val fromSearchSuggestion: Boolean, val fromSearchShortcut: Boolean) : Event() {
|
2019-03-19 00:09:27 +01:00
|
|
|
override val extras: Map<String, String>?
|
2019-03-26 22:45:23 +01:00
|
|
|
get() = mapOf("search_suggestion" to fromSearchSuggestion.toString(),
|
|
|
|
"search_shortcut" to fromSearchShortcut.toString())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Track only built-in engine selection. Do not track user-added engines!
|
|
|
|
data class SearchShortcutSelected(val engine: String) : Event() {
|
|
|
|
override val extras: Map<String, String>?
|
|
|
|
get() = mapOf("engine" to engine)
|
2019-03-19 00:09:27 +01:00
|
|
|
}
|
|
|
|
|
2019-04-03 01:29:26 +02:00
|
|
|
object FindInPageOpened: Event()
|
|
|
|
object FindInPageClosed: Event()
|
|
|
|
object FindInPageNext: Event()
|
|
|
|
object FindInPagePrevious: Event()
|
|
|
|
object FindInPageSearchCommitted: Event()
|
|
|
|
|
|
|
|
|
2019-03-18 22:32:03 +01:00
|
|
|
open val extras: Map<String, String>?
|
2019-03-12 21:09:04 +01:00
|
|
|
get() = null
|
|
|
|
}
|
|
|
|
|
2019-04-03 01:29:26 +02:00
|
|
|
private fun Fact.toEvent(): Event? = when(Pair(component, item)){
|
|
|
|
Pair(Component.FEATURE_FINDINPAGE, "previous") -> Event.FindInPagePrevious
|
|
|
|
Pair(Component.FEATURE_FINDINPAGE, "next") -> Event.FindInPageNext
|
|
|
|
Pair(Component.FEATURE_FINDINPAGE, "close") -> Event.FindInPageClosed
|
|
|
|
Pair(Component.FEATURE_FINDINPAGE, "input") -> Event.FindInPageSearchCommitted
|
|
|
|
else -> null
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2019-03-12 21:09:04 +01:00
|
|
|
interface MetricsService {
|
|
|
|
fun start()
|
|
|
|
fun track(event: Event)
|
|
|
|
fun shouldTrack(event: Event): Boolean
|
|
|
|
}
|
|
|
|
|
2019-03-15 21:09:59 +01:00
|
|
|
class Metrics(private val services: List<MetricsService>, private val isTelemetryEnabled: () -> Boolean) {
|
|
|
|
private var initialized = false
|
|
|
|
|
2019-04-03 01:29:26 +02:00
|
|
|
init {
|
|
|
|
Facts.registerProcessor(object : FactProcessor {
|
|
|
|
override fun process(fact: Fact) {
|
|
|
|
fact.toEvent()?.also {
|
|
|
|
track(it)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2019-03-12 21:09:04 +01:00
|
|
|
fun start() {
|
2019-03-15 21:09:59 +01:00
|
|
|
if (BuildConfig.TELEMETRY && !isTelemetryEnabled.invoke() || initialized) { return }
|
|
|
|
|
2019-03-12 21:09:04 +01:00
|
|
|
services.forEach { it.start() }
|
2019-03-15 21:09:59 +01:00
|
|
|
initialized = true
|
2019-03-12 21:09:04 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
fun track(event: Event) {
|
2019-03-15 21:09:59 +01:00
|
|
|
if (BuildConfig.TELEMETRY && !isTelemetryEnabled.invoke() && !initialized) { return }
|
|
|
|
|
2019-03-12 21:09:04 +01:00
|
|
|
services
|
|
|
|
.filter { it.shouldTrack(event) }
|
|
|
|
.forEach { it.track(event) }
|
|
|
|
}
|
|
|
|
}
|