Skip to content
This repository has been archived by the owner on Feb 20, 2023. It is now read-only.

Commit

Permalink
merged AppAllSourceStartTelemetry.kt and AppStartupTypeTelemetry.kt i…
Browse files Browse the repository at this point in the history
…nto one metric: AppStartupTelemetry.kt

wrote test cases for AppStartupTelemetry.kt
  • Loading branch information
sraturi committed Aug 16, 2020
1 parent e176b43 commit 5f60e64
Show file tree
Hide file tree
Showing 14 changed files with 316 additions and 414 deletions.
43 changes: 14 additions & 29 deletions app/metrics.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,34 +8,6 @@ no_lint:
- CATEGORY_GENERIC

events:
app_startup_type:
type: event
description:
A user opens the application. we record what type of start
up it was. If HomeActivity has a savedInstanceState (a way for
activities to restore to previous state) and we just created the
application, it is cold_saved_instance startuptype. If the
application was created and HomeActivity was created without a
savedInstanceState, it is a cold startup. If application already
exists and HomeActivity is created with savedInstanceState, it is
a warm_saved_instance startup. If application already exists and
HomeActivity is created with savedInstanceState, it is a warm
startup. If both application and HomeActivity exists,
it is a hot startup.
extra_keys:
type:
description: |
startup type for Fenix. Possible values are `cold`,
`cold_saved_instance` , `warm` , `warm_saved_instance` or `hot`
bugs:
- https://github.com/mozilla-mobile/fenix/issues/12573
data_reviews:
- NA
notification_emails:
- esmyth@mozilla.com
- perf-android-fe@mozilla.com
expires: "2021-02-01"

app_opened_all_startup:
type: event
description: |
Expand All @@ -58,14 +30,27 @@ events:
description: |
The method used to open Fenix. Possible values are `app_icon`,
`custom_tab`, `link` or `unknown`
startup_type:
description: |
the startup type for opening fenix. the application and HomeActivity
either needs to be created or started again. possible values are
`cold`, `warm`, `hot`, or `unknown`. `unknown` is for cases
not anticipated.
app created AND HomeActivity created = cold
app started AND HomeActivity created = warm
app started AND HomeActivity started = hot
has_saved_instance_state:
description: |
boolean value whether or not startup type has a savedInstance.
using savedInstance, HomeActivity's previous state can be restored.
bugs:
- https://github.com/mozilla-mobile/fenix/issues/11830
data_reviews:
- https://github.com/mozilla-mobile/fenix/pull/12114#pullrequestreview-445245341
notification_emails:
- esmyth@mozilla.com
- perf-android-fe@mozilla.com
expires: "2020-12-01"
expires: "2021-02-01"
app_received_intent:
type: event
description: |
Expand Down
2 changes: 1 addition & 1 deletion app/src/main/java/org/mozilla/fenix/FenixApplication.kt
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider {

initVisualCompletenessQueueAndQueueTasks()

components.appStartupTypeTelemetry.onFenixApplicationOnCreate()
components.appStartupTelemetry.onFenixApplicationOnCreate()
}

