mirror of
https://github.com/screentinker/screentinker.git
synced 2026-08-14 06:16:20 -06:00
ScheduleEval uses java.time — Instant, LocalDate, ZoneId — which is API 26. minSdk is 24, and core library desugaring was never enabled, so on Android 7.0/7.1 the first evaluation threw NoClassDefFoundError. Those API levels are still common on cheap signage sticks and older TV boxes. The damage was much worse than a failed check, because NoClassDefFoundError is an Error, not an Exception. The evaluator's deliberate fail-open guard — written so that "a blank screen is worse than an over-running promo" — did not catch it. The Error propagated out of scheduleAllows, through firstActiveIndex and updatePlaylist, past another catch(Exception), and was only swallowed at the service boundary. Because updatePlaylist aborted before the download block, no content was fetched either; and on a cold start from cache the same Error reached a handler that clears the playlist cache. So the moment anyone used dayparting or expiry, those panels sat on "waiting for content" with nothing downloaded and nothing cached, and a reboot did not help. The stated contract was inverted on exactly the hardware it was meant to protect. Two changes. Desugaring is the real fix: java.time now exists on API 24/25, so the code runs as written. The guard is widened to Throwable as well, so this class of failure can never again slip past a catch that was written to be total — that is belt and braces, not the fix. Release build assembles cleanly with desugaring on; 134 Android JVM tests green. Still to confirm on a real API 24/25 image before release — the unit tests run on the JVM, where java.time always exists, which is precisely why this was invisible to them. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Uaeo9MvzKoyXuN6ZsbhtkL |
||
|---|---|---|
| .. | ||
| src | ||
| build.gradle.kts | ||
| proguard-rules.pro | ||