Implements #32 and #33: a strictly opt-in, F-Droid-safe debug reporting
client. Nothing ever leaves the device unless the user taps Submit.
#32 capture:
- CrashReporter installs a Thread.setDefaultUncaughtExceptionHandler (wired in
LibreMailApplication) that persists a structured crash record (stack trace +
app/version/device metadata + recent log ring buffer) locally, then delegates
to the previous handler. Never auto-sent.
- RingLogBuffer + AppLog: a bounded in-memory, non-PII log ring buffer.
- DiagnosticsCollector assembles a minimal bundle: app version, Android/device,
a fixed non-PII settings allow-list, and the log buffer.
- ReportStore persists pending reports as JSON files (not Room, so crash-time
saves are robust and independent of the encrypted/migrating DB).
- "Report a problem" entry point in Settings creates a report on demand.
#33 review & submit:
- ReportReviewScreen shows the full payload verbatim (exactly what would be
sent), a free-text comment field, and a prominent PII disclaimer, with
explicit Submit / Discard and Copy / Save-to-file alternatives.
- Submission is user-initiated only: ReportUploadWorker (WorkManager, queue +
retry, success/failure surfaced) POSTs to BuildConfig.DEBUG_REPORT_ENDPOINT,
which is EMPTY by default (ingest server #34 is out of scope for this repo).
- On next launch a saved crash report is offered for review via a dialog.
Tests: 23 JVM unit tests covering crash capture + persistence (offered next
launch), diagnostic-bundle assembly (minimal, non-PII), JSON round-trip, and
the "nothing sent without Submit" invariant.
Closes#32Closes#33
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>