Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[Bug]: Every unlock sends "cmd statusbar send-disable-flag none" and wipes the status bar disable records of other apps

Open Beginner friendly
#1,579 0 comments 0 reactions 1 assignee View on GitHub

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
Tech stack
android, kotlin

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

bug

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 = true path, and the fix below leaves #973's case (allFlags non-empty) untouched.

Code path

  1. EssentialsApp.onCreate() registers SecurityReceiver for SCREEN_OFF / SCREEN_ON / USER_PRESENT — unconditionally, no feature gate.
  2. On ACTION_USER_PRESENT it calls StatusBarManager.reassertFlags(context) (SecurityReceiver.kt:128).
  3. reassertFlags() → applyLocked(context, force = true).
  4. force = true skips both guards in applyLocked():
    • StatusBarManager.kt:101 — if (!force && allFlags.isEmpty() && ...) return
    • StatusBarManager.kt:109 — if (!force && command == lastAppliedCommand) return
  5. With every status-bar pref off (hide_system_icons, hide_clock, hide_notification_icons, hide_gesture_bar_enabled all false, no active disableRequests), 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

  1. Have any app set flags via cmd statusbar send-disable-flag ....
  2. dumpsys statusbar | grep -E "mDisabled1|what1=" → note the value.
  3. Lock, unlock.
  4. 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

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from sameerasw/essentials

All issues in sameerasw/essentials

Similar issues

More Kotlin issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.