Update Transitions trace parse function to only include transition that have full executed in the trace range
Bug: 406453297
Test: atest FlickerLibTests
Change-Id: I4374a963eb83389cb8d752ae53a05dddde4152b4
diff --git a/libraries/flicker/utils/src/android/tools/traces/parsers/perfetto/TransitionsTraceParser.kt b/libraries/flicker/utils/src/android/tools/traces/parsers/perfetto/TransitionsTraceParser.kt
index f2de431..8b30494 100644
--- a/libraries/flicker/utils/src/android/tools/traces/parsers/perfetto/TransitionsTraceParser.kt
+++ b/libraries/flicker/utils/src/android/tools/traces/parsers/perfetto/TransitionsTraceParser.kt
@@ -26,7 +26,7 @@
import android.tools.traces.wm.TransitionsTrace
import android.tools.traces.wm.WmTransitionData
-class TransitionsTraceParser :
+open class TransitionsTraceParser :
AbstractTraceParser<TraceProcessorSession, Transition, Transition, TransitionsTrace>() {
override val traceName = "Transitions Trace"
@@ -71,6 +71,25 @@
override fun onBeforeParse(input: TraceProcessorSession) {}
+ override fun doParse(
+ input: TraceProcessorSession,
+ from: Timestamp,
+ to: Timestamp,
+ addInitialEntry: Boolean,
+ ): TransitionsTrace {
+ val sliceEntries =
+ getEntries(input).filter {
+ (it.wmData.sendTime ?: it.shellData.dispatchTime ?: Timestamps.min()) >= from &&
+ (it.wmData.finishTime
+ ?: it.wmData.abortTime
+ ?: it.shellData.abortTime
+ ?: it.shellData.mergeTime
+ ?: Timestamps.max()) <= to
+ }
+
+ return createTrace(sliceEntries)
+ }
+
override fun doParseEntry(entry: Transition) = entry
companion object {
diff --git a/libraries/flicker/utils/src/android/tools/traces/wm/Transition.kt b/libraries/flicker/utils/src/android/tools/traces/wm/Transition.kt
index c473218..36627b9 100644
--- a/libraries/flicker/utils/src/android/tools/traces/wm/Transition.kt
+++ b/libraries/flicker/utils/src/android/tools/traces/wm/Transition.kt
@@ -44,6 +44,8 @@
}
}
+ // TODO: Rethink the timestamp assigned to transitions, conceptually these are not discrete
+ // entries but continuous time ranges over which a transition lives.
override val timestamp =
wmData.createTime
?: wmData.sendTime
diff --git a/libraries/flicker/utils/test/src/android/tools/parsers/wm/TransitionsTraceParserTest.kt b/libraries/flicker/utils/test/src/android/tools/parsers/wm/TransitionsTraceParserTest.kt
index af20edc..68e7dea 100644
--- a/libraries/flicker/utils/test/src/android/tools/parsers/wm/TransitionsTraceParserTest.kt
+++ b/libraries/flicker/utils/test/src/android/tools/parsers/wm/TransitionsTraceParserTest.kt
@@ -17,10 +17,16 @@
package android.tools.parsers.wm
import android.tools.Cache
+import android.tools.Timestamp
+import android.tools.Timestamps
import android.tools.testutils.CleanFlickerEnvironmentRule
import android.tools.testutils.readAsset
+import android.tools.traces.parsers.perfetto.Row
import android.tools.traces.parsers.perfetto.TraceProcessorSession
import android.tools.traces.parsers.perfetto.TransitionsTraceParser
+import android.tools.traces.wm.ShellTransitionData
+import android.tools.traces.wm.Transition
+import android.tools.traces.wm.WmTransitionData
import com.google.common.truth.Truth
import org.junit.Assume
import org.junit.Before
@@ -64,6 +70,148 @@
}
}
+ @Test
+ fun filtersTransitionWithDispatchTimeBeforeFrom() {
+ val from = Timestamps.from(elapsedNanos = 100)
+ val to = Timestamps.from(elapsedNanos = 200)
+ val transition =
+ createMockTransition(
+ id = 1,
+ dispatchTime = Timestamps.from(elapsedNanos = 99), // Before 'from'
+ finishTime = Timestamps.from(elapsedNanos = 150),
+ )
+ val parser = MockableTransitionsTraceParser(listOf(transition))
+ val trace = parser.parse(MockTraceProcessorSession(), from, to)
+ Truth.assertThat(trace.entries).isEmpty()
+ }
+
+ @Test
+ fun filtersTransitionWithSendTimeBeforeFrom() {
+ val from = Timestamps.from(elapsedNanos = 100)
+ val to = Timestamps.from(elapsedNanos = 200)
+ val transition =
+ createMockTransition(
+ id = 1,
+ sendTime = Timestamps.from(elapsedNanos = 99), // Before 'from'
+ finishTime = Timestamps.from(elapsedNanos = 150),
+ )
+ val parser = MockableTransitionsTraceParser(listOf(transition))
+ val trace = parser.parse(MockTraceProcessorSession(), from, to)
+ Truth.assertThat(trace.entries).isEmpty()
+ }
+
+ @Test
+ fun filtersTransitionWithFinishTimeAfterTo() {
+ val from = Timestamps.from(elapsedNanos = 100)
+ val to = Timestamps.from(elapsedNanos = 200)
+ val transition =
+ createMockTransition(
+ id = 1,
+ dispatchTime = Timestamps.from(elapsedNanos = 110),
+ finishTime = Timestamps.from(elapsedNanos = 201), // After 'to'
+ )
+ val parser = MockableTransitionsTraceParser(listOf(transition))
+ val trace = parser.parse(MockTraceProcessorSession(), from, to)
+ Truth.assertThat(trace.entries).isEmpty()
+ }
+
+ @Test
+ fun filtersTransitionWithWmAbortTimeAfterTo() {
+ val from = Timestamps.from(elapsedNanos = 100)
+ val to = Timestamps.from(elapsedNanos = 200)
+ val transition =
+ createMockTransition(
+ id = 1,
+ dispatchTime = Timestamps.from(elapsedNanos = 110),
+ wmAbortTime = Timestamps.from(elapsedNanos = 201), // After 'to'
+ )
+ val parser = MockableTransitionsTraceParser(listOf(transition))
+ val trace = parser.parse(MockTraceProcessorSession(), from, to)
+ Truth.assertThat(trace.entries).isEmpty()
+ }
+
+ @Test
+ fun filtersTransitionWithShellAbortTimeAfterTo() {
+ val from = Timestamps.from(elapsedNanos = 100)
+ val to = Timestamps.from(elapsedNanos = 200)
+ val transition =
+ createMockTransition(
+ id = 1,
+ dispatchTime = Timestamps.from(elapsedNanos = 110),
+ shellAbortTime = Timestamps.from(elapsedNanos = 201), // After 'to'
+ )
+ val parser = MockableTransitionsTraceParser(listOf(transition))
+ val trace = parser.parse(MockTraceProcessorSession(), from, to)
+ Truth.assertThat(trace.entries).isEmpty()
+ }
+
+ @Test
+ fun filtersTransitionWithMergeTimeAfterTo() {
+ val from = Timestamps.from(elapsedNanos = 100)
+ val to = Timestamps.from(elapsedNanos = 200)
+ val transition =
+ createMockTransition(
+ id = 1,
+ dispatchTime = Timestamps.from(elapsedNanos = 110),
+ mergeTime = Timestamps.from(elapsedNanos = 201), // After 'to'
+ )
+ val parser = MockableTransitionsTraceParser(listOf(transition))
+ val trace = parser.parse(MockTraceProcessorSession(), from, to)
+ Truth.assertThat(trace.entries).isEmpty()
+ }
+
+ @Test
+ fun includesValidTransition() {
+ val from = Timestamps.from(elapsedNanos = 100)
+ val to = Timestamps.from(elapsedNanos = 200)
+ val transition = createMockTransition(id = 1, dispatchTime = from, finishTime = to)
+ val parser = MockableTransitionsTraceParser(listOf(transition))
+ val trace = parser.parse(MockTraceProcessorSession(), from, to)
+ Truth.assertThat(trace.entries).containsExactly(transition)
+ }
+
+ private class MockTraceProcessorSession : TraceProcessorSession {
+ override fun <T> query(sql: String, predicate: (List<Row>) -> T): T {
+ // Not used in tests
+ error("Not implemented")
+ }
+ }
+
+ // Simple mock implementation for testing purposes
+ private class MockableTransitionsTraceParser(private val mockEntries: List<Transition>) :
+ TransitionsTraceParser() {
+ // Override getEntries to return the mocked list directly
+ override fun getEntries(input: TraceProcessorSession): List<Transition> {
+ return mockEntries
+ }
+ }
+
+ private fun createMockTransition(
+ id: Int,
+ sendTime: Timestamp? = null,
+ dispatchTime: Timestamp? = null,
+ finishTime: Timestamp? = null,
+ wmAbortTime: Timestamp? = null,
+ shellAbortTime: Timestamp? = null,
+ mergeTime: Timestamp? = null,
+ ): Transition {
+ return Transition(
+ id = id,
+ wmData =
+ WmTransitionData(
+ sendTime = sendTime,
+ finishTime = finishTime,
+ abortTime = wmAbortTime,
+ ),
+ shellData =
+ ShellTransitionData(
+ dispatchTime = dispatchTime,
+ abortTime = shellAbortTime,
+ mergeTime = mergeTime,
+ ),
+ )
+ }
+
companion object {
@ClassRule @JvmField val ENV_CLEANUP = CleanFlickerEnvironmentRule()
}
diff --git a/libraries/flicker/utils/test/src/android/tools/testutils/TestTraces.kt b/libraries/flicker/utils/test/src/android/tools/testutils/TestTraces.kt
index 2e57e50..9f61c79 100644
--- a/libraries/flicker/utils/test/src/android/tools/testutils/TestTraces.kt
+++ b/libraries/flicker/utils/test/src/android/tools/testutils/TestTraces.kt
@@ -101,11 +101,7 @@
val START_TIME =
Timestamps.from(elapsedNanos = 479583450794, systemUptimeNanos = 0, unixNanos = 0)
val VALID_SLICE_TIME =
- Timestamps.from(
- elapsedNanos = 479583450794 + 5000,
- systemUptimeNanos = 0,
- unixNanos = 0,
- )
+ Timestamps.from(elapsedNanos = 480124777862, systemUptimeNanos = 0, unixNanos = 0)
val INVALID_SLICE_TIME =
Timestamps.from(elapsedNanos = 487330863192 + 1, systemUptimeNanos = 0, unixNanos = 0)
val END_TIME =