Revert "Integrate SF (layers + transactions) perfetto tracing"

This reverts commit c1921fd48f13d11a5cdcf95bd1bce23781cf7574.

Reason for revert: 298512106

Change-Id: Ie08323db2275f6f59f179d7c399c34e263562900
diff --git a/libraries/flicker/src/android/tools/device/flicker/FlickerServiceTracesCollector.kt b/libraries/flicker/src/android/tools/device/flicker/FlickerServiceTracesCollector.kt
index 472a8d1..4e6ecb9 100644
--- a/libraries/flicker/src/android/tools/device/flicker/FlickerServiceTracesCollector.kt
+++ b/libraries/flicker/src/android/tools/device/flicker/FlickerServiceTracesCollector.kt
@@ -24,8 +24,9 @@
 import android.tools.device.traces.SERVICE_TRACE_CONFIG
 import android.tools.device.traces.io.ResultReaderWithLru
 import android.tools.device.traces.io.ResultWriter
-import android.tools.device.traces.monitors.PerfettoTraceMonitor
 import android.tools.device.traces.monitors.events.EventLogMonitor
+import android.tools.device.traces.monitors.surfaceflinger.LayersTraceMonitor
+import android.tools.device.traces.monitors.surfaceflinger.TransactionsTraceMonitor
 import android.tools.device.traces.monitors.wm.ShellTransitionTraceMonitor
 import android.tools.device.traces.monitors.wm.WindowManagerTraceMonitor
 import android.tools.device.traces.monitors.wm.WmTransitionTraceMonitor
@@ -40,9 +41,10 @@
     private val traceMonitors =
         listOf(
             WindowManagerTraceMonitor(),
-            PerfettoTraceMonitor().enableLayersTrace().enableTransactionsTrace(),
+            LayersTraceMonitor(),
             WmTransitionTraceMonitor(),
             ShellTransitionTraceMonitor(),
+            TransactionsTraceMonitor(),
             EventLogMonitor()
         )
 
diff --git a/libraries/flicker/src/android/tools/device/flicker/Utils.kt b/libraries/flicker/src/android/tools/device/flicker/Utils.kt
index af675f2..bea38b7 100644
--- a/libraries/flicker/src/android/tools/device/flicker/Utils.kt
+++ b/libraries/flicker/src/android/tools/device/flicker/Utils.kt
@@ -21,10 +21,11 @@
 import android.tools.device.traces.TRACE_CONFIG_REQUIRE_CHANGES
 import android.tools.device.traces.io.ResultReader
 import android.tools.device.traces.io.ResultWriter
-import android.tools.device.traces.monitors.PerfettoTraceMonitor
 import android.tools.device.traces.monitors.ScreenRecorder
 import android.tools.device.traces.monitors.TraceMonitor
 import android.tools.device.traces.monitors.events.EventLogMonitor
+import android.tools.device.traces.monitors.surfaceflinger.LayersTraceMonitor
+import android.tools.device.traces.monitors.surfaceflinger.TransactionsTraceMonitor
 import android.tools.device.traces.monitors.wm.ShellTransitionTraceMonitor
 import android.tools.device.traces.monitors.wm.WindowManagerTraceMonitor
 import android.tools.device.traces.monitors.wm.WmTransitionTraceMonitor
@@ -96,8 +97,9 @@
             listOf(
                 WmTransitionTraceMonitor(),
                 ShellTransitionTraceMonitor(),
+                TransactionsTraceMonitor(),
                 WindowManagerTraceMonitor(),
-                PerfettoTraceMonitor().enableLayersTrace().enableTransactionsTrace(),
+                LayersTraceMonitor(),
                 EventLogMonitor(),
                 ScreenRecorder(InstrumentationRegistry.getInstrumentation().targetContext)
             ),
diff --git a/libraries/flicker/src/android/tools/device/flicker/legacy/FlickerBuilder.kt b/libraries/flicker/src/android/tools/device/flicker/legacy/FlickerBuilder.kt
index e2c4986..7b1c5d0 100644
--- a/libraries/flicker/src/android/tools/device/flicker/legacy/FlickerBuilder.kt
+++ b/libraries/flicker/src/android/tools/device/flicker/legacy/FlickerBuilder.kt
@@ -18,15 +18,19 @@
 
 import android.app.Instrumentation
 import android.tools.common.io.TraceType
+import android.tools.common.traces.surfaceflinger.LayerTraceEntry
+import android.tools.common.traces.surfaceflinger.LayersTrace
+import android.tools.common.traces.surfaceflinger.TransactionsTrace
 import android.tools.common.traces.wm.TransitionsTrace
 import android.tools.common.traces.wm.WindowManagerState
 import android.tools.common.traces.wm.WindowManagerTrace
 import android.tools.device.traces.getDefaultFlickerOutputDir
 import android.tools.device.traces.monitors.ITransitionMonitor
 import android.tools.device.traces.monitors.NoTraceMonitor
-import android.tools.device.traces.monitors.PerfettoTraceMonitor
 import android.tools.device.traces.monitors.ScreenRecorder
 import android.tools.device.traces.monitors.events.EventLogMonitor
+import android.tools.device.traces.monitors.surfaceflinger.LayersTraceMonitor
+import android.tools.device.traces.monitors.surfaceflinger.TransactionsTraceMonitor
 import android.tools.device.traces.monitors.wm.ShellTransitionTraceMonitor
 import android.tools.device.traces.monitors.wm.WindowManagerTraceMonitor
 import android.tools.device.traces.monitors.wm.WmTransitionTraceMonitor
