closes #23381: add telemetry for wallpapers feature
This commit is contained in:
parent
4c324abfb2
commit
eed42ee96b
|
@ -6954,3 +6954,66 @@ search_terms:
|
|||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
expires: "2022-12-01"
|
||||
|
||||
wallpapers:
|
||||
discovered_wallpaper_feature:
|
||||
type: boolean
|
||||
description: |
|
||||
Whether or not the user has discovered the wallpaper feature.
|
||||
bugs:
|
||||
- https://github.com/mozilla-mobile/fenix/issues/23381
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/fenix/pull/23382
|
||||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
expires: "2023-05-01"
|
||||
new_wallpaper_applied:
|
||||
type: labeled_counter
|
||||
description: |
|
||||
How many and which type of wallpapers were applied.
|
||||
bugs:
|
||||
- https://github.com/mozilla-mobile/fenix/issues/23381
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/fenix/pull/23382
|
||||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
expires: "2023-05-01"
|
||||
selected_wallpaper:
|
||||
type: event
|
||||
description: |
|
||||
Records the wallpaper that is active at session start.
|
||||
extra_keys:
|
||||
name:
|
||||
description: The name of the selected wallpaper
|
||||
type: string
|
||||
is_themed:
|
||||
description: Whether the selected wallpaper is part of a theme.
|
||||
type: boolean
|
||||
bugs:
|
||||
- https://github.com/mozilla-mobile/fenix/issues/23381
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/fenix/pull/23382
|
||||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
expires: "2023-05-01"
|
||||
wallpaper_reset_to_default:
|
||||
type: event
|
||||
description: |
|
||||
The user has reset their wallpaper back to the default background.
|
||||
This means the default is active on startup, and has changed since the
|
||||
previous session.
|
||||
bugs:
|
||||
- https://github.com/mozilla-mobile/fenix/issues/23381
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/fenix/pull/23382
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
expires: "2023-05-01"
|
||||
|
|
|
@ -145,7 +145,7 @@ class Components(private val context: Context) {
|
|||
}
|
||||
|
||||
val wallpaperManager by lazyMonitored {
|
||||
WallpaperManager(settings, WallpapersAssetsStorage(context))
|
||||
WallpaperManager(settings, WallpapersAssetsStorage(context), analytics.metrics)
|
||||
}
|
||||
|
||||
val analytics by lazyMonitored { Analytics(context) }
|
||||
|
|
|
@ -676,6 +676,13 @@ sealed class Event {
|
|||
|
||||
sealed class Search
|
||||
|
||||
sealed class Wallpaper : Event() {
|
||||
object DiscoveredFeature : Wallpaper()
|
||||
data class NewWallpaperApplied(val wallpaper: org.mozilla.fenix.wallpapers.Wallpaper) : Wallpaper()
|
||||
data class WallpaperSelected(val wallpaper: org.mozilla.fenix.wallpapers.Wallpaper) : Wallpaper()
|
||||
object WallpaperResetToDefault : Wallpaper()
|
||||
}
|
||||
|
||||
internal open val extras: Map<*, String>?
|
||||
get() = null
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@ import org.mozilla.fenix.GleanMetrics.ToolbarSettings
|
|||
import org.mozilla.fenix.GleanMetrics.TopSites
|
||||
import org.mozilla.fenix.GleanMetrics.TrackingProtection
|
||||
import org.mozilla.fenix.GleanMetrics.VoiceSearch
|
||||
import org.mozilla.fenix.GleanMetrics.Wallpapers
|
||||
import org.mozilla.fenix.ext.components
|
||||
|
||||
private class EventWrapper<T : Enum<T>>(
|
||||
|
@ -907,6 +908,25 @@ private val Event.wrapper: EventWrapper<*>?
|
|||
is Event.JumpBackInGroupTapped -> EventWrapper<NoExtraKeys>(
|
||||
{ SearchTerms.jumpBackInGroupTapped.record(it) }
|
||||
)
|
||||
is Event.Wallpaper.DiscoveredFeature -> EventWrapper<NoExtraKeys>(
|
||||
{ Wallpapers.discoveredWallpaperFeature.set(true) }
|
||||
)
|
||||
is Event.Wallpaper.NewWallpaperApplied -> EventWrapper<NoExtraKeys>(
|
||||
{ Wallpapers.newWallpaperApplied[this.wallpaper.name].add() }
|
||||
)
|
||||
is Event.Wallpaper.WallpaperSelected -> EventWrapper<NoExtraKeys>(
|
||||
{
|
||||
Wallpapers.selectedWallpaper.record(
|
||||
Wallpapers.SelectedWallpaperExtra(
|
||||
name = this.wallpaper.name,
|
||||
isThemed = this.wallpaper.isThemed,
|
||||
),
|
||||
)
|
||||
},
|
||||
)
|
||||
Event.Wallpaper.WallpaperResetToDefault -> EventWrapper<NoExtraKeys>(
|
||||
{ Wallpapers.wallpaperResetToDefault.record() }
|
||||
)
|
||||
|
||||
// Don't record other events in Glean:
|
||||
is Event.AddBookmark -> null
|
||||
|
|
|
@ -767,6 +767,7 @@ class HomeFragment : Fragment() {
|
|||
if (shouldEnableWallpaper() && context.settings().wallpapersSwitchedByLogoTap) {
|
||||
binding.wordmark.setOnClickListener {
|
||||
val manager = requireComponents.wallpaperManager
|
||||
manager.recordDiscoveredMetric()
|
||||
manager.updateWallpaper(
|
||||
wallpaperContainer = binding.homeLayout,
|
||||
newWallpaper = manager.switchToNextWallpaper()
|
||||
|
|
|
@ -36,6 +36,7 @@ class WallpaperSettingsFragment : Fragment() {
|
|||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
wallpaperManager.recordDiscoveredMetric()
|
||||
return ComposeView(requireContext()).apply {
|
||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||
setContent {
|
||||
|
|
|
@ -166,6 +166,11 @@ class Settings(private val appContext: Context) : PreferencesHolder {
|
|||
default = ""
|
||||
)
|
||||
|
||||
var previousWallpaper by stringPreference(
|
||||
appContext.getPreferenceKey(R.string.pref_key_previous_wallpaper),
|
||||
default = WallpaperManager.defaultWallpaper.name
|
||||
)
|
||||
|
||||
var currentWallpaper by stringPreference(
|
||||
appContext.getPreferenceKey(R.string.pref_key_current_wallpaper),
|
||||
default = WallpaperManager.defaultWallpaper.name
|
||||
|
@ -176,6 +181,11 @@ class Settings(private val appContext: Context) : PreferencesHolder {
|
|||
default = true
|
||||
)
|
||||
|
||||
var wallpapersDiscovered by booleanPreference(
|
||||
appContext.getPreferenceKey(R.string.pref_key_wallpapers_discovered),
|
||||
default = false
|
||||
)
|
||||
|
||||
var openLinksInAPrivateTab by booleanPreference(
|
||||
appContext.getPreferenceKey(R.string.pref_key_open_links_in_a_private_tab),
|
||||
default = false
|
||||
|
|
|
@ -10,10 +10,12 @@ package org.mozilla.fenix.wallpapers
|
|||
* @property portraitPath A file path for the portrait version of this wallpaper.
|
||||
* @property landscapePath A file path for the landscape version of this wallpaper.
|
||||
* @property isDark Indicates if the most predominant color on the wallpaper is dark.
|
||||
* @property isThemed Whether the wallpaper belongs to a themed collection.
|
||||
*/
|
||||
data class Wallpaper(
|
||||
val name: String,
|
||||
val portraitPath: String,
|
||||
val landscapePath: String,
|
||||
val isDark: Boolean
|
||||
val isDark: Boolean,
|
||||
val isThemed: Boolean = false,
|
||||
)
|
||||
|
|
|
@ -14,15 +14,19 @@ import androidx.appcompat.app.AppCompatDelegate
|
|||
import mozilla.components.support.base.log.logger.Logger
|
||||
import mozilla.components.support.ktx.android.content.getColorFromAttr
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.components.metrics.MetricController
|
||||
import org.mozilla.fenix.ext.asActivity
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
/**
|
||||
* Provides access to available wallpapers and manages their states.
|
||||
*/
|
||||
@Suppress("TooManyFunctions")
|
||||
class WallpaperManager(
|
||||
private val settings: Settings,
|
||||
private val wallpaperStorage: WallpaperStorage
|
||||
private val wallpaperStorage: WallpaperStorage,
|
||||
private val metrics: MetricController,
|
||||
) {
|
||||
val logger = Logger("WallpaperManager")
|
||||
var availableWallpapers: List<Wallpaper> = loadWallpapers()
|
||||
|
@ -30,6 +34,7 @@ class WallpaperManager(
|
|||
|
||||
var currentWallpaper: Wallpaper = getCurrentWallpaperFromSettings()
|
||||
set(value) {
|
||||
settings.previousWallpaper = currentWallpaper.name
|
||||
settings.currentWallpaper = value.name
|
||||
field = value
|
||||
}
|
||||
|
@ -50,6 +55,7 @@ class WallpaperManager(
|
|||
currentWallpaper = newWallpaper
|
||||
|
||||
adjustTheme(wallpaperContainer.context)
|
||||
recordWallpaperAppliedMetric(newWallpaper)
|
||||
}
|
||||
|
||||
private fun adjustTheme(context: Context) {
|
||||
|
@ -107,6 +113,8 @@ class WallpaperManager(
|
|||
defaultWallpaper
|
||||
} else {
|
||||
availableWallpapers.find { it.name == currentWallpaper } ?: defaultWallpaper
|
||||
}.also {
|
||||
recordSelectionMetrics(it)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -134,6 +142,28 @@ class WallpaperManager(
|
|||
}
|
||||
}
|
||||
|
||||
fun recordDiscoveredMetric() {
|
||||
val hasSentMetric = settings.wallpapersDiscovered
|
||||
if (!hasSentMetric) {
|
||||
metrics.track(Event.Wallpaper.DiscoveredFeature)
|
||||
settings.wallpapersDiscovered = true
|
||||
}
|
||||
}
|
||||
|
||||
private fun recordWallpaperAppliedMetric(appliedWallpaper: Wallpaper) {
|
||||
metrics.track(Event.Wallpaper.NewWallpaperApplied(appliedWallpaper))
|
||||
}
|
||||
|
||||
private fun recordSelectionMetrics(currentWallpaper: Wallpaper) {
|
||||
val previousWallpaperName = settings.previousWallpaper
|
||||
if (previousWallpaperName != defaultWallpaper.name && currentWallpaper == defaultWallpaper) {
|
||||
metrics.track(Event.Wallpaper.WallpaperResetToDefault)
|
||||
// This metric will continue to be reported unless the previous wallpaper is reset
|
||||
settings.previousWallpaper = currentWallpaper.name
|
||||
}
|
||||
metrics.track(Event.Wallpaper.WallpaperSelected(currentWallpaper))
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val DEFAULT_RESOURCE = R.attr.homeBackground
|
||||
val defaultWallpaper = Wallpaper(
|
||||
|
|
|
@ -189,8 +189,10 @@
|
|||
|
||||
<!-- Wallpaper Settings -->
|
||||
<string name="pref_key_wallpapers" translatable="false">pref_key_wallpapers</string>
|
||||
<string name="pref_key_previous_wallpaper" translatable="false">pref_key_previous_wallpaper</string>
|
||||
<string name="pref_key_current_wallpaper" translatable="false">pref_key_current_wallpaper</string>
|
||||
<string name="pref_key_wallpapers_switched_by_logo_tap">pref_key_wallpapers_switched_by_logo_tap</string>
|
||||
<string name="pref_key_wallpapers_discovered" translatable="false">pref_key_wallpapers_discovered</string>
|
||||
|
||||
<string name="pref_key_encryption_key_generated" translatable="false">pref_key_encryption_key_generated</string>
|
||||
|
||||
|
|
|
@ -0,0 +1,143 @@
|
|||
package org.mozilla.fenix.wallpapers
|
||||
|
||||
import io.mockk.every
|
||||
import io.mockk.just
|
||||
import io.mockk.mockk
|
||||
import io.mockk.runs
|
||||
import io.mockk.slot
|
||||
import io.mockk.verify
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.components.metrics.Event
|
||||
import org.mozilla.fenix.components.metrics.MetricController
|
||||
import org.mozilla.fenix.utils.Settings
|
||||
|
||||
class WallpaperManagerTest {
|
||||
|
||||
private val fakeWallpaper = Wallpaper(
|
||||
name = "fake wallpaper",
|
||||
portraitPath = "",
|
||||
landscapePath = "",
|
||||
isDark = false,
|
||||
isThemed = false,
|
||||
)
|
||||
private val fakeThemedWallpaper = Wallpaper(
|
||||
name = "fake themed wallpaper",
|
||||
portraitPath = "",
|
||||
landscapePath = "",
|
||||
isDark = false,
|
||||
isThemed = true,
|
||||
)
|
||||
private val fakeWallpapers = listOf(fakeWallpaper, fakeThemedWallpaper)
|
||||
|
||||
private val mockSettings: Settings = mockk()
|
||||
private val mockStorage: WallpaperStorage = mockk {
|
||||
every { loadAll() } returns fakeWallpapers
|
||||
}
|
||||
private val mockMetrics: MetricController = mockk()
|
||||
|
||||
@Test
|
||||
fun `WHEN wallpaper set THEN current wallpaper updated in settings`() {
|
||||
every { mockMetrics.track(any()) } just runs
|
||||
val currentCaptureSlot = slot<String>()
|
||||
val updatedWallpaper = fakeWallpaper
|
||||
every { mockSettings.currentWallpaper } returns WallpaperManager.defaultWallpaper.name
|
||||
every { mockSettings.currentWallpaper = capture(currentCaptureSlot) } just runs
|
||||
every { mockSettings.previousWallpaper } returns WallpaperManager.defaultWallpaper.name
|
||||
every { mockSettings.previousWallpaper = capture(slot()) } just runs
|
||||
|
||||
val wallpaperManager = WallpaperManager(mockSettings, mockStorage, mockMetrics)
|
||||
wallpaperManager.currentWallpaper = updatedWallpaper
|
||||
|
||||
assertEquals(updatedWallpaper.name, currentCaptureSlot.captured)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN wallpaper set THEN current wallpaper saved as previous in settings`() {
|
||||
every { mockMetrics.track(any()) } just runs
|
||||
val previousCaptureSlot = slot<String>()
|
||||
val currentWallpaper = fakeWallpaper
|
||||
every { mockSettings.currentWallpaper } returns currentWallpaper.name
|
||||
every { mockSettings.currentWallpaper = capture(slot()) } just runs
|
||||
every { mockSettings.previousWallpaper } returns WallpaperManager.defaultWallpaper.name
|
||||
every { mockSettings.previousWallpaper = capture(previousCaptureSlot) } just runs
|
||||
|
||||
val wallpaperManager = WallpaperManager(mockSettings, mockStorage, mockMetrics)
|
||||
wallpaperManager.currentWallpaper = WallpaperManager.defaultWallpaper
|
||||
|
||||
assertEquals(currentWallpaper.name, previousCaptureSlot.captured)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN wallpaper is initially fetched from settings THEN selection metric reported`() {
|
||||
val defaultWallpaper = WallpaperManager.defaultWallpaper
|
||||
every { mockSettings.previousWallpaper } returns defaultWallpaper.name
|
||||
every { mockSettings.currentWallpaper } returns defaultWallpaper.name
|
||||
every { mockMetrics.track(any()) } just runs
|
||||
|
||||
WallpaperManager(mockSettings, mockStorage, mockMetrics)
|
||||
|
||||
verify { mockMetrics.track(Event.Wallpaper.WallpaperSelected(defaultWallpaper)) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `GIVEN previous wallpaper was not default WHEN current wallpaper is loaded as default THEN selection metric reported and previous reset`() {
|
||||
val defaultWallpaper = WallpaperManager.defaultWallpaper
|
||||
val previousSlot = slot<String>()
|
||||
every { mockSettings.previousWallpaper } returns fakeWallpaper.name
|
||||
every { mockSettings.previousWallpaper = capture(previousSlot) } just runs
|
||||
every { mockSettings.currentWallpaper } returns defaultWallpaper.name
|
||||
every { mockMetrics.track(any()) } just runs
|
||||
|
||||
WallpaperManager(mockSettings, mockStorage, mockMetrics)
|
||||
|
||||
assertEquals(defaultWallpaper.name, previousSlot.captured)
|
||||
verify { mockMetrics.track(Event.Wallpaper.WallpaperResetToDefault) }
|
||||
verify { mockMetrics.track(Event.Wallpaper.WallpaperSelected(defaultWallpaper)) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN wallpaper updated THEN wallpaper applied metric recorded`() {
|
||||
val defaultWallpaper = WallpaperManager.defaultWallpaper
|
||||
every { mockSettings.previousWallpaper } returns defaultWallpaper.name
|
||||
every { mockSettings.previousWallpaper = capture(slot()) } just runs
|
||||
every { mockSettings.currentWallpaper } returns defaultWallpaper.name
|
||||
every { mockSettings.currentWallpaper = capture(slot()) } just runs
|
||||
every { mockMetrics.track(any()) } just runs
|
||||
|
||||
val manager = WallpaperManager(mockSettings, mockStorage, mockMetrics)
|
||||
manager.updateWallpaper(mockk(relaxed = true), defaultWallpaper)
|
||||
|
||||
verify { mockMetrics.track(Event.Wallpaper.NewWallpaperApplied(defaultWallpaper)) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN wallpaper discovered metric not previously recorded WHEN metric record attempted THEN metric sent`() {
|
||||
every { mockSettings.wallpapersDiscovered } returns false
|
||||
every { mockSettings.previousWallpaper } returns WallpaperManager.defaultWallpaper.name
|
||||
every { mockSettings.currentWallpaper } returns WallpaperManager.defaultWallpaper.name
|
||||
every { mockSettings.wallpapersDiscovered = true } just runs
|
||||
every { mockMetrics.track(any()) } just runs
|
||||
|
||||
val wallpaperManager = WallpaperManager(mockSettings, mockStorage, mockMetrics)
|
||||
|
||||
wallpaperManager.recordDiscoveredMetric()
|
||||
|
||||
verify { mockMetrics.track(Event.Wallpaper.DiscoveredFeature) }
|
||||
verify { mockSettings.wallpapersDiscovered = true }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN wallpaper discovered metric previously recorded WHEN metric record attempted THEN metric not sent`() {
|
||||
every { mockSettings.wallpapersDiscovered } returns true
|
||||
every { mockSettings.previousWallpaper } returns WallpaperManager.defaultWallpaper.name
|
||||
every { mockSettings.currentWallpaper } returns WallpaperManager.defaultWallpaper.name
|
||||
every { mockMetrics.track(any()) } just runs
|
||||
|
||||
val wallpaperManager = WallpaperManager(mockSettings, mockStorage, mockMetrics)
|
||||
|
||||
wallpaperManager.recordDiscoveredMetric()
|
||||
|
||||
verify(exactly = 0) { mockMetrics.track(Event.Wallpaper.DiscoveredFeature) }
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue