# Device recipes

`PKG` = the app's debug package (see SKILL.md preflight) unless the user says release.
`PID` = `$(adb shell pidof $PKG)`. Run each recipe **before** (base APK) and
**after** (changed APK) with the same gesture and screen; the user installs each
APK from Android Studio.

## Jank / draw / touch
```bash
adb shell dumpsys gfxinfo $PKG reset
# user performs the gesture now (on cue)
adb shell dumpsys gfxinfo $PKG | grep -E 'Total frames|Janky frames|50th|90th|95th|99th'
adb logcat -d -s <SlowFrameTag>:W | tail -20   # only if the app logs slow frames under its own tag
```
Report: total frames, janky %, p50/p90/p99 ms.

## Main-thread CPU (simpleperf, no root needed for a debuggable/profileable app)
```bash
adb shell simpleperf record --app $PKG -g -f 1000 --duration 20 -o /data/local/tmp/perf.data
adb shell simpleperf report -i /data/local/tmp/perf.data --tids $(adb shell pidof $PKG) --sort symbol --children | head -60
```
Main thread TID equals the PID. Report the top 10 symbols by children %.
The NDK copy under `$ANDROID_HOME/ndk/*/simpleperf/` has
`report_html.py` if the user wants a flame graph.

## Timeline (Perfetto)
```bash
adb push <android-perf-cli base directory>/references/perfetto.cfg /data/local/tmp/app.cfg
adb shell 'cat /data/local/tmp/app.cfg | perfetto --txt -c - -o /data/misc/perfetto-traces/app.perfetto-trace'
adb pull /data/misc/perfetto-traces/app.perfetto-trace <scratchpad>/app-<before|after>.perfetto-trace
```
If `trace_processor` is on PATH, query long main-thread slices:
```sql
select s.name, s.dur/1e6 as ms from slice s
join thread_track tt on s.track_id = tt.id join thread t using(utid)
where t.is_main_thread = 1 and s.dur > 16e6 order by s.dur desc limit 20;
```
If it is not, do **not** download it without asking; tell the user to open the
trace at ui.perfetto.dev and run the same query in its Query tab.

## Cold start
```bash
for i in $(seq 10); do adb shell am start -W -S -n $PKG/<launcher activity> | grep TotalTime; done
```
Get the launcher activity with
`adb shell cmd package resolve-activity --brief -c android.intent.category.LAUNCHER $PKG | tail -1`.
Report the median of 10. If the branch has a StartupBenchmark / `:baselineprofile`
module, offer it instead: it needs
`-Pandroid.testInstrumentationRunnerArguments.androidx.benchmark.enabledRules=…`,
runs one Gradle invocation per device at a time, and is a Gradle run, so ask first.

## ANR repro
```bash
adb shell dumpsys activity anr | head -80
adb shell ls -t /data/anr/ | head
adb shell dumpsys dropbox --print data_app_anr | head -200
```
Read the `"main"` thread stack; name the frame from the diff if it is there.

## Memory
```bash
adb shell dumpsys meminfo $PKG | sed -n '1,40p'
```
Compare TOTAL PSS, Java Heap, Native Heap, Graphics. For a suspected leak:
`adb shell am dumpheap $PKG /data/local/tmp/app.hprof` then pull it; ask first,
it can be hundreds of MB.

## StrictMode
```bash
adb logcat -c && adb logcat -s StrictMode:D
```
This needs the debug build to enable StrictMode with `penaltyLog()`; if it does
not, say so. Run the flow and report each violation's first app frame.