private fun initVisualCompletenessQueueAndQueueTasks() {
Expand Down
14 changes: 7 additions & 7 deletions app/src/main/java/org/mozilla/fenix/HomeActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -221,27 +221,27 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {

captureSnapshotTelemetryMetrics()

setAppAllStartTelemetry(intent.toSafeIntent())

components.appStartupTypeTelemetry.onHomeActivityOnCreate(savedInstanceState != null)
startupTelemetryOnCreateCalled(intent.toSafeIntent(), savedInstanceState != null)

StartupTimeline.onActivityCreateEndHome(this) // DO NOT MOVE ANYTHING BELOW HERE.
}

protected open fun setAppAllStartTelemetry(safeIntent: SafeIntent) {
components.appAllSourceStartTelemetry.receivedIntentInHomeActivity(safeIntent)
protected open fun startupTelemetryOnCreateCalled(safeIntent: SafeIntent, hasSavedInstanceState: Boolean) {
components.appStartupTelemetry.onHomeActivityOnCreate(safeIntent, hasSavedInstanceState)
}

override fun onRestart() {
super.onRestart()

components.appStartupTypeTelemetry.onHomeActivityOnRestart()
components.appStartupTelemetry.onHomeActivityOnRestart()
}

@CallSuper
override fun onResume() {
super.onResume()

components.appStartupTelemetry.onHomeActivityOnResume()

components.backgroundServices.accountManagerAvailableQueue.runIfReadyOrQueue {
lifecycleScope.launch {
// Make sure accountManager is initialized.
Expand Down Expand Up @@ -320,7 +320,7 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
.let(::getIntentAllSource)
?.also { components.analytics.metrics.track(Event.AppReceivedIntent(it)) }

setAppAllStartTelemetry(intent.toSafeIntent())
components.appStartupTelemetry.receivedIntentInHomeActivity(intent.toSafeIntent())
}

/**
Expand Down
7 changes: 2 additions & 5 deletions app/src/main/java/org/mozilla/fenix/components/Components.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ import mozilla.components.lib.publicsuffixlist.PublicSuffixList
import mozilla.components.support.migration.state.MigrationStore
import org.mozilla.fenix.BuildConfig
import org.mozilla.fenix.HomeActivity
import org.mozilla.fenix.components.metrics.AppAllSourceStartTelemetry
import org.mozilla.fenix.components.metrics.AppStartupTypeTelemetry
import org.mozilla.fenix.components.metrics.AppStartupTelemetry
import org.mozilla.fenix.utils.ClipboardHandler
import org.mozilla.fenix.utils.Mockable
import org.mozilla.fenix.utils.Settings
Expand Down Expand Up @@ -83,9 +82,7 @@ class Components(private val context: Context) {
}
}

val appAllSourceStartTelemetry by lazy { AppAllSourceStartTelemetry(analytics.metrics) }

val appStartupTypeTelemetry by lazy { AppStartupTypeTelemetry(analytics.metrics) }
val appStartupTelemetry by lazy { AppStartupTelemetry(analytics.metrics) }

@Suppress("MagicNumber")
val addonUpdater by lazy {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/* 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.Intent
import androidx.annotation.VisibleForTesting
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleObserver
import androidx.lifecycle.OnLifecycleEvent
import androidx.lifecycle.ProcessLifecycleOwner
import mozilla.components.support.utils.SafeIntent
import org.mozilla.fenix.components.metrics.Event.AppOpenedAllSourceStartup
import org.mozilla.fenix.components.metrics.Event.AppOpenedAllSourceStartup.Source
import org.mozilla.fenix.components.metrics.Event.AppOpenedAllSourceStartup.Type
import org.mozilla.fenix.components.metrics.Event.AppOpenedAllSourceStartup.Type.COLD
import org.mozilla.fenix.components.metrics.Event.AppOpenedAllSourceStartup.Type.WARM

/**
* Tracks application startup source, type, and whether or not activity has savedInstance to restore
* the activity from. Sample metric = [source = COLD, type = APP_ICON, hasSavedInstance = false].
* The basic idea is to collect these metrics from different phases of startup through
* [AppOpenedAllSourceStartup]and finally report them on Activity's onResume() function.
* If application wasn't backgrounded before onResume() is called, we don't report the metric.
*
*/
class AppStartupTelemetry(private val metrics: MetricController) : LifecycleObserver {

init {
ProcessLifecycleOwner.get().lifecycle.addObserver(this)
}

private var appOpenedAllSourceStartup = AppOpenedAllSourceStartup()

/** default value is true to capture the first launch of the application. */
private var isMetricRecordedSinceAppWasForegrounded = false
private var wasAppCreateCalledBeforeActivityCreate = false

fun onFenixApplicationOnCreate() {
wasAppCreateCalledBeforeActivityCreate = true
}

fun onHomeActivityOnCreate(safeIntent: SafeIntent, hasSavedInstanceState: Boolean) {
appOpenedAllSourceStartup.hasSavedInstance = hasSavedInstanceState
setAppStartupType()
setStartupSourceFromIntent(safeIntent, false)
}

fun onExternalAppBrowserOnCreate(safeIntent: SafeIntent, hasSavedInstanceState: Boolean) {
appOpenedAllSourceStartup.hasSavedInstance = hasSavedInstanceState
setAppStartupType()
setStartupSourceFromIntent(safeIntent, true)
}

fun onHomeActivityOnRestart() {
appOpenedAllSourceStartup.type = Type.HOT
appOpenedAllSourceStartup.hasSavedInstance = false
}

fun receivedIntentInHomeActivity(safeIntent: SafeIntent) {
setStartupSourceFromIntent(safeIntent, false)
}

private fun setAppStartupType() {
appOpenedAllSourceStartup.type = if (wasAppCreateCalledBeforeActivityCreate) COLD else WARM
wasAppCreateCalledBeforeActivityCreate = false
}

private fun setStartupSourceFromIntent(
intent: SafeIntent,
isExternalAppBrowserActivity: Boolean
) {
appOpenedAllSourceStartup.source = when {
isExternalAppBrowserActivity -> Source.CUSTOM_TAB
intent.isLauncherIntent -> Source.APP_ICON
intent.action == Intent.ACTION_VIEW -> Source.LINK
else -> Source.UNKNOWN
}
}

/**
* The reason we record metric on resume is because we need to wait for onNewIntent(), and
* we are not guaranteed that onNewIntent() will be called before or after onStart().
* However we are guaranteed onResume() will be called after onNewIntent(). Source:
* https://developer.android.com/reference/android/app/Activity#onNewIntent(android.content.Intent)
*
*/
fun onHomeActivityOnResume() {
recordMetric()
}

private fun recordMetric() {
if (!isMetricRecordedSinceAppWasForegrounded) {
metrics.track(appOpenedAllSourceStartup)
isMetricRecordedSinceAppWasForegrounded = true
}
// we don't want any weird previous states to persist on our next metric record.
appOpenedAllSourceStartup = AppOpenedAllSourceStartup()
}

@OnLifecycleEvent(Lifecycle.Event.ON_STOP)
@VisibleForTesting(otherwise = VisibleForTesting.PRIVATE)
fun onApplicationOnStop() {

// application was backgrounded, we need to record the new metric type if
// application was to come to foreground again.
// Therefore we set the isMetricRecorded flag to false.
isMetricRecordedSinceAppWasForegrounded = false
}
}

This file was deleted.

0 comments on commit 5f60e64

Please sign in to comment.