Open Source / ALEAPP #1796

Usage, settings and boot history from bug reports

A bug report records which apps came to the foreground in the last day, why recent processes ended, what every setting held, and why the phone last started. ALEAPP showed those parts as "not read". This contribution adds five tables for them, each with a stated rule for its times.

  • Daniel Addai, SectraTEK Lab
  • Merged
  • CC BY 4.0

Summary

  • A bug report holds the last day of app foreground changes, a history of ended app processes, every settings table and the boot reason history. After the first reader was merged, the Sections table listed these parts of the text as "not read".
  • This change adds five artifacts on the same one-pass reader: Usage Events, Process Exit Info, Settings, Settings Changes and Boot Reasons. The five boot reason properties also become rows of Device Facts.
  • Each time follows a stated rule. Epoch milliseconds are read as UTC, wall-clock text is converted with the report's own time zone, and a value that is not a time keeps its printed text and gets no UTC value.
  • Reason words, event types and setting names are shown as the platform printed them. The artifacts present data only: no severity, no finding, no interpretation.
  • The pull request was stacked on ALEAPP #1795 and merged on 26 October 2026.
  • 5artifacts added
  • 118files in the pull request
  • 6,107lines added, mostly synthetic fixtures and baselines
  • 15,043usage events in the largest of five reports

Methodology note

Drafted with AI assistance and reviewed by the author before publication.

The issue

An examiner has one question about the last day and three about the longer past. Which app was in the foreground around a time of interest? Did an app process end, and with which reason? Is a debugging or developer setting on, and did a setting change? Why did the phone last start? A bug report holds material for all four, spread over five places, each with its own shape. After the first reader was merged, the Sections table listed all of them as "not read" (Figure 1).

The usage list comes in two forms. The Android 16 phones in the research reports print epoch milliseconds; the Android 10 and Android 15 reports print wall-clock text without a zone. Three of the five reports print the list twice, once in the usagestats service dump and once in the CHECKIN USAGESTATS section, so an event can appear twice (3,075 and 3,079 rows on the Huawei report, for example). The two Samsung reports print only the check-in list. Some builds also print a time that was never set, such as 1970-01-01 or 1973-08-29 05:00:27, which would read as a real date if converted without care.

The other parts have their own traps. The settings history prints a month, day and clock time with no year. The activity dump is written more than once, and in the Samsung A-series report the first copy ends at the platform's 500 millisecond limit and holds no exit entries; they are in the second copy. A settings value can run over several lines. Each is a place where a quick extraction returns a plausible table that is short or wrong.

Read By column of the Sections table for five sections, before and after this changeA table with five rows: usagestats, CHECKIN USAGESTATS, activity, settings and SYSTEM PROPERTIES. After the first pull request the first four are marked not read and SYSTEM PROPERTIES is read by Device Facts. After this change they are read by Usage Events, Usage Events, Process Exit Info, Settings and Settings Changes, and Device Facts with Boot Reasons.SectionKindRead By beforeRead By afterusagestatsdumpsys servicenot readUsage EventsCHECKIN USAGESTATScommandnot readUsage Eventsactivitydumpsys servicenot readProcess Exit Infosettingsdumpsys servicenot readSettings; Settings ChangesSYSTEM PROPERTIEScommandDevice FactsDevice Facts; Boot ReasonsRead By is a column of Bug Report - Sections: "not read" means no artifact presents the section.
Show this figure as a table
Read By for five sections before and after ALEAPP #1796
SectionKindRead By beforeRead By after
usagestatsdumpsys servicenot readUsage Events
CHECKIN USAGESTATScommandnot readUsage Events
activitydumpsys servicenot readProcess Exit Info
settingsdumpsys servicenot readSettings; Settings Changes
SYSTEM PROPERTIEScommandDevice FactsDevice Facts; Boot Reasons
Figure 1The section index shows what is and is not presented. Four sections that the first pull request marked "not read" are read by the five artifacts added here. Source: READ_BY table in scripts/dumpstate_reader.py, before and after the change (ALEAPP #1795 and #1796); section names only, not synthetic values.

The essence

Five artifacts are added. Each reads one part of the text through a reader registered for that section, in the same single pass that the earlier artifacts use. Every row carries its source line, and every time keeps its printed text beside the UTC value.

The five artifacts added by ALEAPP #1796
ArtifactSource in the textA row isTime rule
Bug Report - Usage EventsThe "Last 24 hour events" list of each user, in the usagestats service dump and in the CHECKIN USAGESTATS sectionOne event: type, package, class, flags and the other key=value pairsEpoch milliseconds from 2009 to 2100 read as UTC; wall-clock text converted with the report zone; anything else keeps its text and gets no UTC
Bug Report - Process Exit InfoApplicationExitInfo entries in the activity dumpOne entry: process, uid, user, reason, sub-reason, status, importance, descriptionWall-clock time with milliseconds converted with the report zone; before 2009, no UTC
Bug Report - SettingsThe global, secure and system tables of each user in the settings dumpOne entry: name, value, writer, default, defaultSystemSet, preserved in restoreNo time. A value over several lines is joined with one space; a long value is shown up to 2,000 characters with its full length
Bug Report - Settings ChangesThe History (name) entries that the Android 16 reports print under each settingOne change: mode, old value, new value, package, callerYear inferred from the report time (Figure 4)
Bug Report - Boot Reasonspersist.sys.boot.reason.history in the system propertiesOne history entry: reason, sub-reason, positionLast number read as epoch seconds, shown as UTC from 2009 to 2100

The CONFIG SETTINGS table, which held 651 to 2,013 entries in the tested reports, is counted in the log and not listed. The pending-events list and the interval statistics of the usage dump are not read; the notes say so.

Our methodology

Each section was read in real reports before a reader was written for it. A usage line is a set of key=value pairs. An exit entry starts with ApplicationExitInfo #N and continues over several lines. A settings entry starts with _id: and ends in trailing fields. A change entry sits under a History (name) line. Figure 2 shows how each section reaches its artifact.

Time got the most care. A number is read as epoch milliseconds only when it falls between 2009 and 2100, which rejects zero, small counters and garbage without guessing a unit. Wall-clock text is converted only with the zone the report records. A change in the settings history has no year, so the reader takes the latest year, this one or the one before, that does not put the change more than a day after the report time (Figure 4).

From five sections of the bug report text to five artifacts, with the time rule of eachThree columns and five rows. Each row maps a section of the text to the reader that handles it and to the artifact it feeds, with the time rule: usagestats and CHECKIN USAGESTATS feed Usage Events; the activity dump feeds Process Exit Info; the settings dump feeds Settings and Settings Changes; the boot reason history property feeds Boot Reasons.Section of the textReaderArtifact and time ruleusagestats service dumpLast 24 hour events, per userUsageServiceReaderkey=value pairs of each eventUsage Eventsms read as UTC; text via zoneCHECKIN USAGESTATS sectionthe same list, in its other formUsageCheckinReadersame fields; Source Section keptUsage Events (same table)Source Section tells them apartactivity service dumpApplicationExitInfo entriesExitInfoReaderpackage heading, reason, statusProcess Exit Infowall time via zone; < 2009 nonesettings service dumpGLOBAL, SECURE, SYSTEM tablesSettingsReadervalues joined; History (name)Settings; Settings Changeschange year inferred (Figure 4)SYSTEM PROPERTIES (getprop)persist.sys.boot.reason.historyPropertiesReaderreason, sub-reason, epoch sBoot Reasonsepoch seconds, 2009 to 2100
Figure 2Five sections, five readers, one pass. A reader is registered under the name of the section it reads, so the text is still read once per run. Source: scripts/dumpstate_reader.py (UsageServiceReader, UsageCheckinReader, ExitInfoReader, SettingsReader, PropertiesReader) and scripts/artifacts/bugreportActivity.py in ALEAPP #1796; diagram.

The counts were checked the way the first pull request's were. Each row count equals a count made from the raw text with plain regular expressions and the rows of an independent parser written for another tool, compared field by field and, for times, in UTC to the millisecond. The only fields that differ are three settings values with line breaks. The other parser keeps trailing default: tokens in such a value; here the value ends at the first trailing token of its last line and the line break is shown as a space.

One report staged twice in two folders doubled every artifact exactly. Two Android users are in real data too: the Motorola report has 1,229 exit entries and 146 settings rows for user 11. A second user in the usage events was built on constructed text, because only user 0 had events.

The 82 new unit tests add cases that real reports did not contain: calendar edge times (year 1 and year 9999), non-ASCII digits, a damaged line at column 0, a settings value with line breaks that contains the word default:, a last exit entry at the end of the dump, change times around the report time, and a boot history with blank lines, a missing stamp and 550 entries.

Rows per artifact in each of five research bug reportsA grid of five artifacts by five reports with the row counts. Usage Events: 15,043; 4,114; 6,154; 14,147; 9,841. Process Exit Info: 5,154; 7,170; 0; 6,187; 0. Settings: 1,057; 1,290; 938; 647; 439. Settings Changes: 1,807; 1,109; 0; 0; 0. Boot Reasons: 4; 4; 3; 4; 2. Cells with 0 are drawn dashed.Samsung A-seriesAndroid 16Samsung S-seriesAndroid 16HuaweiAndroid 10MotorolaAndroid 15Transsion-brandAndroid 10Usage Events15,0434,1146,15414,1479,841Process Exit Info5,1547,17006,1870Settings1,0571,290938647439Settings Changes1,8071,109000Boot Reasons443420 rows, equal to the count in the raw text: the build prints no such entries.
Show this figure as a table
Rows per artifact and research bug report (ALEAPP #1796)
ArtifactSamsung A-series (Android 16)Samsung S-series (Android 16)Huawei (Android 10)Motorola (Android 15)Transsion-brand (Android 10)
Usage Events15,0434,1146,15414,1479,841
Process Exit Info5,1547,17006,1870
Settings1,0571,290938647439
Settings Changes1,8071,109000
Boot Reasons44342
Figure 3Every count equals a count made from the raw text. A zero is a real result for that build, not a failed read: the Android 10 reports print no exit entries, and only the two Android 16 Samsung reports print a settings history. Source: ALEAPP #1796 pull request text, rows per report. Real aggregate counts from five research bug reports, not synthetic.

Damaged input was tried on the same 14 variants of one real text as in the first pull request. No variant raised an error or failed an artifact. The text repeated twelve times gave exactly twelve times the usage events (118,092) and settings rows (5,268), in 24 seconds with a 318 MB peak. One variant replaces one space in 5,000 with a carriage return, a form feed or a NUL byte. It damages headings, and one usage list (4,884 of 9,841 rows) is lost with its damaged heading. The pull request records that as expected. LAB-TR-0001 lists the same variant as the one altered input that did not meet its expectation, and leaves open whether it is a defect.

Figure 3 shows the real-data runs. Zeros are results: the Android 10 builds print no exit entries, and the settings history exists in the two Android 16 Samsung reports only. An empty table says nothing about the device. Zone conversion was the identity on every real row because all five reports record UTC+0; other zones are in the constructed fixtures.

The value

The first answer is about time. The usage list covers the last 17 to 24 hours in the tested reports, so it can place an app in the foreground around a moment of interest, and the Source Section column tells a duplicate from a new event. The exit history reaches much farther, because it is the history the platform kept and not a log of the last day: the tested reports held entries spanning about six months (Samsung A-series), two and a half years (Samsung S-series) and two years (Motorola). Boot reasons give the last two to four starts with the platform's own words.

The second answer is about state. The Settings table lists what the settings provider held when the dump ran, per user, with the package that wrote each entry. The Settings Changes table, where a build prints it, adds the order in which values changed. Together they let an examiner ask whether a setting was different earlier, which a bare value cannot answer.

How the year of a settings change is inferredTwo timelines from 2025 to 2027. A change printed as 03-14 can be 2025-03-14 or 2026-03-14; both fit before the report time, and the later year, 2026, is used. A change printed as 11-20 cannot be 2026-11-20 because that is after the report time, so 2025-11-20 is used. The report time in this synthetic example is 2026-10-25.Printed in the dump: 03-14 09:21:07.123202520262027report timePrinted in the dump: 11-20 08:00:00.000202520262027report time2026-03-14latest year that fits2025-03-14also fits, but earlier2025-11-20latest year that fits2026-11-20after the report timeRule: the latest year, this one or the one before, that does not put the change more than a day after the report time.
Show this figure as a table
Year inference for two synthetic settings changes (report time 2026-10-25)
PrintedCandidate yearsFits the ruleYear used
03-14 09:21:07.1232026, 20252026-03-14 and 2025-03-142026
11-20 08:00:00.0002026, 20252025-11-20 only2025
Figure 4The settings history prints month, day and time but no year. The reader takes the latest year that does not place the change after the report. A change older than a year would get a year too late. Source: rule from the Settings Changes notes in scripts/artifacts/bugreportActivity.py and setting_change_time in scripts/dumpstate_reader.py; dates are a synthetic example, invented values.

Several limits matter in a case. A usage row records that the usage statistics service noted that event type for that package; it does not say what caused it. An exit row says the platform recorded that a process ended with the printed reason, not who ended it. A boot reason entry says the platform recorded a start with that reason, not why. A setting row says what was configured, not who set it.

Settings also describe the moment of capture, which can include what taking the report required. In the Lab's seven research bug reports, developer options were on in six and USB debugging was off in all seven, a pattern that fits reports taken from the developer options on the device (LAB-TR-0019). Treat such values as observed, not as the user's choice. Values can include text such as device and Bluetooth names, so an export deserves the same care as the report.

Unverified on real data: Android 11 to 13, other vendors, and a second user's usage events. A settings change older than a year would be given a year too late; the tested spans are 297 and 362 days.

Where this sits in the Lab's research

The artifacts support Lab Technical Report LAB-TR-0001, "Making Silent Failures Visible: A Single-Pass Section Reader for Android Bug Reports". Its Table 5 reports that usage events, process exits, settings changes and boot history agreed with a second parser on counts, fields and UTC values on all five reports, and that settings entries differed in three values that span several lines, which the two parsers split differently on purpose. Its Table 7 lists three reader defects that concern this change, all found in validation: a lost last exit entry, wrongly split multi-line settings values, and a pending-events list read as events.

Cite: Addai, D. (2026). Making Silent Failures Visible: A Single-Pass Section Reader for Android Bug Reports. Lab Technical Report LAB-TR-0001, version 1.1. Zenodo. doi:10.5281/zenodo.23719508. Read it on this site at LAB-TR-0001.

The report LAB-TR-0019, "Not Found Is Not Off", is available on this site as a preprint; the Zenodo deposit is pending. It measures what full file systems and seven research bug reports can establish about a phone's security settings. LAB-TR-0017, a white paper also available on this site as a preprint, maps where the same settings tables live in a full file system; it did not examine bug reports.

Sources

Every number and claim in this post, and where it comes from. Numbers that could not be sourced were left out.

Sources for the numbers and claims in this post
Claim or numberSource
Five artifacts added on the same one-pass reader; five boot reason properties become Device Facts rowsPull request text, "What this changes"
Time rules: epoch ms read as UTC (2009 to 2100), wall-clock text via the report zone, 1970-01-01 and 1973-08-29 05:00:27 get no UTCPull request text; plausible_epoch_ms, usage_time in scripts/dumpstate_reader.py
118 files; 6,107 lines addedGitHub summary of the pull request
Rows per report: usage events 15,043, 4,114, 6,154, 14,147, 9,841; exits 5,154, 7,170, 0, 6,187, 0; settings 1,057, 1,290, 938, 647, 439; changes 1,807, 1,109, 0, 0, 0; boot reasons 4, 4, 3, 4, 2Pull request text, rows per report
Usage lists printed in both sections: 3,075 and 3,079 (Huawei), 4,920 and 4,921 (Transsion-brand), 7,073 and 7,074 (Motorola); the two Samsung reports print only the check-in listUsage Events notes in scripts/artifacts/bugreportActivity.py
Usage list spans 17 to 24 hours; exit history spans about six months, two and a half years and two yearsUsage Events and Process Exit Info notes in bugreportActivity.py
Android 10 reports print no exit entries; Android 10 and 15 reports print no settings history; boot reasons 2 to 4 entriesProcess Exit Info, Settings Changes and Boot Reasons notes
Activity dump written more than once; the Samsung A-series first copy ends at a 500 ms timeout and holds no entriesPull request text, "Anything reviewers should know"; Process Exit Info notes
Year of a settings change: latest year, this one or the one before, not more than a day after the report time; tested spans 297 and 362 daysSettings Changes notes; setting_change_time in dumpstate_reader.py; pull request text
CONFIG SETTINGS table of 651 to 2,013 entries counted, not listed; values over 2,000 characters cut with full length shownPull request text; Settings notes
Three settings values with line breaks differ from the independent parserPull request text, row-count check
Motorola report: 1,229 exit entries and 146 settings rows for user 11; same report staged twice doubles every artifactPull request text, "Second input"
243 passing cases against 171; 72 new cases; 1,683 unit tests against 1,601 (82 new)Pull request text, test record
Unit test cases listed (year 1 and 9999, non-ASCII digits, damaged line, 550 entries and others)Pull request text, "Constructed-input unit tests"
Twelve repeats: 118,092 usage events, 5,268 settings rows, 24 s, 318 MB; damaged-space variant loses 4,884 of 9,841 usage events, recorded as expectedPull request text, "Adversarial inputs"
Same variant is the one altered input that did not meet its expectation; cause openLAB-TR-0001, section 5.3 and Table 6
Agreement with the second parser; defects 2, 6 and 7LAB-TR-0001, Table 5 and Table 7
Developer options on in 6 of 7 research bug reports; USB debugging off in all 7LAB-TR-0019, section 5 (observed only)
LAB-TR-0001 DOI; LAB-TR-0019 and LAB-TR-0017 available on this site as preprints; Zenodo deposit pendingLab DOI list (DOIS.md); Lab series plan (INVENTORY.md)
Merged 26 October 2026; stacked on ALEAPP #1795GitHub merge record (mergedAt); pull request text
Dates in Figure 4Invented by the author for illustration (synthetic example)