# Argent — Perfetto TraceConfig (text protobuf) # # The Android twin of packages/tool-server/src/utils/ios-profiler/Argent.tracetemplate. # Pushed to the device and consumed by `perfetto --txt -c `. # # In production this is template-substituted: TARGET_CMDLINE_PLACEHOLDER and # TARGET_PACKAGE_PLACEHOLDER are replaced with the auto-detected foreground app # (mirrors detectRunningApp in native-profiler-start.ts:46-117). # # Buffers sized for ~5 minutes of capture on a typical RN app. Adjust if you # extend RECORDING_CAP_MS beyond the iOS 10-min default. # duration_ms is intentionally omitted — the recording is stopped explicitly via # `kill -TERM ` from native-profiler-stop, mirroring xctrace SIGINT. # If you want a hard cap, set duration_ms here AND keep the stop signal as a # safety net (the perfetto daemon will exit either way). buffers: { size_kb: 65536 # 64 MB — CPU samples + atrace slices fill_policy: DISCARD # ring-buffer once full; we want recency over completeness } buffers: { size_kb: 16384 # 16 MB — frame timeline + ANRs (sparser, smaller buffer) fill_policy: DISCARD } # ---------------------------------------------------------------------------- # Data source 1: CPU callstack sampling (the Time Profiler equivalent) # ---------------------------------------------------------------------------- # Outputs perf_sample rows we GROUP BY callsite + thread in queries/cpu-hotspots.sql. # target_cmdline restricts sampling to the user's app — system-wide noise is # excluded at capture time, not analysis time. data_sources: { config: { name: "linux.perf" target_buffer: 0 perf_event_config: { timebase: { # 100 Hz software CPU clock — matches the iOS coresampler2 default. # Adjust higher (e.g. 1000) for tight CPU-bound investigations. counter: SW_CPU_CLOCK frequency: 100 timestamp_clock: PERF_CLOCK_MONOTONIC } callstack_sampling: { scope: { target_cmdline: "TARGET_CMDLINE_PLACEHOLDER" # Drop the next two if Perfetto warns about missing /proc access: # target_installed_by: "PLAY_STORE" # only for production-builds w/ trusted source } kernel_frames: true # include kernel callsites; great for "stuck in syscall" diagnosis } } } } # ---------------------------------------------------------------------------- # Data source 2: kernel scheduler events + atrace app slices # ---------------------------------------------------------------------------- # Feeds thread_state table; used in queries/ui-hangs.sql to attribute main-thread # stalls to "blocked on I/O", "blocked on lock", etc. # # atrace categories / atrace_apps are nested in ftrace_config (NOT as a separate # `android.atrace` data source with `atrace_config` — that field was removed # from DataSourceConfig and is rejected by perfetto >= v45). See # https://perfetto.dev/docs/data-sources/atrace. data_sources: { config: { name: "linux.ftrace" target_buffer: 0 ftrace_config: { ftrace_events: "sched/sched_switch" ftrace_events: "sched/sched_wakeup" ftrace_events: "sched/sched_wakeup_new" ftrace_events: "sched/sched_process_exit" # sched_blocked_reason gives us the "main thread blocked on what?" answer. ftrace_events: "sched/sched_blocked_reason" # binder events — surfaces IPC contention on the main thread. ftrace_events: "binder/binder_transaction" ftrace_events: "binder/binder_transaction_received" # System atrace categories — see `adb shell atrace --list_categories` for the full set. atrace_categories: "view" # View system: measure/layout/draw atrace_categories: "gfx" # SurfaceFlinger/HWUI atrace_categories: "wm" # WindowManager atrace_categories: "am" # ActivityManager atrace_categories: "input" # input dispatch (key/touch) atrace_categories: "binder_driver" atrace_categories: "dalvik" # GC, JIT, class loading atrace_categories: "ss" # SystemServer atrace_categories: "aidl" # AIDL call slices # Per-app categories — capture slices that the app itself emits via Trace.beginSection. atrace_apps: "TARGET_PACKAGE_PLACEHOLDER" } } } # ---------------------------------------------------------------------------- # Data source 4: SurfaceFlinger frame timeline (the Hangs equivalent + reason codes) # ---------------------------------------------------------------------------- # Produces expected_frame_timeline_slice and actual_frame_timeline_slice rows. # A frame whose actual end > expected end is a jank; the jank_type enum tells us # whose fault (AppDeadlineMissed / BufferStuffing / SfCpu / SfGpu / ...). data_sources: { config: { name: "android.surfaceflinger.frametimeline" target_buffer: 1 } } # ---------------------------------------------------------------------------- # Data source 5: process stats — for the weak RSS-growth signal until phase-2 leak detection lands # ---------------------------------------------------------------------------- data_sources: { config: { name: "linux.process_stats" target_buffer: 1 process_stats_config: { proc_stats_poll_ms: 1000 # 1 s cadence is enough for RSS-trend detection scan_all_processes_on_start: true } } } # Drop incremental_state every 5 s so we recover symbol tables even if perfetto crashes # mid-recording — partial trace is still useful (mirrors iOS handleXctraceExit recovery). incremental_state_config: { clear_period_ms: 5000 } # When the on-device file is large, write it directly instead of going through the # 32 MB ring buffer before flushing. Avoids data loss on long recordings. write_into_file: true file_write_period_ms: 2500