1*288bf522SAndroid Build Coastguard Worker# Android application profiling 2*288bf522SAndroid Build Coastguard Worker 3*288bf522SAndroid Build Coastguard WorkerThis section shows how to profile an Android application. 4*288bf522SAndroid Build Coastguard WorkerSome examples are [Here](https://android.googlesource.com/platform/system/extras/+/main/simpleperf/demo/README.md). 5*288bf522SAndroid Build Coastguard Worker 6*288bf522SAndroid Build Coastguard WorkerProfiling an Android application involves three steps: 7*288bf522SAndroid Build Coastguard Worker1. Prepare an Android application. 8*288bf522SAndroid Build Coastguard Worker2. Record profiling data. 9*288bf522SAndroid Build Coastguard Worker3. Report profiling data. 10*288bf522SAndroid Build Coastguard Worker 11*288bf522SAndroid Build Coastguard Worker[TOC] 12*288bf522SAndroid Build Coastguard Worker 13*288bf522SAndroid Build Coastguard Worker## Prepare an Android application 14*288bf522SAndroid Build Coastguard Worker 15*288bf522SAndroid Build Coastguard WorkerBased on the profiling situation, we may need to customize the build script to generate an apk file 16*288bf522SAndroid Build Coastguard Workerspecifically for profiling. Below are some suggestions. 17*288bf522SAndroid Build Coastguard Worker 18*288bf522SAndroid Build Coastguard Worker1. If you want to profile a debug build of an application: 19*288bf522SAndroid Build Coastguard Worker 20*288bf522SAndroid Build Coastguard WorkerFor the debug build type, Android studio sets android::debuggable="true" in AndroidManifest.xml, 21*288bf522SAndroid Build Coastguard Workerenables JNI checks and may not optimize C/C++ code. It can be profiled by simpleperf without any 22*288bf522SAndroid Build Coastguard Workerchange. 23*288bf522SAndroid Build Coastguard Worker 24*288bf522SAndroid Build Coastguard Worker2. If you want to profile a release build of an application: 25*288bf522SAndroid Build Coastguard Worker 26*288bf522SAndroid Build Coastguard WorkerFor the release build type, Android studio sets android::debuggable="false" in AndroidManifest.xml, 27*288bf522SAndroid Build Coastguard Workerdisables JNI checks and optimizes C/C++ code. However, security restrictions mean that only apps 28*288bf522SAndroid Build Coastguard Workerwith android::debuggable set to true can be profiled. So simpleperf can only profile a release 29*288bf522SAndroid Build Coastguard Workerbuild under these three circumstances: 30*288bf522SAndroid Build Coastguard WorkerIf you are on a rooted device, you can profile any app. 31*288bf522SAndroid Build Coastguard Worker 32*288bf522SAndroid Build Coastguard WorkerIf you are on Android >= Q, you can add profileableFromShell flag in AndroidManifest.xml, this makes 33*288bf522SAndroid Build Coastguard Workera released app profileable by preinstalled profiling tools. In this case, simpleperf downloaded by 34*288bf522SAndroid Build Coastguard Workeradb will invoke simpleperf preinstalled in system image to profile the app. 35*288bf522SAndroid Build Coastguard Worker 36*288bf522SAndroid Build Coastguard Worker``` 37*288bf522SAndroid Build Coastguard Worker<manifest ...> 38*288bf522SAndroid Build Coastguard Worker <application ...> 39*288bf522SAndroid Build Coastguard Worker <profileable android:shell="true" /> 40*288bf522SAndroid Build Coastguard Worker </application> 41*288bf522SAndroid Build Coastguard Worker</manifest> 42*288bf522SAndroid Build Coastguard Worker``` 43*288bf522SAndroid Build Coastguard Worker 44*288bf522SAndroid Build Coastguard WorkerIf you are on Android >= O, we can use [wrap.sh](https://developer.android.com/ndk/guides/wrap-script.html) 45*288bf522SAndroid Build Coastguard Workerto profile a release build: 46*288bf522SAndroid Build Coastguard WorkerStep 1: Add android::debuggable="true" in AndroidManifest.xml to enable profiling. 47*288bf522SAndroid Build Coastguard Worker``` 48*288bf522SAndroid Build Coastguard Worker<manifest ...> 49*288bf522SAndroid Build Coastguard Worker <application android::debuggable="true" ...> 50*288bf522SAndroid Build Coastguard Worker``` 51*288bf522SAndroid Build Coastguard Worker 52*288bf522SAndroid Build Coastguard WorkerStep 2: Add wrap.sh in lib/`arch` directories. wrap.sh runs the app without passing any debug flags 53*288bf522SAndroid Build Coastguard Workerto ART, so the app runs as a release app. wrap.sh can be done by adding the script below in 54*288bf522SAndroid Build Coastguard Workerapp/build.gradle. 55*288bf522SAndroid Build Coastguard Worker``` 56*288bf522SAndroid Build Coastguard Workerandroid { 57*288bf522SAndroid Build Coastguard Worker buildTypes { 58*288bf522SAndroid Build Coastguard Worker release { 59*288bf522SAndroid Build Coastguard Worker sourceSets { 60*288bf522SAndroid Build Coastguard Worker release { 61*288bf522SAndroid Build Coastguard Worker resources { 62*288bf522SAndroid Build Coastguard Worker srcDir { 63*288bf522SAndroid Build Coastguard Worker "wrap_sh_lib_dir" 64*288bf522SAndroid Build Coastguard Worker } 65*288bf522SAndroid Build Coastguard Worker } 66*288bf522SAndroid Build Coastguard Worker } 67*288bf522SAndroid Build Coastguard Worker } 68*288bf522SAndroid Build Coastguard Worker } 69*288bf522SAndroid Build Coastguard Worker } 70*288bf522SAndroid Build Coastguard Worker} 71*288bf522SAndroid Build Coastguard Worker 72*288bf522SAndroid Build Coastguard Workertask createWrapShLibDir 73*288bf522SAndroid Build Coastguard Worker for (String abi : ["armeabi-v7a", "arm64-v8a", "x86", "x86_64"]) { 74*288bf522SAndroid Build Coastguard Worker def dir = new File("app/wrap_sh_lib_dir/lib/" + abi) 75*288bf522SAndroid Build Coastguard Worker dir.mkdirs() 76*288bf522SAndroid Build Coastguard Worker def wrapFile = new File(dir, "wrap.sh") 77*288bf522SAndroid Build Coastguard Worker wrapFile.withWriter { writer -> 78*288bf522SAndroid Build Coastguard Worker writer.write('#!/system/bin/sh\n\$@\n') 79*288bf522SAndroid Build Coastguard Worker } 80*288bf522SAndroid Build Coastguard Worker } 81*288bf522SAndroid Build Coastguard Worker} 82*288bf522SAndroid Build Coastguard Worker``` 83*288bf522SAndroid Build Coastguard Worker 84*288bf522SAndroid Build Coastguard Worker3. If you want to profile C/C++ code: 85*288bf522SAndroid Build Coastguard Worker 86*288bf522SAndroid Build Coastguard WorkerAndroid studio strips symbol table and debug info of native libraries in the apk. So the profiling 87*288bf522SAndroid Build Coastguard Workerresults may contain unknown symbols or broken callgraphs. To fix this, we can pass app_profiler.py 88*288bf522SAndroid Build Coastguard Workera directory containing unstripped native libraries via the -lib option. Usually the directory can 89*288bf522SAndroid Build Coastguard Workerbe the path of your Android Studio project. 90*288bf522SAndroid Build Coastguard Worker 91*288bf522SAndroid Build Coastguard Worker 92*288bf522SAndroid Build Coastguard Worker4. If you want to profile Java code: 93*288bf522SAndroid Build Coastguard Worker 94*288bf522SAndroid Build Coastguard WorkerOn Android >= P, simpleperf supports profiling Java code, no matter whether it is executed by 95*288bf522SAndroid Build Coastguard Workerthe interpreter, or JITed, or compiled into native instructions. So you don't need to do anything. 96*288bf522SAndroid Build Coastguard Worker 97*288bf522SAndroid Build Coastguard WorkerOn Android O, simpleperf supports profiling Java code which is compiled into native instructions, 98*288bf522SAndroid Build Coastguard Workerand it also needs wrap.sh to use the compiled Java code. To compile Java code, we can pass 99*288bf522SAndroid Build Coastguard Workerapp_profiler.py the --compile_java_code option. 100*288bf522SAndroid Build Coastguard Worker 101*288bf522SAndroid Build Coastguard WorkerOn Android N, simpleperf supports profiling Java code that is compiled into native instructions. 102*288bf522SAndroid Build Coastguard WorkerTo compile java code, we can pass app_profiler.py the --compile_java_code option. 103*288bf522SAndroid Build Coastguard Worker 104*288bf522SAndroid Build Coastguard WorkerOn Android <= M, simpleperf doesn't support profiling Java code. 105*288bf522SAndroid Build Coastguard Worker 106*288bf522SAndroid Build Coastguard Worker 107*288bf522SAndroid Build Coastguard WorkerBelow I use application [SimpleperfExampleCpp](https://android.googlesource.com/platform/system/extras/+/main/simpleperf/demo/SimpleperfExampleCpp). 108*288bf522SAndroid Build Coastguard WorkerIt builds an app-debug.apk for profiling. 109*288bf522SAndroid Build Coastguard Worker 110*288bf522SAndroid Build Coastguard Worker```sh 111*288bf522SAndroid Build Coastguard Worker$ git clone https://android.googlesource.com/platform/system/extras 112*288bf522SAndroid Build Coastguard Worker$ cd extras/simpleperf/demo 113*288bf522SAndroid Build Coastguard Worker# Open SimpleperfExampleCpp project with Android studio, and build this project 114*288bf522SAndroid Build Coastguard Worker# successfully, otherwise the `./gradlew` command below will fail. 115*288bf522SAndroid Build Coastguard Worker$ cd SimpleperfExampleCpp 116*288bf522SAndroid Build Coastguard Worker 117*288bf522SAndroid Build Coastguard Worker# On windows, use "gradlew" instead. 118*288bf522SAndroid Build Coastguard Worker$ ./gradlew clean assemble 119*288bf522SAndroid Build Coastguard Worker$ adb install -r app/build/outputs/apk/debug/app-debug.apk 120*288bf522SAndroid Build Coastguard Worker``` 121*288bf522SAndroid Build Coastguard Worker 122*288bf522SAndroid Build Coastguard Worker## Record and report profiling data 123*288bf522SAndroid Build Coastguard Worker 124*288bf522SAndroid Build Coastguard WorkerWe can use [app-profiler.py](scripts_reference.md#app_profilerpy) to profile Android applications. 125*288bf522SAndroid Build Coastguard Worker 126*288bf522SAndroid Build Coastguard Worker```sh 127*288bf522SAndroid Build Coastguard Worker# Cd to the directory of simpleperf scripts. Record perf.data. 128*288bf522SAndroid Build Coastguard Worker# -p option selects the profiled app using its package name. 129*288bf522SAndroid Build Coastguard Worker# --compile_java_code option compiles Java code into native instructions, which isn't needed on 130*288bf522SAndroid Build Coastguard Worker# Android >= P. 131*288bf522SAndroid Build Coastguard Worker# -a option selects the Activity to profile. 132*288bf522SAndroid Build Coastguard Worker# -lib option gives the directory to find debug native libraries. 133*288bf522SAndroid Build Coastguard Worker$ ./app_profiler.py -p simpleperf.example.cpp -a .MixActivity -lib path_of_SimpleperfExampleCpp 134*288bf522SAndroid Build Coastguard Worker``` 135*288bf522SAndroid Build Coastguard Worker 136*288bf522SAndroid Build Coastguard WorkerThis will collect profiling data in perf.data in the current directory, and related native 137*288bf522SAndroid Build Coastguard Workerbinaries in binary_cache/. 138*288bf522SAndroid Build Coastguard Worker 139*288bf522SAndroid Build Coastguard WorkerNormally we need to use the app when profiling, otherwise we may record no samples. But in this 140*288bf522SAndroid Build Coastguard Workercase, the MixActivity starts a busy thread. So we don't need to use the app while profiling. 141*288bf522SAndroid Build Coastguard Worker 142*288bf522SAndroid Build Coastguard Worker```sh 143*288bf522SAndroid Build Coastguard Worker# Report perf.data in stdio interface. 144*288bf522SAndroid Build Coastguard Worker$ ./report.py 145*288bf522SAndroid Build Coastguard WorkerCmdline: /data/data/simpleperf.example.cpp/simpleperf record ... 146*288bf522SAndroid Build Coastguard WorkerArch: arm64 147*288bf522SAndroid Build Coastguard WorkerEvent: task-clock:u (type 1, config 1) 148*288bf522SAndroid Build Coastguard WorkerSamples: 10023 149*288bf522SAndroid Build Coastguard WorkerEvent count: 10023000000 150*288bf522SAndroid Build Coastguard Worker 151*288bf522SAndroid Build Coastguard WorkerOverhead Command Pid Tid Shared Object Symbol 152*288bf522SAndroid Build Coastguard Worker27.04% BusyThread 5703 5729 /system/lib64/libart.so art::JniMethodStart(art::Thread*) 153*288bf522SAndroid Build Coastguard Worker25.87% BusyThread 5703 5729 /system/lib64/libc.so long StrToI<long, ... 154*288bf522SAndroid Build Coastguard Worker... 155*288bf522SAndroid Build Coastguard Worker``` 156*288bf522SAndroid Build Coastguard Worker 157*288bf522SAndroid Build Coastguard Worker[report.py](scripts_reference.md#reportpy) reports profiling data in stdio interface. If there 158*288bf522SAndroid Build Coastguard Workerare a lot of unknown symbols in the report, check [here](README.md#how-to-solve-missing-symbols-in-report). 159*288bf522SAndroid Build Coastguard Worker 160*288bf522SAndroid Build Coastguard Worker```sh 161*288bf522SAndroid Build Coastguard Worker# Report perf.data in html interface. 162*288bf522SAndroid Build Coastguard Worker$ ./report_html.py 163*288bf522SAndroid Build Coastguard Worker 164*288bf522SAndroid Build Coastguard Worker# Add source code and disassembly. Change the path of source_dirs if it not correct. 165*288bf522SAndroid Build Coastguard Worker$ ./report_html.py --add_source_code --source_dirs path_of_SimpleperfExampleCpp \ 166*288bf522SAndroid Build Coastguard Worker --add_disassembly 167*288bf522SAndroid Build Coastguard Worker``` 168*288bf522SAndroid Build Coastguard Worker 169*288bf522SAndroid Build Coastguard Worker[report_html.py](scripts_reference.md#report_htmlpy) generates report in report.html, and pops up 170*288bf522SAndroid Build Coastguard Workera browser tab to show it. 171*288bf522SAndroid Build Coastguard Worker 172*288bf522SAndroid Build Coastguard Worker## Record and report call graph 173*288bf522SAndroid Build Coastguard Worker 174*288bf522SAndroid Build Coastguard WorkerWe can record and report [call graphs](executable_commands_reference.md#record-call-graphs) as below. 175*288bf522SAndroid Build Coastguard Worker 176*288bf522SAndroid Build Coastguard Worker```sh 177*288bf522SAndroid Build Coastguard Worker# Record dwarf based call graphs: add "-g" in the -r option. 178*288bf522SAndroid Build Coastguard Worker$ ./app_profiler.py -p simpleperf.example.cpp \ 179*288bf522SAndroid Build Coastguard Worker -r "-e task-clock:u -f 1000 --duration 10 -g" -lib path_of_SimpleperfExampleCpp 180*288bf522SAndroid Build Coastguard Worker 181*288bf522SAndroid Build Coastguard Worker# Record stack frame based call graphs: add "--call-graph fp" in the -r option. 182*288bf522SAndroid Build Coastguard Worker$ ./app_profiler.py -p simpleperf.example.cpp \ 183*288bf522SAndroid Build Coastguard Worker -r "-e task-clock:u -f 1000 --duration 10 --call-graph fp" \ 184*288bf522SAndroid Build Coastguard Worker -lib path_of_SimpleperfExampleCpp 185*288bf522SAndroid Build Coastguard Worker 186*288bf522SAndroid Build Coastguard Worker# Report call graphs in stdio interface. 187*288bf522SAndroid Build Coastguard Worker$ ./report.py -g 188*288bf522SAndroid Build Coastguard Worker 189*288bf522SAndroid Build Coastguard Worker# Report call graphs in python Tk interface. 190*288bf522SAndroid Build Coastguard Worker$ ./report.py -g --gui 191*288bf522SAndroid Build Coastguard Worker 192*288bf522SAndroid Build Coastguard Worker# Report call graphs in html interface. 193*288bf522SAndroid Build Coastguard Worker$ ./report_html.py 194*288bf522SAndroid Build Coastguard Worker 195*288bf522SAndroid Build Coastguard Worker# Report call graphs in flamegraphs. 196*288bf522SAndroid Build Coastguard Worker# On Windows, use inferno.bat instead of ./inferno.sh. 197*288bf522SAndroid Build Coastguard Worker$ ./inferno.sh -sc 198*288bf522SAndroid Build Coastguard Worker``` 199*288bf522SAndroid Build Coastguard Worker 200*288bf522SAndroid Build Coastguard Worker## Report in html interface 201*288bf522SAndroid Build Coastguard Worker 202*288bf522SAndroid Build Coastguard WorkerWe can use [report_html.py](scripts_reference.md#report_htmlpy) to show profiling results in a web browser. 203*288bf522SAndroid Build Coastguard Workerreport_html.py integrates chart statistics, sample table, flamegraphs, source code annotation 204*288bf522SAndroid Build Coastguard Workerand disassembly annotation. It is the recommended way to show reports. 205*288bf522SAndroid Build Coastguard Worker 206*288bf522SAndroid Build Coastguard Worker```sh 207*288bf522SAndroid Build Coastguard Worker$ ./report_html.py 208*288bf522SAndroid Build Coastguard Worker``` 209*288bf522SAndroid Build Coastguard Worker 210*288bf522SAndroid Build Coastguard Worker## Show flamegraph 211*288bf522SAndroid Build Coastguard Worker 212*288bf522SAndroid Build Coastguard WorkerTo show flamegraphs, we need to first record call graphs. Flamegraphs are shown by 213*288bf522SAndroid Build Coastguard Workerreport_html.py in the "Flamegraph" tab. 214*288bf522SAndroid Build Coastguard WorkerWe can also use [inferno](scripts_reference.md#inferno) to show flamegraphs directly. 215*288bf522SAndroid Build Coastguard Worker 216*288bf522SAndroid Build Coastguard Worker```sh 217*288bf522SAndroid Build Coastguard Worker# On Windows, use inferno.bat instead of ./inferno.sh. 218*288bf522SAndroid Build Coastguard Worker$ ./inferno.sh -sc 219*288bf522SAndroid Build Coastguard Worker``` 220*288bf522SAndroid Build Coastguard Worker 221*288bf522SAndroid Build Coastguard WorkerWe can also build flamegraphs using https://github.com/brendangregg/FlameGraph. 222*288bf522SAndroid Build Coastguard WorkerPlease make sure you have perl installed. 223*288bf522SAndroid Build Coastguard Worker 224*288bf522SAndroid Build Coastguard Worker```sh 225*288bf522SAndroid Build Coastguard Worker$ git clone https://github.com/brendangregg/FlameGraph.git 226*288bf522SAndroid Build Coastguard Worker$ ./report_sample.py --symfs binary_cache >out.perf 227*288bf522SAndroid Build Coastguard Worker$ FlameGraph/stackcollapse-perf.pl out.perf >out.folded 228*288bf522SAndroid Build Coastguard Worker$ FlameGraph/flamegraph.pl out.folded >a.svg 229*288bf522SAndroid Build Coastguard Worker``` 230*288bf522SAndroid Build Coastguard Worker 231*288bf522SAndroid Build Coastguard Worker## Report in Android Studio 232*288bf522SAndroid Build Coastguard Worker 233*288bf522SAndroid Build Coastguard Workersimpleperf report-sample command can convert perf.data into protobuf format accepted by 234*288bf522SAndroid Build Coastguard WorkerAndroid Studio cpu profiler. The conversion can be done either on device or on host. If you have 235*288bf522SAndroid Build Coastguard Workermore symbol info on host, then prefer do it on host with --symdir option. 236*288bf522SAndroid Build Coastguard Worker 237*288bf522SAndroid Build Coastguard Worker```sh 238*288bf522SAndroid Build Coastguard Worker$ simpleperf report-sample --protobuf --show-callchain -i perf.data -o perf.trace 239*288bf522SAndroid Build Coastguard Worker# Then open perf.trace in Android Studio to show it. 240*288bf522SAndroid Build Coastguard Worker``` 241*288bf522SAndroid Build Coastguard Worker 242*288bf522SAndroid Build Coastguard Worker## Deobfuscate Java symbols 243*288bf522SAndroid Build Coastguard Worker 244*288bf522SAndroid Build Coastguard WorkerJava symbols may be obfuscated by ProGuard. To restore the original symbols in a report, we can 245*288bf522SAndroid Build Coastguard Workerpass a Proguard mapping file to the report scripts or report-sample command via 246*288bf522SAndroid Build Coastguard Worker`--proguard-mapping-file`. 247*288bf522SAndroid Build Coastguard Worker 248*288bf522SAndroid Build Coastguard Worker```sh 249*288bf522SAndroid Build Coastguard Worker$ ./report_html.py --proguard-mapping-file proguard_mapping_file.txt 250*288bf522SAndroid Build Coastguard Worker``` 251*288bf522SAndroid Build Coastguard Worker 252*288bf522SAndroid Build Coastguard Worker## Record both on CPU time and off CPU time 253*288bf522SAndroid Build Coastguard Worker 254*288bf522SAndroid Build Coastguard WorkerWe can [record both on CPU time and off CPU time](executable_commands_reference.md#record-both-on-cpu-time-and-off-cpu-time). 255*288bf522SAndroid Build Coastguard Worker 256*288bf522SAndroid Build Coastguard WorkerFirst check if trace-offcpu feature is supported on the device. 257*288bf522SAndroid Build Coastguard Worker 258*288bf522SAndroid Build Coastguard Worker```sh 259*288bf522SAndroid Build Coastguard Worker$ ./run_simpleperf_on_device.py list --show-features 260*288bf522SAndroid Build Coastguard Workerdwarf-based-call-graph 261*288bf522SAndroid Build Coastguard Workertrace-offcpu 262*288bf522SAndroid Build Coastguard Worker``` 263*288bf522SAndroid Build Coastguard Worker 264*288bf522SAndroid Build Coastguard WorkerIf trace-offcpu is supported, it will be shown in the feature list. Then we can try it. 265*288bf522SAndroid Build Coastguard Worker 266*288bf522SAndroid Build Coastguard Worker```sh 267*288bf522SAndroid Build Coastguard Worker$ ./app_profiler.py -p simpleperf.example.cpp -a .SleepActivity \ 268*288bf522SAndroid Build Coastguard Worker -r "-g -e task-clock:u -f 1000 --duration 10 --trace-offcpu" \ 269*288bf522SAndroid Build Coastguard Worker -lib path_of_SimpleperfExampleCpp 270*288bf522SAndroid Build Coastguard Worker$ ./report_html.py --add_disassembly --add_source_code \ 271*288bf522SAndroid Build Coastguard Worker --source_dirs path_of_SimpleperfExampleCpp 272*288bf522SAndroid Build Coastguard Worker``` 273*288bf522SAndroid Build Coastguard Worker 274*288bf522SAndroid Build Coastguard Worker## Profile from launch 275*288bf522SAndroid Build Coastguard Worker 276*288bf522SAndroid Build Coastguard WorkerWe can [profile from launch of an application](scripts_reference.md#profile-from-launch-of-an-application). 277*288bf522SAndroid Build Coastguard Worker 278*288bf522SAndroid Build Coastguard Worker```sh 279*288bf522SAndroid Build Coastguard Worker# Start simpleperf recording, then start the Activity to profile. 280*288bf522SAndroid Build Coastguard Worker$ ./app_profiler.py -p simpleperf.example.cpp -a .MainActivity 281*288bf522SAndroid Build Coastguard Worker 282*288bf522SAndroid Build Coastguard Worker# We can also start the Activity on the device manually. 283*288bf522SAndroid Build Coastguard Worker# 1. Make sure the application isn't running or one of the recent apps. 284*288bf522SAndroid Build Coastguard Worker# 2. Start simpleperf recording. 285*288bf522SAndroid Build Coastguard Worker$ ./app_profiler.py -p simpleperf.example.cpp 286*288bf522SAndroid Build Coastguard Worker# 3. Start the app manually on the device. 287*288bf522SAndroid Build Coastguard Worker``` 288*288bf522SAndroid Build Coastguard Worker 289*288bf522SAndroid Build Coastguard Worker## Control recording in application code 290*288bf522SAndroid Build Coastguard Worker 291*288bf522SAndroid Build Coastguard WorkerSimpleperf supports controlling recording from application code. Below is the workflow: 292*288bf522SAndroid Build Coastguard Worker 293*288bf522SAndroid Build Coastguard Worker1. Run `api_profiler.py prepare -p <package_name>` to allow an app recording itself using 294*288bf522SAndroid Build Coastguard Worker simpleperf. By default, the permission is reset after device reboot. So we need to run the 295*288bf522SAndroid Build Coastguard Worker script every time the device reboots. But on Android >= 13, we can use `--days` options to 296*288bf522SAndroid Build Coastguard Worker set how long we want the permission to last. 297*288bf522SAndroid Build Coastguard Worker 298*288bf522SAndroid Build Coastguard Worker2. Link simpleperf app_api code in the application. The app needs to be debuggable or 299*288bf522SAndroid Build Coastguard Worker profileableFromShell as described [here](#prepare-an-android-application). Then the app can 300*288bf522SAndroid Build Coastguard Worker use the api to start/pause/resume/stop recording. To start recording, the app_api forks a child 301*288bf522SAndroid Build Coastguard Worker process running simpleperf, and uses pipe files to send commands to the child process. After 302*288bf522SAndroid Build Coastguard Worker recording, a profiling data file is generated. 303*288bf522SAndroid Build Coastguard Worker 304*288bf522SAndroid Build Coastguard Worker3. Run `api_profiler.py collect -p <package_name>` to collect profiling data files to host. 305*288bf522SAndroid Build Coastguard Worker 306*288bf522SAndroid Build Coastguard WorkerExamples are CppApi and JavaApi in [demo](https://android.googlesource.com/platform/system/extras/+/main/simpleperf/demo). 307*288bf522SAndroid Build Coastguard Worker 308*288bf522SAndroid Build Coastguard Worker 309*288bf522SAndroid Build Coastguard Worker## Parse profiling data manually 310*288bf522SAndroid Build Coastguard Worker 311*288bf522SAndroid Build Coastguard WorkerWe can also write python scripts to parse profiling data manually, by using 312*288bf522SAndroid Build Coastguard Worker[simpleperf_report_lib.py](scripts_reference.md#simpleperf_report_libpy). Examples are report_sample.py, 313*288bf522SAndroid Build Coastguard Workerreport_html.py. 314