Android Profiler
Android (Google)OfficialCreated by Google LLCDistributed by Android (Google)
- Skill
- Tool integration
- Software development
- Apache-2.0
- Low risk
- Has scripts
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
The android-profiler skill provides a structured approach to capturing and interpreting Android performance data. It acts as an orchestrator for recording system traces, heap dumps, and CPU profiles, and provides workflows for deep-dive analysis using Perfetto. The skill is designed to help developers identify the root causes of UI jank, memory leaks, battery drain, and system-level performance regressions by leveraging standardized trace analysis and SQL-based querying.
What it does
- Records system traces, CPU call stacks, and memory heap profiles.
- Analyzes Perfetto traces to identify UI jank, frame drops, and startup latency.
- Investigates system-level issues like IPC Binder storms and thread scheduling stalls.
- Diagnoses power-related issues including battery drain and kernel wake locks.
- Debugs memory pressure, LMK events, and native or Java heap leaks.
- Executes custom PerfettoSQL queries for advanced trace data exploration.
When to use it
- When you need to investigate app startup latency or intermittent UI jank.
- When diagnosing memory-related crashes like OOMs or excessive allocation churn.
- When analyzing system-wide performance regressions using A/B trace comparisons.
- When you need to profile power consumption or modem power rail activity.
- When you need to perform ad hoc analysis on complex Android system traces.
Advantages
- Provides a unified workflow for both recording and analyzing performance data.
- Reduces ambiguity by enforcing clear intent disambiguation before execution.
- Includes specialized reference hints for CPU, memory, graphics, and power analysis.
- Supports advanced data exploration via PerfettoSQL integration.
- Ensures consistent environment setup through standardized path management.
Usage examples
- “My app is stuttering during scrolling. Can you help me find the cause?”
- The agent will initiate a trace recording session focused on UI jank, then guide you through analyzing the resulting Perfetto trace for frame drops and thread stalls.
- “I suspect a memory leak in my application. How can I investigate?”
- The agent will help you capture a Java or native heap dump and provide steps to analyze the memory allocation patterns to identify potential leaks.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/android/android-profiler/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip android-profiler.zip -d .agents/skills
Documentation by Google LLC
Your primary role is to figure out what the user wants to do (disambiguation), find the right instructions for it (workflow discovery), and follow them step-by-step (following the execution plan). If the request is unclear, work with the user to finalize the execution plan before proceeding.
Prerequisites and Setup
Before executing any workflows, read references/env_setup.md. It defines
what to set $SKILL_ROOT to - the anchor every other path in this skill is
written against.
Intent Disambiguation
Do not guess the user's intent. If the user request is not clear, ask the user what they want to do before proceeding.
Recording
Route all recording requests through recording/recording_orchestrator. This defines guidelines and pre-flight checks or dependency checks that apply to all recording workflows, and ensures you have the necessary setup to proceed. Read the orchestrator and execute the plan it describes based on what the user wants to record (for example, a system trace or a heap dump).
Analysis
Route all analysis requests through analysis/analysis_orchestrator.
Files
- ATTRIBUTION.mdAdded by AutoGineer965 B
- LICENSELicence file added by AutoGineer11.1 KiB
- SKILL.md2.2 KiB
- analysis/analysis_orchestrator.md1.5 KiB
- analysis/workflows/perfetto-sql/perfetto_sql.md969 B
- analysis/workflows/perfetto-trace-analysis/perfetto_trace_analysis.md4.2 KiB
- analysis/workflows/perfetto-trace-analysis/references/hints/hints_cpu.md2.6 KiB
- analysis/workflows/perfetto-trace-analysis/references/hints/hints_graphics.md2.1 KiB
- analysis/workflows/perfetto-trace-analysis/references/hints/hints_io.md1.8 KiB
- analysis/workflows/perfetto-trace-analysis/references/hints/hints_ipc.md1.7 KiB
- analysis/workflows/perfetto-trace-analysis/references/hints/hints_memory.md2.2 KiB
- analysis/workflows/perfetto-trace-analysis/references/hints/hints_power.md1.2 KiB
- analysis/workflows/perfetto-trace-analysis/references/per_candidate_analysis.md8.8 KiB
- analysis/workflows/perfetto-trace-analysis/references/triage.md3.9 KiB
- recording/recording_orchestrator.md1.5 KiB
- recording/workflows/perfetto-trace-recording/perfetto_trace_recording.md4.7 KiB
- recording/workflows/perfetto-trace-recording/references/example-configs/app_jank.pftxt1.0 KiB
- recording/workflows/perfetto-trace-recording/references/example-configs/cpu_profile.pftxt773 B
- recording/workflows/perfetto-trace-recording/references/example-configs/java_heap_dump.pftxt566 B
- recording/workflows/perfetto-trace-recording/references/example-configs/long_background.pftxt1006 B
- recording/workflows/perfetto-trace-recording/references/example-configs/memory_counters.pftxt1.0 KiB
- recording/workflows/perfetto-trace-recording/references/example-configs/native_heap.pftxt589 B
- recording/workflows/perfetto-trace-recording/references/example-configs/sched_cpu.pftxt836 B
- recording/workflows/perfetto-trace-recording/references/trace_config_reference.md4.9 KiB
- references/env_setup.md513 B
- references/perfetto/bin/trace_processorScript10.8 KiB
- references/perfetto/setup.md1.3 KiB
- references/perfetto/sql.md15.8 KiB
references/perfetto/bin/trace_processor
#!/usr/bin/env python3
# Copyright (C) 2021 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# DO NOT EDIT. Auto-generated by tools/gen_amalgamated_python_tools
# !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
# This file should do the same thing when being invoked in any of these ways:
# ./trace_processor
# python trace_processor
# bash trace_processor
# cat ./trace_processor | bash
# cat ./trace_processor | python -
BASH_FALLBACK = """ "
exec python3 - "$@" <<'#'EOF
#""" # yapf: disable
# ----- Amalgamator: begin of python/perfetto/prebuilts/manifests/trace_processor_shell.py
# This file has been generated by: tools/release/roll-prebuilts v58.3
TRACE_PROCESSOR_SHELL_MANIFEST = [
{
'arch': 'mac-amd64',
'file_name': 'trace_processor_shell',
'file_size': 14854504,
'url': (
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v58.3/mac-amd64/trace_processor_shell'
),
'sha256': (
'faba0dbd8a1d362b712536f7740845ad11a0fa27f3bca666ab9559ceb307ac65'
),
'platform': 'darwin',
'machine': ['x86_64'],
},
{
'arch': 'mac-arm64',
'file_name': 'trace_processor_shell',
'file_size': 13597976,
'url': (
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v58.3/mac-arm64/trace_processor_shell'
),
'sha256': (
'99c75cf71711af7206fac27ae96017d91255a19f6a1afbd635dcf653821eda5d'
),
'platform': 'darwin',
'machine': ['arm64'],
},
{
'arch': 'linux-amd64',
'file_name': 'trace_processor_shell',
'file_size': 14897560,
'url': (
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v58.3/linux-amd64/trace_processor_shell'
),
'sha256': (
'f13baf75f5655109a637b041e7f9c78ebe76d7c0f030cd6d611d5679cfcb4fb9'
),
'platform': 'linux',
'machine': ['x86_64'],
},
{
'arch': 'linux-arm',
'file_name': 'trace_processor_shell',
'file_size': 10962664,
'url': (
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v58.3/linux-arm/trace_processor_shell'
),
'sha256': (
'a1b7672785cd3519c24783a95fac65534ecf321014db72abd969ebd7bb54db2a'
),
'platform': 'linux',
'machine': ['armv6l', 'armv7l', 'armv8l'],
},
{
'arch': 'linux-arm64',
'file_name': 'trace_processor_shell',
'file_size': 14086160,
'url': (
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v58.3/linux-arm64/trace_processor_shell'
),
'sha256': (
'c19a09baf07695829339f83dd4a293a2194a6013aeef73c4701f10f31df9cd74'
),
'platform': 'linux',
'machine': ['aarch64'],
},
{
'arch': 'android-arm',
'file_name': 'trace_processor_shell',
'file_size': 10935412,
'url': (
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v58.3/android-arm/trace_processor_shell'
),
'sha256': (
'250dbe2c899c00d804bd11b339e09b9603a03da93bf8d272b3b84a8b53161ee8'
),
},
{
'arch': 'android-arm64',
'file_name': 'trace_processor_shell',
'file_size': 13838680,
'url': (
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v58.3/android-arm64/trace_processor_shell'
),
'sha256': (
'1a9e98aa245831a8bd3c0e3056b0261c566ce9a1b51365283d46654327df4664'
),
},
{
'arch': 'android-x86',
'file_name': 'trace_processor_shell',
'file_size': 15814036,
'url': (
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v58.3/android-x86/trace_processor_shell'
),
'sha256': (
'87083c4e46a06a0290f8c355b8c1fa7b29f7c82dd3eb3e628f45f9a7aafb03a1'
),
},
{
'arch': 'android-x64',
'file_name': 'trace_processor_shell',
'file_size': 14611448,
'url': (
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v58.3/android-x64/trace_processor_shell'
),
'sha256': (
'648debede565a249abd366ec3bfe976737ca5a68c7f5a3a5ae95c74633cda750'
),
},
{
'arch': 'windows-amd64',
'file_name': 'trace_processor_shell.exe',
'file_size': 14439936,
'url': (
'https://commondatastorage.googleapis.com/perfetto-luci-artifacts/v58.3/windows-amd64/trace_processor_shell.exe'
),
'sha256': (
'8868f0d03fba8953247c025d48183f16e2445c983fe1b843e8b13ca2d4319d35'
),
'platform': 'win32',
'machine': ['amd64'],
},
]
# ----- Amalgamator: end of python/perfetto/prebuilts/manifests/trace_processor_shell.py
# ----- Amalgamator: begin of python/perfetto/prebuilts/perfetto_prebuilts.py
# Copyright (C) 2021 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Functions to fetch pre-pinned Perfetto prebuilts.
This function is used in different places:
- Into the //tools/{trace_processor, traceconv} scripts, which are just plain
wrappers around executables.
- Into the //tools/{heap_profiler, record_android_trace} scripts, which contain
some other hand-written python code.
The manifest argument looks as follows:
TRACECONV_MANIFEST = [
{
'arch': 'mac-amd64',
'file_name': 'traceconv',
'file_size': 7087080,
'url': https://commondatastorage.googleapis.com/.../trace_to_text',
'sha256': 7d957c005b0dc130f5bd855d6cec27e060d38841b320d04840afc569f9087490',
'platform': 'darwin',
'machine': 'x86_64'
},
...
]
The intended usage is:
from perfetto.prebuilts.manifests.traceconv import TRACECONV_MANIFEST
bin_path = get_perfetto_prebuilt(TRACECONV_MANIFEST)
subprocess.call(bin_path, ...)
"""
import hashlib
import os
import platform
import random
import subprocess
import sys
def download_or_get_cached(file_name, url, sha256):
"""Downloads a prebuilt or returns a cached version
The first time this is invoked, it downloads the |url| and caches it into
~/.local/share/perfetto/prebuilts/$tool_name-$sha256. On subsequent
invocations it just runs the cached version.
The (short) SHA-256 is embedded in the cached file name so that several
versions of the same tool can coexist on the same machine. This matters when
e.g. two virtualenvs pin different Perfetto releases, or the //tools wrappers
and the Python API request different versions: without the SHA in the name
they would all map to the same path, clobber each other and trigger a
re-download on every switch.
"""
dir = os.path.join(
os.path.expanduser('~'), '.local', 'share', 'perfetto', 'prebuilts'
)
os.makedirs(dir, exist_ok=True)
# Embed the SHA in the file name, preserving any extension (e.g. .exe) as the
# last component since callers (and the OS, on Windows) rely on it.
root, ext = os.path.splitext(file_name)
bin_path = os.path.join(dir, '%s-%s%s' % (root, sha256[:16], ext))
# The cached file is only ever created via an atomic rename after the SHA-256
# has been verified, so if a file at this (SHA-named) path exists we can trust
# it without recomputing the hash on every invocation.
if os.path.exists(bin_path):
return bin_path
# Use a unique random file to guard against concurrent executions.
# See https://github.com/google/perfetto/issues/786 .
tmp_path = '%s.%d.tmp' % (bin_path, random.randint(0, 100000))
print('Downloading ' + url)
subprocess.check_call(['curl', '-f', '-L', '-#', '-o', tmp_path, url])
with open(tmp_path, 'rb') as fd:
actual_sha256 = hashlib.sha256(fd.read()).hexdigest()
if actual_sha256 != sha256:
raise Exception(
'Checksum mismatch for %s (actual: %s, expected: %s)'
% (url, actual_sha256, sha256)
)
os.chmod(tmp_path, 0o755)
os.replace(tmp_path, bin_path)
return bin_path
def get_perfetto_prebuilt(manifest, soft_fail=False, arch=None):
"""Downloads the prebuilt, if necessary, and returns its path on disk."""
plat = sys.platform.lower()
machine = platform.machine().lower()
manifest_entry = None
for entry in manifest:
# If the caller overrides the arch, just match that (for Android prebuilts).
if arch:
if entry.get('arch') == arch:
manifest_entry = entry
break
continue
# Otherwise guess the local machine arch.
if entry.get('platform') == plat and machine in entry.get('machine', []):
manifest_entry = entry
break
if manifest_entry is None:
if soft_fail:
return None
raise Exception(
'No prebuilts available for %s-%s\n' % (plat, machine)
+ 'See https://perfetto.dev/docs/contributing/build-instructions'
)
# Placeholder entries (e.g. before a release has been rolled) have an empty
# URL. Treat them the same as a missing entry when soft_fail is set.
if not manifest_entry.get('url'):
if soft_fail:
return None
raise Exception(
'No prebuilt URL available for %s on %s-%s. '
'The prebuilt may not have been rolled yet.'
% (manifest_entry.get('file_name', '?'), plat, machine)
)
return download_or_get_cached(
file_name=manifest_entry['file_name'],
url=manifest_entry['url'],
sha256=manifest_entry['sha256'],
)
def run_perfetto_prebuilt(manifest):
bin_path = get_perfetto_prebuilt(manifest)
if sys.platform.lower() == 'win32':
sys.exit(subprocess.check_call([bin_path, *sys.argv[1:]]))
os.execv(bin_path, [bin_path] + sys.argv[1:])
# ----- Amalgamator: end of python/perfetto/prebuilts/perfetto_prebuilts.py
if __name__ == '__main__':
run_perfetto_prebuilt(TRACE_PROCESSOR_SHELL_MANIFEST)
# EOF
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
What our scanner noticed· Low risk
- Scripts that your agent may run
This skill includes scripts that your agent may run. Read them before you use it.
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- Google LLC
- Publisher
- Android (Google) (Official)
- Distributed by
- Android (Google)
- Source
- android/skills · profilers/android-profiler · commit bf68e2d
- Licence
- Apache License 2.0 (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE.txt)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Google LLC or Android (Google).
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download android-profiler.zip