For #24638 - Remove Event.wrapper for Logins telemetry

This commit is contained in:
Alexandru2909 2022-04-06 15:09:28 +03:00 committed by mergify[bot]
parent f170772f0c
commit 4d0b79192d
11 changed files with 46 additions and 73 deletions

View File

@ -4726,6 +4726,7 @@ logins:
A user changed their setting for asking to save logins A user changed their setting for asking to save logins
extra_keys: extra_keys:
setting: setting:
type: string
description: | description: |
The new setting for saving logins the user selected. Either The new setting for saving logins the user selected. Either
`ask_to_save` or `never_save` `ask_to_save` or `never_save`

View File

@ -11,7 +11,6 @@ import org.mozilla.fenix.GleanMetrics.AppTheme
import org.mozilla.fenix.GleanMetrics.Autoplay import org.mozilla.fenix.GleanMetrics.Autoplay
import org.mozilla.fenix.GleanMetrics.ContextMenu import org.mozilla.fenix.GleanMetrics.ContextMenu
import org.mozilla.fenix.GleanMetrics.Events import org.mozilla.fenix.GleanMetrics.Events
import org.mozilla.fenix.GleanMetrics.Logins
import org.mozilla.fenix.GleanMetrics.Pocket import org.mozilla.fenix.GleanMetrics.Pocket
import org.mozilla.fenix.GleanMetrics.SearchTerms import org.mozilla.fenix.GleanMetrics.SearchTerms
import org.mozilla.fenix.GleanMetrics.TopSites import org.mozilla.fenix.GleanMetrics.TopSites
@ -47,13 +46,6 @@ sealed class Event {
object TopSiteContilePrivacy : Event() object TopSiteContilePrivacy : Event()
object GoogleTopSiteRemoved : Event() object GoogleTopSiteRemoved : Event()
object BaiduTopSiteRemoved : Event() object BaiduTopSiteRemoved : Event()
object OpenLogins : Event()
object OpenOneLogin : Event()
object CopyLogin : Event()
object DeleteLogin : Event()
object EditLogin : Event()
object EditLoginSave : Event()
object ViewLoginPassword : Event()
object PocketTopSiteClicked : Event() object PocketTopSiteClicked : Event()
object PocketTopSiteRemoved : Event() object PocketTopSiteRemoved : Event()
object PocketHomeRecsShown : Event() object PocketHomeRecsShown : Event()
@ -190,13 +182,6 @@ sealed class Event {
get() = hashMapOf(Addons.openAddonSettingKeys.addonId to addonId) get() = hashMapOf(Addons.openAddonSettingKeys.addonId to addonId)
} }
data class SaveLoginsSettingChanged(val setting: Setting) : Event() {
enum class Setting { NEVER_SAVE, ASK_TO_SAVE }
override val extras: Map<Logins.saveLoginsSettingChangedKeys, String>?
get() = hashMapOf(Logins.saveLoginsSettingChangedKeys.setting to setting.name)
}
data class PerformedSearch(val eventSource: EventSource) : Event() { data class PerformedSearch(val eventSource: EventSource) : Event() {
sealed class EngineSource { sealed class EngineSource {
abstract val engine: SearchEngine abstract val engine: SearchEngine

View File

@ -21,7 +21,6 @@ import org.mozilla.fenix.GleanMetrics.Events
import org.mozilla.fenix.GleanMetrics.ExperimentsDefaultBrowser import org.mozilla.fenix.GleanMetrics.ExperimentsDefaultBrowser
import org.mozilla.fenix.GleanMetrics.HomeMenu import org.mozilla.fenix.GleanMetrics.HomeMenu
import org.mozilla.fenix.GleanMetrics.HomeScreen import org.mozilla.fenix.GleanMetrics.HomeScreen
import org.mozilla.fenix.GleanMetrics.Logins
import org.mozilla.fenix.GleanMetrics.MediaState import org.mozilla.fenix.GleanMetrics.MediaState
import org.mozilla.fenix.GleanMetrics.Metrics import org.mozilla.fenix.GleanMetrics.Metrics
import org.mozilla.fenix.GleanMetrics.Pings import org.mozilla.fenix.GleanMetrics.Pings
@ -128,31 +127,6 @@ private val Event.wrapper: EventWrapper<*>?
is Event.MediaPictureInPictureState -> EventWrapper<NoExtraKeys>( is Event.MediaPictureInPictureState -> EventWrapper<NoExtraKeys>(
{ MediaState.pictureInPicture.record(it) } { MediaState.pictureInPicture.record(it) }
) )
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) }
)
is Event.DeleteLogin -> EventWrapper<NoExtraKeys>(
{ Logins.deleteSavedLogin.record(it) }
)
is Event.EditLogin -> EventWrapper<NoExtraKeys>(
{ Logins.openLoginEditor.record(it) }
)
is Event.EditLoginSave -> EventWrapper<NoExtraKeys>(
{ Logins.saveEditedLogin.record(it) }
)
is Event.SaveLoginsSettingChanged -> EventWrapper(
{ Logins.saveLoginsSettingChanged.record(it) },
{ Logins.saveLoginsSettingChangedKeys.valueOf(it) }
)
is Event.TopSiteOpenDefault -> EventWrapper<NoExtraKeys>( is Event.TopSiteOpenDefault -> EventWrapper<NoExtraKeys>(
{ TopSites.openDefault.record(it) } { TopSites.openDefault.record(it) }
) )

View File

@ -8,9 +8,9 @@ import android.text.InputType
import android.widget.ImageButton import android.widget.ImageButton
import android.widget.TextView import android.widget.TextView
import androidx.appcompat.content.res.AppCompatResources import androidx.appcompat.content.res.AppCompatResources
import mozilla.components.service.glean.private.NoExtras
import org.mozilla.fenix.GleanMetrics.Logins
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components
fun togglePasswordReveal(passwordText: TextView, revealPasswordButton: ImageButton) { fun togglePasswordReveal(passwordText: TextView, revealPasswordButton: ImageButton) {
val context = passwordText.context val context = passwordText.context
@ -18,7 +18,7 @@ fun togglePasswordReveal(passwordText: TextView, revealPasswordButton: ImageButt
if (passwordText.inputType == InputType.TYPE_TEXT_VARIATION_PASSWORD if (passwordText.inputType == InputType.TYPE_TEXT_VARIATION_PASSWORD
or InputType.TYPE_CLASS_TEXT or InputType.TYPE_CLASS_TEXT
) { ) {
context.components.analytics.metrics.track(Event.ViewLoginPassword) Logins.viewPasswordLogin.record(NoExtras())
passwordText.inputType = InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD passwordText.inputType = InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD
revealPasswordButton.setImageDrawable( revealPasswordButton.setImageDrawable(
AppCompatResources.getDrawable(context, R.drawable.mozac_ic_password_hide) AppCompatResources.getDrawable(context, R.drawable.mozac_ic_password_hide)

View File

@ -5,9 +5,9 @@
package org.mozilla.fenix.settings.logins.controller package org.mozilla.fenix.settings.logins.controller
import androidx.navigation.NavController import androidx.navigation.NavController
import mozilla.components.service.glean.private.NoExtras
import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.GleanMetrics.Logins
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.settings.SupportUtils import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.settings.logins.LoginsAction import org.mozilla.fenix.settings.logins.LoginsAction
import org.mozilla.fenix.settings.logins.LoginsFragmentStore import org.mozilla.fenix.settings.logins.LoginsFragmentStore
@ -23,7 +23,6 @@ import org.mozilla.fenix.utils.Settings
* @param navController NavController manages app navigation within a NavHost. * @param navController NavController manages app navigation within a NavHost.
* @param browserNavigator Controller allowing browser navigation to any Uri. * @param browserNavigator Controller allowing browser navigation to any Uri.
* @param settings SharedPreferences wrapper for easier usage. * @param settings SharedPreferences wrapper for easier usage.
* @param metrics Controller that handles telemetry events.
*/ */
class LoginsListController( class LoginsListController(
private val loginsFragmentStore: LoginsFragmentStore, private val loginsFragmentStore: LoginsFragmentStore,
@ -34,12 +33,11 @@ class LoginsListController(
from: BrowserDirection from: BrowserDirection
) -> Unit, ) -> Unit,
private val settings: Settings, private val settings: Settings,
private val metrics: MetricController
) { ) {
fun handleItemClicked(item: SavedLogin) { fun handleItemClicked(item: SavedLogin) {
loginsFragmentStore.dispatch(LoginsAction.LoginSelected(item)) loginsFragmentStore.dispatch(LoginsAction.LoginSelected(item))
metrics.track(Event.OpenOneLogin) Logins.openIndividualLogin.record(NoExtras())
navController.navigate( navController.navigate(
SavedLoginsFragmentDirections.actionSavedLoginsFragmentToLoginDetailFragment(item.guid) SavedLoginsFragmentDirections.actionSavedLoginsFragmentToLoginDetailFragment(item.guid)
) )

View File

@ -20,14 +20,14 @@ import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs import androidx.navigation.fragment.navArgs
import mozilla.components.lib.state.ext.consumeFrom import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.service.glean.private.NoExtras
import mozilla.components.support.ktx.android.view.hideKeyboard import mozilla.components.support.ktx.android.view.hideKeyboard
import org.mozilla.fenix.GleanMetrics.Logins
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.StoreProvider import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.databinding.FragmentEditLoginBinding import org.mozilla.fenix.databinding.FragmentEditLoginBinding
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.redirectToReAuth import org.mozilla.fenix.ext.redirectToReAuth
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.toEditable import org.mozilla.fenix.ext.toEditable
import org.mozilla.fenix.settings.logins.LoginsAction import org.mozilla.fenix.settings.logins.LoginsAction
@ -288,7 +288,7 @@ class EditLoginFragment : Fragment(R.layout.fragment_edit_login) {
binding.usernameText.text.toString(), binding.usernameText.text.toString(),
binding.passwordText.text.toString() binding.passwordText.text.toString()
) )
requireComponents.analytics.metrics.track(Event.EditLoginSave) Logins.saveEditedLogin.record(NoExtras())
true true
} }
else -> false else -> false

View File

@ -20,18 +20,18 @@ import androidx.navigation.fragment.findNavController
import androidx.navigation.fragment.navArgs import androidx.navigation.fragment.navArgs
import com.google.android.material.snackbar.Snackbar import com.google.android.material.snackbar.Snackbar
import mozilla.components.lib.state.ext.consumeFrom import mozilla.components.lib.state.ext.consumeFrom
import mozilla.components.service.glean.private.NoExtras
import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.GleanMetrics.Logins
import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.SecureFragment import org.mozilla.fenix.SecureFragment
import org.mozilla.fenix.components.FenixSnackbar import org.mozilla.fenix.components.FenixSnackbar
import org.mozilla.fenix.components.StoreProvider import org.mozilla.fenix.components.StoreProvider
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.databinding.FragmentLoginDetailBinding import org.mozilla.fenix.databinding.FragmentLoginDetailBinding
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.increaseTapArea import org.mozilla.fenix.ext.increaseTapArea
import org.mozilla.fenix.ext.redirectToReAuth import org.mozilla.fenix.ext.redirectToReAuth
import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.settings import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.ext.simplifiedUrl import org.mozilla.fenix.ext.simplifiedUrl
@ -183,7 +183,7 @@ class LoginDetailFragment : SecureFragment(R.layout.fragment_login_detail) {
} }
private fun editLogin() { private fun editLogin() {
requireComponents.analytics.metrics.track(Event.EditLogin) Logins.openLoginEditor.record(NoExtras())
val directions = val directions =
LoginDetailFragmentDirections.actionLoginDetailFragmentToEditLoginFragment( LoginDetailFragmentDirections.actionLoginDetailFragmentToEditLoginFragment(
login!! login!!
@ -199,7 +199,7 @@ class LoginDetailFragment : SecureFragment(R.layout.fragment_login_detail) {
dialog.cancel() dialog.cancel()
} }
setPositiveButton(R.string.dialog_delete_positive) { dialog: DialogInterface, _ -> setPositiveButton(R.string.dialog_delete_positive) { dialog: DialogInterface, _ ->
requireComponents.analytics.metrics.track(Event.DeleteLogin) Logins.deleteSavedLogin.record(NoExtras())
interactor.onDeleteLogin(args.savedLoginId) interactor.onDeleteLogin(args.savedLoginId)
dialog.dismiss() dialog.dismiss()
} }
@ -221,7 +221,7 @@ class LoginDetailFragment : SecureFragment(R.layout.fragment_login_detail) {
val clipboard = view.context.components.clipboardHandler val clipboard = view.context.components.clipboardHandler
clipboard.text = value clipboard.text = value
showCopiedSnackbar(view.context.getString(snackbarText)) showCopiedSnackbar(view.context.getString(snackbarText))
view.context.components.analytics.metrics.track(Event.CopyLogin) Logins.copyLogin.record(NoExtras())
} }
private fun showCopiedSnackbar(copiedItem: String) { private fun showCopiedSnackbar(copiedItem: String) {

View File

@ -24,9 +24,10 @@ import kotlinx.coroutines.delay
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import mozilla.components.feature.autofill.preference.AutofillPreference import mozilla.components.feature.autofill.preference.AutofillPreference
import mozilla.components.service.fxa.SyncEngine import mozilla.components.service.fxa.SyncEngine
import mozilla.components.service.glean.private.NoExtras
import mozilla.components.support.base.feature.ViewBoundFeatureWrapper import mozilla.components.support.base.feature.ViewBoundFeatureWrapper
import org.mozilla.fenix.GleanMetrics.Logins
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.requireComponents import org.mozilla.fenix.ext.requireComponents
import org.mozilla.fenix.ext.runIfFragmentIsAttached import org.mozilla.fenix.ext.runIfFragmentIsAttached
@ -223,7 +224,7 @@ class SavedLoginsAuthFragment : PreferenceFragmentCompat() {
* Called when authentication succeeds. * Called when authentication succeeds.
*/ */
private fun navigateToSavedLoginsFragment() { private fun navigateToSavedLoginsFragment() {
context?.components?.analytics?.metrics?.track(Event.OpenLogins) Logins.openLogins.record(NoExtras())
val directions = val directions =
SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToLoginsListFragment() SavedLoginsAuthFragmentDirections.actionSavedLoginsAuthFragmentToLoginsListFragment()
findNavController().navigate(directions) findNavController().navigate(directions)

View File

@ -78,7 +78,6 @@ class SavedLoginsFragment : SecureFragment() {
navController = findNavController(), navController = findNavController(),
browserNavigator = ::openToBrowserAndLoad, browserNavigator = ::openToBrowserAndLoad,
settings = requireContext().settings(), settings = requireContext().settings(),
metrics = requireContext().components.analytics.metrics
) )
savedLoginsStorageController = savedLoginsStorageController =
SavedLoginsStorageController( SavedLoginsStorageController(

View File

@ -7,10 +7,9 @@ package org.mozilla.fenix.settings.logins.fragment
import android.os.Bundle import android.os.Bundle
import androidx.preference.Preference import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat import androidx.preference.PreferenceFragmentCompat
import org.mozilla.fenix.GleanMetrics.Logins
import org.mozilla.fenix.R import org.mozilla.fenix.R
import org.mozilla.fenix.components.metrics.Event
import org.mozilla.fenix.ext.components import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.metrics
import org.mozilla.fenix.ext.showToolbar import org.mozilla.fenix.ext.showToolbar
import org.mozilla.fenix.settings.RadioButtonPreference import org.mozilla.fenix.settings.RadioButtonPreference
import org.mozilla.fenix.settings.SharedPreferenceUpdater import org.mozilla.fenix.settings.SharedPreferenceUpdater
@ -35,9 +34,9 @@ class SavedLoginsSettingFragment : PreferenceFragmentCompat() {
preferenceSave.onPreferenceChangeListener = object : SharedPreferenceUpdater() { preferenceSave.onPreferenceChangeListener = object : SharedPreferenceUpdater() {
override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean { override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
if (newValue == true) { if (newValue == true) {
context?.metrics?.track( Logins.saveLoginsSettingChanged.record(
Event.SaveLoginsSettingChanged( Logins.SaveLoginsSettingChangedExtra(
Event.SaveLoginsSettingChanged.Setting.ASK_TO_SAVE Setting.ASK_TO_SAVE.name
) )
) )
} }
@ -54,9 +53,9 @@ class SavedLoginsSettingFragment : PreferenceFragmentCompat() {
preferenceNeverSave.onPreferenceChangeListener = object : SharedPreferenceUpdater() { preferenceNeverSave.onPreferenceChangeListener = object : SharedPreferenceUpdater() {
override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean { override fun onPreferenceChange(preference: Preference, newValue: Any?): Boolean {
if (newValue == true) { if (newValue == true) {
context?.metrics?.track( Logins.saveLoginsSettingChanged.record(
Event.SaveLoginsSettingChanged( Logins.SaveLoginsSettingChangedExtra(
Event.SaveLoginsSettingChanged.Setting.NEVER_SAVE Setting.NEVER_SAVE.name
) )
) )
} }
@ -67,4 +66,9 @@ class SavedLoginsSettingFragment : PreferenceFragmentCompat() {
} }
return preferenceNeverSave return preferenceNeverSave
} }
companion object {
// Setting describing the approach of saving logins, used for telemetry
enum class Setting { NEVER_SAVE, ASK_TO_SAVE }
}
} }

View File

@ -7,11 +7,17 @@ package org.mozilla.fenix.settings.logins
import androidx.navigation.NavController import androidx.navigation.NavController
import io.mockk.mockk import io.mockk.mockk
import io.mockk.verifyAll import io.mockk.verifyAll
import mozilla.components.service.glean.testing.GleanTestRule
import mozilla.components.support.test.robolectric.testContext
import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertNull
import org.junit.Assert.assertTrue
import org.junit.Rule
import org.junit.Test import org.junit.Test
import org.junit.runner.RunWith import org.junit.runner.RunWith
import org.mozilla.fenix.BrowserDirection import org.mozilla.fenix.BrowserDirection
import org.mozilla.fenix.components.metrics.Event import org.mozilla.fenix.GleanMetrics.Logins
import org.mozilla.fenix.components.metrics.MetricController
import org.mozilla.fenix.helpers.FenixRobolectricTestRunner import org.mozilla.fenix.helpers.FenixRobolectricTestRunner
import org.mozilla.fenix.settings.SupportUtils import org.mozilla.fenix.settings.SupportUtils
import org.mozilla.fenix.settings.logins.controller.LoginsListController import org.mozilla.fenix.settings.logins.controller.LoginsListController
@ -20,19 +26,20 @@ import org.mozilla.fenix.utils.Settings
@RunWith(FenixRobolectricTestRunner::class) @RunWith(FenixRobolectricTestRunner::class)
class LoginsListControllerTest { class LoginsListControllerTest {
@get:Rule
val gleanTestRule = GleanTestRule(testContext)
private val store: LoginsFragmentStore = mockk(relaxed = true) private val store: LoginsFragmentStore = mockk(relaxed = true)
private val settings: Settings = mockk(relaxed = true) private val settings: Settings = mockk(relaxed = true)
private val sortingStrategy: SortingStrategy = SortingStrategy.Alphabetically private val sortingStrategy: SortingStrategy = SortingStrategy.Alphabetically
private val navController: NavController = mockk(relaxed = true) private val navController: NavController = mockk(relaxed = true)
private val browserNavigator: (String, Boolean, BrowserDirection) -> Unit = mockk(relaxed = true) private val browserNavigator: (String, Boolean, BrowserDirection) -> Unit = mockk(relaxed = true)
private val metrics: MetricController = mockk(relaxed = true)
private val controller = private val controller =
LoginsListController( LoginsListController(
loginsFragmentStore = store, loginsFragmentStore = store,
navController = navController, navController = navController,
browserNavigator = browserNavigator, browserNavigator = browserNavigator,
settings = settings, settings = settings,
metrics = metrics
) )
@Test @Test
@ -48,16 +55,20 @@ class LoginsListControllerTest {
@Test @Test
fun `handle login item clicked`() { fun `handle login item clicked`() {
val login: SavedLogin = mockk(relaxed = true) val login: SavedLogin = mockk(relaxed = true)
assertFalse(Logins.openIndividualLogin.testHasValue())
controller.handleItemClicked(login) controller.handleItemClicked(login)
verifyAll { verifyAll {
store.dispatch(LoginsAction.LoginSelected(login)) store.dispatch(LoginsAction.LoginSelected(login))
metrics.track(Event.OpenOneLogin)
navController.navigate( navController.navigate(
SavedLoginsFragmentDirections.actionSavedLoginsFragmentToLoginDetailFragment(login.guid) SavedLoginsFragmentDirections.actionSavedLoginsFragmentToLoginDetailFragment(login.guid)
) )
} }
assertTrue(Logins.openIndividualLogin.testHasValue())
assertEquals(1, Logins.openIndividualLogin.testGetValue().size)
assertNull(Logins.openIndividualLogin.testGetValue().single().extra)
} }
@Test @Test