[Bug]: Every unlock sends "cmd statusbar send-disable-flag none" and wipes the status bar disable records of other apps
Maintainers usually reply within 1 day
@sameerasw is already working on this.
Since Oct 28, 2026.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 66/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Domain
- mobile, operating-systems
Research direction
Read StatusBarManager.kt, especially applyLocked() and reassertFlags(), then trace the unlock call from SecurityReceiver.kt:128. Check how empty allFlags and force = true affect the command; done when an unlock with no active Essentials status-bar flags does not send none, while reasserting non-empty flags still works.
Written by the indexing model from the issue text.
Description
Summary
On v20.2 (and earlier), Essentials runs cmd statusbar send-disable-flag none on every unlock, even when no Essentials status-bar feature is enabled. send-disable-flag writes into a shared, last-writer-wins slot, so that single line silently clears the disable flags of any other app using the same command.
Note: this is not #973. That PR fixes Essentials' own icons not coming back after unlock — this is the empty-flag side effect of the same
force = truepath, and the fix below leaves #973's case (allFlagsnon-empty) untouched.
Code path
EssentialsApp.onCreate()registersSecurityReceiverforSCREEN_OFF/SCREEN_ON/USER_PRESENT— unconditionally, no feature gate.- On
ACTION_USER_PRESENTit callsStatusBarManager.reassertFlags(context)(SecurityReceiver.kt:128). reassertFlags()→applyLocked(context, force = true).force = trueskips both guards inapplyLocked():StatusBarManager.kt:101—if (!force && allFlags.isEmpty() && ...) returnStatusBarManager.kt:109—if (!force && command == lastAppliedCommand) return
- With every status-bar pref off (
hide_system_icons,hide_clock,hide_notification_icons,hide_gesture_bar_enabledallfalse, no activedisableRequests),commandFor(emptySet())yields"cmd statusbar send-disable-flag none"and it is executed on every unlock.
Why this hits other apps
AOSP's StatusBarShellCommand registers every shell caller of send-disable-flag under one static token (pkg=android in dumpsys statusbar), so each invocation replaces mDisableRecords[token] instead of OR-ing into it.
I maintain a small app that hides the status bar through that exact command. After an unlock the record goes:
what1=0x00920000 (system-icons | clock | notification-icons)
-> what1=0x00000000 ~110 ms after ACTION_USER_PRESENT finishes
The system status bar comes straight back while the app still reports Hidden.
Repro
- Have any app set flags via
cmd statusbar send-disable-flag .... dumpsys statusbar | grep -E "mDisabled1|what1="→ note the value.- Lock, unlock.
- Repeat the dumpsys immediately after the unlock →
what1=0x00000000,mDisabled1=0x0.
Measured with a 30 ms poll against dumpsys activity broadcasts (ms-precision dispatchClockTime): the wipe lands ~610 ms after ACTION_USER_PRESENT is dispatched, ~110 ms after that broadcast finishes.
Turning all Essentials status-bar options off does not stop it — it only turns the partial wipe (0x920000 -> 0x820000, when hide_clock + hide_notification_icons were on) into a total clear (0x920000 -> 0x0).
Suggested fix
Only send when there is something of ours to say:
private fun applyLocked(context: Context, force: Boolean) {
val allFlags = disableRequests.values.flatten().toMutableSet()
allFlags.addAll(persistentFlags(context, includeSystemIcons = true))
val command = commandFor(allFlags)
// Nothing of ours to (re-)assert: never touched the slot, or already at none.
if (allFlags.isEmpty() && (lastAppliedCommand == null || lastAppliedCommand == command)) return
if (!ShellUtils.hasPermission(context)) return
if (!force && command == lastAppliedCommand) return
lastAppliedCommand = command
ShellUtils.runCommand(context, command, ...)
}
i.e. drop !force && from the first guard: force = true keeps re-asserting whenever Essentials does manage flags (the #973 case, where allFlags is non-empty), but stops broadcasting an empty none when it manages nothing. An equivalent alternative is an early return in reassertFlags() when disableRequests.isEmpty() && persistentFlags(context, true).isEmpty().
Environment
- Essentials v20.2 (versionCode 71), source at
f698c92 - Android 15 / HyperOS, Redmi Note 13
- Shizuku (adb mode)
Side note for whoever tries to reproduce: revoking Essentials' Shizuku permission does not stop it while the process lives — Shizuku.checkSelfPermission() short-circuits on its cached permissionGranted flag, which is only rewritten when the Shizuku binder is (re)received.
- Dominant language
- Kotlin
- Stars
- 3.2k
- Forks
- 87
- Avg merge
- 1d 12h
- Merged PRs (30d)
- 210
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from sameerasw/essentials
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
sameerasw/essentials#1621 ·
Maintainers usually reply within 1 day
-
Difficulty 3/5 1-2 days Newbie friendliness 57/100
sameerasw/essentials#1623 ·
Maintainers usually reply within 1 day
-
Difficulty 4/5 3-5 days Newbie friendliness 48/100
sameerasw/essentials#1622 ·
Maintainers usually reply within 1 day
-
[Bug]: Interference with Gboard voice typing.Possibly taken @sameerasw claimed this 1 day ago. Openbug
sameerasw/essentials#1619 · 1 assignee ·
Maintainers usually reply within 1 day
-
[Bug]: Smart Pixels not covering AoD wallpaperPossibly taken @sameerasw claimed this 1 day ago. Openbug
sameerasw/essentials#1617 · 1 assignee ·
Maintainers usually reply within 1 day
All issues in sameerasw/essentials
Similar issues
-
[Submission] ViaOpensubmit-adaption submit-adaption-violation
Difficulty 1/5 Under an hour Newbie friendliness 78/100
BetterAndroid/android-notification-icon-project#811 · 2 comments ·
Maintainers usually reply within 1 day
-
triage
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Maintainers usually reply within 1 day
-
[BUG] setTargetSourceSet scans the whole classpath once for every class, so scanning is very slowOpenbug
Difficulty 2/5 1-3 hours Newbie friendliness 73/100
sergio-sastre/ComposablePreviewScanner#156 ·
Maintainers usually reply within 1 day
-
pending:code-area pending:issue-category to-triage
Difficulty 2/5 1-3 hours Newbie friendliness 76/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
T31n/YagniLauncher#1096 ·
Maintainers usually reply within 1 day