1
0
Fork 0

For #7295 - Adds new custom ping: 'installation'

master
codrut.topliceanu 2020-02-04 12:52:10 +02:00 committed by Jeff Boek
parent b72550c28a
commit d6ae3d4abe
9 changed files with 286 additions and 2 deletions

View File

@ -1789,3 +1789,70 @@ pocket:
notification_emails: notification_emails:
- fenix-core@mozilla.com - fenix-core@mozilla.com
expires: "2020-09-01" expires: "2020-09-01"
installation:
campaign:
type: string
send_in_pings:
- installation
description: >
Campaign
bugs:
- https://github.com/mozilla-mobile/fenix/issues/7295
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/8074
notification_emails:
- fenix-core@mozilla.com
expires: "2020-09-01"
network:
type: string
send_in_pings:
- installation
description: >
Network
bugs:
- https://github.com/mozilla-mobile/fenix/issues/7295
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/8074
notification_emails:
- fenix-core@mozilla.com
expires: "2020-09-01"
adgroup:
type: string
send_in_pings:
- installation
description: >
AdGroup
bugs:
- https://github.com/mozilla-mobile/fenix/issues/7295
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/8074
notification_emails:
- fenix-core@mozilla.com
expires: "2020-09-01"
creative:
send_in_pings:
- installation
type: string
description: >
Creative
bugs:
- https://github.com/mozilla-mobile/fenix/issues/7295
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/8074
notification_emails:
- fenix-core@mozilla.com
expires: "2020-09-01"
timestamp:
send_in_pings:
- installation
type: string
description: >
Timestamp
bugs:
- https://github.com/mozilla-mobile/fenix/issues/7295
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/8074
notification_emails:
- fenix-core@mozilla.com
expires: "2020-09-01"

View File

@ -18,3 +18,14 @@ activation:
- https://github.com/mozilla-mobile/fenix/pull/1707#issuecomment-486972209 - https://github.com/mozilla-mobile/fenix/pull/1707#issuecomment-486972209
notification_emails: notification_emails:
- fenix-core@mozilla.com - fenix-core@mozilla.com
installation:
description: >
Intended for counting user installs.
include_client_id: false
bugs:
- 7295
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/1707#issuecomment-486972209
notification_emails:
- fenix-core@mozilla.com

View File

@ -38,9 +38,27 @@ class AdjustMetricsService(private val application: Application) : MetricsServic
) )
config.setOnAttributionChangedListener { config.setOnAttributionChangedListener {
it.campaign?.let { campaign -> if (!it.network.isNullOrEmpty()) {
application.applicationContext.settings().adjustCampaignId = campaign application.applicationContext.settings().adjustNetwork =
it.network
} }
if (!it.adgroup.isNullOrEmpty()) {
application.applicationContext.settings().adjustAdGroup =
it.adgroup
}
if (!it.creative.isNullOrEmpty()) {
application.applicationContext.settings().adjustCreative =
it.creative
}
if (!it.campaign.isNullOrEmpty()) {
application.applicationContext.settings().adjustCampaignId =
it.campaign
}
if (application.applicationContext.settings().adjustInstallTimestamp.isEmpty()) {
application.applicationContext.settings().adjustInstallTimestamp =
System.currentTimeMillis().toString()
}
InstallationPing(application).checkAndSend()
} }
config.setLogLevel(LogLevel.SUPRESS) config.setLogLevel(LogLevel.SUPRESS)

View File

