From a81168ad3792cd804922a1a43a7a70c6b8e0b11c Mon Sep 17 00:00:00 2001 From: DreVla Date: Fri, 23 Jun 2023 15:22:30 +0300 Subject: [PATCH] Bug 1837526 - Call StartupTimeline in the Compose Top Sites Because we are migrating Top Sites to Compose, we want to ensure we are still recording when top sites are loaded, therefore the call for StartupTimeline is now called after creating the top sites compose elements. Calling it here will ensure it will be called even after we replace the home page recycler with a Compose view. --- .../mozilla/fenix/home/topsites/TopSites.kt | 8 +++++++ .../fenix/home/topsites/TopSitesViewHolder.kt | 5 +++++ .../fenix/perf/StartupReportFullyDrawn.kt | 22 +++++++++++++++++++ .../org/mozilla/fenix/perf/StartupTimeline.kt | 7 ++++++ 4 files changed, 42 insertions(+) diff --git a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSites.kt b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSites.kt index 46d4fb430..a701fdfc2 100644 --- a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSites.kt +++ b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSites.kt @@ -104,6 +104,7 @@ fun TopSites( onRemoveTopSiteClicked: (topSite: TopSite) -> Unit, onSettingsClicked: () -> Unit, onSponsorPrivacyClicked: () -> Unit, + onTopSitesItemBound: () -> Unit, ) { val pageCount = ceil((topSites.size.toDouble() / TOP_SITES_PER_PAGE)).toInt() @@ -154,6 +155,7 @@ fun TopSites( topSiteColors = topSiteColors, onTopSiteClick = { item -> onTopSiteClick(item) }, onTopSiteLongClick = onTopSiteLongClick, + onTopSitesItemBound = onTopSitesItemBound, ) } } @@ -251,6 +253,7 @@ private fun TopSiteItem( topSiteColors: TopSiteColors, onTopSiteClick: (TopSite) -> Unit, onTopSiteLongClick: (TopSite) -> Unit, + onTopSitesItemBound: () -> Unit, ) { var menuExpanded by remember { mutableStateOf(false) } @@ -339,6 +342,10 @@ private fun TopSiteItem( } } } + + LaunchedEffect(Unit) { + onTopSitesItemBound() + } } /** @@ -587,6 +594,7 @@ private fun TopSitesPreview() { onRemoveTopSiteClicked = {}, onSettingsClicked = {}, onSponsorPrivacyClicked = {}, + onTopSitesItemBound = {}, ) } } diff --git a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesViewHolder.kt b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesViewHolder.kt index 74e67ef26..0e6eb91a1 100644 --- a/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesViewHolder.kt +++ b/app/src/main/java/org/mozilla/fenix/home/topsites/TopSitesViewHolder.kt @@ -9,9 +9,11 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.platform.ComposeView import androidx.lifecycle.LifecycleOwner import mozilla.components.lib.state.ext.observeAsComposableState +import org.mozilla.fenix.HomeActivity import org.mozilla.fenix.components.components import org.mozilla.fenix.compose.ComposeViewHolder import org.mozilla.fenix.home.sessioncontrol.TopSiteInteractor +import org.mozilla.fenix.perf.StartupTimeline import org.mozilla.fenix.wallpapers.WallpaperState /** @@ -49,6 +51,9 @@ class TopSitesViewHolder( onRemoveTopSiteClicked = interactor::onRemoveTopSiteClicked, onSettingsClicked = interactor::onSettingsClicked, onSponsorPrivacyClicked = interactor::onSponsorPrivacyClicked, + onTopSitesItemBound = { + StartupTimeline.onTopSitesItemBound(activity = composeView.context as HomeActivity) + }, ) } } diff --git a/app/src/main/java/org/mozilla/fenix/perf/StartupReportFullyDrawn.kt b/app/src/main/java/org/mozilla/fenix/perf/StartupReportFullyDrawn.kt index 800272b08..66d31d05c 100644 --- a/app/src/main/java/org/mozilla/fenix/perf/StartupReportFullyDrawn.kt +++ b/app/src/main/java/org/mozilla/fenix/perf/StartupReportFullyDrawn.kt @@ -61,6 +61,24 @@ class StartupReportFullyDrawn { } } + /** + * Instruments "visually complete" cold startup time to homescreen for use with FNPRMS. + * + * For FNPRMS, we define "visually complete" to be when top sites is loaded with placeholders; + * the animation to display top sites will occur after this point, as will the asynchronous + * loading of the actual top sites icons. Our focus for visually complete is usability. + * There are no tabs available in our FNPRMS tests so they are ignored for this instrumentation. + */ + fun onTopSitesItemBound(state: StartupState, activity: HomeActivity) { + if (!isInstrumented && + state is StartupState.Cold && state.destination == HOMESCREEN + ) { + isInstrumented = true + + attachReportFullyDrawn(activity) + } + } + private fun attachReportFullyDrawn(activity: Activity, view: View) { // For greater accuracy, we could add an onDrawListener instead of a preDrawListener but: // - single use onDrawListeners are not built-in and it's non-trivial to write one @@ -69,4 +87,8 @@ class StartupReportFullyDrawn { // should be comparable view.doOnPreDraw { activity.reportFullyDrawnSafe(Performance.logger) } } + + private fun attachReportFullyDrawn(activity: Activity) { + activity.reportFullyDrawnSafe(Performance.logger) + } } diff --git a/app/src/main/java/org/mozilla/fenix/perf/StartupTimeline.kt b/app/src/main/java/org/mozilla/fenix/perf/StartupTimeline.kt index 0c3cd8bb2..e87e17af8 100644 --- a/app/src/main/java/org/mozilla/fenix/perf/StartupTimeline.kt +++ b/app/src/main/java/org/mozilla/fenix/perf/StartupTimeline.kt @@ -54,6 +54,13 @@ object StartupTimeline { reportFullyDrawn.onTopSitesItemBound(state, holder) } + /** + * Instruments "visually complete" cold startup time to homescreen for use with FNPRMS. + */ + fun onTopSitesItemBound(activity: HomeActivity) { + reportFullyDrawn.onTopSitesItemBound(state, activity) + } + private fun advanceState(startingActivity: StartupActivity) { state = StartupTimelineStateMachine.getNextState(state, startingActivity) }