Skip to content

fix: Clamp progress percent to [0, 100] to prevent SystemUI crash#214

Merged
D4vidDf merged 1 commit into
D4vidDf:masterfrom
Wangtaotaoo:fix/clamp-negative-progress
Jun 11, 2026
Merged

fix: Clamp progress percent to [0, 100] to prevent SystemUI crash#214
D4vidDf merged 1 commit into
D4vidDf:masterfrom
Wangtaotaoo:fix/clamp-negative-progress

Conversation

@Wangtaotaoo

@Wangtaotaoo Wangtaotaoo commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Problem

When a third-party app (e.g. WhatsApp) sends a progress notification with a negative EXTRA_PROGRESS value (such as -1 during chat backup initialization), ProgressTranslator and DownloadTranslator calculate a negative percent and pass it directly into the Dynamic Island JSON payload.

SystemUI's CircularProgressBar.setProgress() throws an IllegalArgumentException when it receives a value less than 0. Since this runs on the main thread, it causes a fatal crash. From the user's perspective, SystemUI force-closes repeatedly, resulting in a black screen or continuous UI restart loop until the offending notification is dismissed.

Root Cause

// Before fix — no bounds checking
val percent = if (max > 0) {
    ((current.toFloat() / max.toFloat()) * 100).toInt()
} else {
    textPercent ?: 0
}

When current = -1 and max = 100, this produces percent = -1, which is sent to SystemUI and triggers the crash.

Fix

Applied .coerceIn(0, 100) to the calculated percent in both ProgressTranslator and DownloadTranslator, ensuring only valid progress values are forwarded to SystemUI regardless of what the source notification contains.

Files Changed

  • app/src/main/java/com/d4viddf/hyperbridge/service/translators/ProgressTranslator.kt
  • app/src/main/java/com/d4viddf/hyperbridge/service/translators/DownloadTranslator.kt

Crash Stack (from production logs)

java.lang.IllegalArgumentException: Progress value can not be less than 0
    at miui.systemui.widget.CircularProgressBar.setProgress()
    at miui.systemui.dynamicisland.module.IslandProgressViewHolder.bind()
    at miui.systemui.dynamicisland.module.IslandProgressViewHolder.updatePartial()
    at miui.systemui.dynamicisland.module.IslandCombineImageViewHolder.bind()
    at miui.systemui.dynamicisland.module.IslandModuleViewHolderAdapter.bindData()

Tested On

  • Redmi (tanzanite), HyperOS 3.0, Android 16
  • Reproduced by sending a notification with setProgress(100, -1, false)
  • Verified crash no longer occurs after the fix

Fixes #215

When a third-party app (e.g. WhatsApp) sends a progress notification with
a negative EXTRA_PROGRESS value (such as -1 during backup initialization),
ProgressTranslator and DownloadTranslator would pass the negative percent
directly into the Dynamic Island JSON payload. This causes SystemUI's
CircularProgressBar.setProgress() to throw an IllegalArgumentException,
resulting in a fatal crash on the main thread. The user experiences
repeated SystemUI force-closes (black screen / UI restart loop).

Fix: apply .coerceIn(0, 100) to the calculated percent value before it is
forwarded to the island builder, ensuring only valid progress values reach
SystemUI regardless of what the source notification contains.
@D4vidDf D4vidDf merged commit 04761b0 into D4vidDf:master Jun 11, 2026
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.

[BUG] Please add progress lower-bound validation in HyperBridge to prevent SystemUI crash

2 participants