Skip to content

Commit

Permalink
For mozilla-mobile#7295 - Adds new custom ping: 'installation'
Browse files Browse the repository at this point in the history
  • Loading branch information
codrut.topliceanu committed Feb 4, 2020
1 parent 604ac83 commit 9d53bf2
Show file tree
Hide file tree
Showing 9 changed files with 286 additions and 2 deletions.
67 changes: 67 additions & 0 deletions app/metrics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1776,3 +1776,70 @@ app_theme:
notification_emails:
- fenix-core@mozilla.com
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/6746
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/6746
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/6746
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/6746
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/6746
notification_emails:
- fenix-core@mozilla.com
expires: "2020-09-01"
11 changes: 11 additions & 0 deletions app/pings.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,14 @@ activation:
- https://github.com/mozilla-mobile/fenix/pull/1707#issuecomment-486972209
notification_emails:
- 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
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,27 @@ class AdjustMetricsService(private val application: Application) : MetricsServic
)

config.setOnAttributionChangedListener {
it.campaign?.let { campaign ->
application.applicationContext.settings().adjustCampaignId = campaign
if (!it.network.isNullOrEmpty()) {
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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -564,6 +564,7 @@ class GleanMetricsService(private val context: Context) : MetricsService {
}

activationPing.checkAndSend()
InstallationPing(context).checkAndSend()
}

override fun stop() {
Expand Down
Original file line number Diff line number Diff line change
@@ -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()
}
}
20 changes: 20 additions & 0 deletions app/src/main/java/org/mozilla/fenix/utils/Settings.kt
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,26 @@ class Settings private constructor(
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(
appContext.getPreferenceKey(R.string.pref_key_open_links_in_a_private_tab),
default = false
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/values/preference_keys.xml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,11 @@
<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_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_total_uri" translatable="false">pref_key_total_uri</string>
Expand Down
Original file line number Diff line number Diff line change
@@ -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() }
}
}
14 changes: 14 additions & 0 deletions docs/metrics.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ This means you might have to go searching through the dependency tree to get a f
- [activation](#activation)
- [baseline](#baseline)
- [events](#events)
- [installation](#installation)
- [metrics](#metrics)


Expand Down Expand Up @@ -167,6 +168,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_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/6746)||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/6746)||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/6746)||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/6746)||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/6746)||2020-09-01 |

## metrics
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).
Expand Down

0 comments on commit 9d53bf2

Please sign in to comment.