diff --git a/app/metrics.yaml b/app/metrics.yaml
index a60f8e4f1..c47fddb55 100644
--- a/app/metrics.yaml
+++ b/app/metrics.yaml
@@ -1207,8 +1207,8 @@ metrics:
start_reason_activity_error:
type: boolean
description: |
- The `AppStartReasonProvider.ActivityLifecycleCallbacks.onCreate` was
- unexpectedly called twice. We can use this metric to validate our
+ The `AppStartReasonProvider.ActivityLifecycleCallbacks.onActivityCreated`
+ was unexpectedly called twice. We can use this metric to validate our
assumptions about how these APIs are called. This probe can be removed
once we validate these assumptions.
bugs:
@@ -1221,6 +1221,23 @@ metrics:
- perf-android-fe@mozilla.com
- mcomella@mozilla.com
expires: "2021-08-11"
+ activity_state_provider_error:
+ type: boolean
+ description: |
+ The `StartupActivityStateProvider...onActivityStarted` was unexpectedly
+ called twice. We can use this metric to validate our assumptions about
+ how these APIs are called. This probe can be removed once we validate
+ these assumptions.
+ bugs:
+ - https://github.com/mozilla-mobile/fenix/issues/18426
+ data_reviews:
+ - TODO
+ data_sensitivity:
+ - technical
+ notification_emails:
+ - perf-android-fe@mozilla.com
+ - mcomella@mozilla.com
+ expires: "2021-08-11"
preferences:
show_search_suggestions:
diff --git a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
index 568d8a3ca..22657333f 100644
--- a/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
+++ b/app/src/main/java/org/mozilla/fenix/FenixApplication.kt
@@ -51,7 +51,6 @@ import org.mozilla.fenix.components.metrics.MetricServiceType
import org.mozilla.fenix.components.metrics.SecurePrefsTelemetry
import org.mozilla.fenix.ext.measureNoInline
import org.mozilla.fenix.ext.settings
-import org.mozilla.fenix.perf.AppStartReasonProvider
import org.mozilla.fenix.perf.ProfilerMarkerFactProcessor
import org.mozilla.fenix.perf.StartupTimeline
import org.mozilla.fenix.perf.StorageStatsMetrics
@@ -192,6 +191,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
// }
components.appStartReasonProvider.registerInAppOnCreate(this)
+ components.startupActivityStateProvider.registerInAppOnCreate(this)
initVisualCompletenessQueueAndQueueTasks()
components.appStartupTelemetry.onFenixApplicationOnCreate()
diff --git a/app/src/main/java/org/mozilla/fenix/components/Components.kt b/app/src/main/java/org/mozilla/fenix/components/Components.kt
index b63095a0b..9990d32fb 100644
--- a/app/src/main/java/org/mozilla/fenix/components/Components.kt
+++ b/app/src/main/java/org/mozilla/fenix/components/Components.kt
@@ -29,6 +29,7 @@ import org.mozilla.fenix.components.metrics.AppStartupTelemetry
import org.mozilla.fenix.ext.components
import org.mozilla.fenix.ext.settings
import org.mozilla.fenix.perf.AppStartReasonProvider
+import org.mozilla.fenix.perf.StartupActivityStateProvider
import org.mozilla.fenix.perf.lazyMonitored
import org.mozilla.fenix.utils.ClipboardHandler
import org.mozilla.fenix.utils.Mockable
@@ -173,4 +174,5 @@ class Components(private val context: Context) {
}
val appStartReasonProvider by lazyMonitored { AppStartReasonProvider() }
+ val startupActivityStateProvider by lazyMonitored { StartupActivityStateProvider() }
}
diff --git a/app/src/main/java/org/mozilla/fenix/perf/StartupActivityStateProvider.kt b/app/src/main/java/org/mozilla/fenix/perf/StartupActivityStateProvider.kt
new file mode 100644
index 000000000..693281902
--- /dev/null
+++ b/app/src/main/java/org/mozilla/fenix/perf/StartupActivityStateProvider.kt
@@ -0,0 +1,77 @@
+/* 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.perf
+
+import android.app.Activity
+import android.app.Application
+import mozilla.components.support.base.log.logger.Logger
+import org.mozilla.fenix.GleanMetrics.Metrics
+import org.mozilla.fenix.HomeActivity
+import org.mozilla.fenix.android.DefaultActivityLifecycleCallbacks
+
+private val logger = Logger("StartupActivityState")
+
+/**
+ * Provides meta information about the Activities that occur during the initial parts of start up
+ * and their state.
+ *
+ * [registerInAppOnCreate] must be called for this class to work correctly.
+ */
+class StartupActivityStateProvider {
+
+ enum class FirstForegroundActivity {
+ TO_BE_DETERMINED,
+ HOME_ACTIVITY,
+ UNKNOWN
+ }
+
+ enum class FirstForegroundActivityState {
+ BEFORE_FOREGROUND,
+ CURRENTLY_FOREGROUNDED,
+ AFTER_FOREGROUND,
+ }
+
+ /** The first [Activity] that has been foreground in this process lifetime. */
+ var firstForegroundActivityOfProcess = FirstForegroundActivity.TO_BE_DETERMINED
+ private set
+
+ /** The current foreground state of the [firstForegroundActivityOfProcess]. */
+ var firstForegroundActivityState = FirstForegroundActivityState.BEFORE_FOREGROUND
+ private set
+
+ /**
+ * Registers the handlers needed by this class: this is expected to be called from
+ * [Application.onCreate].
+ */
+ fun registerInAppOnCreate(application: Application) {
+ application.registerActivityLifecycleCallbacks(StateActivityLifecycleCallbacks())
+ }
+
+ private inner class StateActivityLifecycleCallbacks : DefaultActivityLifecycleCallbacks {
+ override fun onActivityStarted(activity: Activity) {
+ if (firstForegroundActivityOfProcess != FirstForegroundActivity.TO_BE_DETERMINED) {
+ // This should never happen because we remove the listener in onStop and old activities
+ // should be stopped before new ones are started but the call order may change slightly
+ // between devices.
+ Metrics.activityStateProviderError.set(true)
+ logger.error("StartupActivityStateProvider...onActivityStarted unexpectedly called twice.")
+ return
+ }
+
+ firstForegroundActivityOfProcess = when (activity) {
+ is HomeActivity -> FirstForegroundActivity.HOME_ACTIVITY
+ else -> FirstForegroundActivity.UNKNOWN
+ }
+
+ firstForegroundActivityState = FirstForegroundActivityState.CURRENTLY_FOREGROUNDED
+ }
+
+ override fun onActivityStopped(activity: Activity) {
+ firstForegroundActivityState = FirstForegroundActivityState.AFTER_FOREGROUND
+
+ activity.application.unregisterActivityLifecycleCallbacks(this) // no more state updates needed.
+ }
+ }
+}
diff --git a/docs/metrics.md b/docs/metrics.md
index 2c88c57ea..d78df39fe 100644
--- a/docs/metrics.md
+++ b/docs/metrics.md
@@ -312,6 +312,7 @@ In addition to those built-in metrics, the following metrics are added to the pi
| engine_tab.kills |[labeled_counter](https://mozilla.github.io/glean/book/user/metrics/labeled_counters.html) |How often was the content process of a foreground (selected) or background tab killed. |[mozilla-mobile/fenix#17864](https://github.com/mozilla-mobile/fenix/pull/17864)|
foreground
background
|2021-12-31 |1 |
| events.normal_and_private_uri_count |[counter](https://mozilla.github.io/glean/book/user/metrics/counter.html) |A counter of URIs visited by the user in the current session, including page reloads. This includes private browsing. This does not include background page requests and URIs from embedded pages but may be incremented without user interaction by website scripts that programmatically redirect to a new location. |[mozilla-mobile/fenix#17935](https://github.com/mozilla-mobile/fenix/pull/17935)||2022-08-01 |2 |
| events.total_uri_count |[counter](https://mozilla.github.io/glean/book/user/metrics/counter.html) |A counter of URIs visited by the user in the current session, including page reloads. This does not include background page requests and URIs from embedded pages or private browsing but may be incremented without user interaction by website scripts that programmatically redirect to a new location. |[mozilla-mobile/fenix#1785](https://github.com/mozilla-mobile/fenix/pull/1785), [mozilla-mobile/fenix#8314](https://github.com/mozilla-mobile/fenix/pull/8314), [mozilla-mobile/fenix#15713](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 |
+| metrics.activity_state_provider_error |[boolean](https://mozilla.github.io/glean/book/user/metrics/boolean.html) |The `StartupActivityStateProvider...onActivityStarted` was unexpectedly called twice. We can use this metric to validate our assumptions about how these APIs are called. This probe can be removed once we validate these assumptions. |[Review 1](TODO)||2021-08-11 |1 |
| metrics.adjust_ad_group |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |A string containing the Adjust ad group ID from which the user installed Fenix. This will not send on the first session the user runs. If the install is organic, this will be empty. |[mozilla-mobile/fenix#9253](https://github.com/mozilla-mobile/fenix/pull/9253), [mozilla-mobile/fenix#15713](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 |
| metrics.adjust_campaign |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |A string containing the Adjust campaign ID from which the user installed Fenix. This will not send on the first session the user runs. If the install is organic, this will be empty. |[mozilla-mobile/fenix#5579](https://github.com/mozilla-mobile/fenix/pull/5579), [mozilla-mobile/fenix#15713](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |1 |
| metrics.adjust_creative |[string](https://mozilla.github.io/glean/book/user/metrics/string.html) |A string containing the Adjust creative ID from which the user installed Fenix. This will not send on the first session the user runs. If the install is organic, this will be empty. |[mozilla-mobile/fenix#9253](https://github.com/mozilla-mobile/fenix/pull/9253), [mozilla-mobile/fenix#15713](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 |
@@ -331,7 +332,7 @@ In addition to those built-in metrics, the following metrics are added to the pi
| metrics.recently_used_pwa_count |[counter](https://mozilla.github.io/glean/book/user/metrics/counter.html) |A counter that indicates how many PWAs a user has recently used. Threshold for "recency" set in HomeActivity#PWA_RECENTLY_USED_THRESHOLD. Currently we are not told by the OS when a PWA is removed by the user, so we use the "recently used" heuristic to judge how many PWAs are still active, as a proxy for "installed". This value will only be set if the user has at least *one* recently used PWA. If they have 0, this metric will not be sent, resulting in a null value during analysis on the server-side. To disambiguate between a failed `recently_used_pwa_count` metric and 0 recent PWAs, please see `has_recent_pwas`. |[mozilla-mobile/fenix#11982](https://github.com/mozilla-mobile/fenix/pull/11982#pullrequestreview-437963817), [mozilla-mobile/fenix#15713](https://github.com/mozilla-mobile/fenix/pull/15713#issuecomment-703972068)||2021-08-01 |2 |
| metrics.search_count |[labeled_counter](https://mozilla.github.io/glean/book/user/metrics/labeled_counters.html) |The labels for this counter are `.