Skip to content

Fix: Adaptive Brightness has no effect on physical brightness while KompaktX is running - #7

Open
chadchad4423 wants to merge 3 commits into
ScreenSensitive:mainfrom
chadchad4423:fix/release-overlay-under-adaptive-brightness
Open

Fix: Adaptive Brightness has no effect on physical brightness while KompaktX is running#7
chadchad4423 wants to merge 3 commits into
ScreenSensitive:mainfrom
chadchad4423:fix/release-overlay-under-adaptive-brightness

Conversation

@chadchad4423

Copy link
Copy Markdown

Fix: Adaptive Brightness has no effect on physical brightness while KompaktX is running

KompaktX drives the physical backlight through a persistent 1x1 overlay
window (WindowManager.LayoutParams.screenBrightness), separate from
Android's own brightness system. That overlay's brightness value was set
once and never released, so even after a user turned Adaptive Brightness
back on, the overlay kept pinning the screen to its last static value —
physical brightness stopped responding to ambient light entirely, even
though the Adaptive Brightness toggle itself correctly showed "on."

A second, related path made this worse: brightnessObserver (the
ContentObserver watching Settings.System.SCREEN_BRIGHTNESS) would react
to any external brightness write — including the ones Android's own
adaptive-brightness algorithm makes continuously — by re-pinning the overlay
back to a stale target, fighting the system's live adjustments in real time.

This PR:

  • Adds a ContentObserver on Settings.System.SCREEN_BRIGHTNESS_MODE that
    releases the overlay/panel/lockscreen brightness overrides the moment
    Adaptive Brightness is turned on, so the physical backlight goes back to
    being fully system-controlled.
  • Adds an isAdaptiveBrightnessOn() guard at the top of
    brightnessObserver's onChange(), so it stops reacting to
    SCREEN_BRIGHTNESS writes at all while adaptive mode is active — it no
    longer fights the system's own live adjustments.
  • Changes the passive reapply path (applyBrightness(forceManualMode = false), used by reapplyBrightness() / loadSavedBrightness()) to skip
    overlay pinning entirely while Adaptive Brightness is already on.

Testing

Built on top of #5 (Fix 2) since this change depends on the
forceManualMode parameter it introduces. Verified on a physical Mudita
Kompakt (MuditaOS K 1.5), standalone and combined with the other three
fixes (Fix 1 + Fix 2 + Fix 3 + Fix 4 together, cherry-picked onto one
branch):

  • Full 6-step protocol — panel-open, cross-screen consistency, repeated
    Settings → Display checks, sleep/wake, KompaktX slider drag, System UI
    slider sync — 100% pass.
  • Additional stress test using a flashlight to force real ambient-light
    swings: confirmed brightness tracked it live, not just holding a static
    value that happened to pass the screen-based checks.

Note: this PR is best reviewed/merged alongside #4 (Fix 1) — both
independently touch brightnessObserver, and combined testing confirmed
they merge and behave correctly together, but each is written to be
correct and independently mergeable on its own.

Chad added 3 commits August 24, 2026 19:26
applyBrightness() unconditionally forced Settings.System.SCREEN_BRIGHTNESS_MODE
to MANUAL every time it ran -- including from reapplyBrightness(), which fires
on every ACTION_SCREEN_ON broadcast and every accessibility-service reconnect,
and from loadSavedBrightness(), which fires whenever the touch-strip service
(re)starts. Neither of those is the user touching a brightness control; both
are KompaktX passively restoring its last-known brightness. The net effect:
once KompaktX had ever set a brightness (which happens the first time its
overlay brightness control is used, and persists across restarts), turning
Adaptive Brightness back on in system settings never stuck -- the very next
screen wake silently flipped it back to manual.

Add a forceManualMode parameter to applyBrightness(), defaulting to true so
every direct user gesture (slider drag, sun-icon tap, front-light toggle)
keeps forcing manual mode, matching stock Android's own behavior when you
drag its brightness slider. The two passive-restore call sites now pass
false, so they reapply the physical brightness (still correct) without
silently overriding a system setting the user didn't just touch.

Scope note: buildBrightnessSection() and buildBrightnessSubPanel() still
force manual mode once each, at the top of the function, whenever KompaktX's
own brightness UI is displayed (not only when it's touched). That's a
smaller, separate quirk left out of this patch to keep it narrowly scoped to
the dominant bug -- the continuous every-wake override -- rather than
touching every place brightness mode is set.
Adaptive Brightness now stays on as a setting (fix/preserve-adaptive-brightness),
but the physical backlight never actually became adaptive: brightnessOverlay's
WindowManager.LayoutParams.screenBrightness permanently pins the real screen to a
static value the moment it's first applied, and nothing ever released it back to
'no override' in response to SCREEN_BRIGHTNESS_MODE.

- Add a ContentObserver on SCREEN_BRIGHTNESS_MODE so flipping Adaptive Brightness
  on releases the overlay, the panel window, and the lockscreen accessibility
  overlay immediately.
- applyBrightness(forceManualMode = false) - the passive reapply path used on
  screen wake and service restart - now checks current mode first and skips all
  Settings.System writes and overlay pinning entirely when Adaptive Brightness is
  already on, instead of re-clamping the screen to a stale target every time.

Built on fix/preserve-adaptive-brightness: without that branch's change,
reapplyBrightness()/loadSavedBrightness() would keep forcing manual mode on every
wake, undoing this the moment the screen slept and woke again.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant