Usagestats: Android App Usage Events
Android usagestats files: app foreground and background events, screen and keyguard state, XML and protobuf formats, paths per version and retention.
- Location
- /data/system_ce/0/usagestats/ (Android 11+), /data/system/usagestats/0/ (Android 8 to 10)
- Proves
- When each app's activities came to the foreground and left it, when the screen turned on and off, when the keyguard was shown and dismissed, device startup and shutdown
- Timestamps
- File names are the interval start in Unix milliseconds (UTC); event times are stored as millisecond offsets from that start and must be added to it
- Access
- Full file system (root, exploit or agent); credential-encrypted from Android 11, so AFU only on 11+. Logical and bugreport: recent in-memory events via dumpsys usagestats. Not in ADB backup.
- Retention
- AOSP defaults: daily files about 10 days, weekly about 4 weeks, monthly about 6 months, yearly a few years; detailed events are in the daily files
- Collection
- Full file system extraction, adb shell dumpsys usagestats, adb bugreport
Tools
Compare all toolsWhat it is
UsageStatsService is the Android system service that tracks how apps are used. The OS relies on it for app standby buckets, battery optimisation and the usage access API that Digital Wellbeing and parental control apps read. To do that it records timestamped events per user profile and writes them to disk in interval files. For an investigator, usagestats is the closest thing Android has to an execution and interaction log: it can show that an app was on screen at 17:43 and that the phone was unlocked two minutes earlier.
Where it lives
| Android | Path | Format |
|---|---|---|
| 8, 9 | /data/system/usagestats/<user>/ | XML files |
| 10 | /data/system/usagestats/<user>/ | Protobuf (files migrated from XML on upgrade) |
| 11 to 16 | /data/system_ce/<user>/usagestats/ | Protobuf, package and class names replaced by integer tokens resolved through the mappings file in the same folder |
Inside the folder: daily/, weekly/, monthly/, yearly/ and a version file. Each interval file is named after its start time in Unix milliseconds, for example daily/1727654400000. Upgraded phones sometimes keep an older /data/system/usagestats/ tree next to the new one: collect both. OEM builds keep the AOSP layout; the Digital Wellbeing app keeps a separate database in its own sandbox.
What it proves
- An app's activity came to the foreground (
ACTIVITY_RESUMED) and left it (ACTIVITY_PAUSED,ACTIVITY_STOPPED), with the component name, which tells you which screen of the app. - The screen became interactive or went off (
SCREEN_INTERACTIVE,SCREEN_NON_INTERACTIVE). - The lock screen was shown or dismissed (
KEYGUARD_SHOWN,KEYGUARD_HIDDEN), a good proxy for unlocks. - The device started or shut down, a user profile was unlocked or stopped.
- A foreground service started or stopped, a notification interrupted the user, an app's standby bucket changed.
It does not show what the user did inside the app, and some events come from system actions (an app launched by another app, a notification trampoline). Aggregates in weekly, monthly and yearly files give totals, not individual sessions.
Key fields
| Event type | Value | Meaning |
|---|---|---|
ACTIVITY_RESUMED (MOVE_TO_FOREGROUND) | 1 | Activity visible and in front |
ACTIVITY_PAUSED (MOVE_TO_BACKGROUND) | 2 | Activity left the foreground |
CONFIGURATION_CHANGE | 5 | Rotation, locale, dark mode |
USER_INTERACTION | 7 | User interacted with the app (including notifications) |
SHORTCUT_INVOCATION | 8 | App shortcut used |
STANDBY_BUCKET_CHANGED | 11 | App standby bucket changed |
NOTIFICATION_INTERRUPTION | 12 | Notification made sound, vibrated or peeked |
SCREEN_INTERACTIVE / SCREEN_NON_INTERACTIVE | 15 / 16 | Screen on / off |
KEYGUARD_SHOWN / KEYGUARD_HIDDEN | 17 / 18 | Lock screen shown / dismissed |
FOREGROUND_SERVICE_START / _STOP | 19 / 20 | Foreground service lifecycle |
ACTIVITY_STOPPED | 23 | Activity no longer visible |
DEVICE_SHUTDOWN / DEVICE_STARTUP | 26 / 27 | Power cycle |
USER_UNLOCKED / USER_STOPPED | 28 / 29 | Profile unlocked (CE storage available) / stopped |
Each event also carries the package, the class (activity) where relevant, and for some types an instance ID or task root.
Timestamps
The file name is the interval start in Unix milliseconds. In both the XML and protobuf formats, event times are stored as offsets in milliseconds from that start, so the absolute UTC time is filename + offset. Parsers do this for you; if you decode by hand, a set of events all in January 1970 means you forgot to add the base. The XML era also stores per-package aggregates such as lastTimeActive and timeActive (offsets and durations in milliseconds).
# Android 8/9: events of one daily file, with absolute times
base=1727654400000
xmllint --xpath '//event' daily/$base | head
# Android 10+: inspect a protobuf file without a schema
protoc --decode_raw < daily/1727654400000 | head -40
Retention
AOSP prunes old files by interval: roughly 10 days of daily files, 4 weeks of weekly, 6 months of monthly and a few years of yearly files. The per-event log is kept in the daily files, so individual foreground events usually reach back only about ten days; older periods only have aggregates. OEMs can change these values, and a factory reset or user removal deletes the store.
Collection
- Full file system extraction: copy the whole
usagestatsfolder, includingmappingsandversion. On Android 11 and later it lives in credential-encrypted storage, so the phone must be AFU (see file-based encryption). - Logical:
adb shell dumpsys usagestatsprints recent in-memory stats and events without root. Save it immediately; it reflects only the current in-memory window. - Bugreport: the
usagestatsservice dump is included.
Parsing
- ALEAPP parses usagestats in both XML and protobuf formats, resolves tokens through
mappings, and adds the file base time. - blackboxprotobuf and
protoc --decode_rawlet you inspect a protobuf file field by field when a parser disagrees or a new release changes the layout. - Commercial suites (AXIOM, UFED, Oxygen) include usagestats in their activity timelines.
Investigator tips
- Pair
KEYGUARD_HIDDENwith the nextACTIVITY_RESUMEDto show the user unlocked the phone and opened a specific app, for example Settings before an accessibility service was enabled. - Use
DEVICE_SHUTDOWNandDEVICE_STARTUPto explain gaps in other artifacts and to spot a reboot right before seizure. - Put usagestats next to installed packages: a new app's first
ACTIVITY_RESUMEDshould follow its install time; a background-only app with no activity events but foreground services is suspicious. - Confirm that Chrome or WhatsApp was in the foreground when a visit or a sent message is attributed to the user.
- Android 11+ files without their
mappingsfile show numbers instead of package names: make sure the extraction captured it.
See also
Related artifacts
- Installed Apps: packages.xml and packages.list
- Chrome on Android: the History Database
- WhatsApp on Android: msgstore.db and wa.db
- Wi-Fi Networks on Android: WifiConfigStore.xml
- Digital Wellbeing: app_usage Database
- Batterystats and Battery History on Android
- Recent Tasks and Snapshots: recent_tasks, snapshots
- Android Notification History and notification_log.db