Generated banner for Android Profiler
Generated logo for Android Profiler

Android Profiler

Android (Google)OfficialCreated by Google LLCDistributed by Android (Google)

  • Skill
  • Tool integration
  • Software development
  • Apache-2.0
  • Low risk
  • Has scripts

From the author

Records and analyzes Android performance data and diagnoses performance bottlenecks across user apps, system apps, and system services, even if the user does not explicitly mention profiling or traces. Use when: recording system traces, CPU call stacks, Vulkan GPU/DRM memory, or Java/native heap profiles; analyzing Perfetto traces for UI jank, frame drops, ANRs, or app startup latency issues; investigating CPU bottlenecks, IPC/Binder storms, or thread scheduling stalls; diagnosing battery drain, modem power rails, and kernel wake locks; debugging memory pressure, Low Memory Kills (LMK), OOMs, leaks, and allocation churn; performing A/B baseline trace comparisons to find regressions; executing ad hoc PerfettoSQL queries on Android traces.
— the description by Google LLC

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

  1. Download the skill as a ZIP:

    https://mp-staging.autogineer.com/agent-skills/android/android-profiler/download
  2. Unzip 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

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