KT

OpenLumen

Open-source CF.Lumen successor -- root-grade display color filter for Android with rootless fallback

KotlinAndroid
Delivery
Source-first
Browse code, README, and release notes on GitHub.
Primary lane
Kotlin / Android lane
The clearest adjacent context for this project inside the portfolio.
Freshness
Updated Jul 9, 2026
Latest release
No tag yet
README is the clearest project overview right now.

Preview

Using the generated project card as a clean fallback until a live capture is available.

OpenLumen card

Source at github.com/SysAdminDoc/OpenLumen.

README

Cached at build time, cleaned up for in-site reading, and linked back to the canonical GitHub source.

6 min read 1,246 words 13 sections
Contents
  1. OpenLumen
  2. Why OpenLumen?
  3. Display drivers
  4. Features (v0.6.5)
  5. Privacy
  6. Requirements
  7. Build
  8. Module layout
  9. Documentation
  10. Emergency off
  11. Roadmap
  12. License
  13. Acknowledgements

OpenLumen

![Version](https://img.shields.io/badge/version-0.6.5-cba6f7?style=flat-square) ![License: GPL-3.0](https://img.shields.io/badge/license-GPL--3.0--or--later-a6e3a1?style=flat-square) ![Platform: Android](https://img.shields.io/badge/platform-Android%208.0%2B-89b4fa?style=flat-square) ![Min SDK](https://img.shields.io/badge/minSdk-26-f9e2af?style=flat-square) ![No INTERNET](https://img.shields.io/badge/INTERNET-not%20requested-94e2d5?style=flat-square)

Open-source spiritual successor to Chainfire's CF.Lumen. Brings root-grade display color shifting and overlay-based fallback to modern Android, with the AOSP ColorDisplayManager path that CF.Lumen never had.

CF.Lumen has been dormant since December 2020. Red Moon, the main open-source overlay-only competitor, has been unmaintained since August 2022. OpenLumen exists to fill that gap on Android 14 / 15 with a clean Compose UI, no telemetry, and four runtime-selectable display drivers.


Why OpenLumen?

  • Four display drivers, runtime-detected — Auto uses a root driver when root is available; non-root devices use Overlay.
  • No INTERNET permission, ever. Fully offline, F-Droid-clean.
  • Catppuccin Mocha + AMOLED true-black Compose UI. Dark by default.
  • Quick Settings tile for one-tap toggling. CF.Lumen never shipped a tile.
  • GPL-3.0-or-later, aligned with Red Moon's lineage.
  • Modern Android targets — minSdk 26, targetSdk 35 (Android 15).
  • Stack: Kotlin · Jetpack Compose · Material 3 · Hilt · DataStore · kotlinx.serialization.

Display drivers

OpenLumen ships four ColorEngine implementations and probes each at first launch:

Driver Root? SoC Quality Notes
ColorDisplayManager No¹ Any (AOSP-derived) Framebuffer Same path the system Night Light uses. API 28+.
SurfaceFlinger Yes Any Framebuffer service call SurfaceFlinger color-transform. Works on Tensor/Exynos/MediaTek too.
KCAL Yes Qualcomm Panel driver Requires custom kernel exposing /sys/devices/platform/kcal_ctrl.0/kcal*.
Overlay No Any Compositor blend Universal fallback. Capped at ~80% opacity by Android 12+ rules.

¹ Some builds require granting WRITE_SECURE_SETTINGS via: adb shell pm grant com.openlumen android.permission.WRITE_SECURE_SETTINGS

The app falls back gracefully — Auto prefers the best available root path (SurfaceFlinger, then KCAL). Non-root devices use Overlay by default. If you want a specific driver such as ColorDisplayManager, Settings → Driver lets you pin one; if that pinned driver later probes as unavailable, OpenLumen resets to Auto instead of leaving the filter enabled with no visible effect.

Features (v0.6.5)

Color

  • Named presets: Night · Amber · Red · Salmon · Sepia · Grayscale · Deep Sleep · Protan · Deutan · Tritan
  • Custom R/G/B picker on Home with live color preview
  • Kelvin color-temperature slider (1000–10 000 K) with Tanner Helland conversion
  • Per-channel gamma sliders (γR / γG / γB, range 0.5–2.5)
  • Intensity slider (0–100% lerp toward identity) and dim slider (0–95%)
  • Contrast multiplier (0.5–2.0×)
  • AMOLED true-black clamp (opt-in; snaps very dim subpixels to fully off)
  • Blue-channel reduction indicator (physical measurement; not a sleep claim)

Scheduling

  • Solar-position schedule (NOAA algorithm, hand-rolled, no external library)
  • Sunset / sunrise offset sliders (±180 minutes)
  • Fixed-time schedule with Material 3 24-hour time pickers
  • Exact-alarm warning with a settings action when Android downgrades timed transitions to inexact alarms
  • "Until my next alarm" mode driven by the system alarm clock
  • Manual location entry with bundled offline city picker (~95 cities, no Play Services)
  • No runtime location permission; solar scheduling uses coordinates the user enters
  • Ambient-light-sensor trigger (lux below threshold engages filter; OR with schedule)
  • Live lux readout + "calibrate: use current reading" button
  • Smooth fade-in / fade-out transitions (Instant / 30 s / 5 min / 15 min / 30 min)
  • Schedule timezone hint so fixed-time windows are unambiguous after travel

Command surfaces

  • Quick Settings tile (subtitle shows active preset; long-press opens the app)
  • 1 × 1 toggle widget
  • 4 × 1 favorites widget (tap a chip to switch presets)
  • Foreground-service notification with Turn-off and Next-preset actions
  • Documented Tasker / Termux / ADB intent surface (docs/automation.md)

Persistence + reliability

  • Foreground service with specialUse type (Android 14+ compliant)
  • AlarmManager-driven schedule transitions (setExactAndAllowWhileIdle, Doze-resilient)
  • Boot persistence with crash-window safety net (no auto-restart after a recent crash)
  • Profile export / import as JSON via Storage Access Framework, with diff preview
  • Named profile library — save current configuration, load it back later
  • Previous-preset restore (one-tap undo of a preset change)
  • Local-only crash log + structured diagnostics log (filesDir/, viewable in-app)
  • Versioned preference schema with explicit migrations

Trust + privacy

  • No INTERNET permission, ever (local release checks reject builds that contain one)
  • No Play Services / Firebase / Google APIs (local release checks reject builds that pull them in)
  • No accessibility service, no usage-stats permission, no foreground-app detection
  • Permission rationale card for SYSTEM_ALERT_WINDOW (overlay driver)
  • In-app driver report (Copy or Share) with zero PII — captures device, build, granted permissions, every engine's probe result

Privacy

OpenLumen requests zero network permissions. No telemetry, no crash reporting, no remote config. Verify with:

aapt dump permissions OpenLumen-release.apk | grep INTERNET
# (no output)

Requirements

  • Android 8.0 (API 26) or higher
  • For best results: root with Magisk-managed su, OR a Pixel / Android-One device whose system Night Light is functional (the AOSP driver piggy-backs on it).

Build

git clone https://github.com/SysAdminDoc/OpenLumen.git
cd OpenLumen
./gradlew assembleRelease
# Fails unless release signing env vars are present.

Signed release builds require:

export OPENLUMEN_KEYSTORE=/path/to/release.jks
export OPENLUMEN_KEYSTORE_PASSWORD=...
export OPENLUMEN_KEY_ALIAS=openlumen
export OPENLUMEN_KEY_PASSWORD=...
./gradlew assembleRelease

Unsigned release output is only for local reproducibility or F-Droid rebuild checks:

./gradlew assembleRelease -Popenlumen.allowUnsignedRelease=true

Run the full local release gate before tagging:

py -3 tools/local_release_gate.py

Review stable version-catalog updates during release planning:

py -3 tools/dependency_update_review.py

Lint user-facing copy for unsupported health claims:

py -3 tools/health_claim_lint.py

For local reproducibility or F-Droid rebuild checks without signing keys:

py -3 tools/local_release_gate.py --allow-unsigned-release

Gate outputs are written to build/reports/openlumen-release-gate/: SBOM JSON, advisory report, release classpath, SHA-256 sums, and signature status.

Module layout

OpenLumen/
├── app/             — Compose UI, foreground service, tile, boot receiver
├── core-engine/     — ColorEngine abstraction + 4 driver impls + DriverProbe
├── core-schedule/   — NOAA solar calculator, schedule modes, light sensor adapter
└── core-prefs/      — DataStore-backed prefs, JSON serialization

Documentation

For users
For contributors
  • Architecture overview — modules, runtime flow, engine contract
  • Contributing — style, tests, driver-work expectations
  • Translations and localization — how to contribute a translation
  • Device validation matrix — per-engine smoke flow, current device coverage
  • Driver report matrix helper: py -3.12 tools/driver_report_matrix.py report.txt
  • Overlay viewport smoke: rtk powershell -NoProfile -ExecutionPolicy Bypass -File tools\overlay_viewport_smoke.ps1 -Serial emulator-5554 -Package com.openlumen.debug
  • Profile import lineage formats — notes for future Red Moon / CF.Lumen importers
For distributors and packagers
Security and supply chain
Roadmap and design

Emergency off

If a release goes wrong and the overlay or root driver leaves your screen in a bad state, the canonical escape hatch is:

adb shell am broadcast -a com.openlumen.action.TURN_OFF \
    -n com.openlumen/.service.AutomationReceiver

See docs/root-safety.md for more recovery paths.

Roadmap

See ROADMAP.md for the source-backed release plan and the candidate inventory. The Now candidates through v0.6.0 are largely shipped; deferred items have design sketches in docs/deferred-candidates.md and docs/overlay-and-per-app-design.md.

Post-v0.6.5 work clusters around:

  • A Shizuku-backed privileged path for per-app behavior (C06)
  • Wear OS companion as a separate F-Droid package (C21)
  • Real-device validation rows in docs/device-matrix.md (C01)

License

GPL-3.0-or-later. See LICENSE.

Acknowledgements

  • Chainfire (Jorrit Jongma) for the original CF.Lumen and for documenting the driver-backend approach so thoroughly that this project could be built without the original source.
  • LibreShift/red-moon for proving open-source overlay shifting works on Android.

Read on GitHub → github.com/SysAdminDoc/OpenLumen

Start with the strongest work, a key route, or the full archive.