forked from mozilla-mobile/fenix
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
For mozilla-mobile#7295 - Adds new custom ping: 'installation'
- Loading branch information
codrut.topliceanu
committed
Feb 4, 2020
1 parent
604ac83
commit 47b5fae
Showing
9 changed files
with
286 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
93 changes: 93 additions & 0 deletions
93
app/src/main/java/org/mozilla/fenix/components/metrics/InstallationPing.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
app/src/test/java/org/mozilla/fenix/components/metrics/InstallationPingTest.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters