The equalizer drawables were never in the shipped binary. Verified by
pulling base.apk off the device and reading it:
res/drawable/ic_stat_pluriwave.xml PRESENT (added 02-07)
res/drawable/ic_auto_eq_on.xml ABSENT (added 31-07, 2540556)
res/drawable/ic_auto_eq_off.xml ABSENT
Neither as a zip entry nor as a name in resources.arsc. Both files are in
git with content and on disk; the older sibling in the same folder is in
the APK. The difference is when they were added.
This runner is self-hosted and the workflow never cleaned, so build/
survives between runs and Gradle's incremental resource merge went stale:
resources present when the cache was built kept working, resources added
afterwards silently never made it in.
The cost was weeks of wrong diagnosis. getResourceId returned 0 for that
icon, PlaybackStateCompat.CustomAction.Builder throws on a 0 icon, and
that throw aborts AudioService.setState BEFORE mediaSession.setActive --
so Android Auto held a frozen, inactive session. On the device that
surfaced as a dead playback screen, a play button that never became
pause, PluriWave losing its pane to whichever app did have an active
session, and audio that played "as if it were not the app". One cause,
four symptoms.
Dart changes always shipped because Dart is recompiled every build, which
is exactly why this hid for so long: every fix appeared to land and
nothing behaved differently.
flutter clean costs build time. It buys the guarantee that what is in git
is what is in the binary, which this project just spent weeks not having.
Adds tool/check_arb_placeholder_corruption.py, a static check that flags
literal "?" glued to an ICU placeholder brace in any lib/l10n/app_*.arb
value that has a placeholders metadata block. This is the exact corruption
shape fixed in the previous commit; flutter analyze doesn't catch it since
the JSON/ICU stays syntactically valid. Wired as a CI step before
flutter analyze so it fails fast.
Also audited lib/l10n/app_localizations_ext.dart (hand-maintained weekday/
month/date-sentence maps, not covered by ARB tooling): all 22 locale maps
have the full 13/13 keys with no corruption or leftover English — no
changes needed there.
The app is stable, so mark this as the 1.0.0 milestone. The CI bump step
now honors a [version set] marker: when present it ships the pinned semver
as-is and only advances the build number (Play requires it monotonic),
instead of the automatic patch bump that cannot cross the 0.x -> 1.0.0
boundary. Normal commits keep auto-incrementing the patch (1.0.1, 1.0.2, ...).
- Remove complex Python wrapper that caused timeout issues
- Use direct flutter test with --concurrency=1 --timeout=60s
- Simplify cleanup with pkill instead of Python loop
- Increase timeout from 4m to 15m (tests take ~10s but CI overhead is high)