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