1 /*
<lambda>null2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.tools
18 
19 import android.app.Instrumentation
20 import android.tools.flicker.datastore.CachedResultWriter
21 import android.tools.flicker.legacy.AbstractFlickerTestData
22 import android.tools.flicker.legacy.FlickerBuilder
23 import android.tools.flicker.legacy.FlickerTestData
24 import android.tools.io.PERFETTO_EXT
25 import android.tools.io.Reader
26 import android.tools.io.WINSCOPE_EXT
27 import android.tools.parsers.events.EventLogParser
28 import android.tools.rules.DataStoreCleanupRule
29 import android.tools.traces.monitors.ITransitionMonitor
30 import android.tools.traces.monitors.PerfettoTraceMonitor
31 import android.tools.traces.monitors.wm.WindowManagerTraceMonitor
32 import android.tools.traces.parsers.WindowManagerStateHelper
33 import android.tools.traces.parsers.perfetto.LayersTraceParser
34 import android.tools.traces.parsers.perfetto.TraceProcessorSession
35 import android.tools.traces.parsers.perfetto.TransactionsTraceParser
36 import android.tools.traces.parsers.wm.LegacyTransitionTraceParser
37 import android.tools.traces.parsers.wm.WindowManagerTraceParser
38 import android.tools.utils.CleanFlickerEnvironmentRule
39 import android.tools.utils.ParsedTracesReader
40 import android.tools.utils.TEST_SCENARIO
41 import android.tools.utils.TestArtifact
42 import android.tools.utils.readAsset
43 import androidx.test.platform.app.InstrumentationRegistry
44 import androidx.test.uiautomator.UiDevice
45 import java.io.File
46 import kotlin.io.path.createTempDirectory
47 import org.junit.rules.RuleChain
48 import org.mockito.Mockito
49 
50 fun CleanFlickerEnvironmentRuleWithDataStore(): RuleChain =
51     CleanFlickerEnvironmentRule().around(DataStoreCleanupRule())
52 
53 internal fun getTraceReaderFromScenario(scenario: String): Reader {
54     val scenarioTraces = getScenarioTraces(scenario)
55 
56     val (layersTrace, transactionsTrace) =
57         TraceProcessorSession.loadPerfettoTrace(scenarioTraces.perfetto.readBytes()) { session ->
58             val layersTrace = LayersTraceParser().parse(session)
59             val transactionsTrace = TransactionsTraceParser().parse(session)
60             Pair(layersTrace, transactionsTrace)
61         }
62 
63     return ParsedTracesReader(
64         artifact = TestArtifact(scenario),
65         wmTrace = WindowManagerTraceParser().parse(scenarioTraces.wmTrace.readBytes()),
66         layersTrace = layersTrace,
67         transitionsTrace =
68             LegacyTransitionTraceParser()
69                 .parse(
70                     scenarioTraces.wmTransitions.readBytes(),
71                     scenarioTraces.shellTransitions.readBytes()
72                 ),
73         transactionsTrace = transactionsTrace,
74         eventLog = EventLogParser().parse(scenarioTraces.eventLog.readBytes()),
75     )
76 }
77 
getScenarioTracesnull78 fun getScenarioTraces(scenario: String): FlickerBuilder.TraceFiles {
79     lateinit var wmTrace: File
80     lateinit var perfettoTrace: File
81     lateinit var wmTransitionTrace: File
82     lateinit var shellTransitionTrace: File
83     lateinit var eventLog: File
84     val traces =
85         mapOf<String, (File) -> Unit>(
86             "wm_trace$WINSCOPE_EXT" to { wmTrace = it },
87             "layers_and_transactions_trace$PERFETTO_EXT" to { perfettoTrace = it },
88             "wm_transition_trace$WINSCOPE_EXT" to { wmTransitionTrace = it },
89             "shell_transition_trace$WINSCOPE_EXT" to { shellTransitionTrace = it },
90             "eventlog$WINSCOPE_EXT" to { eventLog = it }
91         )
92     for ((traceFileName, resultSetter) in traces.entries) {
93         val traceBytes = readAsset("scenarios/$scenario/$traceFileName")
94         val traceFile = File.createTempFile(traceFileName, "")
95         traceFile.writeBytes(traceBytes)
96         resultSetter.invoke(traceFile)
97     }
98 
99     return FlickerBuilder.TraceFiles(
100         wmTrace,
101         perfettoTrace,
102         wmTransitionTrace,
103         shellTransitionTrace,
104         eventLog,
105     )
106 }
107 
createMockedFlickernull108 fun createMockedFlicker(
109     setup: List<FlickerTestData.() -> Unit> = emptyList(),
110     teardown: List<FlickerTestData.() -> Unit> = emptyList(),
111     transitions: List<FlickerTestData.() -> Unit> = emptyList(),
112     extraMonitor: ITransitionMonitor? = null
113 ): FlickerTestData {
114     val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
115     val uiDevice: UiDevice = UiDevice.getInstance(instrumentation)
116     val mockedFlicker = Mockito.mock(AbstractFlickerTestData::class.java)
117     val monitors: MutableList<ITransitionMonitor> =
118         mutableListOf(
119             WindowManagerTraceMonitor(),
120             PerfettoTraceMonitor.newBuilder().enableLayersTrace().build()
121         )
122     extraMonitor?.let { monitors.add(it) }
123     Mockito.`when`(mockedFlicker.wmHelper).thenReturn(WindowManagerStateHelper())
124     Mockito.`when`(mockedFlicker.device).thenReturn(uiDevice)
125     Mockito.`when`(mockedFlicker.outputDir).thenReturn(createTempDirectory().toFile())
126     Mockito.`when`(mockedFlicker.traceMonitors).thenReturn(monitors)
127     Mockito.`when`(mockedFlicker.transitionSetup).thenReturn(setup)
128     Mockito.`when`(mockedFlicker.transitionTeardown).thenReturn(teardown)
129     Mockito.`when`(mockedFlicker.transitions).thenReturn(transitions)
130     return mockedFlicker
131 }
132 
newTestCachedResultWriternull133 internal fun newTestCachedResultWriter(scenario: Scenario = TEST_SCENARIO) =
134     CachedResultWriter()
135         .forScenario(scenario)
136         .withOutputDir(createTempDirectory().toFile())
137         .setRunComplete()
138