Capturing system diagnostics on Android has traditionally relied on the monolithic bugreport utility, which aggregates thousands of log lines, radio dumps, and service dumps into large multi-megabyte text files. While comprehensive, parsing these massive text logs is slow, resource-heavy, and difficult to automate in continuous integration pipelines. Furthermore, legacy bugreports often capture sensitive user information, posing compliance and privacy challenges when sharing logs across distributed development teams.
To modernise device diagnostics, Android introduced the Incident Reporting Framework, powered by the incidentd system daemon. Incident reporting captures system diagnostics as structured, Protocol Buffer (protobuf) encoded streams. By using adb shell dumpsys incident and the companion incident command-line utility, Android developers and QA engineers can trigger modular diagnostic reports, filter out private user data, and extract individual subsystem metrics in machine-readable binary or JSON formats.
Architecture of the Android Incident Framework
The Incident framework operates through a dedicated system service, incidentd, which registers individual diagnostic sections defined in the Android Open Source Project (AOSP) protobuf schema (frameworks/base/core/proto/android/os/incident.proto). Key advantages include:
- Structured Schema: Diagnostics are mapped into strict, strongly-typed protobuf fields rather than unstructured text dumps.
- Granular Section Targeting: Developers can request specific diagnostic sections (such as battery status, package manager, or thermal throttles) without triggering an expensive full-system dump.
- Multi-Tier Privacy Filtering: Every field in the schema is tagged with a privacy specification:
EXPLICIT(contains sensitive user data),LOCAL(contains device-identifying data safe for local debugging), orAUTOMATIC(completely anonymised data safe for automated cloud reporting). - High Performance: Generating binary protobuf data requires fewer CPU cycles and avoids formatting text output inside device memory.
Inspecting incidentd Service State with dumpsys
To inspect the status of the incident reporting daemon and verify active listener registrations, connect your Android device with USB debugging enabled and run:
# Query the incident reporting daemon status
adb shell dumpsys incident
The output presents the daemon’s internal state, active report queues, and section dispatch timings:
Incidentd status:
Running: true
Pending reports: 0
Batching enabled: true
Registered sections: 1000, 1001, 1002, 1100, 1114, 2000...
Each registered section corresponds to a specific numerical ID within the protobuf schema. For example, Section 1000 represents the system log buffer, Section 1114 represents battery stats, and Section 3000 represents the package manager.
Generating a Full Incident Report
To generate and retrieve a complete structured incident report, invoke the native incident binary via ADB and redirect the standard output to a file on your local workstation:
# Generate a full protobuf incident report
adb shell incident > device_incident.proto
To enforce privacy filtering during generation, specify the desired privacy level using the -p argument:
# Generate a privacy-safe report suitable for automated sharing
adb shell incident -p AUTOMATIC > safe_incident.proto
# Generate a local-level report including hardware identifiers
adb shell incident -p LOCAL > local_incident.proto
Targeting Specific Diagnostic Sections
Rather than dumping the entire device state, you can capture individual diagnostic sections by passing their numeric section IDs. This reduces capture time from several minutes to mere milliseconds:
# Capture only BatteryStats (Section 1114)
adb shell incident 1114 > battery_stats.proto
# Capture only DiskStats (Section 1108) and Process Memory (Section 2001)
adb shell incident 1108 2001 > storage_and_memory.proto
To view a comprehensive list of all available section numbers and their descriptive names directly from the device:
# List all supported incident report sections
adb shell incident -l
The terminal outputs a mapped index of section identifiers:
1000: /system/bin/logcat -b events -t 2000 -v threadtime
1001: /system/bin/logcat -b radio -t 2000 -v threadtime
1100: /system/bin/dumpsys -t 10 alarm --proto
1108: /system/bin/dumpsys -t 10 diskstats --proto
1114: /system/bin/dumpsys -t 30 batterystats --proto
2000: /system/bin/dumpsys -t 10 meminfo --proto
3000: /system/bin/dumpsys -t 30 package --proto
Parsing and Decoding Incident Protobufs
Because the captured output is binary protobuf data, you can parse and decode the report on your development machine using the standard Protocol Buffer compiler (protoc) or Google’s open-source incident-section-gen tools:
# Decode binary protobuf into human-readable text using protoc
protoc --decode=android.os.IncidentProto \
-I $ANDROID_BUILD_TOP/frameworks/base/core/proto/ \
frameworks/base/core/proto/android/os/incident.proto < battery_stats.proto
The decoded output formats the diagnostics into clean, structured JSON-like text fields:
batterystats {
subsystem: "battery"
charge_counter_uah: 4250000
battery_level: 85
plugged: PLUGGED_USB
battery_temperature_decicelsius: 295
}
Using dumpsys incident and targeted section captures enables automated testing suites to gather consistent, structured diagnostic data without bogging down device resources or violating user privacy standards.