@ -571,6 +571,7 @@ class GleanMetricsService(private val context: Context) : MetricsService {
} }
activationPing.checkAndSend() activationPing.checkAndSend()
InstallationPing(context).checkAndSend()
} }
override fun stop() { override fun stop() {

View File

@ -0,0 +1,93 @@
/* 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
import android.content.Context
import android.content.SharedPreferences
import androidx.annotation.VisibleForTesting
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import mozilla.components.support.base.log.logger.Logger
import org.mozilla.fenix.GleanMetrics.Installation
import org.mozilla.fenix.GleanMetrics.Pings
import org.mozilla.fenix.ext.settings
class InstallationPing(private val context: Context) {
private val prefs: SharedPreferences by lazy {
context.getSharedPreferences(
"${this.javaClass.canonicalName}.prefs", Context.MODE_PRIVATE
)
}
/**
* Checks whether or not the installation ping was already
* triggered by the application.
*
* Note that this only tells us that Fenix triggered the
* ping and then delegated the transmission to Glean. We
* have no way to tell if it was actually sent or not.
*
* @return true if it was already triggered, false otherwise.
*/
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal fun wasAlreadyTriggered(): Boolean {
return prefs.getBoolean("ping_sent", false)
}
/**
* Marks the "installation" ping as triggered by the application.
* This ensures the ping is not triggered again at the next app
* start.
*/
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal fun markAsTriggered() {
prefs.edit().putBoolean("ping_sent", true).apply()
}
/**
* Fills the metrics and triggers the 'installation' ping.
* This is a separate function to simplify unit-testing.
*/
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal fun triggerPing() {
if (checkMetricsNotEmpty()
) {
Installation.campaign.set(context.settings().adjustCampaignId)
Installation.adgroup.set(context.settings().adjustAdGroup)
Installation.creative.set(context.settings().adjustCreative)
Installation.network.set(context.settings().adjustNetwork)
Installation.timestamp.set(context.settings().adjustInstallTimestamp)
CoroutineScope(Dispatchers.IO).launch {
Pings.installation.submit()
markAsTriggered()
}
}
}
/**
* Check that required metrics are not empty before attempting to send ping.
* */
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
internal fun checkMetricsNotEmpty(): Boolean = listOf(
context.settings().adjustAdGroup,
context.settings().adjustCreative,
context.settings().adjustNetwork
).all { it.isNotEmpty() }
/**
* Trigger sending the `installation` ping if it wasn't sent already.
* Then, mark it so that it doesn't get triggered next time Fenix
* starts.
*/
fun checkAndSend() {
if (wasAlreadyTriggered()) {
Logger.debug("InstallationPing - already generated")
return
}
triggerPing()
}
}

View File

@ -95,6 +95,26 @@ class Settings private constructor(
default = "" default = ""
) )
var adjustNetwork by stringPreference(
appContext.getPreferenceKey(R.string.pref_key_adjust_network),
default = ""
)
var adjustAdGroup by stringPreference(
appContext.getPreferenceKey(R.string.pref_key_adjust_adgroup),
default = ""
)
var adjustCreative by stringPreference(
appContext.getPreferenceKey(R.string.pref_key_adjust_creative),
default = ""
)
var adjustInstallTimestamp by stringPreference(
appContext.getPreferenceKey(R.string.pref_key_adjust_install_timestamp),
default = ""
)
var openLinksInAPrivateTab by booleanPreference( var openLinksInAPrivateTab by booleanPreference(
appContext.getPreferenceKey(R.string.pref_key_open_links_in_a_private_tab), appContext.getPreferenceKey(R.string.pref_key_open_links_in_a_private_tab),
default = false default = false

View File

@ -133,6 +133,11 @@
<string name="pref_key_bounce_quick_action" translatable="false">pref_key_bounce_quick_action</string> <string name="pref_key_bounce_quick_action" translatable="false">pref_key_bounce_quick_action</string>
<string name="pref_key_reader_mode_notification" translatable="false">pref_key_reader_mode_notification</string> <string name="pref_key_reader_mode_notification" translatable="false">pref_key_reader_mode_notification</string>
<string name="pref_key_adjust_campaign" translatable="false">pref_key_adjust_campaign</string> <string name="pref_key_adjust_campaign" translatable="false">pref_key_adjust_campaign</string>
<string name="pref_key_adjust_network" translatable="false">pref_key_adjust_network</string>
<string name="pref_key_adjust_adgroup" translatable="false">pref_key_adjust_adgroup</string>
<string name="pref_key_adjust_creative" translatable="false">pref_key_adjust_creative</string>
<string name="pref_key_adjust_install_timestamp" translatable="false">pref_key_adjust_install_timestamp</string>
<string name="pref_key_testing_stage" translatable="false">pref_key_testing_stage</string> <string name="pref_key_testing_stage" translatable="false">pref_key_testing_stage</string>
<string name="pref_key_encryption_key_generated" translatable="false">pref_key_encryption_key_generated</string> <string name="pref_key_encryption_key_generated" translatable="false">pref_key_encryption_key_generated</string>

View File

@ -0,0 +1,55 @@
/* 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
import android.content.Context
import io.mockk.Runs
import io.mockk.every
import io.mockk.just
import io.mockk.mockk
import io.mockk.mockkStatic
import io.mockk.spyk
import io.mockk.verify
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.test.runBlockingTest
import org.junit.Test
import org.mozilla.fenix.TestApplication
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.utils.Settings
import org.robolectric.annotation.Config
@ExperimentalCoroutinesApi
@Config(application = TestApplication::class)
internal class InstallationPingTest {
@Test
fun `checkAndSend() triggers the ping if it wasn't marked as triggered`() = runBlockingTest {
val mockedContext: Context = mockk(relaxed = true)
val mockedSettings: Settings = mockk(relaxed = true)
mockkStatic("org.mozilla.fenix.ext.ContextKt")
every { mockedContext.settings() } returns mockedSettings
val mockAp = spyk(InstallationPing(mockedContext), recordPrivateCalls = true)
every { mockAp.checkMetricsNotEmpty() } returns true
every { mockAp.wasAlreadyTriggered() } returns false
every { mockAp.markAsTriggered() } just Runs
mockAp.checkAndSend()
verify(exactly = 1) { mockAp.triggerPing() }
// Marking the ping as triggered happens in a co-routine off the main thread,
// so wait a bit for it.
verify(exactly = 1) { mockAp.markAsTriggered() }
}
@Test
fun `checkAndSend() doesn't trigger the ping again if it was marked as triggered`() {
val mockAp = spyk(InstallationPing(mockk()), recordPrivateCalls = true)
every { mockAp.wasAlreadyTriggered() } returns true
mockAp.checkAndSend()
verify(exactly = 0) { mockAp.triggerPing() }
}
}

View File

@ -10,6 +10,7 @@ This means you might have to go searching through the dependency tree to get a f
- [activation](#activation) - [activation](#activation)
- [baseline](#baseline) - [baseline](#baseline)
- [events](#events) - [events](#events)
- [installation](#installation)
- [metrics](#metrics) - [metrics](#metrics)
@ -169,6 +170,19 @@ The following metrics are added to the ping:
| user_specified_search_engines.custom_engine_added |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user added a new custom search engine |[1](https://github.com/mozilla-mobile/fenix/pull/6918)||2020-09-01 | | user_specified_search_engines.custom_engine_added |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user added a new custom search engine |[1](https://github.com/mozilla-mobile/fenix/pull/6918)||2020-09-01 |
| user_specified_search_engines.custom_engine_deleted |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user deleted a custom search engine |[1](https://github.com/mozilla-mobile/fenix/pull/6918)||2020-09-01 | | user_specified_search_engines.custom_engine_deleted |[event](https://mozilla.github.io/glean/book/user/metrics/event.html) |A user deleted a custom search engine |[1](https://github.com/mozilla-mobile/fenix/pull/6918)||2020-09-01 |
## installation
Intended for counting user installs.
The following metrics are added to the ping:
| Name | Type | Description | Data reviews | Extras | Expiration |
| --- | --- | --- | --- | --- | --- |
| installation.adgroup |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |AdGroup |[1](https://github.com/mozilla-mobile/fenix/pull/8074)||2020-09-01 |
| installation.campaign |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |Campaign |[1](https://github.com/mozilla-mobile/fenix/pull/8074)||2020-09-01 |
| installation.creative |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |Creative |[1](https://github.com/mozilla-mobile/fenix/pull/8074)||2020-09-01 |
| installation.network |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |Network |[1](https://github.com/mozilla-mobile/fenix/pull/8074)||2020-09-01 |
| installation.timestamp |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |Timestamp |[1](https://github.com/mozilla-mobile/fenix/pull/8074)||2020-09-01 |
## metrics ## metrics
This is a built-in ping that is assembled out of the box by the Glean SDK. This is a built-in ping that is assembled out of the box by the Glean SDK.
See the Glean SDK documentation for the [`metrics` ping](https://mozilla.github.io/glean/book/user/pings/metrics.html). See the Glean SDK documentation for the [`metrics` ping](https://mozilla.github.io/glean/book/user/pings/metrics.html).