зеркало из https://github.com/mozilla/glean.git
Use the client activity API in the Kotlin language Bindings
This additionally moves the logic from the GleanLifecycleObserver to the Glean.kt file. The logic was spread between the two files, making it harder than needed to understand what happened when changing the state. This additionally fixes the tests.
This commit is contained in:
Родитель
73f43c54fc
Коммит
d200c48d4a
|
@ -48,19 +48,19 @@ This ping includes the [client id](https://mozilla.github.io/glean/book/user/pin
|
|||
|
||||
**Reasons this ping may be sent:**
|
||||
|
||||
- `background`: The ping was submitted before going to background.
|
||||
|
||||
- `dirty_startup`: The ping was submitted at startup, because the application process was
|
||||
killed before the Glean SDK had the chance to generate this ping, when
|
||||
going to background, in the last session.
|
||||
|
||||
*Note*: this ping will not contain the `glean.baseline.duration` metric.
|
||||
|
||||
- `foreground`: The ping was submitted when the application went to foreground, which
|
||||
- `active`: The ping was submitted when the application became active again, which
|
||||
includes when the application starts.
|
||||
|
||||
*Note*: this ping will not contain the `glean.baseline.duration` metric.
|
||||
|
||||
- `dirty_startup`: The ping was submitted at startup, because the application process was
|
||||
killed before the Glean SDK had the chance to generate this ping, before
|
||||
becoming inactive, in the last session.
|
||||
|
||||
*Note*: this ping will not contain the `glean.baseline.duration` metric.
|
||||
|
||||
- `inactive`: The ping was submitted before becoming inactive.
|
||||
|
||||
|
||||
The following metrics are added to the ping:
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import com.sun.jna.StringArray
|
|||
import kotlinx.coroutines.Job
|
||||
import kotlinx.coroutines.MainScope
|
||||
import kotlinx.coroutines.launch
|
||||
import mozilla.telemetry.glean.GleanMetrics.GleanBaseline
|
||||
import mozilla.telemetry.glean.config.Configuration
|
||||
import mozilla.telemetry.glean.config.FfiConfiguration
|
||||
import mozilla.telemetry.glean.utils.getLocaleTag
|
||||
|
@ -562,16 +563,42 @@ open class GleanInternalAPI internal constructor () {
|
|||
* Handle the foreground event and send the appropriate pings.
|
||||
*/
|
||||
internal fun handleForegroundEvent() {
|
||||
Pings.baseline.submit(Pings.baselineReasonCodes.foreground)
|
||||
GleanValidation.foregroundCount.add(1)
|
||||
|
||||
// Note that this is sending the length of the last foreground session
|
||||
// because it belongs to the baseline ping and that ping is sent every
|
||||
// time the app goes to background.
|
||||
@Suppress("EXPERIMENTAL_API_USAGE")
|
||||
Dispatchers.API.launch {
|
||||
LibGleanFFI.INSTANCE.glean_handle_client_active()
|
||||
|
||||
// The above call may generate pings, so we need to trigger
|
||||
// the uploader. It's fine to trigger it if no ping was generated:
|
||||
// it will bail out.
|
||||
PingUploadWorker.enqueueWorker(applicationContext)
|
||||
}
|
||||
|
||||
// Start the timespan for the new activity period.
|
||||
GleanBaseline.duration.start()
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle the background event and send the appropriate pings.
|
||||
*/
|
||||
internal fun handleBackgroundEvent() {
|
||||
Pings.baseline.submit(Pings.baselineReasonCodes.background)
|
||||
Pings.events.submit(Pings.eventsReasonCodes.background)
|
||||
// We're going to background, so store how much time we spent
|
||||
// on foreground.
|
||||
GleanBaseline.duration.stop()
|
||||
|
||||
@Suppress("EXPERIMENTAL_API_USAGE")
|
||||
Dispatchers.API.launch {
|
||||
LibGleanFFI.INSTANCE.glean_handle_client_inactive()
|
||||
|
||||
// The above call may generate pings, so we need to trigger
|
||||
// the uploader. It's fine to trigger it if no ping was generated:
|
||||
// it will bail out.
|
||||
PingUploadWorker.enqueueWorker(applicationContext)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -97,6 +97,10 @@ internal interface LibGleanFFI : Library {
|
|||
|
||||
fun glean_is_dirty_flag_set(): Byte
|
||||
|
||||
fun glean_handle_client_active()
|
||||
|
||||
fun glean_handle_client_inactive()
|
||||
|
||||
fun glean_test_clear_all_stores()
|
||||
|
||||
fun glean_is_first_run(): Byte
|
||||
|
|
|
@ -7,11 +7,7 @@ package mozilla.telemetry.glean.scheduler
|
|||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import mozilla.telemetry.glean.Dispatchers
|
||||
import mozilla.telemetry.glean.Glean
|
||||
import mozilla.telemetry.glean.GleanMetrics.GleanBaseline
|
||||
import mozilla.telemetry.glean.rust.LibGleanFFI
|
||||
import mozilla.telemetry.glean.rust.toByte
|
||||
|
||||
/**
|
||||
* Connects process lifecycle events from Android to Glean's handleEvent
|
||||
|
@ -24,22 +20,9 @@ internal class GleanLifecycleObserver : LifecycleEventObserver {
|
|||
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
|
||||
when (event) {
|
||||
Lifecycle.Event.ON_STOP -> {
|
||||
// We're going to background, so store how much time we spent
|
||||
// on foreground.
|
||||
GleanBaseline.duration.stop()
|
||||
Glean.handleBackgroundEvent()
|
||||
|
||||
// Clear the "dirty flag" as the last thing when going to background.
|
||||
// If the application is not being force-closed, we should still be
|
||||
// alive and allowed to change this. If we're being force-closed and
|
||||
// don't get to this point, next time Glean runs it will be detected.
|
||||
@Suppress("EXPERIMENTAL_API_USAGE")
|
||||
Dispatchers.API.launch {
|
||||
LibGleanFFI.INSTANCE.glean_set_dirty_flag(false.toByte())
|
||||
}
|
||||
}
|
||||
Lifecycle.Event.ON_START -> {
|
||||
// Updates the baseline.duration metric when entering the foreground.
|
||||
// We use ON_START here because we don't want to incorrectly count metrics in
|
||||
// ON_RESUME as pause/resume can happen when interacting with things like the
|
||||
// navigation shade which could lead to incorrectly recording the start of a
|
||||
|
@ -47,17 +30,7 @@ internal class GleanLifecycleObserver : LifecycleEventObserver {
|
|||
//
|
||||
// https://developer.android.com/reference/android/app/Activity.html#onStart()
|
||||
|
||||
// Note that this is sending the length of the last foreground session
|
||||
// because it belongs to the baseline ping and that ping is sent every
|
||||
// time the app goes to background.
|
||||
Glean.handleForegroundEvent()
|
||||
GleanBaseline.duration.start()
|
||||
|
||||
// Set the "dirty flag" to `true`.
|
||||
@Suppress("EXPERIMENTAL_API_USAGE")
|
||||
Dispatchers.API.launch {
|
||||
LibGleanFFI.INSTANCE.glean_set_dirty_flag(true.toByte())
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
// For other lifecycle events, do nothing
|
||||
|
|
|
@ -74,6 +74,6 @@ public class GleanFromJavaTest {
|
|||
// submit() can be called without parameters.
|
||||
Pings.INSTANCE.baseline().submit();
|
||||
// submit() can be called with a `reason`.
|
||||
Pings.INSTANCE.baseline().submit(Pings.baselineReasonCodes.background);
|
||||
Pings.INSTANCE.baseline().submit(Pings.baselineReasonCodes.inactive);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -232,7 +232,7 @@ class GleanTest {
|
|||
// - seq: 2, reason: foreground, duration: null
|
||||
if (seq == 1) {
|
||||
val baselineMetricsObject = json.getJSONObject("metrics")
|
||||
assertEquals("background", json.getJSONObject("ping_info").getString("reason"))
|
||||
assertEquals("inactive", json.getJSONObject("ping_info").getString("reason"))
|
||||
val baselineTimespanMetrics = baselineMetricsObject.getJSONObject("timespan")
|
||||
assertEquals(1, baselineTimespanMetrics.length())
|
||||
assertNotNull(baselineTimespanMetrics.get("glean.baseline.duration"))
|
||||
|
|
Загрузка…
Ссылка в новой задаче