@@ -48,15 +52,19 @@
     private val traceMonitors: MutableList<ITransitionMonitor> =
         mutableListOf<ITransitionMonitor>().also {
             it.add(WindowManagerTraceMonitor())
-            it.add(PerfettoTraceMonitor().enableLayersTrace().enableTransactionsTrace())
+            it.add(LayersTraceMonitor())
             it.add(WmTransitionTraceMonitor())
             it.add(ShellTransitionTraceMonitor())
+            it.add(TransactionsTraceMonitor())
             it.add(ScreenRecorder(instrumentation.targetContext))
             it.add(EventLogMonitor())
         }
 ) {
     private var usingExistingTraces = false
 
+    /** Disable [WindowManagerTraceMonitor]. */
+    fun withoutWindowManagerTracing(): FlickerBuilder = apply { withWindowManagerTracing { null } }
+
     /**
      * Configure a [WindowManagerTraceMonitor] to obtain [WindowManagerTrace]
      *
@@ -71,6 +79,25 @@
             addMonitor(traceMonitor())
         }
 
+    /** Disable [LayersTraceMonitor]. */
+    fun withoutLayerTracing(): FlickerBuilder = apply { withLayerTracing { null } }
+
+    /**
+     * Configure a [LayersTraceMonitor] to obtain [LayersTrace].
+     *
+     * By default the tracing is always active. To disable tracing return null
+     *
+     * If this tracing is disabled, the assertions for [LayersTrace] and [LayerTraceEntry] will not
+     * be executed
+     */
+    fun withLayerTracing(traceMonitor: () -> LayersTraceMonitor?): FlickerBuilder = apply {
+        traceMonitors.removeIf { it is LayersTraceMonitor }
+        addMonitor(traceMonitor())
+    }
+
+    /** Disable [WmTransitionTraceMonitor]. */
+    fun withoutTransitionTracing(): FlickerBuilder = apply { withTransitionTracing { null } }
+
     /**
      * Configure a [WmTransitionTraceMonitor] to obtain [TransitionsTrace].
      *
@@ -82,6 +109,20 @@
             addMonitor(traceMonitor())
         }
 
+    /** Disable [TransactionsTraceMonitor]. */
+    fun withoutTransactionsTracing(): FlickerBuilder = apply { withTransactionsTracing { null } }
+
+    /**
+     * Configure a [TransactionsTraceMonitor] to obtain [TransactionsTrace].
+     *
+     * By default, shell transition tracing is disabled.
+     */
+    fun withTransactionsTracing(traceMonitor: () -> TransactionsTraceMonitor?): FlickerBuilder =
+        apply {
+            traceMonitors.removeIf { it is TransactionsTraceMonitor }
+            addMonitor(traceMonitor())
+        }
+
     /**
      * Configure a [ScreenRecorder].
      *
@@ -116,7 +157,8 @@
 
     data class TraceFiles(
         val wmTrace: File,
-        val perfetto: File,
+        val layersTrace: File,
+        val transactions: File,
         val wmTransitions: File,
         val shellTransitions: File,
         val eventLog: File
@@ -128,8 +170,10 @@
         // Remove all trace monitor and use only monitor that read from existing trace file
         this.traceMonitors.clear()
         addMonitor(NoTraceMonitor { it.addTraceResult(TraceType.WM, traceFiles.wmTrace) })
-        addMonitor(NoTraceMonitor { it.addTraceResult(TraceType.SF, traceFiles.perfetto) })
-        addMonitor(NoTraceMonitor { it.addTraceResult(TraceType.TRANSACTION, traceFiles.perfetto) })
+        addMonitor(NoTraceMonitor { it.addTraceResult(TraceType.SF, traceFiles.layersTrace) })
+        addMonitor(
+            NoTraceMonitor { it.addTraceResult(TraceType.TRANSACTION, traceFiles.transactions) }
+        )
         addMonitor(
             NoTraceMonitor { it.addTraceResult(TraceType.WM_TRANSITION, traceFiles.wmTransitions) }
         )
diff --git a/libraries/flicker/test/Android.bp b/libraries/flicker/test/Android.bp
index 31c56cd..70b08d4 100644
--- a/libraries/flicker/test/Android.bp
+++ b/libraries/flicker/test/Android.bp
@@ -34,7 +34,6 @@
     },
     static_libs: [
         "flickerlib",
-        "flickerlib-trace_processor_shell",
         "FlickerLibTest-Utils",
         "launcher-aosp-tapl",
         "mockito-target-extended-minus-junit4"
diff --git a/libraries/flicker/test/src/android/tools/Utils.kt b/libraries/flicker/test/src/android/tools/Utils.kt
index 9959816..09a7fc5 100644
--- a/libraries/flicker/test/src/android/tools/Utils.kt
+++ b/libraries/flicker/test/src/android/tools/Utils.kt
@@ -19,7 +19,6 @@
 import android.app.Instrumentation
 import android.tools.common.Scenario
 import android.tools.common.ScenarioBuilder
-import android.tools.common.io.PERFETTO_EXT
 import android.tools.common.io.Reader
 import android.tools.common.io.WINSCOPE_EXT
 import android.tools.common.parsers.events.EventLogParser
@@ -31,16 +30,16 @@
 import android.tools.device.traces.io.ResultReader
 import android.tools.device.traces.io.ResultWriter
 import android.tools.device.traces.monitors.ITransitionMonitor
-import android.tools.device.traces.monitors.PerfettoTraceMonitor
 import android.tools.device.traces.monitors.ScreenRecorder
 import android.tools.device.traces.monitors.events.EventLogMonitor
+import android.tools.device.traces.monitors.surfaceflinger.LayersTraceMonitor
+import android.tools.device.traces.monitors.surfaceflinger.TransactionsTraceMonitor
 import android.tools.device.traces.monitors.wm.ShellTransitionTraceMonitor
 import android.tools.device.traces.monitors.wm.WindowManagerTraceMonitor
 import android.tools.device.traces.monitors.wm.WmTransitionTraceMonitor
 import android.tools.device.traces.parsers.WindowManagerStateHelper
-import android.tools.device.traces.parsers.perfetto.LayersTraceParser
-import android.tools.device.traces.parsers.perfetto.TraceProcessorSession
-import android.tools.device.traces.parsers.perfetto.TransactionsTraceParser
+import android.tools.device.traces.parsers.surfaceflinger.LayersTraceParser
+import android.tools.device.traces.parsers.surfaceflinger.TransactionsTraceParser
 import android.tools.device.traces.parsers.wm.TransitionTraceParser
 import android.tools.device.traces.parsers.wm.WindowManagerTraceParser
 import android.tools.rules.DataStoreCleanupRule
@@ -60,54 +59,51 @@
     CleanFlickerEnvironmentRule().around(DataStoreCleanupRule())
 
 internal fun getTraceReaderFromScenario(scenario: String): Reader {
-    val scenarioTraces = getScenarioTraces(scenario)
-
-    val (layersTrace, transactionsTrace) =
-        TraceProcessorSession.loadPerfettoTrace(scenarioTraces.perfetto.readBytes()) { session ->
-            val layersTrace = LayersTraceParser().parse(session)
-            val transactionsTrace = TransactionsTraceParser().parse(session)
-            Pair(layersTrace, transactionsTrace)
-        }
+    val scenarioTraces = getScenarioTraces("AppLaunch")
 
     return ParsedTracesReader(
         artifact = InMemoryArtifact(scenario),
         wmTrace = WindowManagerTraceParser().parse(scenarioTraces.wmTrace.readBytes()),
-        layersTrace = layersTrace,
+        layersTrace = LayersTraceParser().parse(scenarioTraces.layersTrace.readBytes()),
         transitionsTrace =
             TransitionTraceParser()
                 .parse(
                     scenarioTraces.wmTransitions.readBytes(),
                     scenarioTraces.shellTransitions.readBytes()
                 ),
-        transactionsTrace = transactionsTrace,
+        transactionsTrace =
+            TransactionsTraceParser().parse(scenarioTraces.transactions.readBytes()),
         eventLog = EventLogParser().parse(scenarioTraces.eventLog.readBytes()),
     )
 }
 
 fun getScenarioTraces(scenario: String): FlickerBuilder.TraceFiles {
     lateinit var wmTrace: File
-    lateinit var perfettoTrace: File
+    lateinit var layersTrace: File
+    lateinit var transactionsTrace: File
     lateinit var wmTransitionTrace: File
     lateinit var shellTransitionTrace: File
     lateinit var eventLog: File
     val traces =
         mapOf<String, (File) -> Unit>(
-            "wm_trace$WINSCOPE_EXT" to { wmTrace = it },
-            "layers_and_transactions_trace$PERFETTO_EXT" to { perfettoTrace = it },
-            "wm_transition_trace$WINSCOPE_EXT" to { wmTransitionTrace = it },
-            "shell_transition_trace$WINSCOPE_EXT" to { shellTransitionTrace = it },
-            "eventlog$WINSCOPE_EXT" to { eventLog = it }
+            "wm_trace" to { wmTrace = it },
+            "layers_trace" to { layersTrace = it },
+            "transactions_trace" to { transactionsTrace = it },
+            "wm_transition_trace" to { wmTransitionTrace = it },
+            "shell_transition_trace" to { shellTransitionTrace = it },
+            "eventlog" to { eventLog = it }
         )
-    for ((traceFileName, resultSetter) in traces.entries) {
-        val traceBytes = readAsset("scenarios/$scenario/$traceFileName")
-        val traceFile = File.createTempFile(traceFileName, "")
+    for ((traceName, resultSetter) in traces.entries) {
+        val traceBytes = readAsset("scenarios/$scenario/$traceName$WINSCOPE_EXT")
+        val traceFile = File.createTempFile(traceName, WINSCOPE_EXT)
         traceFile.writeBytes(traceBytes)
         resultSetter.invoke(traceFile)
     }
 
     return FlickerBuilder.TraceFiles(
         wmTrace,
-        perfettoTrace,
+        layersTrace,
+        transactionsTrace,
         wmTransitionTrace,
         shellTransitionTrace,
         eventLog,
@@ -124,7 +120,7 @@
     val uiDevice: UiDevice = UiDevice.getInstance(instrumentation)
     val mockedFlicker = Mockito.mock(AbstractFlickerTestData::class.java)
     val monitors: MutableList<ITransitionMonitor> =
-        mutableListOf(WindowManagerTraceMonitor(), PerfettoTraceMonitor().enableLayersTrace())
+        mutableListOf(WindowManagerTraceMonitor(), LayersTraceMonitor())
     extraMonitor?.let { monitors.add(it) }
     Mockito.`when`(mockedFlicker.wmHelper).thenReturn(WindowManagerStateHelper())
     Mockito.`when`(mockedFlicker.device).thenReturn(uiDevice)
@@ -150,10 +146,11 @@
         listOf(
             ScreenRecorder(instrumentation.targetContext),
             EventLogMonitor(),
+            TransactionsTraceMonitor(),
             WmTransitionTraceMonitor(),
             ShellTransitionTraceMonitor(),
             WindowManagerTraceMonitor(),
-            PerfettoTraceMonitor().enableLayersTrace().enableTransactionsTrace(),
+            LayersTraceMonitor()
         )
     try {
         monitors.forEach { it.start() }
diff --git a/libraries/flicker/test/src/android/tools/common/flicker/FlickerServiceTracesCollectorTest.kt b/libraries/flicker/test/src/android/tools/common/flicker/FlickerServiceTracesCollectorTest.kt
index 6139913..0f2e15b 100644
--- a/libraries/flicker/test/src/android/tools/common/flicker/FlickerServiceTracesCollectorTest.kt
+++ b/libraries/flicker/test/src/android/tools/common/flicker/FlickerServiceTracesCollectorTest.kt
@@ -17,7 +17,6 @@
 package android.tools.common.flicker
 
 import android.app.Instrumentation
-import android.tools.common.io.TraceType
 import android.tools.device.apphelpers.BrowserAppHelper
 import android.tools.device.flicker.FlickerServiceTracesCollector
 import android.tools.device.flicker.isShellTransitionsEnabled
@@ -106,10 +105,11 @@
         val expectedTraces =
             listOf(
                 "wm_trace.winscope",
+                "layers_trace.winscope",
+                "transactions_trace.winscope",
                 "wm_transition_trace.winscope",
                 "shell_transition_trace.winscope",
-                "eventlog.winscope",
-                TraceType.SF.fileName
+                "eventlog.winscope"
             )
 
         @ClassRule
diff --git a/libraries/flicker/test/src/android/tools/common/flicker/extractor/ShellTransitionScenarioExtractorTest.kt b/libraries/flicker/test/src/android/tools/common/flicker/extractor/ShellTransitionScenarioExtractorTest.kt
index 289a1cf..178b5db 100644
--- a/libraries/flicker/test/src/android/tools/common/flicker/extractor/ShellTransitionScenarioExtractorTest.kt
+++ b/libraries/flicker/test/src/android/tools/common/flicker/extractor/ShellTransitionScenarioExtractorTest.kt
@@ -82,7 +82,7 @@
         Truth.assertThat(slices.first().endTimestamp)
             .isEqualTo(
                 Timestamps.from(
-                    unixNanos = 1682433277025674745,
+                    unixNanos = 1682433277025674723,
                     systemUptimeNanos = 2767865667794,
                     elapsedNanos = 2767949503328
                 )
diff --git a/libraries/flicker/test/src/android/tools/common/flicker/subject/surfaceflinger/LayerSubjectTest.kt b/libraries/flicker/test/src/android/tools/common/flicker/subject/surfaceflinger/LayerSubjectTest.kt
index 619b7d1..0087a59 100644
--- a/libraries/flicker/test/src/android/tools/common/flicker/subject/surfaceflinger/LayerSubjectTest.kt
+++ b/libraries/flicker/test/src/android/tools/common/flicker/subject/surfaceflinger/LayerSubjectTest.kt
@@ -39,7 +39,7 @@
 
     @Test
     fun exceptionContainsDebugInfoImaginary() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val foundLayer = LayersTraceSubject(trace, reader).first().layer("ImaginaryLayer", 0)
         Truth.assertWithMessage("ImaginaryLayer is not found").that(foundLayer).isNull()
@@ -47,7 +47,7 @@
 
     @Test
     fun canTestAssertionsOnLayer() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         LayersTraceSubject(trace, reader)
             .layer("SoundVizWallpaperV2", 26033)
diff --git a/libraries/flicker/test/src/android/tools/common/flicker/subject/surfaceflinger/LayerTraceEntrySubjectTest.kt b/libraries/flicker/test/src/android/tools/common/flicker/subject/surfaceflinger/LayerTraceEntrySubjectTest.kt
index 94394b1..aa435a4 100644
--- a/libraries/flicker/test/src/android/tools/common/flicker/subject/surfaceflinger/LayerTraceEntrySubjectTest.kt
+++ b/libraries/flicker/test/src/android/tools/common/flicker/subject/surfaceflinger/LayerTraceEntrySubjectTest.kt
@@ -51,7 +51,7 @@
 
     @Test
     fun exceptionContainsDebugInfo() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val error =
             assertThrows<AssertionError> {
@@ -63,7 +63,8 @@
 
     @Test
     fun testCanInspectBeginning() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         LayerTraceEntrySubject(trace.entries.first(), reader)
             .isVisible(ComponentNameMatcher.NAV_BAR)
@@ -73,7 +74,8 @@
 
     @Test
     fun testCanInspectEnd() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         LayerTraceEntrySubject(trace.entries.last(), reader)
             .isVisible(ComponentNameMatcher.NAV_BAR)
@@ -83,7 +85,7 @@
     // b/75276931
     @Test
     fun canDetectUncoveredRegion() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val expectedRegion = Region.from(0, 0, 1440, 2960)
         assertFail("SkRegion((0,0,1440,1440)) should cover at least SkRegion((0,0,1440,2960))") {
@@ -97,7 +99,7 @@
     // Visible region tests
     @Test
     fun canTestLayerVisibleRegion_layerDoesNotExist() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val expectedVisibleRegion = Region.from(0, 0, 1, 1)
         assertFail(TestComponents.IMAGINARY.toWindowIdentifier()) {
@@ -110,7 +112,7 @@
 
     @Test
     fun canTestLayerVisibleRegion_layerDoesNotHaveExpectedVisibleRegion() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val expectedVisibleRegion = Region.from(0, 0, 1, 1)
         assertFail("[empty] should cover exactly SkRegion((0,0,1,1))") {
@@ -123,7 +125,7 @@
 
     @Test
     fun canTestLayerVisibleRegion_layerIsHiddenByParent() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val expectedVisibleRegion = Region.from(0, 0, 1, 1)
         assertFail("[empty] should cover exactly SkRegion((0,0,1,1))") {
@@ -136,7 +138,7 @@
 
     @Test
     fun canTestLayerVisibleRegion_incorrectRegionSize() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val expectedVisibleRegion = Region.from(0, 0, 1440, 99)
         assertFail("SkRegion((0,0,1440,171)) should cover exactly SkRegion((0,0,1440,99))") {
@@ -149,7 +151,8 @@
 
     @Test
     fun canTestLayerVisibleRegion() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val expectedVisibleRegion = Region.from(0, 0, 1080, 145)
         LayersTraceSubject(trace, reader)
@@ -161,7 +164,10 @@
     @Test
     fun canTestLayerVisibleRegion_layerIsNotVisible() {
         val reader =
-            getLayerTraceReaderFromAsset("layers_trace_invalid_layer_visibility.perfetto-trace")
+            getLayerTraceReaderFromAsset(
+                "layers_trace_invalid_layer_visibility.pb",
+                legacyTrace = true
+            )
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         assertFail("Bounds is 0x0") {
             LayersTraceSubject(trace, reader)
@@ -354,7 +360,7 @@
 
     @Test
     fun detectOccludedLayerBecauseOfRoundedCorners() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_rounded_corners.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_rounded_corners.winscope")
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val entry =
             LayersTraceSubject(trace, reader)
@@ -385,28 +391,6 @@
             .isGreaterThan(0)
     }
 
-    @Test
-    fun canDetectInvisibleLayerOutOfScreen() {
-        val reader =
-            getLayerTraceReaderFromAsset("layers_trace_visible_outside_bounds.perfetto-trace")
-        val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
-        val subject =
-            LayersTraceSubject(trace, reader)
-                .getEntryBySystemUpTime(1253267561044, byElapsedTimestamp = true)
-        val region = subject.visibleRegion(ComponentNameMatcher.IME_SNAPSHOT)
-        region.isEmpty()
-        subject.isInvisible(ComponentNameMatcher.IME_SNAPSHOT)
-    }
-
-    @Test
-    fun canDetectInvisibleLayerOutOfScreen_ConsecutiveLayers() {
-        val reader =
-            getLayerTraceReaderFromAsset("layers_trace_visible_outside_bounds.perfetto-trace")
-        val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
-        val subject = LayersTraceSubject(trace, reader)
-        subject.visibleLayersShownMoreThanOneConsecutiveEntry()
-    }
-
     companion object {
         @ClassRule @JvmField val ENV_CLEANUP = CleanFlickerEnvironmentRule()
     }
diff --git a/libraries/flicker/test/src/android/tools/common/flicker/subject/surfaceflinger/LayersTraceSubjectTest.kt b/libraries/flicker/test/src/android/tools/common/flicker/subject/surfaceflinger/LayersTraceSubjectTest.kt
index afda9d9..a411f4b 100644
--- a/libraries/flicker/test/src/android/tools/common/flicker/subject/surfaceflinger/LayersTraceSubjectTest.kt
+++ b/libraries/flicker/test/src/android/tools/common/flicker/subject/surfaceflinger/LayersTraceSubjectTest.kt
@@ -55,7 +55,8 @@
 
     @Test
     fun exceptionContainsDebugInfo() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val error = assertThrows<AssertionError> { LayersTraceSubject(trace, reader).isEmpty() }
         assertThatErrorContainsDebugInfo(error)
@@ -63,7 +64,7 @@
 
     @Test
     fun testCanDetectEmptyRegionFromLayerTrace() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         assertFail("SkRegion((0,0,1440,1440)) should cover at least SkRegion((0,0,1440,2880))") {
             LayersTraceSubject(trace, reader)
@@ -76,7 +77,8 @@
 
     @Test
     fun testCanInspectBeginning() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         LayersTraceSubject(trace, reader)
             .first()
@@ -87,7 +89,8 @@
 
     @Test
     fun testCanInspectEnd() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         LayersTraceSubject(trace, reader)
             .last()
@@ -97,7 +100,8 @@
 
     @Test
     fun testAssertionsOnRange() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
 
         LayersTraceSubject(trace, reader)
@@ -113,7 +117,8 @@
 
     @Test
     fun testCanDetectChangingAssertions() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         LayersTraceSubject(trace, reader)
             .isVisible(ComponentNameMatcher.NAV_BAR)
@@ -131,7 +136,10 @@
     @Test
     fun testCanDetectIncorrectVisibilityFromLayerTrace() {
         val reader =
-            getLayerTraceReaderFromAsset("layers_trace_invalid_layer_visibility.perfetto-trace")
+            getLayerTraceReaderFromAsset(
+                "layers_trace_invalid_layer_visibility.pb",
+                legacyTrace = true
+            )
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val error =
             assertThrows<AssertionError> {
@@ -144,7 +152,7 @@
 
         Truth.assertThat(error)
             .hasMessageThat()
-            .contains("layers_trace_invalid_layer_visibility.perfetto-trace")
+            .contains("layers_trace_invalid_layer_visibility.pb")
         Truth.assertThat(error).hasMessageThat().contains("2d22h13m14s303ms")
         Truth.assertThat(error).hasMessageThat().contains("!isVisible")
         Truth.assertThat(error)
@@ -158,7 +166,10 @@
     @Test
     fun testCanDetectInvalidVisibleLayerForMoreThanOneConsecutiveEntry() {
         val reader =
-            getLayerTraceReaderFromAsset("layers_trace_invalid_visible_layers.perfetto-trace")
+            getLayerTraceReaderFromAsset(
+                "layers_trace_invalid_visible_layers.pb",
+                legacyTrace = true
+            )
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val error =
             assertThrows<AssertionError> {
@@ -183,14 +194,17 @@
     @Test
     fun testCanDetectVisibleLayersMoreThanOneConsecutiveEntry() {
         testCanDetectVisibleLayersMoreThanOneConsecutiveEntry(
-            getLayerTraceReaderFromAsset("layers_trace_snapshot_visible.perfetto-trace")
+            getLayerTraceReaderFromAsset("layers_trace_snapshot_visible.pb", legacyTrace = true)
         )
     }
 
     @Test
     fun testCanIgnoreLayerEqualNameInVisibleLayersMoreThanOneConsecutiveEntry() {
         val reader =
-            getLayerTraceReaderFromAsset("layers_trace_invalid_visible_layers.perfetto-trace")
+            getLayerTraceReaderFromAsset(
+                "layers_trace_invalid_visible_layers.pb",
+                legacyTrace = true
+            )
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         LayersTraceSubject(trace, reader)
             .visibleLayersShownMoreThanOneConsecutiveEntry(listOf(ComponentNameMatcher.STATUS_BAR))
@@ -199,7 +213,8 @@
 
     @Test
     fun testCanIgnoreLayerShorterNameInVisibleLayersMoreThanOneConsecutiveEntry() {
-        val reader = getLayerTraceReaderFromAsset("one_visible_layer_launcher_trace.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("one_visible_layer_launcher_trace.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val launcherComponent =
             ComponentNameMatcher(
@@ -212,7 +227,7 @@
     }
 
     private fun detectRootLayer(fileName: String) {
-        val reader = getLayerTraceReaderFromAsset(fileName)
+        val reader = getLayerTraceReaderFromAsset(fileName, legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         for (entry in trace.entries) {
             val rootLayers = entry.children
@@ -228,17 +243,17 @@
 
     @Test
     fun testCanDetectRootLayer() {
-        detectRootLayer("layers_trace_root.perfetto-trace")
+        detectRootLayer("layers_trace_root.pb")
     }
 
     @Test
     fun testCanDetectRootLayerAOSP() {
-        detectRootLayer("layers_trace_root_aosp.perfetto-trace")
+        detectRootLayer("layers_trace_root_aosp.pb")
     }
 
     @Test
     fun canTestLayerOccludedBySplashScreenLayerIsNotVisible() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_occluded.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_occluded.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val entry =
             LayersTraceSubject(trace, reader)
@@ -249,7 +264,7 @@
 
     @Test
     fun testCanDetectLayerExpanding() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_openchrome.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_openchrome.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val animation =
             LayersTraceSubject(trace, reader).layers("animation-leash of app_transition#0")
@@ -270,7 +285,7 @@
 
     @Test
     fun checkVisibleRegionAppMinusPipLayer() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_pip_wmshell.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_pip_wmshell.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val subject = LayersTraceSubject(trace, reader).last()
 
@@ -288,7 +303,7 @@
 
     @Test
     fun checkVisibleRegionAppPlusPipLayer() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_pip_wmshell.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_pip_wmshell.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val subject = LayersTraceSubject(trace, reader).last()
         val pipRegion = subject.visibleRegion(TestComponents.PIP_APP).region
@@ -300,7 +315,8 @@
 
     @Test
     fun checkCanDetectSplashScreen() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_splashscreen.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("layers_trace_splashscreen.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         LayersTraceSubject(trace, reader)
             .isVisible(TestComponents.LAUNCHER)
@@ -321,7 +337,8 @@
 
     @Test
     fun checkCanDetectMissingSplashScreen() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_splashscreen.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("layers_trace_splashscreen.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
 
         // No splashscreen because no matching activity record
@@ -336,7 +353,7 @@
     fun snapshotStartingWindowLayerCoversExactlyApp() {
         val reader =
             getLayerTraceReaderFromAsset(
-                "layers_trace_snapshotStartingWindowLayerCoversExactlyApp.perfetto-trace",
+                "layers_trace_snapshotStartingWindowLayerCoversExactlyApp.winscope",
                 from = Timestamps.from(systemUptimeNanos = 1688243428961872440),
                 to = Timestamps.from(systemUptimeNanos = 1688243432147782644)
             )
diff --git a/libraries/flicker/test/src/android/tools/common/flicker/traces/surfaceflinger/LayerTraceEntrySubjectTest.kt b/libraries/flicker/test/src/android/tools/common/flicker/traces/surfaceflinger/LayerTraceEntrySubjectTest.kt
new file mode 100644
index 0000000..c56e851
--- /dev/null
+++ b/libraries/flicker/test/src/android/tools/common/flicker/traces/surfaceflinger/LayerTraceEntrySubjectTest.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.tools.common.flicker.traces.surfaceflinger
+
+import android.tools.common.flicker.subject.layers.LayersTraceSubject
+import android.tools.common.traces.component.ComponentNameMatcher
+import android.tools.utils.TestComponents
+import android.tools.utils.assertThatErrorContainsDebugInfo
+import android.tools.utils.assertThrows
+import android.tools.utils.getLayerTraceReaderFromAsset
+import org.junit.Test
+
+class LayerTraceEntrySubjectTest {
+    @Test
+    fun exceptionContainsDebugInfo() {
+        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.pb", legacyTrace = true)
+        val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
+        val error =
+            assertThrows<AssertionError> {
+                LayersTraceSubject(trace, reader).first().contains(TestComponents.IMAGINARY)
+            }
+        assertThatErrorContainsDebugInfo(error)
+    }
+
+    @Test
+    fun canDetectInvisibleLayerOutOfScreen() {
+        val reader = getLayerTraceReaderFromAsset("layers_trace_visible_outside_bounds.winscope")
+        val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
+        val subject =
+            LayersTraceSubject(trace, reader)
+                .getEntryBySystemUpTime(1253267561044, byElapsedTimestamp = true)
+        val region = subject.visibleRegion(ComponentNameMatcher.IME_SNAPSHOT)
+        region.isEmpty()
+        subject.isInvisible(ComponentNameMatcher.IME_SNAPSHOT)
+    }
+
+    @Test
+    fun canDetectInvisibleLayerOutOfScreen_ConsecutiveLayers() {
+        val reader = getLayerTraceReaderFromAsset("layers_trace_visible_outside_bounds.winscope")
+        val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
+        val subject = LayersTraceSubject(trace, reader)
+        subject.visibleLayersShownMoreThanOneConsecutiveEntry()
+    }
+}
diff --git a/libraries/flicker/test/src/android/tools/common/flicker/traces/surfaceflinger/LayerTraceSubjectTest.kt b/libraries/flicker/test/src/android/tools/common/flicker/traces/surfaceflinger/LayerTraceSubjectTest.kt
index c86020b..10ef0ad 100644
--- a/libraries/flicker/test/src/android/tools/common/flicker/traces/surfaceflinger/LayerTraceSubjectTest.kt
+++ b/libraries/flicker/test/src/android/tools/common/flicker/traces/surfaceflinger/LayerTraceSubjectTest.kt
@@ -25,7 +25,7 @@
 class LayerTraceSubjectTest {
     @Test
     fun exceptionContainsDebugInfo() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val error = assertThrows<AssertionError> { LayersTraceSubject(trace, reader).isEmpty() }
         assertThatErrorContainsDebugInfo(error)
diff --git a/libraries/flicker/utils/Android.bp b/libraries/flicker/utils/Android.bp
index 72ec9eb..ec1d00e 100644
--- a/libraries/flicker/utils/Android.bp
+++ b/libraries/flicker/utils/Android.bp
@@ -39,7 +39,6 @@
     ],
     static_libs: [
         "flickerlib-parsers",
-        "flickerlib-trace_processor_shell",
         "androidx.test.uiautomator_uiautomator",
     ],
 }
@@ -66,8 +65,8 @@
     static_libs: [
         "flickerlib-common",
         "androidx.benchmark_benchmark-macro",
-        "perfetto_config-lite",
         "platformprotosnano",
+        "layersprotoslite",
         "view_capture_proto",
         "WindowManager-Shell-proto",
     ],
diff --git a/libraries/flicker/utils/src/android/tools/common/io/Consts.kt b/libraries/flicker/utils/src/android/tools/common/io/Consts.kt
index 98f5f88..9b057d6 100644
--- a/libraries/flicker/utils/src/android/tools/common/io/Consts.kt
+++ b/libraries/flicker/utils/src/android/tools/common/io/Consts.kt
@@ -19,6 +19,5 @@
 import android.tools.common.FLICKER_TAG
 
 const val WINSCOPE_EXT = ".winscope"
-const val PERFETTO_EXT = ".perfetto-trace"
 const val FLICKER_IO_TAG = "$FLICKER_TAG-IO"
 const val BUFFER_SIZE = 2048
diff --git a/libraries/flicker/utils/src/android/tools/common/io/TraceType.kt b/libraries/flicker/utils/src/android/tools/common/io/TraceType.kt
index ce120d9..1b19cd1 100644
--- a/libraries/flicker/utils/src/android/tools/common/io/TraceType.kt
+++ b/libraries/flicker/utils/src/android/tools/common/io/TraceType.kt
@@ -18,13 +18,13 @@
 
 /** Types of traces/dumps that cna be in a flicker result */
 enum class TraceType(val fileName: String, val isTrace: Boolean) {
-    SF("trace$PERFETTO_EXT", isTrace = true),
+    SF("layers_trace$WINSCOPE_EXT", isTrace = true),
     WM("wm_trace$WINSCOPE_EXT", isTrace = true),
-    TRANSACTION("trace$PERFETTO_EXT", isTrace = true),
+    TRANSACTION("transactions_trace$WINSCOPE_EXT", isTrace = true),
     WM_TRANSITION("wm_transition_trace$WINSCOPE_EXT", isTrace = true),
     SHELL_TRANSITION("shell_transition_trace$WINSCOPE_EXT", isTrace = true),
     EVENT_LOG("eventlog$WINSCOPE_EXT", isTrace = true),
     SCREEN_RECORDING("transition.mp4", isTrace = true),
-    SF_DUMP("trace$PERFETTO_EXT", isTrace = false),
-    WM_DUMP("trace$WINSCOPE_EXT", isTrace = false)
+    SF_DUMP("sf_dump$WINSCOPE_EXT", isTrace = false),
+    WM_DUMP("wm_dump$WINSCOPE_EXT", isTrace = false)
 }
diff --git a/libraries/flicker/utils/src/android/tools/device/traces/Utils.kt b/libraries/flicker/utils/src/android/tools/device/traces/Utils.kt
index 0648ca6..1ad6ef5 100644
--- a/libraries/flicker/utils/src/android/tools/device/traces/Utils.kt
+++ b/libraries/flicker/utils/src/android/tools/device/traces/Utils.kt
@@ -28,7 +28,6 @@
 import android.tools.common.traces.NullableDeviceStateDump
 import android.tools.common.traces.surfaceflinger.LayerTraceEntry
 import android.tools.common.traces.wm.WindowManagerState
-import android.tools.device.traces.monitors.PerfettoTraceMonitor
 import android.tools.device.traces.parsers.DeviceDumpParser
 import androidx.test.platform.app.InstrumentationRegistry
 import java.text.SimpleDateFormat
@@ -81,6 +80,8 @@
 
 private fun getCurrentWindowManagerState() = doBinderDump("window")
 
+private fun getCurrentLayersState() = doBinderDump("SurfaceFlinger")
+
 /**
  * Gets the current device state dump containing the [WindowManagerState] (optional) and the
  * [LayerTraceEntry] (optional) in raw (byte) data.
@@ -108,7 +109,7 @@
         }
     val layersTraceData =
         if (dumpTypes.contains(TraceType.SF_DUMP)) {
-            PerfettoTraceMonitor().enableLayersDump().withTracing {}
+            getCurrentLayersState()
         } else {
             ByteArray(0)
         }
diff --git a/libraries/flicker/utils/src/android/tools/device/traces/io/ArtifactBuilder.kt b/libraries/flicker/utils/src/android/tools/device/traces/io/ArtifactBuilder.kt
index f2844a2..7b5f3cb 100644
--- a/libraries/flicker/utils/src/android/tools/device/traces/io/ArtifactBuilder.kt
+++ b/libraries/flicker/utils/src/android/tools/device/traces/io/ArtifactBuilder.kt
@@ -126,21 +126,8 @@
     private fun writeToZip(file: File, files: Map<ResultArtifactDescriptor, File>) {
         ZipOutputStream(BufferedOutputStream(FileOutputStream(file), BUFFER_SIZE)).use {
             zipOutputStream ->
-            val writtenFileNames = HashSet<String>()
             files.forEach { (descriptor, artifact) ->
-                if (!writtenFileNames.contains(descriptor.fileNameInArtifact)) {
-                    addFile(
-                        zipOutputStream,
-                        artifact,
-                        nameInArchive = descriptor.fileNameInArtifact
-                    )
-                    writtenFileNames.add(descriptor.fileNameInArtifact)
-                } else {
-                    Logger.d(
-                        FLICKER_IO_TAG,
-                        "Not adding duplicated ${descriptor.fileNameInArtifact} to zip"
-                    )
-                }
+                addFile(zipOutputStream, artifact, nameInArchive = descriptor.fileNameInArtifact)
             }
         }
     }
diff --git a/libraries/flicker/utils/src/android/tools/device/traces/io/ResultReader.kt b/libraries/flicker/utils/src/android/tools/device/traces/io/ResultReader.kt
index ccf53bc..17d552f 100644
--- a/libraries/flicker/utils/src/android/tools/device/traces/io/ResultReader.kt
+++ b/libraries/flicker/utils/src/android/tools/device/traces/io/ResultReader.kt
@@ -33,9 +33,8 @@
 import android.tools.common.traces.wm.WindowManagerTrace
 import android.tools.device.traces.TraceConfig
 import android.tools.device.traces.TraceConfigs
-import android.tools.device.traces.parsers.perfetto.LayersTraceParser
-import android.tools.device.traces.parsers.perfetto.TraceProcessorSession
-import android.tools.device.traces.parsers.perfetto.TransactionsTraceParser
+import android.tools.device.traces.parsers.surfaceflinger.LayersTraceParser
+import android.tools.device.traces.parsers.surfaceflinger.TransactionsTraceParser
 import android.tools.device.traces.parsers.wm.TransitionTraceParser
 import android.tools.device.traces.parsers.wm.WindowManagerDumpParser
 import android.tools.device.traces.parsers.wm.WindowManagerTraceParser
@@ -124,16 +123,14 @@
             val descriptor = ResultArtifactDescriptor(TraceType.SF)
             artifact.readBytes(descriptor)?.let {
                 val trace =
-                    TraceProcessorSession.loadPerfettoTrace(it) { session ->
-                        LayersTraceParser()
-                            .parse(
-                                session,
-                                transitionTimeRange.start,
-                                transitionTimeRange.end,
-                                addInitialEntry = true,
-                                clearCache = true
-                            )
-                    }
+                    LayersTraceParser()
+                        .parse(
+                            it,
+                            transitionTimeRange.start,
+                            transitionTimeRange.end,
+                            addInitialEntry = true,
+                            clearCache = true
+                        )
                 val minimumEntries = minimumTraceEntriesForConfig(traceConfig.layersTrace)
                 require(trace.entries.size >= minimumEntries) {
                     "Layers trace contained ${trace.entries.size} entries, " +
@@ -156,13 +153,7 @@
         return Logger.withTracing("readLayersDump#$tag") {
             val descriptor = ResultArtifactDescriptor(TraceType.SF_DUMP, tag)
             val traceData = artifact.readBytes(descriptor)
-            if (traceData != null) {
-                TraceProcessorSession.loadPerfettoTrace(traceData) { session ->
-                    LayersTraceParser().parse(session, clearCache = true)
-                }
-            } else {
-                null
-            }
+            traceData?.let { LayersTraceParser().parse(it, clearCache = true) }
         }
     }
 
@@ -180,10 +171,7 @@
     private fun doReadTransactionsTrace(from: Timestamp, to: Timestamp): TransactionsTrace? {
         val traceData = artifact.readBytes(ResultArtifactDescriptor(TraceType.TRANSACTION))
         return traceData?.let {
-            val trace =
-                TraceProcessorSession.loadPerfettoTrace(traceData) { session ->
-                    TransactionsTraceParser().parse(session, from, to, addInitialEntry = true)
-                }
+            val trace = TransactionsTraceParser().parse(it, from, to, addInitialEntry = true)
             require(trace.entries.isNotEmpty()) { "Transactions trace cannot be empty" }
             trace
         }
diff --git a/libraries/flicker/utils/src/android/tools/device/traces/monitors/MonitorUtils.kt b/libraries/flicker/utils/src/android/tools/device/traces/monitors/MonitorUtils.kt
index e31f57f..6e4d0fe 100644
--- a/libraries/flicker/utils/src/android/tools/device/traces/monitors/MonitorUtils.kt
+++ b/libraries/flicker/utils/src/android/tools/device/traces/monitors/MonitorUtils.kt
@@ -15,24 +15,17 @@
  */
 
 @file:JvmName("MonitorUtils")
-@file:OptIn(
-    androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi::class,
-    androidx.benchmark.perfetto.ExperimentalPerfettoTraceProcessorApi::class
-)
 
 package android.tools.device.traces.monitors
 
 import android.tools.common.traces.DeviceTraceDump
 import android.tools.common.traces.surfaceflinger.LayersTrace
-import android.tools.common.traces.surfaceflinger.TransactionsTrace
 import android.tools.common.traces.wm.WindowManagerTrace
+import android.tools.device.traces.monitors.surfaceflinger.LayersTraceMonitor
 import android.tools.device.traces.monitors.wm.WindowManagerTraceMonitor
 import android.tools.device.traces.parsers.DeviceDumpParser
-import android.tools.device.traces.parsers.perfetto.LayersTraceParser
-import android.tools.device.traces.parsers.perfetto.TraceProcessorSession
-import android.tools.device.traces.parsers.perfetto.TransactionsTraceParser
+import android.tools.device.traces.parsers.surfaceflinger.LayersTraceParser
 import android.tools.device.traces.parsers.wm.WindowManagerTraceParser
-import perfetto.protos.PerfettoConfig.SurfaceFlingerLayersConfig
 
 /**
  * Acquire the [WindowManagerTrace] with the device state changes that happen when executing the
@@ -49,34 +42,16 @@
  * Acquire the [LayersTrace] with the device state changes that happen when executing the commands
  * defined in the [predicate].
  *
- * @param flags Flags to indicate tracing level
+ * @param traceFlags Flags to indicate tracing level
  * @param predicate Commands to execute
  * @throws UnsupportedOperationException If tracing is already activated
  */
 @JvmOverloads
 fun withSFTracing(
-    flags: List<SurfaceFlingerLayersConfig.TraceFlag>? = null,
+    traceFlags: Int = LayersTraceMonitor.TRACE_FLAGS,
     predicate: () -> Unit
 ): LayersTrace {
-    val trace = PerfettoTraceMonitor().enableLayersTrace(flags).withTracing(predicate)
-    return TraceProcessorSession.loadPerfettoTrace(trace) { session ->
-        LayersTraceParser().parse(session)
-    }
-}
-
-/**
- * Acquire the [TransactionsTrace] with the device state changes that happen when executing the
- * commands defined in the [predicate].
- *
- * @param predicate Commands to execute
- * @throws UnsupportedOperationException If tracing is already activated
- */
-@JvmOverloads
-fun withTransactionsTracing(predicate: () -> Unit): TransactionsTrace {
-    val trace = PerfettoTraceMonitor().enableTransactionsTrace().withTracing(predicate)
-    return TraceProcessorSession.loadPerfettoTrace(trace) { session ->
-        TransactionsTraceParser().parse(session)
-    }
+    return LayersTraceParser().parse(LayersTraceMonitor(traceFlags).withTracing(predicate))
 }
 
 /**
@@ -104,7 +79,7 @@
 fun recordTraces(predicate: () -> Unit): Pair<ByteArray, ByteArray> {
     var wmTraceData = ByteArray(0)
     val layersTraceData =
-        PerfettoTraceMonitor().enableLayersTrace().withTracing {
+        LayersTraceMonitor().withTracing {
             wmTraceData = WindowManagerTraceMonitor().withTracing(predicate)
         }
 
diff --git a/libraries/flicker/utils/src/android/tools/device/traces/monitors/PerfettoTraceMonitor.kt b/libraries/flicker/utils/src/android/tools/device/traces/monitors/PerfettoTraceMonitor.kt
deleted file mode 100644
index 49f3f79..0000000
--- a/libraries/flicker/utils/src/android/tools/device/traces/monitors/PerfettoTraceMonitor.kt
+++ /dev/null
@@ -1,224 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.tools.device.traces.monitors
-
-import android.tools.common.io.TraceType
-import android.tools.device.traces.executeShellCommand
-import java.io.File
-import java.io.FileOutputStream
-import java.util.concurrent.locks.ReentrantLock
-import perfetto.protos.PerfettoConfig.DataSourceConfig
-import perfetto.protos.PerfettoConfig.SurfaceFlingerLayersConfig
-import perfetto.protos.PerfettoConfig.SurfaceFlingerTransactionsConfig
-import perfetto.protos.PerfettoConfig.TraceConfig
-
-/* Captures traces from Perfetto. */
-open class PerfettoTraceMonitor : TraceMonitor() {
-    override val traceType = TraceType.SF // TODO: is this ok for the time being?
-    override val isEnabled
-        get() = perfettoPid != null
-
-    private val DEFAULT_SF_LAYER_FLAGS =
-        listOf(
-            SurfaceFlingerLayersConfig.TraceFlag.TRACE_FLAG_INPUT,
-            SurfaceFlingerLayersConfig.TraceFlag.TRACE_FLAG_COMPOSITION,
-            SurfaceFlingerLayersConfig.TraceFlag.TRACE_FLAG_VIRTUAL_DISPLAYS
-        )
-
-    private var isLayersTraceEnabled = false
-    private var layersTraceFlags = DEFAULT_SF_LAYER_FLAGS
-
-    private var isLayersDumpEnabled = false
-    private var layersDumpFlags = DEFAULT_SF_LAYER_FLAGS
-
-    private var isTransactionsTraceEnabled = false
-
-    private var perfettoPid: Int? = null
-    private var tempConfigFile: File? = null
-    private var traceFile: File? = null
-    private val PERFETTO_CONFIGS_DIR = File("/data/misc/perfetto-configs")
-    private val PERFETTO_TRACES_DIR = File("/data/misc/perfetto-traces")
-
-    fun enableLayersTrace(
-        flags: List<SurfaceFlingerLayersConfig.TraceFlag>? = null
-    ): PerfettoTraceMonitor {
-        isLayersTraceEnabled = true
-        if (flags != null) {
-            layersTraceFlags = flags
-        }
-        return this
-    }
-
-    fun enableLayersDump(
-        flags: List<SurfaceFlingerLayersConfig.TraceFlag>? = null
-    ): PerfettoTraceMonitor {
-        isLayersDumpEnabled = true
-        if (flags != null) {
-            layersDumpFlags = flags
-        }
-        return this
-    }
-
-    fun enableTransactionsTrace(): PerfettoTraceMonitor {
-        isTransactionsTraceEnabled = true
-        return this
-    }
-
-    override fun doStart() {
-        tempConfigFile = File.createTempFile("flickerlib-config-", ".cfg")
-        traceFile = File.createTempFile(traceType.fileName, "")
-
-        val configBuilder =
-            TraceConfig.newBuilder()
-                .setDurationMs(0)
-                .addBuffers(
-                    TraceConfig.BufferConfig.newBuilder().setSizeKb(TRACE_BUFFER_SIZE_KB).build()
-                )
-
-        if (isLayersTraceEnabled) {
-            configBuilder.addDataSources(createLayersTraceDataSourceConfig())
-        }
-
-        if (isLayersDumpEnabled) {
-            configBuilder.addDataSources(createLayersDumpDataSourceConfig())
-        }
-
-        if (isTransactionsTraceEnabled) {
-            configBuilder.addDataSources(createTransactionsDataSourceConfig())
-        }
-
-        val config = configBuilder.build()
-
-        FileOutputStream(tempConfigFile).use { config.writeTo(it) }
-        executeShellCommand(
-            "cp ${tempConfigFile?.absolutePath} ${PERFETTO_CONFIGS_DIR.absolutePath}"
-        )
-
-        val command =
-            "perfetto --background-wait" +
-                " --config ${PERFETTO_CONFIGS_DIR.absolutePath}/${tempConfigFile?.name}" +
-                " --out ${PERFETTO_TRACES_DIR.absolutePath}/${traceFile?.name}"
-        val stdout = String(executeShellCommand(command))
-        val pid = stdout.trim().toInt()
-        perfettoPid = pid
-        allPerfettoPidsLock.lock()
-        try {
-            allPerfettoPids.add(pid)
-        } finally {
-            allPerfettoPidsLock.unlock()
-        }
-    }
-
-    override fun doStop(): File {
-        require(isEnabled) { "Attempted to stop disabled trace monitor" }
-        killPerfettoProcess(perfettoPid!!)
-        waitPerfettoProcessExits(perfettoPid!!)
-        executeShellCommand("rm ${PERFETTO_CONFIGS_DIR.absolutePath}/${tempConfigFile?.name}")
-        executeShellCommand(
-            "mv ${PERFETTO_TRACES_DIR.absolutePath}/${traceFile?.name} ${traceFile?.absolutePath}"
-        )
-        perfettoPid = null
-        return traceFile!!
-    }
-
-    private fun createLayersTraceDataSourceConfig(): TraceConfig.DataSource {
-        return TraceConfig.DataSource.newBuilder()
-            .setConfig(
-                DataSourceConfig.newBuilder()
-                    .setName(SF_LAYERS_DATA_SOURCE)
-                    .setSurfaceflingerLayersConfig(
-                        SurfaceFlingerLayersConfig.newBuilder()
-                            .setMode(SurfaceFlingerLayersConfig.Mode.MODE_ACTIVE)
-                            .apply { layersTraceFlags.forEach { addTraceFlags(it) } }
-                            .build()
-                    )
-                    .build()
-            )
-            .build()
-    }
-
-    private fun createLayersDumpDataSourceConfig(): TraceConfig.DataSource {
-        return TraceConfig.DataSource.newBuilder()
-            .setConfig(
-                DataSourceConfig.newBuilder()
-                    .setName(SF_LAYERS_DATA_SOURCE)
-                    .setSurfaceflingerLayersConfig(
-                        SurfaceFlingerLayersConfig.newBuilder()
-                            .setMode(SurfaceFlingerLayersConfig.Mode.MODE_DUMP)
-                            .apply { layersDumpFlags.forEach { addTraceFlags(it) } }
-                            .build()
-                    )
-                    .build()
-            )
-            .build()
-    }
-
-    private fun createTransactionsDataSourceConfig(): TraceConfig.DataSource {
-        return TraceConfig.DataSource.newBuilder()
-            .setConfig(
-                DataSourceConfig.newBuilder()
-                    .setName(SF_TRANSACTIONS_DATA_SOURCE)
-                    .setSurfaceflingerTransactionsConfig(
-                        SurfaceFlingerTransactionsConfig.newBuilder()
-                            .setMode(SurfaceFlingerTransactionsConfig.Mode.MODE_ACTIVE)
-                            .build()
-                    )
-                    .build()
-            )
-            .build()
-    }
-
-    companion object {
-        private const val TRACE_BUFFER_SIZE_KB = 1024 * 1024
-
-        private const val SF_LAYERS_DATA_SOURCE = "android.surfaceflinger.layers"
-        private const val SF_TRANSACTIONS_DATA_SOURCE = "android.surfaceflinger.transactions"
-
-        private val allPerfettoPids = mutableListOf<Int>()
-        private val allPerfettoPidsLock = ReentrantLock()
-
-        fun stopAllSessions() {
-            allPerfettoPidsLock.lock()
-            try {
-                allPerfettoPids.forEach { killPerfettoProcess(it) }
-                allPerfettoPids.forEach { waitPerfettoProcessExits(it) }
-            } finally {
-                allPerfettoPidsLock.unlock()
-            }
-        }
-
-        fun killPerfettoProcess(pid: Int) {
-            if (isPerfettoProcessUp(pid)) {
-                executeShellCommand("kill $pid")
-            }
-        }
-
-        private fun waitPerfettoProcessExits(pid: Int) {
-            while (true) {
-                if (!isPerfettoProcessUp(pid)) {
-                    break
-                }
-                Thread.sleep(50)
-            }
-        }
-
-        private fun isPerfettoProcessUp(pid: Int): Boolean {
-            val out = String(executeShellCommand("ps -p $pid -o CMD"))
-            return out.contains("perfetto")
-        }
-    }
-}
diff --git a/libraries/flicker/utils/src/android/tools/device/traces/monitors/surfaceflinger/LayersTraceMonitor.kt b/libraries/flicker/utils/src/android/tools/device/traces/monitors/surfaceflinger/LayersTraceMonitor.kt
new file mode 100644
index 0000000..5639e26
--- /dev/null
+++ b/libraries/flicker/utils/src/android/tools/device/traces/monitors/surfaceflinger/LayersTraceMonitor.kt
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.tools.device.traces.monitors.surfaceflinger
+
+import android.tools.common.io.TraceType
+import android.tools.common.io.WINSCOPE_EXT
+import android.tools.common.traces.surfaceflinger.LayersTrace
+import android.tools.device.traces.monitors.TraceMonitor
+import android.view.WindowManagerGlobal
+import java.io.File
+
+/** Captures [LayersTrace] from SurfaceFlinger. */
+open class LayersTraceMonitor @JvmOverloads constructor(private val traceFlags: Int = TRACE_FLAGS) :
+    TraceMonitor() {
+    private val windowManager =
+        WindowManagerGlobal.getWindowManagerService() ?: error("Unable to acquire WindowManager")
+    override val traceType = TraceType.SF
+    override val isEnabled
+        get() = windowManager.isLayerTracing
+
+    override fun doStart() {
+        windowManager.setLayerTracingFlags(traceFlags)
+        windowManager.isLayerTracing = true
+    }
+
+    override fun doStop(): File {
+        windowManager.isLayerTracing = false
+        return TRACE_DIR.resolve("layers_trace$WINSCOPE_EXT")
+    }
+
+    companion object {
+        const val TRACE_FLAGS = 0x47 // TRACE_CRITICAL|TRACE_INPUT|TRACE_COMPOSITION|TRACE_SYNC
+    }
+}
diff --git a/libraries/flicker/utils/src/android/tools/device/traces/monitors/surfaceflinger/TransactionsTraceMonitor.kt b/libraries/flicker/utils/src/android/tools/device/traces/monitors/surfaceflinger/TransactionsTraceMonitor.kt
new file mode 100644
index 0000000..9818607
--- /dev/null
+++ b/libraries/flicker/utils/src/android/tools/device/traces/monitors/surfaceflinger/TransactionsTraceMonitor.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.tools.device.traces.monitors.surfaceflinger
+
+import android.tools.common.io.TraceType
+import android.tools.common.io.WINSCOPE_EXT
+import android.tools.common.traces.surfaceflinger.TransactionsTrace
+import android.tools.device.traces.monitors.TraceMonitor
+import android.view.WindowManagerGlobal
+import java.io.File
+
+/** Captures [TransactionsTrace] from SurfaceFlinger. */
+open class TransactionsTraceMonitor : TraceMonitor() {
+    private val windowManager =
+        WindowManagerGlobal.getWindowManagerService() ?: error("Unable to acquire WindowManager")
+    override val isEnabled = true
+    override val traceType = TraceType.TRANSACTION
+
+    override fun doStart() {
+        windowManager.setActiveTransactionTracing(true)
+    }
+
+    override fun validateStart() {
+        // No validation required
+    }
+
+    override fun doStop(): File {
+        windowManager.setActiveTransactionTracing(false)
+        return TRACE_DIR.resolve("transactions_trace$WINSCOPE_EXT")
+    }
+}
diff --git a/libraries/flicker/utils/src/android/tools/device/traces/parsers/DeviceDumpParser.kt b/libraries/flicker/utils/src/android/tools/device/traces/parsers/DeviceDumpParser.kt
index bc21588..c90468e 100644
--- a/libraries/flicker/utils/src/android/tools/device/traces/parsers/DeviceDumpParser.kt
+++ b/libraries/flicker/utils/src/android/tools/device/traces/parsers/DeviceDumpParser.kt
@@ -24,8 +24,7 @@
 import android.tools.common.traces.surfaceflinger.LayersTrace
 import android.tools.common.traces.wm.WindowManagerState
 import android.tools.common.traces.wm.WindowManagerTrace
-import android.tools.device.traces.parsers.perfetto.LayersTraceParser
-import android.tools.device.traces.parsers.perfetto.TraceProcessorSession
+import android.tools.device.traces.parsers.surfaceflinger.LayersTraceParser
 import android.tools.device.traces.parsers.wm.WindowManagerDumpParser
 import android.tools.device.traces.parsers.wm.WindowManagerTraceParser
 
@@ -67,12 +66,10 @@
                         },
                     layerState =
                         if (layersTraceData.isNotEmpty()) {
-                            TraceProcessorSession.loadPerfettoTrace(layersTraceData) { session ->
-                                LayersTraceParser()
-                                    .parse(session, clearCache = clearCacheAfterParsing)
-                                    .entries
-                                    .getOrNull(0)
-                            }
+                            LayersTraceParser()
+                                .parse(layersTraceData, clearCache = clearCacheAfterParsing)
+                                .entries
+                                .first()
                         } else {
                             null
                         }
