From e60141e98d92c8144397232cff527368f0015c52 Mon Sep 17 00:00:00 2001 From: Michael Comella Date: Fri, 6 Dec 2019 10:46:17 -0800 Subject: [PATCH] For perf-frontend-issues#33: Add HotStartPerformanceMonitor. As mentioned in the class comment, we could use an alternative implementation to measure perf from outside the application however it's more complicated to set up and less consistent with our cold startup methodology so we'll start with this. --- .../java/org/mozilla/fenix/HomeActivity.kt | 13 ++++++ .../fenix/perf/HotStartPerformanceMonitor.kt | 40 +++++++++++++++++++ .../org/mozilla/fenix/perf/Performance.kt | 12 ++++++ 3 files changed, 65 insertions(+) create mode 100644 app/src/main/java/org/mozilla/fenix/perf/HotStartPerformanceMonitor.kt create mode 100644 app/src/main/java/org/mozilla/fenix/perf/Performance.kt diff --git a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt index 4958fe725..f1da210e4 100644 --- a/app/src/main/java/org/mozilla/fenix/HomeActivity.kt +++ b/app/src/main/java/org/mozilla/fenix/HomeActivity.kt @@ -52,6 +52,7 @@ import org.mozilla.fenix.home.intent.SpeechProcessingIntentProcessor import org.mozilla.fenix.home.intent.StartSearchIntentProcessor import org.mozilla.fenix.library.bookmarks.BookmarkFragmentDirections import org.mozilla.fenix.library.history.HistoryFragmentDirections +import org.mozilla.fenix.perf.HotStartPerformanceMonitor import org.mozilla.fenix.search.SearchFragmentDirections import org.mozilla.fenix.settings.AboutFragmentDirections import org.mozilla.fenix.settings.DefaultBrowserSettingsFragmentDirections @@ -69,6 +70,8 @@ open class HomeActivity : AppCompatActivity() { private var sessionObserver: SessionManager.Observer? = null + private val hotStartMonitor = HotStartPerformanceMonitor() + private val navHost by lazy { supportFragmentManager.findFragmentById(R.id.container) as NavHostFragment } @@ -125,6 +128,16 @@ open class HomeActivity : AppCompatActivity() { } } + final override fun onRestart() { + hotStartMonitor.onRestartFirstMethodCall() + super.onRestart() + } + + final override fun onPostResume() { + super.onPostResume() + hotStartMonitor.onPostResumeFinalMethodCall() + } + private fun unsetOpenLinksInAPrivateTabIfNecessary() { // Toggle off the open_link_in_private_tab pref if we are no longer set as the default browser // We do this on a separate thread to alleviate performance issues diff --git a/app/src/main/java/org/mozilla/fenix/perf/HotStartPerformanceMonitor.kt b/app/src/main/java/org/mozilla/fenix/perf/HotStartPerformanceMonitor.kt new file mode 100644 index 000000000..8e1577af5 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/perf/HotStartPerformanceMonitor.kt @@ -0,0 +1,40 @@ +/* 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.os.SystemClock +import android.util.Log + +/** + * Monitors and reports elapsed time to complete hot startup of an Activity. Callers are expected + * to call the appropriate lifecycle methods at the appropriate times. + * + * A "hot startup" is when the application moves from the background to the foreground and both the + * Application/process and the Activity under measurement are already created. + * + * Unfortunately, this monitor does not capture the entire duration of hot start because the + * framework calls several Android framework methods in the application's process before we are able + * to add monitoring code (i.e. the first time our application code is called in onRestart). An + * alternative implementation could measure performance from outside the application. + * + * To see logs from this class, the user must enable VERBOSE logging for the appropriate tag: + * adb shell setprop log.tag.FenixPerf VERBOSE + */ +class HotStartPerformanceMonitor { + + private var onRestartMillis: Long = -1 + + fun onRestartFirstMethodCall() { + onRestartMillis = SystemClock.elapsedRealtime() + } + + fun onPostResumeFinalMethodCall() { + // If onRestart was never called, this is not a hot start: ignore it. + if (onRestartMillis >= 0) { + val elapsedMillis = SystemClock.elapsedRealtime() - onRestartMillis + Log.v(Performance.TAG, "hot start: $elapsedMillis") // android log to minimize overhead. + } + } +} diff --git a/app/src/main/java/org/mozilla/fenix/perf/Performance.kt b/app/src/main/java/org/mozilla/fenix/perf/Performance.kt new file mode 100644 index 000000000..ea4bd81f9 --- /dev/null +++ b/app/src/main/java/org/mozilla/fenix/perf/Performance.kt @@ -0,0 +1,12 @@ +/* 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 + +/** + * A collection of objects related to app performance. + */ +object Performance { + const val TAG = "FenixPerf" +}