for #13479, added a VisualCompletenessQueue.kt class to handle all the functionality related to visual completeness
parent
655d2b8a88
commit
5ccbca25c0
|
@ -159,15 +159,15 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun initVisualCompletenessQueueAndQueueTasks() {
|
private fun initVisualCompletenessQueueAndQueueTasks() {
|
||||||
val taskQueue = components.performance.visualCompletenessQueue
|
val queue = components.performance.visualCompletenessQueue.queue
|
||||||
|
|
||||||
fun initQueue() {
|
fun initQueue() {
|
||||||
registerActivityLifecycleCallbacks(PerformanceActivityLifecycleCallbacks(taskQueue))
|
registerActivityLifecycleCallbacks(PerformanceActivityLifecycleCallbacks(queue))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun queueInitExperiments() {
|
fun queueInitExperiments() {
|
||||||
if (settings().isExperimentationEnabled) {
|
if (settings().isExperimentationEnabled) {
|
||||||
taskQueue.runIfReadyOrQueue {
|
queue.runIfReadyOrQueue {
|
||||||
Experiments.initialize(
|
Experiments.initialize(
|
||||||
applicationContext = applicationContext,
|
applicationContext = applicationContext,
|
||||||
onExperimentsUpdated = {
|
onExperimentsUpdated = {
|
||||||
|
@ -188,7 +188,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun queueInitStorageAndServices() {
|
fun queueInitStorageAndServices() {
|
||||||
components.performance.visualCompletenessQueue.runIfReadyOrQueue {
|
components.performance.visualCompletenessQueue.queue.runIfReadyOrQueue {
|
||||||
GlobalScope.launch(Dispatchers.IO) {
|
GlobalScope.launch(Dispatchers.IO) {
|
||||||
logger.info("Running post-visual completeness tasks...")
|
logger.info("Running post-visual completeness tasks...")
|
||||||
logElapsedTime(logger, "Storage initialization") {
|
logElapsedTime(logger, "Storage initialization") {
|
||||||
|
@ -208,7 +208,7 @@ open class FenixApplication : LocaleAwareApplication(), Provider {
|
||||||
|
|
||||||
fun queueMetrics() {
|
fun queueMetrics() {
|
||||||
if (SDK_INT >= Build.VERSION_CODES.O) { // required by StorageStatsMetrics.
|
if (SDK_INT >= Build.VERSION_CODES.O) { // required by StorageStatsMetrics.
|
||||||
taskQueue.runIfReadyOrQueue {
|
queue.runIfReadyOrQueue {
|
||||||
// Because it may be slow to capture the storage stats, it might be preferred to
|
// Because it may be slow to capture the storage stats, it might be preferred to
|
||||||
// create a WorkManager task for this metric, however, I ran out of
|
// create a WorkManager task for this metric, however, I ran out of
|
||||||
// implementation time and WorkManager is harder to test.
|
// implementation time and WorkManager is harder to test.
|
||||||
|
|
|
@ -21,7 +21,6 @@ import androidx.annotation.VisibleForTesting
|
||||||
import androidx.annotation.VisibleForTesting.PROTECTED
|
import androidx.annotation.VisibleForTesting.PROTECTED
|
||||||
import androidx.appcompat.app.ActionBar
|
import androidx.appcompat.app.ActionBar
|
||||||
import androidx.appcompat.widget.Toolbar
|
import androidx.appcompat.widget.Toolbar
|
||||||
import androidx.core.view.doOnPreDraw
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.NavDestination
|
import androidx.navigation.NavDestination
|
||||||
import androidx.navigation.NavDirections
|
import androidx.navigation.NavDirections
|
||||||
|
@ -56,7 +55,6 @@ import mozilla.components.support.ktx.android.content.share
|
||||||
import mozilla.components.support.ktx.kotlin.isUrl
|
import mozilla.components.support.ktx.kotlin.isUrl
|
||||||
import mozilla.components.support.ktx.kotlin.toNormalizedUrl
|
import mozilla.components.support.ktx.kotlin.toNormalizedUrl
|
||||||
import mozilla.components.support.locale.LocaleAwareAppCompatActivity
|
import mozilla.components.support.locale.LocaleAwareAppCompatActivity
|
||||||
import mozilla.components.support.utils.RunWhenReadyQueue
|
|
||||||
import mozilla.components.support.utils.SafeIntent
|
import mozilla.components.support.utils.SafeIntent
|
||||||
import mozilla.components.support.utils.toSafeIntent
|
import mozilla.components.support.utils.toSafeIntent
|
||||||
import mozilla.components.support.webextensions.WebExtensionPopupFeature
|
import mozilla.components.support.webextensions.WebExtensionPopupFeature
|
||||||
|
@ -104,6 +102,7 @@ import org.mozilla.fenix.tabtray.TabTrayDialogFragmentDirections
|
||||||
import org.mozilla.fenix.theme.DefaultThemeManager
|
import org.mozilla.fenix.theme.DefaultThemeManager
|
||||||
import org.mozilla.fenix.theme.ThemeManager
|
import org.mozilla.fenix.theme.ThemeManager
|
||||||
import org.mozilla.fenix.utils.BrowsersCache
|
import org.mozilla.fenix.utils.BrowsersCache
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The main activity of the application. The application is primarily a single Activity (this one)
|
* The main activity of the application. The application is primarily a single Activity (this one)
|
||||||
|
@ -122,7 +121,6 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
|
||||||
|
|
||||||
private var isVisuallyComplete = false
|
private var isVisuallyComplete = false
|
||||||
|
|
||||||
private var visualCompletenessQueue: RunWhenReadyQueue? = null
|
|
||||||
private var privateNotificationObserver: PrivateNotificationFeature<PrivateNotificationService>? = null
|
private var privateNotificationObserver: PrivateNotificationFeature<PrivateNotificationService>? = null
|
||||||
|
|
||||||
private var isToolbarInflated = false
|
private var isToolbarInflated = false
|
||||||
|
@ -164,13 +162,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
|
||||||
|
|
||||||
// Must be after we set the content view
|
// Must be after we set the content view
|
||||||
if (isVisuallyComplete) {
|
if (isVisuallyComplete) {
|
||||||
rootContainer.doOnPreDraw {
|
components.performance.visualCompletenessQueue
|
||||||
// This delay is temporary. We are delaying 5 seconds until the performance
|
.attachViewToRunVisualCompletenessQueueLater(WeakReference(rootContainer))
|
||||||
// team can locate the real point of visual completeness.
|
|
||||||
it.postDelayed({
|
|
||||||
visualCompletenessQueue!!.ready()
|
|
||||||
}, delay)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionObserver = UriOpenedObserver(this)
|
sessionObserver = UriOpenedObserver(this)
|
||||||
|
@ -678,9 +671,8 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
|
||||||
* The root container is null at this point, so let the HomeActivity know that
|
* The root container is null at this point, so let the HomeActivity know that
|
||||||
* we are visually complete.
|
* we are visually complete.
|
||||||
*/
|
*/
|
||||||
fun postVisualCompletenessQueue(visualCompletenessQueue: RunWhenReadyQueue) {
|
fun setVisualCompletenessQueueReady() {
|
||||||
isVisuallyComplete = true
|
isVisuallyComplete = true
|
||||||
this.visualCompletenessQueue = visualCompletenessQueue
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun captureSnapshotTelemetryMetrics() = CoroutineScope(Dispatchers.IO).launch {
|
private fun captureSnapshotTelemetryMetrics() = CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
@ -717,7 +709,6 @@ open class HomeActivity : LocaleAwareAppCompatActivity(), NavHostActivity {
|
||||||
const val PRIVATE_BROWSING_MODE = "private_browsing_mode"
|
const val PRIVATE_BROWSING_MODE = "private_browsing_mode"
|
||||||
const val EXTRA_DELETE_PRIVATE_TABS = "notification_delete_and_open"
|
const val EXTRA_DELETE_PRIVATE_TABS = "notification_delete_and_open"
|
||||||
const val EXTRA_OPENED_FROM_NOTIFICATION = "notification_open"
|
const val EXTRA_OPENED_FROM_NOTIFICATION = "notification_open"
|
||||||
const val delay = 5000L
|
|
||||||
const val START_IN_RECENTS_SCREEN = "start_in_recents_screen"
|
const val START_IN_RECENTS_SCREEN = "start_in_recents_screen"
|
||||||
|
|
||||||
// PWA must have been used within last 30 days to be considered "recently used" for the
|
// PWA must have been used within last 30 days to be considered "recently used" for the
|
||||||
|
|
|
@ -5,10 +5,11 @@
|
||||||
package org.mozilla.fenix.components
|
package org.mozilla.fenix.components
|
||||||
|
|
||||||
import mozilla.components.support.utils.RunWhenReadyQueue
|
import mozilla.components.support.utils.RunWhenReadyQueue
|
||||||
|
import org.mozilla.fenix.perf.VisualCompletenessQueue
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component group for all functionality related to performance.
|
* Component group for all functionality related to performance.
|
||||||
*/
|
*/
|
||||||
class PerformanceComponent {
|
class PerformanceComponent {
|
||||||
val visualCompletenessQueue by lazy { RunWhenReadyQueue() }
|
val visualCompletenessQueue by lazy { VisualCompletenessQueue(RunWhenReadyQueue()) }
|
||||||
}
|
}
|
||||||
|
|
|
@ -725,7 +725,7 @@ class GleanMetricsService(private val context: Context) : MetricsService {
|
||||||
|
|
||||||
// The code below doesn't need to execute immediately, so we'll add them to the visual
|
// The code below doesn't need to execute immediately, so we'll add them to the visual
|
||||||
// completeness task queue to be run later.
|
// completeness task queue to be run later.
|
||||||
context.components.performance.visualCompletenessQueue.runIfReadyOrQueue {
|
context.components.performance.visualCompletenessQueue.queue.runIfReadyOrQueue {
|
||||||
// We have to initialize Glean *on* the main thread, because it registers lifecycle
|
// We have to initialize Glean *on* the main thread, because it registers lifecycle
|
||||||
// observers. However, the activation ping must be sent *off* of the main thread,
|
// observers. However, the activation ping must be sent *off* of the main thread,
|
||||||
// because it calls Google ad APIs that must be called *off* of the main thread.
|
// because it calls Google ad APIs that must be called *off* of the main thread.
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/* 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.view.View
|
||||||
|
import androidx.core.view.doOnPreDraw
|
||||||
|
import mozilla.components.support.utils.RunWhenReadyQueue
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
|
||||||
|
/**
|
||||||
|
* class for all functionality related to Visual completeness queue
|
||||||
|
*/
|
||||||
|
class VisualCompletenessQueue(val queue: RunWhenReadyQueue) {
|
||||||
|
@Suppress("MagicNumber")
|
||||||
|
val delay = 5000L
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param containerWeakReference a weak reference to the root view of a view hierarchy. Weak
|
||||||
|
* reference is to avoid memory leak.
|
||||||
|
*/
|
||||||
|
fun attachViewToRunVisualCompletenessQueueLater(containerWeakReference: WeakReference<View>) {
|
||||||
|
containerWeakReference.get()?.doOnPreDraw {
|
||||||
|
// This delay is temporary. We are delaying 5 seconds until the performance
|
||||||
|
// team can locate the real point of visual completeness.
|
||||||
|
it.postDelayed({
|
||||||
|
queue.ready()
|
||||||
|
}, delay)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -51,7 +51,7 @@ class PerformanceActivityLifecycleCallbacks(
|
||||||
if (activity is HomeActivity) {
|
if (activity is HomeActivity) {
|
||||||
// We should delay the visualCompletenessQueue when reaching the HomeActivity
|
// We should delay the visualCompletenessQueue when reaching the HomeActivity
|
||||||
// to ensure all tasks are delayed until after visual completeness
|
// to ensure all tasks are delayed until after visual completeness
|
||||||
activity.postVisualCompletenessQueue(visualCompletenessQueue)
|
activity.setVisualCompletenessQueueReady()
|
||||||
} else if (shouldStartVisualCompletenessQueueImmediately()) {
|
} else if (shouldStartVisualCompletenessQueueImmediately()) {
|
||||||
// If we do not go through the home activity, we have to start the tasks
|
// If we do not go through the home activity, we have to start the tasks
|
||||||
// immediately to avoid spending time implementing it.
|
// immediately to avoid spending time implementing it.
|
||||||
|
|
Loading…
Reference in New Issue