@@ -126,9 +123,7 @@
                         },
                     layersTrace =
                         if (layersTraceData.isNotEmpty()) {
-                            TraceProcessorSession.loadPerfettoTrace(layersTraceData) { session ->
-                                LayersTraceParser().parse(session, clearCache = clearCache)
-                            }
+                            LayersTraceParser().parse(layersTraceData, clearCache = clearCache)
                         } else {
                             null
                         }
diff --git a/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/Args.kt b/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/Args.kt
index fe98f6e..c2e7208 100644
--- a/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/Args.kt
+++ b/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/Args.kt
@@ -146,7 +146,7 @@
                 val key = it.get("key")
                 val value = it.get("value")
                 val valueType = it.get("value_type")
-                if (valueType != "null" && value != null) {
+                if (valueType != "null") {
                     args.add(key as String, value as String, valueType as String)
                 }
             }
diff --git a/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/LayersTraceParser.kt b/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/LayersTraceParser.kt
index 16a433e..0450e9a 100644
--- a/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/LayersTraceParser.kt
+++ b/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/LayersTraceParser.kt
@@ -16,7 +16,6 @@
 
 package android.tools.device.traces.parsers.perfetto
 
-import android.tools.common.Logger
 import android.tools.common.Timestamp
 import android.tools.common.datatypes.ActiveBuffer
 import android.tools.common.datatypes.Color
