Mob.PostMortem.Android (mob v0.8.3)

Copy Markdown View Source

ApplicationExitInfo-backed post-mortem ingest for Android.

Pulls the OS-held history of process exits via ActivityManager.getHistoricalProcessExitReasons (available on Android 11 / API 30 and later), filters against a persistent marker so each exit is emitted exactly once across boots, and hands each new entry to Mob.Defect.emit_appexit_reason/1 as a capsule on Mob.Defect.Bus.

What the OS gives us

ApplicationExitInfo records the reason a previous process instance of this app died — an ANR, a crash, an OOM, a user-initiated kill. The list survives reboots and app updates, and the OS trims it eventually (usually 16 entries per app). We do NOT run every boot hoping to catch a live incident: we sweep whenever the caller does and take whatever the OS still holds since the last sweep.

Persistent marker

Without a marker, every sweep on a fresh install re-emits the entire historical list; every subsequent boot would re-emit the same entries. The native NIF persists the highest-seen exit timestamp to <filesDir>/mob_post_mortem_appexit_marker.txt and filters the OS list to entries strictly newer. First sweep on a fresh install still emits the current history (that is the point of a first sweep); every subsequent sweep emits only what accumulated since.

Platform gating

The NIF is registered on both platforms (iOS returns [] unconditionally — the iOS substrate is MetricKit, MOB-179). This module gates on :mob_nif.platform() == :android so a caller on iOS or in a host test does no work at all. On an Android device below API 30 the native side also returns [] — the API was added in Android 11.

Redaction

The emitted capsule carries: numeric reason code, pid (an OS identifier, not user data), timestamp, process name (normally the app's package name; also OS-controlled), and a short OS-generated description string like "remote process crash". NOT included this phase: the trace file contents an ANR carries — those can hold app strings and need the same Mob.Agent.Receipt.summarize_error/3-style discipline before they can safely reach the bus.

Summary

Functions

Sweep any ApplicationExitInfo entries the OS has recorded since the persisted marker was last written.

Functions

sweep()

@spec sweep() :: [Mob.Defect.Capsule.t()]

Sweep any ApplicationExitInfo entries the OS has recorded since the persisted marker was last written.

Returns the list of capsules emitted, in the order the NIF returned them (typically OS-chronological). Empty on iOS, on Android < 11, on a host test with the NIF not loaded, or any time the marker filters everything out.