1 /* <lambda>null2 * Copyright 2024 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 androidx.benchmark.traceprocessor 18 19 import androidx.annotation.RequiresApi 20 import androidx.benchmark.perfetto.ExperimentalPerfettoCaptureApi 21 import androidx.benchmark.perfetto.PerfettoCapture 22 import androidx.benchmark.perfetto.PerfettoCapture.PerfettoSdkConfig.InitialProcessState 23 import androidx.benchmark.perfetto.PerfettoCaptureWrapper 24 import androidx.benchmark.perfetto.PerfettoConfig 25 import androidx.benchmark.perfetto.UiState 26 import androidx.benchmark.perfetto.appendUiState 27 import androidx.test.platform.app.InstrumentationRegistry 28 import java.io.File 29 30 /** 31 * Record a Perfetto System Trace for the specified [block]. 32 * 33 * ``` 34 * PerfettoTrace.record("myTrace") { 35 * // content in here is traced to myTrace_<timestamp>.perfetto_trace 36 * } 37 * ``` 38 * 39 * Reentrant Perfetto trace capture is not supported, so this API may not be combined with 40 * `BenchmarkRule`, `MacrobenchmarkRule`, or `PerfettoTraceRule`. 41 * 42 * If the block throws, the trace is still captured and passed to [traceCallback]. 43 */ 44 @RequiresApi(23) 45 @ExperimentalPerfettoCaptureApi 46 fun PerfettoTrace.Companion.record( 47 /** 48 * Output trace file names are labelled `<fileLabel>_<timestamp>.perfetto_trace` 49 * 50 * This timestamp is used for uniqueness when trace files are pulled automatically to Studio. 51 */ 52 fileLabel: String, 53 /** 54 * Target process to trace with app tag (enables android.os.Trace / androidx.Trace). 55 * 56 * By default, traces this process. 57 */ 58 appTagPackages: List<String> = 59 listOf(InstrumentationRegistry.getInstrumentation().targetContext.packageName), 60 /** 61 * Process to trace with userspace tracing, i.e. `androidx.tracing:tracing-perfetto`, ignored 62 * below API 30. 63 * 64 * This tracing is lower overhead than standard `android.os.Trace` tracepoints, but is currently 65 * experimental. 66 */ 67 userspaceTracingPackage: String? = null, 68 /** 69 * Callback for trace capture. 70 * 71 * This callback allows you to process the trace even if the block throws, e.g. during a test 72 * failure. 73 */ 74 traceCallback: ((PerfettoTrace) -> Unit)? = null, 75 /** Block to be traced. */ 76 block: () -> Unit 77 ) = 78 record( 79 fileLabel = fileLabel, 80 config = 81 PerfettoConfig.Benchmark( 82 appTagPackages = appTagPackages, 83 useStackSamplingConfig = true 84 ), 85 userspaceTracingPackage = userspaceTracingPackage, 86 traceCallback = traceCallback, 87 block = block 88 ) 89 90 /** 91 * Record a Perfetto System Trace for the specified [block], with a fully custom Perfetto config, 92 * either text or binary. 93 * 94 * ``` 95 * PerfettoTrace.record("myTrace", config = """...""") { 96 * // content in here is traced to myTrace_<timestamp>.perfetto_trace 97 * } 98 * ``` 99 * 100 * Reentrant Perfetto trace capture is not supported, so this API may not be combined with 101 * `BenchmarkRule`, `MacrobenchmarkRule`, or `PerfettoTraceRule`. 102 * 103 * If the block throws, the trace is still captured and passed to [traceCallback]. 104 */ 105 @RequiresApi(23) 106 @ExperimentalPerfettoCaptureApi 107 fun PerfettoTrace.Companion.record( 108 /** 109 * Output trace file names are labelled `<fileLabel>_<timestamp>.perfetto_trace` 110 * 111 * This timestamp is used for uniqueness when trace files are pulled automatically to Studio. 112 */ 113 fileLabel: String, 114 /** Trace recording configuration. */ 115 config: PerfettoConfig, 116 /** 117 * Process to emphasize in the tracing UI. 118 * 119 * Used to emphasize the target process, e.g. by pre-populating Studio trace viewer process 120 * selection. 121 * 122 * Defaults to the test's target process. Note that for self-instrumenting tests that measure 123 * another app, you must pass that target app package. 124 */ 125 highlightPackage: String = 126 InstrumentationRegistry.getInstrumentation().targetContext.packageName, 127 /** 128 * Process to trace with userspace tracing, i.e. `androidx.tracing:tracing-perfetto`, ignored 129 * below API 30. 130 * 131 * This tracing is lower overhead than standard `android.os.Trace` tracepoints, but is currently 132 * experimental. 133 */ 134 userspaceTracingPackage: String? = null, 135 /** 136 * Callback for trace capture. 137 * 138 * This callback allows you to process the trace even if the block throws, e.g. during a test 139 * failure. 140 */ 141 traceCallback: ((PerfettoTrace) -> Unit)? = null, 142 /** Block to be traced. */ 143 block: () -> Unit 144 ) { 145 PerfettoCaptureWrapper() 146 .record( 147 fileLabel = fileLabel, 148 config, 149 perfettoSdkConfig = 150 userspaceTracingPackage?.let { 151 PerfettoCapture.PerfettoSdkConfig(it, InitialProcessState.Unknown) 152 }, 153 traceCallback = { path -> 154 File(path) 155 .appendUiState( 156 UiState( 157 timelineStart = null, 158 timelineEnd = null, 159 highlightPackage = highlightPackage 160 ) 161 ) 162 traceCallback?.invoke(PerfettoTrace(path)) 163 }, 164 block = block 165 ) 166 } 167