@@ -55,26 +54,17 @@
     override fun shouldParseEntry(entry: LayerTraceEntry) = true
 
     override fun getEntries(session: TraceProcessorSession): List<LayerTraceEntry> {
-        val realToMonotonicTimeOffsetNs =
-            queryRealToMonotonicTimeOffsetNs(session, "surfaceflinger_layers_snapshot")
+        val realToMonotonicTimeOffsetNs = queryRealToMonotonicTimeOffsetNs(session)
 
         return session.query(getSqlQuerySnapshots()) { snapshotsRows ->
             val traceEntries = ArrayList<LayerTraceEntry>()
             val snapshotGroups = snapshotsRows.groupBy { it.get("snapshot_id") }
 
             for (snapshotId in 0L..(snapshotGroups.size - 1)) {
-                Logger.withTracing("query + build entry") {
-                    val layerRows =
-                        Logger.withTracing("query layer rows") {
-                            session.query(getSqlQueryLayers(snapshotId)) { it }
-                        }
-                    Logger.withTracing("build entry") {
-                        val snapshotRows = snapshotGroups[snapshotId]!!
-                        val entry =
-                            buildTraceEntry(snapshotRows, layerRows, realToMonotonicTimeOffsetNs)
-                        traceEntries.add(entry)
-                    }
-                }
+                val layerRows = session.query(getSqlQueryLayers(snapshotId)) { it }
+                val snapshotRows = snapshotGroups[snapshotId]!!
+                val entry = buildTraceEntry(snapshotRows, layerRows, realToMonotonicTimeOffsetNs)
+                traceEntries.add(entry)
             }
 
             traceEntries
@@ -123,6 +113,36 @@
     }
 
     companion object {
+        private fun queryRealToMonotonicTimeOffsetNs(session: TraceProcessorSession): Long {
+            val monotonic = queryLastClockSnapshot(session, "MONOTONIC")
+            val real = queryLastClockSnapshot(session, "REALTIME")
+            return real - monotonic
+        }
+
+        private fun queryLastClockSnapshot(
+            session: TraceProcessorSession,
+            clockName: String
+        ): Long {
+            val sql =
+                """
+                SELECT
+                    snapshot_id, clock_name, clock_value
+                FROM clock_snapshot
+                WHERE
+                    snapshot_id = ( SELECT MAX(snapshot_id) FROM clock_snapshot )
+                    AND clock_name = '$clockName';
+            """
+                    .trimIndent()
+            val value =
+                session.query(sql) { rows ->
+                    require(rows.size == 1) {
+                        "Perfetto trace expected to contain at least one clock snapshot"
+                    }
+                    rows.get(0).get("clock_value") as Long
+                }
+            return value
+        }
+
         private fun getSqlQuerySnapshots(): String {
             return """
                 SELECT
diff --git a/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/TraceProcessorSession.kt b/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/TraceProcessorSession.kt
index 4f7643d..0b5dcc7 100644
--- a/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/TraceProcessorSession.kt
+++ b/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/TraceProcessorSession.kt
@@ -21,7 +21,6 @@
 
 package android.tools.device.traces.parsers.perfetto
 
-import android.tools.common.Logger
 import android.tools.common.io.TraceType
 import androidx.benchmark.perfetto.PerfettoTrace
 import androidx.benchmark.perfetto.PerfettoTraceProcessor
@@ -38,25 +37,21 @@
     }
 
     fun <T> query(sql: String, predicate: (List<Row>) -> T): T {
-        return Logger.withTracing("TraceProcessorSession#query") {
-            val rows = session.query(sql)
-            predicate(rows.toList())
-        }
+        val rows = session.query(sql)
+        return predicate(rows.toList())
     }
 
     companion object {
         fun <T> loadPerfettoTrace(trace: ByteArray, predicate: (TraceProcessorSession) -> T): T {
-            return Logger.withTracing("TraceProcessorSession#loadPerfettoTrace") {
-                val traceFile = File.createTempFile(TraceType.SF.fileName, "")
-                FileOutputStream(traceFile).use { it.write(trace) }
-                val result =
-                    PerfettoTraceProcessor.runServer {
-                        loadTrace(PerfettoTrace(traceFile.absolutePath)) {
-                            predicate(TraceProcessorSession(this))
-                        }
+            val traceFile = File.createTempFile(TraceType.SF.fileName, "")
+            FileOutputStream(traceFile).use { it.write(trace) }
+            val result =
+                PerfettoTraceProcessor.runServer {
+                    loadTrace(PerfettoTrace(traceFile.absolutePath)) {
+                        predicate(TraceProcessorSession(this))
                     }
-                result
-            }
+                }
+            return result
         }
     }
 }
diff --git a/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/TransactionsTraceParser.kt b/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/TransactionsTraceParser.kt
deleted file mode 100644
index be899d4..0000000
--- a/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/TransactionsTraceParser.kt
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.tools.device.traces.parsers.perfetto
-
-import android.tools.common.CrossPlatform
-import android.tools.common.Timestamp
-import android.tools.common.parsers.AbstractTraceParser
-import android.tools.common.traces.surfaceflinger.Transaction
-import android.tools.common.traces.surfaceflinger.TransactionsTrace
-import android.tools.common.traces.surfaceflinger.TransactionsTraceEntry
-import kotlin.math.min
-
-/** Parser for [TransactionsTrace] */
-class TransactionsTraceParser :
-    AbstractTraceParser<
-        TraceProcessorSession, TransactionsTraceEntry, TransactionsTraceEntry, TransactionsTrace
-    >() {
-
-    override val traceName = "Layers trace (SF)"
-
-    override fun createTrace(entries: List<TransactionsTraceEntry>): TransactionsTrace {
-        return TransactionsTrace(entries.toTypedArray())
-    }
-
-    override fun doDecodeByteArray(bytes: ByteArray): TraceProcessorSession {
-        error("This parser can only read from perfetto trace processor")
-    }
-
-    override fun shouldParseEntry(entry: TransactionsTraceEntry) = true
-
-    override fun getEntries(session: TraceProcessorSession): List<TransactionsTraceEntry> {
-        val traceEntries = ArrayList<TransactionsTraceEntry>()
-
-        val realToMonotonicTimeOffsetNs =
-            queryRealToMonotonicTimeOffsetNs(session, "surfaceflinger_transactions")
-        val entriesCount = queryTraceEntriesCount(session)
-
-        for (startEntryId in 0L..(entriesCount - 1) step BATCH_SIZE) {
-            val endEntryId = min(startEntryId + BATCH_SIZE, entriesCount)
-
-            val batchRows = session.query(getSqlQueryTransactions(startEntryId, endEntryId)) { it }
-            val entryGroups = batchRows.groupBy { it.get("trace_entry_id") }
-
-            for (entryId in startEntryId..(endEntryId - 1)) {
-                val rows = entryGroups[entryId]!!
-                val entry = buildTraceEntry(rows, realToMonotonicTimeOffsetNs)
-                traceEntries.add(entry)
-            }
-        }
-
-        return traceEntries
-    }
-
-    override fun getTimestamp(entry: TransactionsTraceEntry): Timestamp = entry.timestamp
-
-    override fun onBeforeParse(input: TraceProcessorSession) {}
-
-    override fun doParseEntry(entry: TransactionsTraceEntry) = entry
-
-    companion object {
-        private const val BATCH_SIZE = 200L
-
-        private fun queryTraceEntriesCount(session: TraceProcessorSession): Long {
-            val sql =
-                """
-                SELECT count(*) FROM surfaceflinger_transactions;
-            """
-                    .trimIndent()
-            return session.query(sql) { rows ->
-                require(rows.size == 1) { "Expected one row with count of trace entries." }
-                rows.get(0).get("count(*)") as Long
-            }
-        }
-
-        private fun getSqlQueryTransactions(startEntryId: Long, endEntryId: Long): String {
-            return """
-               SELECT sft.id AS trace_entry_id, args.key, args.display_value AS value, args.value_type
-               FROM surfaceflinger_transactions AS sft
-               INNER JOIN args ON sft.arg_set_id = args.arg_set_id
-               WHERE trace_entry_id BETWEEN $startEntryId AND ${endEntryId - 1};
-            """
-                .trimIndent()
-        }
-
-        private fun buildTraceEntry(
-            rows: List<Row>,
-            realToMonotonicTimeOffsetNs: Long
-        ): TransactionsTraceEntry {
-            val args = Args.build(rows)
-            val transactions: Array<Transaction> =
-                args
-                    .getChildren("transactions")
-                    ?.map { transaction ->
-                        Transaction(
-                            transaction.getChild("pid")?.getInt() ?: -1,
-                            transaction.getChild("uid")?.getInt() ?: -1,
-                            transaction.getChild("vsync_id")?.getLong() ?: -1,
-                            transaction.getChild("post_time")?.getLong() ?: -1,
-                            transaction.getChild("transaction_id")?.getLong() ?: -1,
-                            transaction
-                                .getChildren("merged_transaction_ids")
-                                ?.map { it.getLong() }
-                                ?.toTypedArray()
-                                ?: arrayOf()
-                        )
-                    }
-                    ?.toTypedArray()
-                    ?: arrayOf()
-
-            val traceEntry =
-                TransactionsTraceEntry(
-                    CrossPlatform.timestamp.from(
-                        elapsedNanos = args.getChild("elapsed_realtime_nanos")?.getLong() ?: 0,
-                        elapsedOffsetNanos = realToMonotonicTimeOffsetNs
-                    ),
-                    args.getChild("vsync_id")?.getLong() ?: -1,
-                    transactions
-                )
-
-            transactions.forEach { it.appliedInEntry = traceEntry }
-
-            return traceEntry
-        }
-    }
-}
diff --git a/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/Utils.kt b/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/Utils.kt
deleted file mode 100644
index a6b5970..0000000
--- a/libraries/flicker/utils/src/android/tools/device/traces/parsers/perfetto/Utils.kt
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.tools.device.traces.parsers.perfetto
-
-fun queryRealToMonotonicTimeOffsetNs(session: TraceProcessorSession, tableName: String): Long {
-    val elapsed = queryLastEntryTimestamp(session, tableName)
-    if (elapsed == null) {
-        return 0L
-    }
-    val monotonic = queryToMonotonic(session, elapsed)
-    val real = queryToRealtime(session, elapsed)
-    return real - monotonic
-}
-
-fun queryLastEntryTimestamp(session: TraceProcessorSession, tableName: String): Long? {
-    val sql =
-        """
-                SELECT
-                    ts
-                FROM $tableName
-                WHERE
-                    id = ( SELECT MAX(id) FROM $tableName );
-            """
-            .trimIndent()
-    val value =
-        session.query(sql) { rows ->
-            if (rows.size == 1) {
-                rows.get(0).get("ts") as Long
-            } else {
-                null
-            }
-        }
-    return value
-}
-
-fun queryToMonotonic(session: TraceProcessorSession, elapsedTimestamp: Long): Long {
-    val sql = "SELECT TO_MONOTONIC($elapsedTimestamp) as ts;"
-    val value =
-        session.query(sql) { rows ->
-            require(rows.size == 1)
-            rows.get(0).get("ts") as Long
-        }
-    return value
-}
-
-fun queryToRealtime(session: TraceProcessorSession, elapsedTimestamp: Long): Long {
-    val sql = "SELECT TO_REALTIME($elapsedTimestamp) as ts;"
-    val value =
-        session.query(sql) { rows ->
-            require(rows.size == 1)
-            rows.get(0).get("ts") as Long
-        }
-    return value
-}
diff --git a/libraries/flicker/utils/src/android/tools/device/traces/parsers/surfaceflinger/LayersTraceParser.kt b/libraries/flicker/utils/src/android/tools/device/traces/parsers/surfaceflinger/LayersTraceParser.kt
new file mode 100644
index 0000000..31950aa
--- /dev/null
+++ b/libraries/flicker/utils/src/android/tools/device/traces/parsers/surfaceflinger/LayersTraceParser.kt
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.tools.device.traces.parsers.surfaceflinger
+
+import android.surfaceflinger.Common
+import android.surfaceflinger.Display
+import android.surfaceflinger.Layers
+import android.surfaceflinger.Layerstrace
+import android.tools.common.Timestamp
+import android.tools.common.Timestamps
+import android.tools.common.datatypes.ActiveBuffer
+import android.tools.common.datatypes.Color
+import android.tools.common.datatypes.Matrix33
+import android.tools.common.datatypes.Rect
+import android.tools.common.datatypes.RectF
+import android.tools.common.datatypes.Region
+import android.tools.common.datatypes.Size
+import android.tools.common.parsers.AbstractTraceParser
+import android.tools.common.traces.surfaceflinger.HwcCompositionType
+import android.tools.common.traces.surfaceflinger.Layer
+import android.tools.common.traces.surfaceflinger.LayerTraceEntry
+import android.tools.common.traces.surfaceflinger.LayerTraceEntryBuilder
+import android.tools.common.traces.surfaceflinger.LayersTrace
+import android.tools.common.traces.surfaceflinger.Transform
+import android.tools.common.traces.surfaceflinger.Transform.Companion.isFlagClear
+import android.tools.common.traces.surfaceflinger.Transform.Companion.isFlagSet
+
+/** Parser for [LayersTrace] objects containing traces or state dumps */
+class LayersTraceParser(
+    private val ignoreLayersStackMatchNoDisplay: Boolean = true,
+    private val ignoreLayersInVirtualDisplay: Boolean = true,
+    private val legacyTrace: Boolean = false,
+    private val orphanLayerCallback: ((Layer) -> Boolean)? = null,
+) :
+    AbstractTraceParser<
+        Layerstrace.LayersTraceFileProto, Layerstrace.LayersTraceProto, LayerTraceEntry, LayersTrace
+    >() {
+    private var realToElapsedTimeOffsetNanos = 0L
+
+    override val traceName: String = "Layers Trace"
+
+    override fun doDecodeByteArray(bytes: ByteArray): Layerstrace.LayersTraceFileProto =
+        Layerstrace.LayersTraceFileProto.parseFrom(bytes)
+
+    override fun createTrace(entries: List<LayerTraceEntry>): LayersTrace =
+        LayersTrace(entries.toTypedArray())
+
+    override fun getEntries(
+        input: Layerstrace.LayersTraceFileProto
+    ): List<Layerstrace.LayersTraceProto> = input.entryList
+
+    override fun getTimestamp(entry: Layerstrace.LayersTraceProto): Timestamp {
+        require(legacyTrace || realToElapsedTimeOffsetNanos != 0L)
+        return Timestamps.from(
+            systemUptimeNanos = entry.elapsedRealtimeNanos,
+            unixNanos = entry.elapsedRealtimeNanos + realToElapsedTimeOffsetNanos
+        )
+    }
+
+    override fun onBeforeParse(input: Layerstrace.LayersTraceFileProto) {
+        realToElapsedTimeOffsetNanos = input.realToElapsedTimeOffsetNanos
+    }
+
+    override fun doParseEntry(entry: Layerstrace.LayersTraceProto): LayerTraceEntry {
+        val layers = entry.layers.layersList.map { newLayer(it) }.toTypedArray()
+        val displays = entry.displaysList.map { newDisplay(it) }.toTypedArray()
+        val builder =
+            LayerTraceEntryBuilder()
+                .setElapsedTimestamp(entry.elapsedRealtimeNanos.toString())
+                .setLayers(layers)
+                .setDisplays(displays)
+                .setVSyncId(entry.vsyncId.toString())
+                .setHwcBlob(entry.hwcBlob)
+                .setWhere(entry.where)
+                .setRealToElapsedTimeOffsetNs(realToElapsedTimeOffsetNanos.toString())
+                .setOrphanLayerCallback(orphanLayerCallback)
+                .ignoreLayersStackMatchNoDisplay(ignoreLayersStackMatchNoDisplay)
+                .ignoreVirtualDisplay(ignoreLayersInVirtualDisplay)
+        return builder.build()
+    }
+
+    companion object {
+        private fun newLayer(
+            proto: Layers.LayerProto,
+            excludeCompositionState: Boolean = false
+        ): Layer {
+            // Differentiate between the cases when there's no HWC data on
+            // the trace, and when the visible region is actually empty
+            val activeBuffer = proto.activeBuffer.toBuffer()
+            val visibleRegion = proto.visibleRegion.toRegion() ?: Region.EMPTY
+            val crop = proto.crop?.toCropRect()
+            return Layer.from(
+                proto.name ?: "",
+                proto.id,
+                proto.parent,
+                proto.z,
+                visibleRegion,
+                activeBuffer,
+                proto.flags,
+                proto.bounds?.toRectF() ?: RectF.EMPTY,
+                proto.color.toColor(),
+                proto.isOpaque,
+                proto.shadowRadius,
+                proto.cornerRadius,
+                proto.screenBounds?.toRectF() ?: RectF.EMPTY,
+                createTransformFromProto(proto.transform, proto.position),
+                proto.currFrame,
+                proto.effectiveScalingMode,
+                createTransformFromProto(proto.bufferTransform, position = null),
+                toHwcCompositionType(proto.hwcCompositionType),
+                proto.backgroundBlurRadius,
+                crop,
+                proto.isRelativeOf,
+                proto.zOrderRelativeOf,
+                proto.layerStack,
+                excludeCompositionState
+            )
+        }
+
+        private fun newDisplay(
+            proto: Display.DisplayProto
+        ): android.tools.common.traces.surfaceflinger.Display {
+            return android.tools.common.traces.surfaceflinger.Display.from(
+                "${proto.id}",
+                proto.name,
+                proto.layerStack,
+                proto.size.toSize(),
+                proto.layerStackSpaceRect.toRect(),
+                createTransformFromProto(proto.transform, position = null),
+                proto.isVirtual
+            )
+        }
+
+        private fun Layers.FloatRectProto?.toRectF(): RectF? {
+            return this?.let { RectF.from(left = left, top = top, right = right, bottom = bottom) }
+        }
+
+        private fun Common.SizeProto?.toSize(): Size {
+            return this?.let { Size.from(this.w, this.h) } ?: Size.EMPTY
+        }
+
+        private fun Common.ColorProto?.toColor(): Color {
+            return this?.let { Color.from(r, g, b, a) } ?: Color.EMPTY
+        }
+
+        private fun Layers.ActiveBufferProto?.toBuffer(): ActiveBuffer {
+            return this?.let { ActiveBuffer.from(width, height, stride, format) }
+                ?: ActiveBuffer.EMPTY
+        }
+
+        private fun toHwcCompositionType(value: Layers.HwcCompositionType): HwcCompositionType {
+            return when (value) {
+                Layers.HwcCompositionType.INVALID -> HwcCompositionType.HWC_TYPE_UNSPECIFIED
+                Layers.HwcCompositionType.CLIENT -> HwcCompositionType.HWC_TYPE_CLIENT
+                Layers.HwcCompositionType.DEVICE -> HwcCompositionType.HWC_TYPE_DEVICE
+                Layers.HwcCompositionType.SOLID_COLOR -> HwcCompositionType.HWC_TYPE_SOLID_COLOR
+                Layers.HwcCompositionType.CURSOR -> HwcCompositionType.HWC_TYPE_CURSOR
+                Layers.HwcCompositionType.SIDEBAND -> HwcCompositionType.HWC_TYPE_SIDEBAND
+                else -> HwcCompositionType.HWC_TYPE_UNRECOGNIZED
+            }
+        }
+
+        private fun Common.RectProto?.toCropRect(): Rect? {
+            return when {
+                this == null -> Rect.EMPTY
+                // crop (0,0) (-1,-1) means no crop
+                right == -1 && left == 0 && bottom == -1 && top == 0 -> null
+                (right - left) <= 0 || (bottom - top) <= 0 -> Rect.EMPTY
+                else -> Rect.from(left, top, right, bottom)
+            }
+        }
+
+        /**
+         * Extracts [Rect] from [Common.RegionProto] by returning a rect that encompasses all the
+         * rectangles making up the region.
+         */
+        private fun Common.RegionProto?.toRegion(): Region? {
+            return this?.let {
+                val rectArray = this.rectList.map { it.toRect() }.toTypedArray()
+                return Region(rectArray)
+            }
+        }
+
+        private fun Common.RectProto?.toRect(): Rect =
+            Rect.from(this?.left ?: 0, this?.top ?: 0, this?.right ?: 0, this?.bottom ?: 0)
+
+        fun createTransformFromProto(
+            transform: Common.TransformProto?,
+            position: Layers.PositionProto?
+        ) = Transform.from(transform?.type, getMatrix(transform, position))
+
+        private fun getMatrix(
+            transform: Common.TransformProto?,
+            position: Layers.PositionProto?
+        ): Matrix33 {
+            val x = position?.x ?: 0f
+            val y = position?.y ?: 0f
+
+            return when {
+                transform == null || Transform.isSimpleTransform(transform.type) ->
+                    transform?.type.getDefaultTransform(x, y)
+                else ->
+                    Matrix33.from(
+                        transform.dsdx,
+                        transform.dtdx,
+                        x,
+                        transform.dsdy,
+                        transform.dtdy,
+                        y
+                    )
+            }
+        }
+
+        private fun Int?.getDefaultTransform(x: Float, y: Float): Matrix33 {
+            return when {
+                // IDENTITY
+                this == null -> Matrix33.identity(x, y)
+                // // ROT_270 = ROT_90|FLIP_H|FLIP_V
+                isFlagSet(Transform.ROT_90_VAL or Transform.FLIP_V_VAL or Transform.FLIP_H_VAL) ->
+                    Matrix33.rot270(x, y)
+                // ROT_180 = FLIP_H|FLIP_V
+                isFlagSet(Transform.FLIP_V_VAL or Transform.FLIP_H_VAL) -> Matrix33.rot180(x, y)
+                // ROT_90
+                isFlagSet(Transform.ROT_90_VAL) -> Matrix33.rot90(x, y)
+                // IDENTITY
+                isFlagClear(Transform.SCALE_VAL or Transform.ROTATE_VAL) -> Matrix33.identity(x, y)
+                else -> throw IllegalStateException("Unknown transform type $this")
+            }
+        }
+    }
+}
diff --git a/libraries/flicker/utils/src/android/tools/device/traces/parsers/surfaceflinger/TransactionsTraceParser.kt b/libraries/flicker/utils/src/android/tools/device/traces/parsers/surfaceflinger/TransactionsTraceParser.kt
new file mode 100644
index 0000000..5e69665
--- /dev/null
+++ b/libraries/flicker/utils/src/android/tools/device/traces/parsers/surfaceflinger/TransactionsTraceParser.kt
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.tools.device.traces.parsers.surfaceflinger
+
+import android.surfaceflinger.proto.Transactions
+import android.surfaceflinger.proto.Transactions.TransactionState
+import android.surfaceflinger.proto.Transactions.TransactionTraceFile
+import android.tools.common.Timestamp
+import android.tools.common.Timestamps
+import android.tools.common.parsers.AbstractTraceParser
+import android.tools.common.traces.surfaceflinger.Transaction
+import android.tools.common.traces.surfaceflinger.TransactionsTrace
+import android.tools.common.traces.surfaceflinger.TransactionsTraceEntry
+import android.tools.common.traces.wm.TransitionsTrace
+
+/** Parser for [TransitionsTrace] objects */
+class TransactionsTraceParser :
+    AbstractTraceParser<
+        TransactionTraceFile,
+        Transactions.TransactionTraceEntry,
+        TransactionsTraceEntry,
+        TransactionsTrace
+    >() {
+    private var timestampOffset = 0L
+    override val traceName: String = "Transactions trace"
+
+    override fun onBeforeParse(input: TransactionTraceFile) {
+        timestampOffset = input.realToElapsedTimeOffsetNanos
+    }
+
+    override fun getTimestamp(entry: Transactions.TransactionTraceEntry): Timestamp {
+        require(timestampOffset != 0L)
+        return Timestamps.from(
+            elapsedNanos = entry.elapsedRealtimeNanos,
+            unixNanos = entry.elapsedRealtimeNanos + timestampOffset
+        )
+    }
+
+    override fun createTrace(entries: List<TransactionsTraceEntry>): TransactionsTrace =
+        TransactionsTrace(entries.toTypedArray())
+
+    override fun getEntries(input: TransactionTraceFile): List<Transactions.TransactionTraceEntry> =
+        input.entryList
+
+    override fun doDecodeByteArray(bytes: ByteArray): TransactionTraceFile =
+        TransactionTraceFile.parseFrom(bytes)
+
+    override fun doParseEntry(entry: Transactions.TransactionTraceEntry): TransactionsTraceEntry {
+        val transactions = parseTransactionsProto(entry.transactionsList)
+        val transactionsTraceEntry =
+            TransactionsTraceEntry(
+                Timestamps.from(
+                    elapsedNanos = entry.elapsedRealtimeNanos,
+                    elapsedOffsetNanos = timestampOffset
+                ),
+                entry.vsyncId,
+                transactions
+            )
+        transactions.forEach { it.appliedInEntry = transactionsTraceEntry }
+        return transactionsTraceEntry
+    }
+
+    private fun parseTransactionsProto(
+        transactionStates: List<TransactionState>
+    ): Array<Transaction> {
+        val transactions = mutableListOf<Transaction>()
+        for (state in transactionStates) {
+            val transaction =
+                Transaction(
+                    state.pid,
+                    state.uid,
+                    state.vsyncId,
+                    state.postTime,
+                    state.transactionId,
+                    state.mergedTransactionIdsList.toTypedArray()
+                )
+            transactions.add(transaction)
+        }
+
+        return transactions.toTypedArray()
+    }
+}
diff --git a/libraries/flicker/utils/test/Android.bp b/libraries/flicker/utils/test/Android.bp
index 19e082f..348ff5f 100644
--- a/libraries/flicker/utils/test/Android.bp
+++ b/libraries/flicker/utils/test/Android.bp
@@ -60,7 +60,6 @@
     static_libs: [
         "flickerlib-parsers",
         "flickerlib-apphelpers",
-        "flickerlib-trace_processor_shell",
         "FlickerLibTest-Utils",
         "androidx.test.runner",
         "truth-prebuilt",
diff --git a/libraries/flicker/utils/test/AndroidManifest.xml b/libraries/flicker/utils/test/AndroidManifest.xml
index c733105..b942915 100644
--- a/libraries/flicker/utils/test/AndroidManifest.xml
+++ b/libraries/flicker/utils/test/AndroidManifest.xml
@@ -18,9 +18,6 @@
     <uses-permission android:name="android.permission.DUMP" />
     <!-- Allow the test to write directly to /sdcard/ -->
     <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
-    <!-- Allow the test to connect to perfetto trace processor -->
-    <uses-permission android:name="android.permission.INTERNET"/>
-
 
     <uses-sdk android:minSdkVersion="29" android:targetSdkVersion="29"/>
     <application android:label="FlickerLibUtilsTest"
diff --git a/libraries/flicker/utils/test/assets/trace_processor_shell_aarch64 b/libraries/flicker/utils/test/assets/trace_processor_shell_aarch64
new file mode 100755
index 0000000..a672999
--- /dev/null
+++ b/libraries/flicker/utils/test/assets/trace_processor_shell_aarch64
Binary files differ
diff --git a/libraries/flicker/utils/test/assets/trace_processor_shell_x86 b/libraries/flicker/utils/test/assets/trace_processor_shell_x86
new file mode 100755
index 0000000..b454559
--- /dev/null
+++ b/libraries/flicker/utils/test/assets/trace_processor_shell_x86
Binary files differ
diff --git a/libraries/flicker/utils/test/assets/trace_processor_shell_x86_64 b/libraries/flicker/utils/test/assets/trace_processor_shell_x86_64
new file mode 100755
index 0000000..577f7f0
--- /dev/null
+++ b/libraries/flicker/utils/test/assets/trace_processor_shell_x86_64
Binary files differ
diff --git a/libraries/flicker/utils/test/src/android/tools/common/traces/surfaceflinger/LayersTraceEntryTest.kt b/libraries/flicker/utils/test/src/android/tools/common/traces/surfaceflinger/LayersTraceEntryTest.kt
index 3dfcc02..9a7f6c6 100644
--- a/libraries/flicker/utils/test/src/android/tools/common/traces/surfaceflinger/LayersTraceEntryTest.kt
+++ b/libraries/flicker/utils/test/src/android/tools/common/traces/surfaceflinger/LayersTraceEntryTest.kt
@@ -37,7 +37,7 @@
 
     @Test
     fun canParseAllLayers() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         Truth.assertThat(trace.entries).isNotEmpty()
         Truth.assertThat(trace.entries.first().timestamp.systemUptimeNanos).isEqualTo(922839428857)
@@ -47,7 +47,8 @@
 
     @Test
     fun canParseVisibleLayersLauncher() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val visibleLayers =
             trace
@@ -65,7 +66,8 @@
 
     @Test
     fun canParseVisibleLayersSplitScreen() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val visibleLayers =
             trace
@@ -84,7 +86,8 @@
 
     @Test
     fun canParseVisibleLayersInTransition() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("layers_trace_launch_split_screen.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val visibleLayers =
             trace
@@ -107,7 +110,7 @@
 
     @Test
     fun canParseLayerHierarchy() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_emptyregion.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         Truth.assertThat(trace.entries).isNotEmpty()
         Truth.assertThat(trace.entries.first().timestamp.systemUptimeNanos).isEqualTo(922839428857)
@@ -124,8 +127,9 @@
         try {
             val reader =
                 getLayerTraceReaderFromAsset(
-                    "layers_trace_orphanlayers.perfetto-trace",
-                    ignoreOrphanLayers = false
+                    "layers_trace_orphanlayers.pb",
+                    ignoreOrphanLayers = false,
+                    legacyTrace = true
                 )
             reader.readLayersTrace()?.entries?.first()?.flattenedLayers
             error("Failed to detect orphaned layers.")
@@ -141,7 +145,8 @@
     @Test
     fun testCanParseNonCroppedLayerWithHWC() {
         val layerName = "BackColorSurface#0"
-        val reader = getLayerTraceReaderFromAsset("layers_trace_backcolorsurface.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("layers_trace_backcolorsurface.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val entry = trace.getEntryExactlyAt(Timestamps.from(systemUptimeNanos = 131954021476))
         Truth.assertWithMessage("$layerName should not be visible")
@@ -156,7 +161,8 @@
 
     @Test
     fun canParseTraceEmptyState() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_empty_state.perfetto-trace")
+        val reader =
+            getLayerTraceReaderFromAsset("layers_trace_empty_state.winscope", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val emptyStates = trace.entries.filter { it.flattenedLayers.isEmpty() }
 
diff --git a/libraries/flicker/utils/test/src/android/tools/common/traces/surfaceflinger/LayersTraceTest.kt b/libraries/flicker/utils/test/src/android/tools/common/traces/surfaceflinger/LayersTraceTest.kt
index 8baa47c..d5b833a 100644
--- a/libraries/flicker/utils/test/src/android/tools/common/traces/surfaceflinger/LayersTraceTest.kt
+++ b/libraries/flicker/utils/test/src/android/tools/common/traces/surfaceflinger/LayersTraceTest.kt
@@ -31,8 +31,8 @@
 /** Contains [LayersTrace] tests. To run this test: `atest FlickerLibTest:LayersTraceTest` */
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 class LayersTraceTest {
-    private fun detectRootLayer(fileName: String) {
-        val reader = getLayerTraceReaderFromAsset(fileName)
+    private fun detectRootLayer(fileName: String, legacyTrace: Boolean = false) {
+        val reader = getLayerTraceReaderFromAsset(fileName, legacyTrace = legacyTrace)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         for (entry in trace.entries) {
             val rootLayers = entry.children
@@ -53,17 +53,17 @@
 
     @Test
     fun testCanDetectRootLayer() {
-        detectRootLayer("layers_trace_root.perfetto-trace")
+        detectRootLayer("layers_trace_root.pb", legacyTrace = true)
     }
 
     @Test
     fun testCanDetectRootLayerAOSP() {
-        detectRootLayer("layers_trace_root_aosp.perfetto-trace")
+        detectRootLayer("layers_trace_root_aosp.pb", legacyTrace = true)
     }
 
     @Test
     fun canTestLayerOccludedByAppLayerHasVisibleRegion() {
-        val reader = getLayerTraceReaderFromAsset("layers_trace_occluded.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_occluded.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val entry = trace.getEntryExactlyAt(Timestamps.from(systemUptimeNanos = 1700382131522L))
         val component =
@@ -91,7 +91,7 @@
     fun canTestLayerOccludedByAppLayerIsOccludedBySplashScreen() {
         val layerName = "com.android.server.wm.flicker.testapp.SimpleActivity#0"
         val component = ComponentNameMatcher("", layerName)
-        val reader = getLayerTraceReaderFromAsset("layers_trace_occluded.perfetto-trace")
+        val reader = getLayerTraceReaderFromAsset("layers_trace_occluded.pb", legacyTrace = true)
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val entry = trace.getEntryExactlyAt(Timestamps.from(systemUptimeNanos = 1700382131522L))
         val layer = entry.getLayerWithBuffer(component)
@@ -113,7 +113,10 @@
     @Test
     fun getFirstEntryWithOnDisplay() {
         val reader =
-            getLayerTraceReaderFromAsset("layers_trace_unlock_and_lock_device.perfetto-trace")
+            getLayerTraceReaderFromAsset(
+                "layers_trace_unlock_and_lock_device.pb",
+                legacyTrace = false
+            )
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val matchingEntry = trace.getFirstEntryWithOnDisplayAfter(Timestamps.min())
 
@@ -130,7 +133,10 @@
     @Test
     fun getLastEntryWithOnDisplay() {
         val reader =
-            getLayerTraceReaderFromAsset("layers_trace_unlock_and_lock_device.perfetto-trace")
+            getLayerTraceReaderFromAsset(
+                "layers_trace_unlock_and_lock_device.pb",
+                legacyTrace = false
+            )
         val trace = reader.readLayersTrace() ?: error("Unable to read layers trace")
         val matchingEntry = trace.getLastEntryWithOnDisplayBefore(Timestamps.max())
 
diff --git a/libraries/flicker/utils/test/src/android/tools/device/traces/io/ResultWriterTest.kt b/libraries/flicker/utils/test/src/android/tools/device/traces/io/ResultWriterTest.kt
index d09202f..89d9f2a 100644
--- a/libraries/flicker/utils/test/src/android/tools/device/traces/io/ResultWriterTest.kt
+++ b/libraries/flicker/utils/test/src/android/tools/device/traces/io/ResultWriterTest.kt
@@ -182,12 +182,12 @@
                 .addTraceResult(TraceType.SHELL_TRANSITION, TestTraces.TransitionTrace.SHELL_FILE)
         val result = writer.write()
         val reader = ResultReader(result, TRACE_CONFIG_REQUIRE_CHANGES)
-        Truth.assertWithMessage("File count").that(reader.countFiles()).isEqualTo(4)
+        Truth.assertWithMessage("File count").that(reader.countFiles()).isEqualTo(5)
         Truth.assertWithMessage("Has file with type")
             .that(reader.hasTraceFile(TraceType.WM))
             .isTrue()
         Truth.assertWithMessage("Has file with type")
-            .that(reader.hasTraceFile(TraceType.SF))
+            .that(reader.hasTraceFile(TraceType.WM))
             .isTrue()
         Truth.assertWithMessage("Has file with type")
             .that(reader.hasTraceFile(TraceType.WM_TRANSITION))
diff --git a/libraries/flicker/utils/test/src/android/tools/device/traces/monitors/PerfettoTraceMonitorTest.kt b/libraries/flicker/utils/test/src/android/tools/device/traces/monitors/PerfettoTraceMonitorTest.kt
deleted file mode 100644
index c6f7ae6..0000000
--- a/libraries/flicker/utils/test/src/android/tools/device/traces/monitors/PerfettoTraceMonitorTest.kt
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.tools.device.traces.monitors
-
-import android.tools.common.io.TraceType
-import android.tools.device.traces.parsers.perfetto.LayersTraceParser
-import android.tools.device.traces.parsers.perfetto.TraceProcessorSession
-import android.tools.utils.CleanFlickerEnvironmentRule
-import com.google.common.truth.Truth
-import org.junit.ClassRule
-import org.junit.FixMethodOrder
-import org.junit.Test
-import org.junit.runners.MethodSorters
-
-/**
- * Contains [PerfettoTraceMonitor] tests. To run this test: `atest
- * FlickerLibTest:PerfettoTraceMonitorTest`
- */
-@FixMethodOrder(MethodSorters.NAME_ASCENDING)
-class PerfettoTraceMonitorTest : TraceMonitorTest<PerfettoTraceMonitor>() {
-    override val traceType = TraceType.SF // TODO: ???
-    override fun getMonitor() = PerfettoTraceMonitor().enableLayersTrace().enableTransactionsTrace()
-
-    override fun assertTrace(traceData: ByteArray) {
-        Truth.assertThat(traceData.size).isGreaterThan(0)
-    }
-
-    @Test
-    fun withSFTracingTest() {
-        val trace = withSFTracing {
-            device.pressHome()
-            device.pressRecentApps()
-        }
-
-        Truth.assertWithMessage("Could not obtain layers trace").that(trace.entries).isNotEmpty()
-    }
-
-    @Test
-    fun withTransactionsTracingTest() {
-        val trace = withTransactionsTracing {
-            device.pressHome()
-            device.pressRecentApps()
-        }
-
-        Truth.assertWithMessage("Could not obtain transactions trace")
-            .that(trace.entries)
-            .isNotEmpty()
-    }
-
-    @Test
-    fun layersDump() {
-        val traceData = PerfettoTraceMonitor().enableLayersDump().withTracing {}
-        assertTrace(traceData)
-
-        val trace =
-            TraceProcessorSession.loadPerfettoTrace(traceData) { session ->
-                LayersTraceParser().parse(session)
-            }
-        Truth.assertWithMessage("Could not obtain layers dump")
-            .that(trace.entries.size)
-            .isEqualTo(1)
-    }
-
-    companion object {
-        @ClassRule @JvmField val ENV_CLEANUP = CleanFlickerEnvironmentRule()
-    }
-}
diff --git a/libraries/flicker/utils/test/src/android/tools/device/traces/monitors/surfaceflinger/LayersTraceMonitorTest.kt b/libraries/flicker/utils/test/src/android/tools/device/traces/monitors/surfaceflinger/LayersTraceMonitorTest.kt
new file mode 100644
index 0000000..66c5d53
--- /dev/null
+++ b/libraries/flicker/utils/test/src/android/tools/device/traces/monitors/surfaceflinger/LayersTraceMonitorTest.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.tools.device.traces.monitors.surfaceflinger
+
+import android.surfaceflinger.Layerstrace
+import android.tools.common.io.TraceType
+import android.tools.device.traces.monitors.TraceMonitorTest
+import android.tools.device.traces.monitors.withSFTracing
+import android.tools.utils.CleanFlickerEnvironmentRule
+import com.google.common.truth.Truth
+import org.junit.ClassRule
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runners.MethodSorters
+
+/**
+ * Contains [LayersTraceMonitor] tests. To run this test: `atest
+ * FlickerLibTest:LayersTraceMonitorTest`
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class LayersTraceMonitorTest : TraceMonitorTest<LayersTraceMonitor>() {
+    override val traceType = TraceType.SF
+    override fun getMonitor() = LayersTraceMonitor()
+
+    override fun assertTrace(traceData: ByteArray) {
+        val trace = Layerstrace.LayersTraceFileProto.parseFrom(traceData)
+        Truth.assertThat(trace.magicNumber)
+            .isEqualTo(
+                Layerstrace.LayersTraceFileProto.MagicNumber.MAGIC_NUMBER_H.number.toLong() shl
+                    32 or
+                    Layerstrace.LayersTraceFileProto.MagicNumber.MAGIC_NUMBER_L.number.toLong()
+            )
+    }
+
+    @Test
+    fun withSFTracingTest() {
+        val trace = withSFTracing {
+            device.pressHome()
+            device.pressRecentApps()
+        }
+
+        Truth.assertWithMessage("Could not obtain SF trace").that(trace.entries).isNotEmpty()
+    }
+
+    companion object {
+        @ClassRule @JvmField val ENV_CLEANUP = CleanFlickerEnvironmentRule()
+    }
+}
diff --git a/libraries/flicker/utils/test/src/android/tools/device/traces/monitors/wm/WindowManagerTraceMonitorTest.kt b/libraries/flicker/utils/test/src/android/tools/device/traces/monitors/wm/WindowManagerTraceMonitorTest.kt
index 8c00990..f3d9b8f 100644
--- a/libraries/flicker/utils/test/src/android/tools/device/traces/monitors/wm/WindowManagerTraceMonitorTest.kt
+++ b/libraries/flicker/utils/test/src/android/tools/device/traces/monitors/wm/WindowManagerTraceMonitorTest.kt
@@ -27,7 +27,10 @@
 import org.junit.Test
 import org.junit.runners.MethodSorters
 
-/** Contains [WindowManagerTraceMonitor] tests. */
+/**
+ * Contains [WindowManagerTraceMonitor] tests. To run this test: `atest
+ * FlickerLibTest:LayersTraceMonitorTest`
+ */
 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
 class WindowManagerTraceMonitorTest : TraceMonitorTest<WindowManagerTraceMonitor>() {
     override val traceType = TraceType.WM
diff --git a/libraries/flicker/utils/test/src/android/tools/device/traces/parsers/perfetto/TransactionsTraceParserTest.kt b/libraries/flicker/utils/test/src/android/tools/device/traces/parsers/surfaceflinger/LayerTraceParserTest.kt
similarity index 60%
rename from libraries/flicker/utils/test/src/android/tools/device/traces/parsers/perfetto/TransactionsTraceParserTest.kt
rename to libraries/flicker/utils/test/src/android/tools/device/traces/parsers/surfaceflinger/LayerTraceParserTest.kt
index 34eaffa..7397bfd 100644
--- a/libraries/flicker/utils/test/src/android/tools/device/traces/parsers/perfetto/TransactionsTraceParserTest.kt
+++ b/libraries/flicker/utils/test/src/android/tools/device/traces/parsers/surfaceflinger/LayerTraceParserTest.kt
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package android.tools.device.traces.parsers.perfetto
+package android.tools.device.traces.parsers.surfaceflinger
 
 import android.tools.common.Cache
 import android.tools.utils.CleanFlickerEnvironmentRule
@@ -24,7 +24,7 @@
 import org.junit.ClassRule
 import org.junit.Test
 
-class TransactionsTraceParserTest {
+class LayerTraceParserTest {
     @Before
     fun before() {
         Cache.clear()
@@ -33,15 +33,22 @@
     @Test
     fun canParseFromTrace() {
         val trace =
-            TraceProcessorSession.loadPerfettoTrace(
-                readAsset("transactions_trace.perfetto-trace")
-            ) { session ->
-                TransactionsTraceParser().parse(session)
-            }
+            LayersTraceParser(legacyTrace = true).parse(readAsset("layers_trace_occluded.pb"))
         Truth.assertWithMessage("Trace").that(trace.entries).asList().isNotEmpty()
-        Truth.assertWithMessage("Trace contains entries")
-            .that(trace.entries.map { it.timestamp.elapsedNanos })
-            .contains(1556111744859L)
+        Truth.assertWithMessage("Trace contains entry")
+            .that(trace.entries.map { it.elapsedTimestamp })
+            .contains(1700382131522L)
+    }
+
+    @Test
+    fun canParseFromDumpWithDisplay() {
+        val trace =
+            LayersTraceParser(legacyTrace = true).parse(readAsset("layers_dump_with_display.pb"))
+        Truth.assertWithMessage("Dump").that(trace.entries).asList().isNotEmpty()
+        Truth.assertWithMessage("Dump contains display")
+            .that(trace.entries.first().displays)
+            .asList()
+            .isNotEmpty()
     }
 
     companion object {
diff --git a/libraries/flicker/utils/test/src/android/tools/rules/StopAllTracesRule.kt b/libraries/flicker/utils/test/src/android/tools/rules/StopAllTracesRule.kt
index 7285a8a..bbbd495 100644
--- a/libraries/flicker/utils/test/src/android/tools/rules/StopAllTracesRule.kt
+++ b/libraries/flicker/utils/test/src/android/tools/rules/StopAllTracesRule.kt
@@ -16,8 +16,9 @@
 
 package android.tools.rules
 
-import android.tools.device.traces.monitors.PerfettoTraceMonitor
 import android.tools.device.traces.monitors.TraceMonitor
+import android.tools.device.traces.monitors.surfaceflinger.LayersTraceMonitor
+import android.tools.device.traces.monitors.surfaceflinger.TransactionsTraceMonitor
 import android.tools.device.traces.monitors.wm.ShellTransitionTraceMonitor
 import android.tools.device.traces.monitors.wm.WindowManagerTraceMonitor
 import android.tools.device.traces.monitors.wm.WmTransitionTraceMonitor
@@ -30,7 +31,8 @@
     override fun apply(base: Statement?, description: Description?): Statement {
         return object : Statement() {
             override fun evaluate() {
-                PerfettoTraceMonitor.stopAllSessions()
+                LayersTraceMonitor().stopIfEnabled()
+                TransactionsTraceMonitor().stopIfEnabled()
                 ShellTransitionTraceMonitor().stopIfEnabled()
                 WindowManagerTraceMonitor().stopIfEnabled()
                 WmTransitionTraceMonitor().stopIfEnabled()
diff --git a/libraries/flicker/utils/test/src/android/tools/utils/TestTraces.kt b/libraries/flicker/utils/test/src/android/tools/utils/TestTraces.kt
index 58b600d..39c77a0 100644
--- a/libraries/flicker/utils/test/src/android/tools/utils/TestTraces.kt
+++ b/libraries/flicker/utils/test/src/android/tools/utils/TestTraces.kt
@@ -22,7 +22,7 @@
 
 object TestTraces {
     object LayerTrace {
-        private const val ASSET = "layers_trace.perfetto-trace"
+        private const val ASSET = "layers_trace.winscope"
         val START_TIME = Timestamps.from(systemUptimeNanos = 1618663562444)
         val SLICE_TIME = Timestamps.from(systemUptimeNanos = 1618715108595)
         val END_TIME = Timestamps.from(systemUptimeNanos = 1620770824112)
@@ -49,7 +49,7 @@
     }
 
     object TransactionTrace {
-        private const val ASSET = "transactions_trace.perfetto-trace"
+        private const val ASSET = "transactions_trace.winscope"
         val START_TIME =
             Timestamps.from(systemUptimeNanos = 1556111744859, elapsedNanos = 1556111744859)
         val VALID_SLICE_TIME =
diff --git a/libraries/flicker/utils/test/src/android/tools/utils/Utils.kt b/libraries/flicker/utils/test/src/android/tools/utils/Utils.kt
index 147620e..733f463 100644
--- a/libraries/flicker/utils/test/src/android/tools/utils/Utils.kt
+++ b/libraries/flicker/utils/test/src/android/tools/utils/Utils.kt
@@ -27,8 +27,7 @@
 import android.tools.common.io.RunStatus
 import android.tools.device.traces.io.ArtifactBuilder
 import android.tools.device.traces.io.ResultWriter
-import android.tools.device.traces.parsers.perfetto.LayersTraceParser
-import android.tools.device.traces.parsers.perfetto.TraceProcessorSession
+import android.tools.device.traces.parsers.surfaceflinger.LayersTraceParser
 import android.tools.device.traces.parsers.wm.WindowManagerDumpParser
 import android.tools.device.traces.parsers.wm.WindowManagerTraceParser
 import android.tools.rules.CacheCleanupRule
@@ -133,20 +132,22 @@
 fun getLayerTraceReaderFromAsset(
     relativePath: String,
     ignoreOrphanLayers: Boolean = true,
+    legacyTrace: Boolean = false,
     from: Timestamp = Timestamps.min(),
     to: Timestamp = Timestamps.max()
 ): Reader {
-    val layersTrace =
-        TraceProcessorSession.loadPerfettoTrace(readAsset(relativePath)) { session ->
+    return ParsedTracesReader(
+        artifact = InMemoryArtifact(relativePath),
+        layersTrace =
             LayersTraceParser(
                     ignoreLayersStackMatchNoDisplay = false,
                     ignoreLayersInVirtualDisplay = false,
+                    legacyTrace = legacyTrace,
                 ) {
                     ignoreOrphanLayers
                 }
-                .parse(session, from, to)
-        }
-    return ParsedTracesReader(artifact = InMemoryArtifact(relativePath), layersTrace = layersTrace)
+                .parse(readAsset(relativePath), from, to)
+    )
 }
 
 @Throws(Exception::class)