@ -7,7 +7,9 @@ package org.mozilla.fenix.ui
import android.util.Log
import android.view.View
import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.children
import androidx.recyclerview.widget.RecyclerView
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.uiautomator.UiDevice
import kotlinx.android.synthetic.main.activity_home.*
@ -24,6 +26,7 @@ private const val EXPECTED_SUPPRESSION_COUNT = 11
private const val EXPECTED _RUNBLOCKING _COUNT = 2
private const val EXPECTED _COMPONENT _INIT _COUNT = 42
private const val EXPECTED _VIEW _HIERARCHY _DEPTH = 12
private const val EXPECTED _RECYCLER _VIEW _CONSTRAINT _LAYOUT _CHILDREN = 4
private val failureMsgStrictMode = getErrorMessage (
shortName = " StrictMode suppression " ,
@ -46,6 +49,13 @@ private val failureMsgViewHierarchyDepth = getErrorMessage(
) + " Please note that we're not sure if this is a useful metric to assert: with your feedback, " +
" we'll find out over time if it is or is not. "
private val failureMsgRecyclerViewConstraintLayoutChildren = getErrorMessage (
shortName = " ConstraintLayout being a common direct descendant of a RecyclerView " ,
implications = " ConstraintLayouts are slow to inflate and are primarily used to flatten deep " +
" view hierarchies so can be under-performant as a common RecyclerView child? "
) + " Please note that we're not sure if this is a useful metric to assert: with your feedback, " +
" we'll find out over time if it is or is not. "
/ * *
* A performance test to limit the number of StrictMode suppressions and number of runBlocking used
* on startup .
@ -79,12 +89,20 @@ class StartupExcessiveResourceUseTest {
val actualSuppresionCount = activityTestRule . activity . components . strictMode . suppressionCount . get ( ) . toInt ( )
val actualRunBlocking = RunBlockingCounter . count . get ( )
val actualComponentInitCount = ComponentInitCount . count . get ( )
val actualViewHierarchyDepth = countAndLogViewHierarchyDepth ( activityTestRule . activity . rootContainer , 1 )
val rootView = activityTestRule . activity . rootContainer
val actualViewHierarchyDepth = countAndLogViewHierarchyDepth ( rootView , 1 )
val actualRecyclerViewConstraintLayoutChildren = countRecyclerViewConstraintLayoutChildren ( rootView , null )
assertEquals ( failureMsgStrictMode , EXPECTED _SUPPRESSION _COUNT , actualSuppresionCount )
assertEquals ( failureMsgRunBlocking , EXPECTED _RUNBLOCKING _COUNT , actualRunBlocking )
assertEquals ( failureMsgComponentInit , EXPECTED _COMPONENT _INIT _COUNT , actualComponentInitCount )
assertEquals ( failureMsgViewHierarchyDepth , EXPECTED _VIEW _HIERARCHY _DEPTH , actualViewHierarchyDepth )
assertEquals (
failureMsgRecyclerViewConstraintLayoutChildren ,
EXPECTED _RECYCLER _VIEW _CONSTRAINT _LAYOUT _CHILDREN ,
actualRecyclerViewConstraintLayoutChildren
)
}
}
@ -101,6 +119,20 @@ private fun countAndLogViewHierarchyDepth(view: View, level: Int): Int {
}
}
private fun countRecyclerViewConstraintLayoutChildren ( view : View , parent : View ? ) : Int {
val viewValue = if ( parent is RecyclerView && view is ConstraintLayout ) {
1
} else {
0
}
return if ( view !is ViewGroup ) {
viewValue
} else {
viewValue + view . children . sumBy { countRecyclerViewConstraintLayoutChildren ( it , view ) }
}
}
private fun getErrorMessage ( shortName : String , implications : String ) = """ $shortName count does not match expected count.
If this PR removed a $ shortName call , great ! Please decrease the count .