Releases: SysAdminDoc/OpenLumen
OpenLumen v0.5.0
OpenLumen v0.5.0 — first signed release (#1).
Rolls up the rev 5 distribution / platform / CI refresh, the 21-fix rev 6 audit pass (C146-C165 + C170), the three rev-6 follow-ups (C166, C168, C169), and the small backlog batch (C114, C53 stretch, C115, C107, C110).
Highlights
- Direct Boot restore: tint returns on reboot before unlock.
- 4x1 widget highlights the currently-active preset.
- Fine ±0.5% dim nudge buttons (PWM-sensitive users).
- Diagnostic log filters.
- Matrix-backed CVD presets.
- Roborazzi screenshot goldens for visual regression.
Fixed (release pipeline)
- v0.4.0 shipped as an unsigned APK (
OpenLumen-v0.4.0-release.apkhad no certificates, Android rejected install with "Install Parse Failed No Certificates"). v0.5.0 is signed with the production key under v2 + v3 schemes. - Hardened release workflow now hard-fails if the keystore secret is missing instead of silently uploading unsigned APKs as if they were release artifacts.
- Regenerated stale
gradle/verification-metadata.xmlthat had 93+ missing checksums blocking every Gradle invocation.
Install
Sideload OpenLumen-v0.5.0-release.apk from the release assets. v0.4.0 users will need to uninstall the unsigned APK first (different signing chain — Android will refuse to upgrade across signers).
See CHANGELOG.md for the full audit trail.
OpenLumen v0.4.0
⚠️ This release is broken — install v0.5.0+
The v0.4.0 OpenLumen-v0.4.0-release.apk asset was uploaded unsigned (the keystore secrets weren't configured at release time). Android will reject it with "Install Parse Failed No Certificates" (#1).
Use v0.5.0 or newer — those releases are signed by the workflow's hardened signing path.
Original v0.4.0 changelog still applies — see CHANGELOG.md. All v0.4.0 fixes are included in v0.5.0.
OpenLumen v0.3.0
Changelog
All notable changes to OpenLumen are documented here.
The format is loosely based on Keep a Changelog,
and this project adheres to Semantic Versioning.
[0.3.0] — 2026-05-16
Added
Schedule.nextTransition()— pure function that returns the next moment the
active state would flip for a givenScheduleMode. Returns null for
AlwaysOn/AlwaysOff.ScheduleAlarmReceiver— fires theACTION_REEVALUATEintent at the
scheduled transition time, nudging the foreground service to re-apply.- AlarmManager-driven schedule:
LumenServicenow reschedules
setExactAndAllowWhileIdleafter every re-evaluation. Survives Doze; falls
back tosetAndAllowWhileIdleifSCHEDULE_EXACT_ALARMis denied or the OEM
throws a SecurityException. - Profile export / import via Storage Access Framework
(ActivityResultContracts.CreateDocument+OpenDocument). Default filename
uses today's date. JSON is pretty-printed. CrashLogger— local-only uncaught-exception handler that appends a
timestamped stack trace tofilesDir/crash.log. Auto-trims to ~32 KB once it
exceeds 64 KB. About screen gains a "View crash log" dialog with Clear/Close.- About screen is now scrollable; gains "Backup" and "Diagnostics" cards.
Changed
LumenService60-second ticker has been removed. Schedule transitions are
driven by the AlarmManager broadcast, light-sensor changes by the existing
Flow collector. Net effect: zero background work between transitions.- Manifest declares
SCHEDULE_EXACT_ALARM+USE_EXACT_ALARMpermissions and
theScheduleAlarmReceiver. PreferencesStoreJson now usesprettyPrint = trueso exported files are
human-readable.
Privacy
- Crash log is local-only — the app still has no
INTERNETpermission. No
upload, no telemetry. Users can share manually if they choose.
[0.2.0] — 2026-05-16
Added
- Custom RGB color picker on the Home screen with three labeled sliders
(R / G / B), each with a colored swatch and a live numeric value, plus a
combined preview swatch. - Per-channel gamma sliders (γR / γG / γB, range 0.5–2.5).
LumenMatrix.scaledRgb()
now folds gamma into the math:effective = pow(scale * (1 - dim), 1 / gamma). - Intensity slider (0–100%) that lerps the active preset toward identity, so the
user can fade the filter without re-selecting presets. - Material 3 24-hour
TimePickerDialogfor fixed-time schedule's start/end. - Manual decimal-degrees location entry dialog (no Play Services dep) with
lat/lng range validation. - Sunset and sunrise offset sliders (±180 minutes, 5-minute step) for the
solar schedule mode. - Ambient-light-sensor activation: switch + threshold slider (0–200 lux) +
live lux readout + calibration button. Activation logic is now an OR
between schedule-active andlux < threshold. OverlayPermissionCardon Home — whenSYSTEM_ALERT_WINDOWis not granted,
surfaces a rationale + button that opensMANAGE_OVERLAY_PERMISSIONfor the
package. Self-hides once granted.- Gradle 8.11.1 wrapper (jar + properties +
gradlew+gradlew.bat) so the
project builds without a system Gradle install.
Changed
LumenService.matrixFor()now always applies user gamma onto the chosen matrix
(preset OR custom). Gamma is a global "tone" knob independent of preset.ScheduleScreenmode cards are now whole-card clickable (not just the radio
button). Whole screen is vertically scrollable.
Fixed
LumenServicebrokencurrentPrefs()pattern that calledcollectLatest
inside a suspend function and never returned. Replaced with an
AtomicReference<Preferences?>written by the single long-lived collector;
ticker reads the snapshot.- Activation/decision logic no longer triggers spurious engine re-applies when
the schedule state hasn't changed and the matrix is equal (proper==
comparison on the data class).
[0.1.0] — 2026-05-16
Initial scaffold release.
Added
- Four
ColorEngineimplementations:ColorDisplayManagerEngine,
SurfaceFlingerEngine,KcalEngine,OverlayEngine. - Runtime
DriverProbethat picks the highest-rank available engine, with a
user override in Settings → Driver. - 11 named presets (Night / Amber / Red / Salmon / Sepia / Grayscale / Deep Sleep /
Protan / Deutan / Tritan / Off). - NOAA solar-position calculator (hand-rolled, no external library) for
sunset-to-sunrise scheduling. - Fixed-time schedule mode with midnight wrap.
- Ambient-light sensor adapter with EMA smoothing.
- Foreground service with
specialUseforegroundServiceType (Android 14+ compliant). - Quick Settings tile for one-tap toggle.
- Boot receiver — restores filter on
BOOT_COMPLETED. - DataStore-backed preferences with JSON whole-blob serialization.
- Compose UI with five tabs (Home / Schedule / Presets / Driver / About).
- Catppuccin Mocha theme + AMOLED true-black surface.
Privacy
- No
INTERNETpermission requested. App is fully offline. - No analytics, no crash reporting, no telemetry.
OpenLumen v0.2.0
Changelog
All notable changes to OpenLumen are documented here.
The format is loosely based on Keep a Changelog,
and this project adheres to Semantic Versioning.
[0.2.0] — 2026-05-16
Added
- Custom RGB color picker on the Home screen with three labeled sliders
(R / G / B), each with a colored swatch and a live numeric value, plus a
combined preview swatch. - Per-channel gamma sliders (γR / γG / γB, range 0.5–2.5).
LumenMatrix.scaledRgb()
now folds gamma into the math:effective = pow(scale * (1 - dim), 1 / gamma). - Intensity slider (0–100%) that lerps the active preset toward identity, so the
user can fade the filter without re-selecting presets. - Material 3 24-hour
TimePickerDialogfor fixed-time schedule's start/end. - Manual decimal-degrees location entry dialog (no Play Services dep) with
lat/lng range validation. - Sunset and sunrise offset sliders (±180 minutes, 5-minute step) for the
solar schedule mode. - Ambient-light-sensor activation: switch + threshold slider (0–200 lux) +
live lux readout + calibration button. Activation logic is now an OR
between schedule-active andlux < threshold. OverlayPermissionCardon Home — whenSYSTEM_ALERT_WINDOWis not granted,
surfaces a rationale + button that opensMANAGE_OVERLAY_PERMISSIONfor the
package. Self-hides once granted.- Gradle 8.11.1 wrapper (jar + properties +
gradlew+gradlew.bat) so the
project builds without a system Gradle install.
Changed
LumenService.matrixFor()now always applies user gamma onto the chosen matrix
(preset OR custom). Gamma is a global "tone" knob independent of preset.ScheduleScreenmode cards are now whole-card clickable (not just the radio
button). Whole screen is vertically scrollable.
Fixed
LumenServicebrokencurrentPrefs()pattern that calledcollectLatest
inside a suspend function and never returned. Replaced with an
AtomicReference<Preferences?>written by the single long-lived collector;
ticker reads the snapshot.- Activation/decision logic no longer triggers spurious engine re-applies when
the schedule state hasn't changed and the matrix is equal (proper==
comparison on the data class).
[0.1.0] — 2026-05-16
Initial scaffold release.
Added
- Four
ColorEngineimplementations:ColorDisplayManagerEngine,
SurfaceFlingerEngine,KcalEngine,OverlayEngine. - Runtime
DriverProbethat picks the highest-rank available engine, with a
user override in Settings → Driver. - 11 named presets (Night / Amber / Red / Salmon / Sepia / Grayscale / Deep Sleep /
Protan / Deutan / Tritan / Off). - NOAA solar-position calculator (hand-rolled, no external library) for
sunset-to-sunrise scheduling. - Fixed-time schedule mode with midnight wrap.
- Ambient-light sensor adapter with EMA smoothing.
- Foreground service with
specialUseforegroundServiceType (Android 14+ compliant). - Quick Settings tile for one-tap toggle.
- Boot receiver — restores filter on
BOOT_COMPLETED. - DataStore-backed preferences with JSON whole-blob serialization.
- Compose UI with five tabs (Home / Schedule / Presets / Driver / About).
- Catppuccin Mocha theme + AMOLED true-black surface.
Privacy
- No
INTERNETpermission requested. App is fully offline. - No analytics, no crash reporting, no telemetry.