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/. */
|
2019-07-12 20:38:15 +02:00
|
|
|
|
2019-03-12 21:09:04 +01:00
|
|
|
package org.mozilla.fenix.components.metrics
|
|
|
|
|
|
|
|
import android.content.Context
|
2019-07-12 20:38:15 +02:00
|
|
|
import kotlinx.coroutines.Job
|
2019-11-13 05:14:23 +01:00
|
|
|
import kotlinx.coroutines.MainScope
|
2019-11-26 01:43:32 +01:00
|
|
|
import kotlinx.coroutines.launch
|
2019-07-12 20:38:15 +02:00
|
|
|
import mozilla.components.service.glean.BuildConfig
|
2019-03-12 21:09:04 +01:00
|
|
|
import mozilla.components.service.glean.Glean
|
2019-07-12 20:38:15 +02:00
|
|
|
import mozilla.components.service.glean.config.Configuration
|
2019-10-04 19:28:23 +02:00
|
|
|
import mozilla.components.service.glean.net.ConceptFetchHttpUploader
|
2019-04-09 17:57:50 +02:00
|
|
|
import mozilla.components.service.glean.private.NoExtraKeys
|
2019-03-18 21:30:25 +01:00
|
|
|
import mozilla.components.support.utils.Browsers
|
2019-04-17 19:37:36 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.BookmarksManagement
|
2019-08-14 20:39:54 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.Collections
|
2019-04-17 19:37:36 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.ContextMenu
|
2019-03-27 03:08:16 +01:00
|
|
|
import org.mozilla.fenix.GleanMetrics.CrashReporter
|
2019-04-17 19:37:36 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.CustomTab
|
2019-11-12 00:38:06 +01:00
|
|
|
import org.mozilla.fenix.GleanMetrics.DownloadNotification
|
2019-07-12 20:38:15 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.ErrorPage
|
2019-03-27 03:08:16 +01:00
|
|
|
import org.mozilla.fenix.GleanMetrics.Events
|
|
|
|
import org.mozilla.fenix.GleanMetrics.FindInPage
|
2019-07-16 21:21:03 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.History
|
2019-07-12 20:38:15 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.Library
|
2019-11-13 00:55:36 +01:00
|
|
|
import org.mozilla.fenix.GleanMetrics.Logins
|
2019-09-27 17:02:29 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.MediaNotification
|
2019-11-13 02:24:30 +01:00
|
|
|
import org.mozilla.fenix.GleanMetrics.MediaState
|
2019-03-25 17:35:58 +01:00
|
|
|
import org.mozilla.fenix.GleanMetrics.Metrics
|
2019-05-15 23:51:55 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.Pings
|
2019-08-28 23:41:37 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.PrivateBrowsingMode
|
2019-09-10 18:42:46 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.PrivateBrowsingShortcut
|
2019-07-12 20:38:15 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.QrScanner
|
2019-08-01 02:58:37 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.ReaderMode
|
2019-08-14 20:39:54 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.SearchDefaultEngine
|
2019-08-20 00:25:48 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.SearchShortcuts
|
2019-08-14 20:39:54 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.SearchWidget
|
2019-05-24 17:25:00 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.SyncAccount
|
|
|
|
import org.mozilla.fenix.GleanMetrics.SyncAuth
|
2019-09-20 23:49:27 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.Tab
|
2019-11-26 01:43:32 +01:00
|
|
|
import org.mozilla.fenix.GleanMetrics.ToolbarSettings
|
2019-09-18 21:59:30 +02:00
|
|
|
import org.mozilla.fenix.GleanMetrics.TrackingProtection
|
2019-08-14 20:39:54 +02:00
|
|
|
import org.mozilla.fenix.ext.components
|
2019-09-27 17:56:33 +02:00
|
|
|
import org.mozilla.fenix.ext.settings
|
2019-03-12 21:09:04 +01:00
|
|
|
|
2019-03-22 07:05:28 +01:00
|
|
|
private class EventWrapper<T : Enum<T>>(
|
2019-04-02 14:31:30 +02:00
|
|
|
private val recorder: ((Map<T, String>?) -> Unit),
|
2019-04-03 01:47:11 +02:00
|
|
|
private val keyMapper: ((String) -> T)? = null
|
2019-03-22 07:05:28 +01:00
|
|
|
) {
|
2019-10-22 23:33:44 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts snake_case string to camelCase.
|
|
|
|
*/
|
|
|
|
private fun String.asCamelCase(): String {
|
|
|
|
val parts = split("_")
|
|
|
|
val builder = StringBuilder()
|
|
|
|
|
|
|
|
for ((index, part) in parts.withIndex()) {
|
|
|
|
if (index == 0) {
|
|
|
|
builder.append(part)
|
|
|
|
} else {
|
|
|
|
builder.append(part[0].toUpperCase())
|
|
|
|
builder.append(part.substring(1))
|
|
|
|
}
|
2019-03-26 17:13:59 +01:00
|
|
|
}
|
|
|
|
|
2019-10-22 23:33:44 +02:00
|
|
|
return builder.toString()
|
|
|
|
}
|
|
|
|
|
2019-03-22 07:05:28 +01:00
|
|
|
fun track(event: Event) {
|
|
|
|
val extras = if (keyMapper != null) {
|
2019-10-22 23:33:44 +02:00
|
|
|
event.extras?.mapKeys { (key) ->
|
|
|
|
keyMapper.invoke(key.toString().asCamelCase())
|
|
|
|
}
|
2019-03-22 07:05:28 +01:00
|
|
|
} else {
|
|
|
|
null
|
|
|
|
}
|
|
|
|
|
2019-04-02 14:31:30 +02:00
|
|
|
this.recorder(extras)
|
2019-03-22 07:05:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-20 00:25:48 +02:00
|
|
|
private val Event.wrapper: EventWrapper<*>?
|
2019-03-19 04:49:17 +01:00
|
|
|
get() = when (this) {
|
2019-04-02 14:31:30 +02:00
|
|
|
is Event.OpenedApp -> EventWrapper(
|
|
|
|
{ Events.appOpened.record(it) },
|
|
|
|
{ Events.appOpenedKeys.valueOf(it) }
|
|
|
|
)
|
|
|
|
is Event.SearchBarTapped -> EventWrapper(
|
|
|
|
{ Events.searchBarTapped.record(it) },
|
|
|
|
{ Events.searchBarTappedKeys.valueOf(it) }
|
|
|
|
)
|
|
|
|
is Event.EnteredUrl -> EventWrapper(
|
|
|
|
{ Events.enteredUrl.record(it) },
|
|
|
|
{ Events.enteredUrlKeys.valueOf(it) }
|
|
|
|
)
|
|
|
|
is Event.PerformedSearch -> EventWrapper(
|
2019-04-17 01:31:35 +02:00
|
|
|
{
|
|
|
|
Metrics.searchCount[this.eventSource.countLabel].add(1)
|
|
|
|
Events.performedSearch.record(it)
|
|
|
|
},
|
2019-04-02 14:31:30 +02:00
|
|
|
{ Events.performedSearchKeys.valueOf(it) }
|
|
|
|
)
|
2019-08-20 00:25:48 +02:00
|
|
|
is Event.SearchShortcutSelected -> EventWrapper(
|
|
|
|
{ SearchShortcuts.selected.record(it) },
|
|
|
|
{ SearchShortcuts.selectedKeys.valueOf(it) }
|
|
|
|
)
|
|
|
|
is Event.ReaderModeAvailable -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ ReaderMode.available.record(it) }
|
|
|
|
)
|
2019-04-03 01:47:11 +02:00
|
|
|
is Event.FindInPageOpened -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ FindInPage.opened.record(it) }
|
|
|
|
)
|
|
|
|
is Event.FindInPageClosed -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ FindInPage.closed.record(it) }
|
|
|
|
)
|
|
|
|
is Event.FindInPageNext -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ FindInPage.nextResult.record(it) }
|
|
|
|
)
|
2019-04-03 03:18:14 +02:00
|
|
|
is Event.FindInPagePrevious -> EventWrapper<NoExtraKeys>(
|
2019-04-03 01:47:11 +02:00
|
|
|
{ FindInPage.previousResult.record(it) }
|
|
|
|
)
|
|
|
|
is Event.FindInPageSearchCommitted -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ FindInPage.searchedPage.record(it) }
|
|
|
|
)
|
2019-04-03 03:18:14 +02:00
|
|
|
is Event.ContextMenuItemTapped -> EventWrapper(
|
|
|
|
{ ContextMenu.itemTapped.record(it) },
|
|
|
|
{ ContextMenu.itemTappedKeys.valueOf(it) }
|
|
|
|
)
|
2019-03-27 02:36:58 +01:00
|
|
|
is Event.CrashReporterOpened -> EventWrapper<NoExtraKeys>(
|
2019-06-13 18:57:56 +02:00
|
|
|
{ CrashReporter.opened.record(it) }
|
2019-03-27 02:36:58 +01:00
|
|
|
)
|
|
|
|
is Event.CrashReporterClosed -> EventWrapper(
|
2019-06-13 18:57:56 +02:00
|
|
|
{ CrashReporter.closed.record(it) },
|
2019-03-27 02:36:58 +01:00
|
|
|
{ CrashReporter.closedKeys.valueOf(it) }
|
|
|
|
)
|
2019-03-27 03:08:16 +01:00
|
|
|
is Event.BrowserMenuItemTapped -> EventWrapper(
|
2019-06-13 18:57:56 +02:00
|
|
|
{ Events.browserMenuAction.record(it) },
|
2019-03-27 03:08:16 +01:00
|
|
|
{ Events.browserMenuActionKeys.valueOf(it) }
|
|
|
|
)
|
2019-04-17 19:37:36 +02:00
|
|
|
is Event.OpenedBookmarkInNewTab -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ BookmarksManagement.openInNewTab.record(it) }
|
|
|
|
)
|
|
|
|
is Event.OpenedBookmarksInNewTabs -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ BookmarksManagement.openInNewTabs.record(it) }
|
|
|
|
)
|
|
|
|
is Event.OpenedBookmarkInPrivateTab -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ BookmarksManagement.openInPrivateTab.record(it) }
|
|
|
|
)
|
|
|
|
is Event.OpenedBookmarksInPrivateTabs -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ BookmarksManagement.openInPrivateTabs.record(it) }
|
|
|
|
)
|
|
|
|
is Event.EditedBookmark -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ BookmarksManagement.edited.record(it) }
|
|
|
|
)
|
|
|
|
is Event.MovedBookmark -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ BookmarksManagement.moved.record(it) }
|
|
|
|
)
|
|
|
|
is Event.RemoveBookmark -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ BookmarksManagement.removed.record(it) }
|
|
|
|
)
|
|
|
|
is Event.RemoveBookmarks -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ BookmarksManagement.multiRemoved.record(it) }
|
|
|
|
)
|
|
|
|
is Event.ShareBookmark -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ BookmarksManagement.shared.record(it) }
|
|
|
|
)
|
|
|
|
is Event.CopyBookmark -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ BookmarksManagement.copied.record(it) }
|
|
|
|
)
|
|
|
|
is Event.AddBookmarkFolder -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ BookmarksManagement.folderAdd.record(it) }
|
|
|
|
)
|
2019-07-02 17:41:20 +02:00
|
|
|
is Event.RemoveBookmarkFolder -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ BookmarksManagement.folderRemove.record(it) }
|
|
|
|
)
|
2019-04-17 20:13:48 +02:00
|
|
|
is Event.CustomTabsMenuOpened -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ CustomTab.menu.record(it) }
|
|
|
|
)
|
|
|
|
is Event.CustomTabsActionTapped -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ CustomTab.actionButton.record(it) }
|
|
|
|
)
|
|
|
|
is Event.CustomTabsClosed -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ CustomTab.closed.record(it) }
|
|
|
|
)
|
2019-04-26 09:43:02 +02:00
|
|
|
is Event.UriOpened -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Events.totalUriCount.add(1) }
|
|
|
|
)
|
2019-05-15 19:01:26 +02:00
|
|
|
is Event.QRScannerOpened -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ QrScanner.opened.record(it) }
|
|
|
|
)
|
|
|
|
is Event.QRScannerPromptDisplayed -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ QrScanner.promptDisplayed.record(it) }
|
|
|
|
)
|
|
|
|
is Event.QRScannerNavigationAllowed -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ QrScanner.navigationAllowed.record(it) }
|
|
|
|
)
|
|
|
|
is Event.QRScannerNavigationDenied -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ QrScanner.navigationDenied.record(it) }
|
|
|
|
)
|
2019-05-15 23:26:21 +02:00
|
|
|
is Event.LibraryOpened -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Library.opened.record(it) }
|
|
|
|
)
|
|
|
|
is Event.LibraryClosed -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Library.closed.record(it) }
|
|
|
|
)
|
|
|
|
is Event.LibrarySelectedItem -> EventWrapper(
|
2019-06-13 18:57:56 +02:00
|
|
|
{ Library.selectedItem.record(it) },
|
2019-05-15 23:26:21 +02:00
|
|
|
{ Library.selectedItemKeys.valueOf(it) }
|
|
|
|
)
|
2019-05-14 23:17:58 +02:00
|
|
|
is Event.ErrorPageVisited -> EventWrapper(
|
2019-06-13 18:57:56 +02:00
|
|
|
{ ErrorPage.visitedError.record(it) },
|
2019-05-14 23:17:58 +02:00
|
|
|
{ ErrorPage.visitedErrorKeys.valueOf(it) }
|
|
|
|
)
|
2019-05-24 17:25:00 +02:00
|
|
|
is Event.SyncAuthOpened -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SyncAuth.opened.record(it) }
|
2019-05-22 19:43:23 +02:00
|
|
|
)
|
2019-05-24 17:25:00 +02:00
|
|
|
is Event.SyncAuthClosed -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SyncAuth.closed.record(it) }
|
2019-05-22 19:43:23 +02:00
|
|
|
)
|
2019-05-24 17:25:00 +02:00
|
|
|
is Event.SyncAuthSignIn -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SyncAuth.signIn.record(it) }
|
2019-05-22 19:43:23 +02:00
|
|
|
)
|
2019-08-23 01:56:13 +02:00
|
|
|
is Event.SyncAuthSignUp -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SyncAuth.signUp.record(it) }
|
|
|
|
)
|
|
|
|
is Event.SyncAuthPaired -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SyncAuth.paired.record(it) }
|
|
|
|
)
|
|
|
|
is Event.SyncAuthOtherExternal -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SyncAuth.otherExternal.record(it) }
|
|
|
|
)
|
|
|
|
is Event.SyncAuthFromShared -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SyncAuth.autoLogin.record(it) }
|
|
|
|
)
|
|
|
|
is Event.SyncAuthRecovered -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SyncAuth.recovered.record(it) }
|
|
|
|
)
|
2019-08-14 22:48:45 +02:00
|
|
|
is Event.SyncAuthSignOut -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SyncAuth.signOut.record(it) }
|
|
|
|
)
|
2019-05-24 17:25:00 +02:00
|
|
|
is Event.SyncAuthScanPairing -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SyncAuth.scanPairing.record(it) }
|
2019-05-22 19:43:23 +02:00
|
|
|
)
|
2019-05-24 17:25:00 +02:00
|
|
|
is Event.SyncAccountOpened -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SyncAccount.opened.record(it) }
|
2019-05-22 19:43:23 +02:00
|
|
|
)
|
2019-05-24 17:25:00 +02:00
|
|
|
is Event.SyncAccountClosed -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SyncAccount.closed.record(it) }
|
|
|
|
)
|
|
|
|
is Event.SyncAccountSyncNow -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SyncAccount.syncNow.record(it) }
|
|
|
|
)
|
2019-09-04 17:46:34 +02:00
|
|
|
is Event.SignInToSendTab -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SyncAccount.signInToSendTab.record(it) }
|
|
|
|
)
|
|
|
|
is Event.SendTab -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SyncAccount.sendTab.record(it) }
|
|
|
|
)
|
2019-06-10 22:56:12 +02:00
|
|
|
is Event.PreferenceToggled -> EventWrapper(
|
|
|
|
{ Events.preferenceToggled.record(it) },
|
|
|
|
{ Events.preferenceToggledKeys.valueOf(it) }
|
|
|
|
)
|
2019-07-16 21:21:03 +02:00
|
|
|
is Event.HistoryOpened -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ History.opened.record(it) }
|
|
|
|
)
|
|
|
|
is Event.HistoryItemShared -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ History.shared.record(it) }
|
|
|
|
)
|
|
|
|
is Event.HistoryItemOpened -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ History.openedItem.record(it) }
|
|
|
|
)
|
|
|
|
is Event.HistoryItemRemoved -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ History.removed.record(it) }
|
|
|
|
)
|
|
|
|
is Event.HistoryAllItemsRemoved -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ History.removedAll.record(it) }
|
|
|
|
)
|
2019-07-19 01:05:42 +02:00
|
|
|
is Event.CollectionRenamed -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Collections.renamed.record(it) }
|
|
|
|
)
|
|
|
|
is Event.CollectionTabRestored -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Collections.tabRestored.record(it) }
|
|
|
|
)
|
|
|
|
is Event.CollectionAllTabsRestored -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Collections.allTabsRestored.record(it) }
|
|
|
|
)
|
|
|
|
is Event.CollectionTabRemoved -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Collections.tabRemoved.record(it) }
|
|
|
|
)
|
|
|
|
is Event.CollectionShared -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Collections.shared.record(it) }
|
|
|
|
)
|
|
|
|
is Event.CollectionRemoved -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Collections.removed.record(it) }
|
|
|
|
)
|
|
|
|
is Event.CollectionTabSelectOpened -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Collections.tabSelectOpened.record(it) }
|
|
|
|
)
|
2019-08-01 02:58:37 +02:00
|
|
|
is Event.ReaderModeOpened -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ ReaderMode.opened.record(it) }
|
|
|
|
)
|
|
|
|
is Event.ReaderModeAppearanceOpened -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ ReaderMode.appearance.record(it) }
|
|
|
|
)
|
2019-08-01 02:07:41 +02:00
|
|
|
is Event.CollectionTabLongPressed -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Collections.longPress.record(it) }
|
|
|
|
)
|
|
|
|
is Event.CollectionSaveButtonPressed -> EventWrapper(
|
|
|
|
{ Collections.saveButton.record(it) },
|
|
|
|
{ Collections.saveButtonKeys.valueOf(it) }
|
|
|
|
)
|
|
|
|
is Event.CollectionAddTabPressed -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Collections.addTabButton.record(it) }
|
|
|
|
)
|
2019-08-08 01:05:20 +02:00
|
|
|
is Event.CollectionRenamePressed -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Collections.renameButton.record(it) }
|
|
|
|
)
|
2019-08-07 19:26:52 +02:00
|
|
|
is Event.CollectionSaved -> EventWrapper(
|
|
|
|
{ Collections.saved.record(it) },
|
|
|
|
{ Collections.savedKeys.valueOf(it) }
|
|
|
|
)
|
|
|
|
is Event.CollectionTabsAdded -> EventWrapper(
|
|
|
|
{ Collections.tabsAdded.record(it) },
|
|
|
|
{ Collections.tabsAddedKeys.valueOf(it) }
|
|
|
|
)
|
2019-08-14 20:39:54 +02:00
|
|
|
is Event.SearchWidgetNewTabPressed -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SearchWidget.newTabButton.record(it) }
|
|
|
|
)
|
|
|
|
is Event.SearchWidgetVoiceSearchPressed -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ SearchWidget.voiceButton.record(it) }
|
|
|
|
)
|
2019-08-28 23:41:37 +02:00
|
|
|
is Event.PrivateBrowsingGarbageIconTapped -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ PrivateBrowsingMode.garbageIcon.record(it) }
|
|
|
|
)
|
|
|
|
is Event.PrivateBrowsingSnackbarUndoTapped -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ PrivateBrowsingMode.snackbarUndo.record(it) }
|
|
|
|
)
|
|
|
|
is Event.PrivateBrowsingNotificationTapped -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ PrivateBrowsingMode.notificationTapped.record(it) }
|
|
|
|
)
|
|
|
|
is Event.PrivateBrowsingNotificationOpenTapped -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ PrivateBrowsingMode.notificationOpen.record(it) }
|
|
|
|
)
|
|
|
|
is Event.PrivateBrowsingNotificationDeleteAndOpenTapped -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ PrivateBrowsingMode.notificationDelete.record(it) }
|
|
|
|
)
|
2019-09-10 18:42:46 +02:00
|
|
|
is Event.PrivateBrowsingCreateShortcut -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ PrivateBrowsingShortcut.createShortcut.record(it) }
|
|
|
|
)
|
|
|
|
is Event.PrivateBrowsingAddShortcutCFR -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ PrivateBrowsingShortcut.cfrAddShortcut.record(it) }
|
|
|
|
)
|
|
|
|
is Event.PrivateBrowsingCancelCFR -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ PrivateBrowsingShortcut.cfrCancel.record(it) }
|
|
|
|
)
|
|
|
|
is Event.PrivateBrowsingPinnedShortcutPrivateTab -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ PrivateBrowsingShortcut.pinnedShortcutPriv.record(it) }
|
|
|
|
)
|
|
|
|
is Event.PrivateBrowsingStaticShortcutTab -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ PrivateBrowsingShortcut.staticShortcutTab.record(it) }
|
|
|
|
)
|
|
|
|
is Event.PrivateBrowsingStaticShortcutPrivateTab -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ PrivateBrowsingShortcut.staticShortcutPriv.record(it) }
|
|
|
|
)
|
2019-09-04 17:57:59 +02:00
|
|
|
is Event.WhatsNewTapped -> EventWrapper(
|
|
|
|
{ Events.whatsNewTapped.record(it) },
|
|
|
|
{ Events.whatsNewTappedKeys.valueOf(it) }
|
|
|
|
)
|
2019-09-20 23:49:27 +02:00
|
|
|
is Event.TabMediaPlay -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Tab.mediaPlay.record(it) }
|
|
|
|
)
|
|
|
|
is Event.TabMediaPause -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Tab.mediaPause.record(it) }
|
|
|
|
)
|
2019-11-13 02:24:30 +01:00
|
|
|
is Event.MediaPlayState -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ MediaState.play.record(it) }
|
|
|
|
)
|
|
|
|
is Event.MediaPauseState -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ MediaState.pause.record(it) }
|
|
|
|
)
|
|
|
|
is Event.MediaStopState -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ MediaState.stop.record(it) }
|
|
|
|
)
|
2019-11-12 00:38:06 +01:00
|
|
|
is Event.InAppNotificationDownloadOpen -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ DownloadNotification.inAppOpen.record(it) }
|
|
|
|
)
|
|
|
|
is Event.InAppNotificationDownloadTryAgain -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ DownloadNotification.inAppTryAgain.record(it) }
|
|
|
|
)
|
|
|
|
is Event.NotificationDownloadCancel -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ DownloadNotification.cancel.record(it) }
|
|
|
|
)
|
|
|
|
is Event.NotificationDownloadOpen -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ DownloadNotification.open.record(it) }
|
|
|
|
)
|
|
|
|
is Event.NotificationDownloadPause -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ DownloadNotification.pause.record(it) }
|
|
|
|
)
|
|
|
|
is Event.NotificationDownloadResume -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ DownloadNotification.resume.record(it) }
|
|
|
|
)
|
|
|
|
is Event.NotificationDownloadTryAgain -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ DownloadNotification.tryAgain.record(it) }
|
|
|
|
)
|
2019-09-27 17:02:29 +02:00
|
|
|
is Event.NotificationMediaPlay -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ MediaNotification.play.record(it) }
|
|
|
|
)
|
|
|
|
is Event.NotificationMediaPause -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ MediaNotification.pause.record(it) }
|
|
|
|
)
|
2019-09-18 21:59:30 +02:00
|
|
|
is Event.TrackingProtectionTrackerList -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ TrackingProtection.etpTrackerList.record(it) }
|
|
|
|
)
|
|
|
|
is Event.TrackingProtectionIconPressed -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ TrackingProtection.etpShield.record(it) }
|
|
|
|
)
|
|
|
|
is Event.TrackingProtectionSettingsPanel -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ TrackingProtection.panelSettings.record(it) }
|
|
|
|
)
|
|
|
|
is Event.TrackingProtectionSettings -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ TrackingProtection.etpSettings.record(it) }
|
|
|
|
)
|
|
|
|
is Event.TrackingProtectionException -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ TrackingProtection.exceptionAdded.record(it) }
|
|
|
|
)
|
|
|
|
is Event.TrackingProtectionSettingChanged -> EventWrapper(
|
|
|
|
{ TrackingProtection.etpSettingChanged.record(it) },
|
|
|
|
{ TrackingProtection.etpSettingChangedKeys.valueOf(it) }
|
|
|
|
)
|
2019-10-25 02:16:49 +02:00
|
|
|
is Event.OpenedLink -> EventWrapper(
|
|
|
|
{ Events.openedLink.record(it) },
|
|
|
|
{ Events.openedLinkKeys.valueOf(it) }
|
|
|
|
)
|
2019-11-13 00:55:36 +01:00
|
|
|
is Event.OpenLogins -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Logins.openLogins.record(it) }
|
|
|
|
)
|
|
|
|
is Event.OpenOneLogin -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Logins.openIndividualLogin.record(it) }
|
|
|
|
)
|
|
|
|
is Event.CopyLogin -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Logins.copyLogin.record(it) }
|
|
|
|
)
|
|
|
|
is Event.ViewLoginPassword -> EventWrapper<NoExtraKeys>(
|
|
|
|
{ Logins.viewPasswordLogin.record(it) }
|
|
|
|
)
|
2019-11-26 01:43:32 +01:00
|
|
|
is Event.ToolbarPositionChanged -> EventWrapper(
|
|
|
|
{ ToolbarSettings.changedPosition.record(it) },
|
|
|
|
{ ToolbarSettings.changedPositionKeys.valueOf(it) }
|
|
|
|
)
|
2019-08-20 00:25:48 +02:00
|
|
|
// Don't record other events in Glean:
|
|
|
|
is Event.AddBookmark -> null
|
|
|
|
is Event.OpenedBookmark -> null
|
|
|
|
is Event.OpenedAppFirstRun -> null
|
|
|
|
is Event.InteractWithSearchURLArea -> null
|
|
|
|
is Event.ClearedPrivateData -> null
|
|
|
|
is Event.DismissedOnboarding -> null
|
2019-03-18 22:54:36 +01:00
|
|
|
}
|
|
|
|
|
2019-03-12 21:09:04 +01:00
|
|
|
class GleanMetricsService(private val context: Context) : MetricsService {
|
2019-04-09 19:29:09 +02:00
|
|
|
private var initialized = false
|
2019-05-01 02:45:56 +02:00
|
|
|
/*
|
|
|
|
* We need to keep an eye on when we are done starting so that we don't
|
|
|
|
* accidentally stop ourselves before we've ever started.
|
|
|
|
*/
|
2019-11-13 05:14:23 +01:00
|
|
|
private lateinit var gleanInitializer: Job
|
|
|
|
private lateinit var gleanSetStartupMetrics: Job
|
2019-04-09 19:29:09 +02:00
|
|
|
|
2019-05-03 16:40:22 +02:00
|
|
|
private val activationPing = ActivationPing(context)
|
|
|
|
|
2019-03-12 21:09:04 +01:00
|
|
|
override fun start() {
|
2019-05-15 23:51:55 +02:00
|
|
|
Glean.setUploadEnabled(true)
|
2019-05-01 02:45:56 +02:00
|
|
|
|
2019-04-09 19:29:09 +02:00
|
|
|
if (initialized) return
|
2019-05-01 02:45:56 +02:00
|
|
|
initialized = true
|
2019-04-09 19:29:09 +02:00
|
|
|
|
2019-10-01 18:20:49 +02:00
|
|
|
// We have to initialize Glean *on* the main thread, because it registers lifecycle
|
|
|
|
// observers. However, the activation ping must be sent *off* of the main thread,
|
|
|
|
// because it calls Google ad APIs that must be called *off* of the main thread.
|
|
|
|
// These two things actually happen in parallel, but that should be ok because Glean
|
|
|
|
// can handle events being recorded before it's initialized.
|
2019-11-13 05:14:23 +01:00
|
|
|
gleanInitializer = MainScope().launch {
|
2019-05-15 23:51:55 +02:00
|
|
|
Glean.registerPings(Pings)
|
2019-10-04 19:28:23 +02:00
|
|
|
Glean.initialize(context,
|
|
|
|
Configuration(channel = BuildConfig.BUILD_TYPE,
|
|
|
|
httpClient = ConceptFetchHttpUploader(
|
|
|
|
lazy(LazyThreadSafetyMode.NONE) { context.components.core.client }
|
|
|
|
)))
|
2019-09-18 19:11:49 +02:00
|
|
|
}
|
2019-11-13 05:14:23 +01:00
|
|
|
// setStartupMetrics is not a fast function. It does not need to be done before we can consider
|
|
|
|
// ourselves initialized. So, let's do it, well, later.
|
|
|
|
gleanSetStartupMetrics = MainScope().launch {
|
|
|
|
setStartupMetrics()
|
|
|
|
}
|
2019-11-07 04:10:56 +01:00
|
|
|
|
|
|
|
context.settings().totalUriCount = 0
|
2019-09-18 19:11:49 +02:00
|
|
|
}
|
2019-04-12 22:25:16 +02:00
|
|
|
|
2019-09-18 19:11:49 +02:00
|
|
|
internal fun setStartupMetrics() {
|
|
|
|
Metrics.apply {
|
|
|
|
defaultBrowser.set(Browsers.all(context).isDefaultBrowser)
|
|
|
|
MozillaProductDetector.getMozillaBrowserDefault(context)?.also {
|
|
|
|
defaultMozBrowser.set(it)
|
2019-05-01 02:45:56 +02:00
|
|
|
}
|
2019-09-18 19:11:49 +02:00
|
|
|
mozillaProducts.set(MozillaProductDetector.getInstalledMozillaProducts(context))
|
2019-09-27 17:56:33 +02:00
|
|
|
adjustCampaign.set(context.settings().adjustCampaignId)
|
2019-10-30 19:02:33 +01:00
|
|
|
totalUriCount.set(context.settings().totalUriCount.toString())
|
2019-11-26 01:43:32 +01:00
|
|
|
toolbarPosition.set(context.settings().toolbarSettingString)
|
2019-09-18 19:11:49 +02:00
|
|
|
}
|
2019-05-03 16:40:22 +02:00
|
|
|
|
2019-09-18 19:11:49 +02:00
|
|
|
SearchDefaultEngine.apply {
|
|
|
|
val defaultEngine = context
|
|
|
|
.components
|
|
|
|
.search
|
|
|
|
.searchEngineManager
|
|
|
|
.defaultSearchEngine ?: return@apply
|
|
|
|
|
|
|
|
code.set(defaultEngine.identifier)
|
|
|
|
name.set(defaultEngine.name)
|
|
|
|
submissionUrl.set(defaultEngine.buildSearchUrl(""))
|
2019-05-01 02:45:56 +02:00
|
|
|
}
|
2019-09-18 19:11:49 +02:00
|
|
|
|
|
|
|
activationPing.checkAndSend()
|
2019-03-12 21:09:04 +01:00
|
|
|
}
|
|
|
|
|
2019-04-03 20:59:08 +02:00
|
|
|
override fun stop() {
|
2019-11-13 05:14:23 +01:00
|
|
|
gleanInitializer.cancel()
|
|
|
|
gleanSetStartupMetrics.cancel()
|
2019-04-03 20:59:08 +02:00
|
|
|
Glean.setUploadEnabled(false)
|
|
|
|
}
|
|
|
|
|
2019-03-18 22:32:03 +01:00
|
|
|
override fun track(event: Event) {
|
2019-03-22 07:05:28 +01:00
|
|
|
event.wrapper?.track(event)
|
2019-03-18 22:32:03 +01:00
|
|
|
}
|
2019-03-12 21:09:04 +01:00
|
|
|
|
2019-03-18 22:32:03 +01:00
|
|
|
override fun shouldTrack(event: Event): Boolean {
|
2019-04-09 19:29:09 +02:00
|
|
|
return event.wrapper != null
|
2019-03-12 21:09:04 +01:00
|
|
|
}
|
|
|
|
}
|