70 lines
3.2 KiB
Kotlin
70 lines
3.2 KiB
Kotlin
/* 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.view.View
|
|
import androidx.core.view.doOnPreDraw
|
|
import kotlinx.android.synthetic.main.activity_home.*
|
|
import org.mozilla.fenix.HomeActivity
|
|
import org.mozilla.fenix.home.sessioncontrol.viewholders.topsites.TopSiteItemViewHolder
|
|
import org.mozilla.fenix.perf.StartupTimelineStateMachine.StartupDestination.APP_LINK
|
|
import org.mozilla.fenix.perf.StartupTimelineStateMachine.StartupDestination.HOMESCREEN
|
|
import org.mozilla.fenix.perf.StartupTimelineStateMachine.StartupState
|
|
|
|
/**
|
|
* Instruments the Android framework method [Activity.reportFullyDrawn], which prints time to visual
|
|
* completeness to logcat.
|
|
*
|
|
* At the time of writing (2020-02-26), this functionality is tightly coupled to FNPRMS, our internal
|
|
* startup measurement system. However, these values may also appear in the Google Play Vitals
|
|
* dashboards.
|
|
*/
|
|
class StartupReportFullyDrawn {
|
|
|
|
// Ideally we'd incorporate this state into the StartupState but we're short on implementation time.
|
|
private var isInstrumented = false
|
|
|
|
/**
|
|
* Instruments "visually complete" cold startup time for app link for use with FNPRMS.
|
|
*/
|
|
fun onActivityCreateEndHome(state: StartupState, activity: HomeActivity) {
|
|
if (!isInstrumented &&
|
|
state is StartupState.Cold && state.destination == APP_LINK) {
|
|
// Instrumenting the first frame drawn should be good enough for app link for now.
|
|
isInstrumented = true
|
|
attachReportFullyDrawn(activity, activity.rootContainer)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 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, holder: TopSiteItemViewHolder) {
|
|
if (!isInstrumented &&
|
|
state is StartupState.Cold && state.destination == HOMESCREEN) {
|
|
isInstrumented = true
|
|
|
|
// Ideally we wouldn't cast to HomeActivity but we want to save implementation time.
|
|
val view = holder.itemView
|
|
attachReportFullyDrawn(view.context as HomeActivity, view)
|
|
}
|
|
}
|
|
|
|
private fun attachReportFullyDrawn(activity: HomeActivity, 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
|
|
// - the difference in timing is minimal (< 7ms on Pixel 2)
|
|
// - if we compare against another app using a preDrawListener, as we are with Fennec, it
|
|
// should be comparable
|
|
view.doOnPreDraw { activity.reportFullyDrawn() }
|
|
}
|
|
}
|