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.monitors
18 
19 import android.tools.device.apphelpers.BrowserAppHelper
20 import android.tools.io.TraceType
21 import android.tools.traces.monitors.PerfettoTraceMonitor
22 import android.tools.traces.monitors.withSFTracing
23 import android.tools.traces.monitors.withTransactionsTracing
24 import android.tools.traces.parsers.WindowManagerStateHelper
25 import android.tools.traces.parsers.perfetto.LayersTraceParser
26 import android.tools.traces.parsers.perfetto.TraceProcessorSession
27 import android.tools.traces.parsers.perfetto.TransitionsTraceParser
28 import android.tools.utils.CleanFlickerEnvironmentRule
29 import com.android.server.wm.flicker.helpers.ImeAppHelper
30 import com.google.common.truth.Truth
31 import org.junit.Assume.assumeTrue
32 import org.junit.ClassRule
33 import org.junit.FixMethodOrder
34 import org.junit.Test
35 import org.junit.runners.MethodSorters
36 
37 /**
38  * Contains [PerfettoTraceMonitor] tests. To run this test: `atest
39  * FlickerLibTest:PerfettoTraceMonitorTest`
40  */
41 @FixMethodOrder(MethodSorters.NAME_ASCENDING)
42 class PerfettoTraceMonitorTest : TraceMonitorTest<PerfettoTraceMonitor>() {
43     override val traceType = TraceType.PERFETTO
44 
45     override fun getMonitor() =
46         PerfettoTraceMonitor.newBuilder().enableLayersTrace().enableTransactionsTrace().build()
47 
48     override fun assertTrace(traceData: ByteArray) {
49         Truth.assertThat(traceData.size).isGreaterThan(0)
50     }
51 
52     @Test
53     fun withSFTracingTest() {
54         val trace = withSFTracing {
55             device.pressHome()
56             device.pressRecentApps()
57         }
58 
59         Truth.assertWithMessage("Could not obtain layers trace").that(trace.entries).isNotEmpty()
60     }
61 
62     @Test
63     fun withTransactionsTracingTest() {
64         val trace = withTransactionsTracing {
65             device.pressHome()
66             device.pressRecentApps()
67         }
68 
69         Truth.assertWithMessage("Could not obtain transactions trace")
70             .that(trace.entries)
71             .isNotEmpty()
72     }
73 
74     @Test
75     fun layersDump() {
76         val traceData = PerfettoTraceMonitor.newBuilder().enableLayersDump().build().withTracing {}
77         assertTrace(traceData)
78 
79         val trace =
80             TraceProcessorSession.loadPerfettoTrace(traceData) { session ->
81                 LayersTraceParser().parse(session)
82             }
83         Truth.assertWithMessage("Could not obtain layers dump")
84             .that(trace.entries.size)
85             .isEqualTo(1)
86     }
87 
88     @Test
89     fun withTransitionTracingTest() {
90         assumeTrue(
91             "PerfettoTransitionTracing flag should be enabled",
92             android.tracing.Flags.perfettoTransitionTracing()
93         )
94 
95         val traceMonitor = PerfettoTraceMonitor.newBuilder().enableTransitionsTrace().build()
96         val traceData =
97             traceMonitor.withTracing {
98                 BrowserAppHelper().launchViaIntent()
99                 device.pressHome()
100                 device.pressRecentApps()
101             }
102         assertTrace(traceData)
103 
104         val trace =
105             TraceProcessorSession.loadPerfettoTrace(traceData) { session ->
106                 TransitionsTraceParser().parse(session)
107             }
108         Truth.assertWithMessage("Could not obtain transition trace")
109             .that(trace.entries)
110             .isNotEmpty()
111     }
112 
113     @Test
114     fun imeTracingTest() {
115         assumeTrue("PerfettoIme flag should be enabled", android.tracing.Flags.perfettoIme())
116 
117         val traceMonitor = PerfettoTraceMonitor.newBuilder().enableImeTrace().build()
118         val traceData = traceMonitor.withTracing {
119             val wmHelper = WindowManagerStateHelper()
120             val imeApp = ImeAppHelper(instrumentation)
121             imeApp.launchViaIntent(wmHelper)
122             imeApp.openIME(wmHelper)
123         }
124         assertTrace(traceData)
125 
126         val queryRowsCount = { session: TraceProcessorSession, tableName: String ->
127             val sql =
128                 "INCLUDE PERFETTO MODULE android.winscope.inputmethod;" +
129                         "SELECT COUNT(*) FROM $tableName;"
130             session.query(
131                 sql,
132                 { rows ->
133                     require(rows.size == 1)
134                     rows.get(0).get("COUNT(*)") as Long
135                 }
136             )
137         }
138 
139         val (countRowsClients, countRowsManagerService, countRowsService) =
140             TraceProcessorSession.loadPerfettoTrace(traceData) { session ->
141                 Triple(
142                     queryRowsCount(session, "android_inputmethod_clients"),
143                     queryRowsCount(session, "android_inputmethod_manager_service"),
144                     queryRowsCount(session, "android_inputmethod_service")
145                 )
146             }
147 
148         Truth.assertWithMessage("TP doesn't contain IME client rows")
149             .that(countRowsClients).isGreaterThan(0L)
150         Truth.assertWithMessage("TP doesn't contain IME manager service rows")
151             .that(countRowsManagerService).isGreaterThan(0L)
152         Truth.assertWithMessage("TP doesn't contain IME service rows")
153             .that(countRowsService).isGreaterThan(0L)
154     }
155 
156     @Test
157     fun viewCaptureTracingTest() {
158         assumeTrue(
159             "PerfettoViewCaptureTracing flag should be enabled",
160             android.tracing.Flags.perfettoViewCaptureTracing()
161         )
162 
163         val traceMonitor = PerfettoTraceMonitor.newBuilder().enableViewCaptureTrace().build()
164         val traceData =
165             traceMonitor.withTracing {
166                 BrowserAppHelper().launchViaIntent()
167                 device.pressHome()
168                 device.pressRecentApps()
169             }
170         assertTrace(traceData)
171 
172         val countRows =
173             TraceProcessorSession.loadPerfettoTrace(traceData) { session ->
174                 val sql =
175                     "INCLUDE PERFETTO MODULE android.winscope.viewcapture;" +
176                         "SELECT COUNT(*) FROM android_viewcapture;"
177                 session.query(
178                     sql,
179                     { rows ->
180                         require(rows.size == 1)
181                         rows.get(0).get("COUNT(*)") as Long
182                     }
183                 )
184             }
185 
186         Truth.assertWithMessage("TP doesn't contain ViewCapture rows")
187             .that(countRows)
188             .isGreaterThan(0L)
189     }
190 
191     companion object {
192         @ClassRule @JvmField val ENV_CLEANUP = CleanFlickerEnvironmentRule()
193     }
194 }
195