Tier 0 — Glassbox: diagnostics for any app

A scan sweeps across pending jobs and a verdict appears: 7 pending — DeferredByDoze(deep), basis REPORTED.

Glassbox requires no migration. WorkManager jobs are the app’s own JobScheduler jobs, so the platform already reports on them (pending reasons, API 34+); two lines of integration expose that report.

// Application.onCreate
GlassBox.install(this)

// Anywhere, later:
Log.i(TAG, GlassBox.explain().render())
// device: DeferredByDoze(deep=true), DeferredByStandbyBucket(bucket=40)
// jobs:   DeferredByDoze(deep=true) [REPORTED]
//   DOZE = Doze(mode=DEEP)
//   STANDBY_BUCKET = Bucket(bucket=40)
//   ... one evidence line per sampled signal

The Explanation type

GlassBox.explain() returns a typed Explanation rather than a string:

  • Device-level causes — standby bucket, Doze state, background restriction, Data Saver.
  • Per-job causes — the platform’s own pending-job reasons for each of the app’s jobs.
  • Basis — every cause is labeled REPORTED (the platform said so, via getPendingJobReasons) or INFERRED (deduced from signal state). The distinction is preserved so you know how much to trust each line.
  • Evidence — the raw signal observations the verdict was folded from.

The signal hub

Glassbox reads twelve platform signals into snapshots and persists their transitions: standby bucket, Doze, background restriction, Data Saver, pending-job reasons, network validation, battery-optimization exemption, maintenance windows, process deaths, thermal status, charge time, and thread pressure. Sampling is never polled — snapshots are taken when platform broadcasts fire and again on demand when you ask for an explanation.

The same hub powers the full runtime’s diagnostics when you adopt later tiers.


This site uses Just the Docs, a documentation theme for Jekyll.