Skip to content

fix: skip ShortcutBadger on API 26+ to prevent SIGSEGV on Xiaomi devices#2570

Open
fadi-george wants to merge 1 commit into5.7-mainfrom
fix/shortcutbadger-sigsegv-api26
Open

fix: skip ShortcutBadger on API 26+ to prevent SIGSEGV on Xiaomi devices#2570
fadi-george wants to merge 1 commit into5.7-mainfrom
fix/shortcutbadger-sigsegv-api26

Conversation

@fadi-george
Copy link
Contributor

Description

One Line Summary

Skip ShortcutBadger badge updates on Android 8+ (API 26) to prevent native SIGSEGV crashes on Xiaomi devices.

Details

Motivation

ShortcutBadger causes a native SIGSEGV (segmentation fault) on certain Xiaomi devices (Redmi 10C, Redmi 9A) running Android 11-13. The crash occurs in ShortcutBadger.applyCountOrThrow when DefaultBadger.executeBadge sends a broadcast that MIUI's framework handles with buggy native code. Since SIGSEGV is a native crash, Java try-catch cannot intercept it, so the only safe fix is to avoid calling ShortcutBadger on affected API levels.

Reported in OneSignal/react-native-onesignal#1766 and #2222.

Scope

On API 26+ (Android 8+), NotificationChannel handles app icon badges natively, making ShortcutBadger redundant. This change skips ShortcutBadger on those versions. Pre-API 26 devices still use ShortcutBadger as before.

Testing

Unit testing

No existing tests for BadgeCountUpdater. The change is a straightforward API level guard.

Manual testing

The crash was reported on Xiaomi Redmi 10C (Android 13) and Redmi 9A (Android 11). The fix prevents the code path from being reached on those devices.

Affected code checklist

  • Notifications
    • Display
    • Open
    • Push Processing
    • Confirm Deliveries
  • Outcomes
  • Sessions
  • In-App Messaging
  • REST API requests
  • Public API changes

Checklist

Overview

  • I have filled out all REQUIRED sections above
  • PR does one thing
  • Any Public API changes are explained in the PR details and conform to existing APIs

Testing

  • I have included test coverage for these changes, or explained why they are not needed
  • All automated tests pass, or I explained why that is not possible
  • I have personally tested this on my device, or explained why that is not possible

Final pass

  • Code is as readable as possible.
  • I have reviewed this PR myself, ensuring it meets each checklist item

Made with Cursor

@fadi-george fadi-george changed the base branch from main to 5.7-main March 11, 2026 20:54
@fadi-george fadi-george force-pushed the fix/shortcutbadger-sigsegv-api26 branch from 26c7e3a to 905aefb Compare March 11, 2026 21:00
@github-actions
Copy link
Contributor

github-actions bot commented Mar 11, 2026

📊 Diff Coverage Report

Diff Coverage Report (Changed Lines Only)

Threshold: 80%

Changed Files Coverage

  • SyncJobService.kt: 0/4 changed lines (0.0%) (31 changed lines)
    • ⚠️ Below threshold: 4 uncovered changed lines
  • AndroidUtils.kt: 0/4 changed lines (0.0%) (22 changed lines)
    • ⚠️ Below threshold: 4 uncovered changed lines
  • JSONUtils.kt: 30/30 changed lines (100.0%) (58 changed lines)
  • ⚠️ CoreModule.kt: Not in coverage report (may not be compiled/tested)
  • IParamsBackendService.kt: 0/8 changed lines (0.0%) (11 changed lines)
    • ⚠️ Below threshold: 8 uncovered changed lines
  • ParamsBackendService.kt: 0/8 changed lines (0.0%) (12 changed lines)
    • ⚠️ Below threshold: 8 uncovered changed lines
  • BackgroundManager.kt: 0/1 changed lines (0.0%) (1 changed lines)
    • ⚠️ Below threshold: 1 uncovered changed lines
  • ConfigModel.kt: 0/14 changed lines (0.0%) (42 changed lines)
    • ⚠️ Below threshold: 14 uncovered changed lines
  • ConfigModelStore.kt: 0/1 changed lines (0.0%) (2 changed lines)
    • ⚠️ Below threshold: 1 uncovered changed lines
  • ConfigModelStoreListener.kt: 0/2 changed lines (0.0%) (3 changed lines)
    • ⚠️ Below threshold: 2 uncovered changed lines
  • HttpClient.kt: 3/3 changed lines (100.0%) (5 changed lines)
  • OperationModelStore.kt: 0/1 changed lines (0.0%) (3 changed lines)
    • ⚠️ Below threshold: 1 uncovered changed lines
  • OperationRepo.kt: 3/3 changed lines (100.0%) (3 changed lines)
  • Time.kt: 0/1 changed lines (0.0%) (6 changed lines)
    • ⚠️ Below threshold: 1 uncovered changed lines
  • LogLevel.kt: 0/1 changed lines (0.0%) (48 changed lines)
    • ⚠️ Below threshold: 1 uncovered changed lines
  • OneSignalCrashHandlerFactory.kt: 0/5 changed lines (0.0%) (38 changed lines)
    • ⚠️ Below threshold: 5 uncovered changed lines
  • OneSignalCrashUploaderWrapper.kt: 0/17 changed lines (0.0%) (60 changed lines)
    • ⚠️ Below threshold: 17 uncovered changed lines
  • OtelAnrDetector.kt: 0/100 changed lines (0.0%) (221 changed lines)
    • ⚠️ Below threshold: 100 uncovered changed lines
  • OtelSdkSupport.kt: 0/4 changed lines (0.0%) (27 changed lines)
    • ⚠️ Below threshold: 4 uncovered changed lines
  • Logging.kt: 4/24 changed lines (16.7%) (75 changed lines)
    • ⚠️ Below threshold: 20 uncovered changed lines
  • AndroidOtelLogger.kt: 9/9 changed lines (100.0%) (26 changed lines)
  • OtelIdResolver.kt: 0/96 changed lines (0.0%) (247 changed lines)
    • ⚠️ Below threshold: 96 uncovered changed lines
  • OtelPlatformProvider.kt: 0/76 changed lines (0.0%) (164 changed lines)
    • ⚠️ Below threshold: 76 uncovered changed lines
  • OneSignalImp.kt: 0/5 changed lines (0.0%) (14 changed lines)
    • ⚠️ Below threshold: 5 uncovered changed lines
  • OtelConfigEvaluator.kt: 20/20 changed lines (100.0%) (68 changed lines)
  • OtelLifecycleManager.kt: 0/117 changed lines (0.0%) (240 changed lines)
    • ⚠️ Below threshold: 117 uncovered changed lines
  • ChannelTracker.kt: 63/81 changed lines (77.8%) (128 changed lines)
    • ⚠️ Below threshold: 18 uncovered changed lines
  • OutcomeEventsController.kt: 5/5 changed lines (100.0%) (5 changed lines)
  • OutcomeSourceBody.kt: 2/8 changed lines (25.0%) (13 changed lines)
    • ⚠️ Below threshold: 6 uncovered changed lines
  • SessionListener.kt: 3/4 changed lines (75.0%) (6 changed lines)
    • ⚠️ Below threshold: 1 uncovered changed lines
  • IUserManager.kt: 0/3 changed lines (0.0%) (11 changed lines)
    • ⚠️ Below threshold: 3 uncovered changed lines
  • ⚠️ UserModule.kt: Not in coverage report (may not be compiled/tested)
  • UserManager.kt: 4/6 changed lines (66.7%) (16 changed lines)
    • ⚠️ Below threshold: 2 uncovered changed lines
  • CustomEventBackendService.kt: 20/21 changed lines (95.2%) (53 changed lines)
  • CustomEventController.kt: 15/15 changed lines (100.0%) (36 changed lines)
  • CustomEventMetadata.kt: 16/16 changed lines (100.0%) (49 changed lines)
  • IdentityModelStore.kt: 0/1 changed lines (0.0%) (3 changed lines)
    • ⚠️ Below threshold: 1 uncovered changed lines
  • TrackCustomEventOperation.kt: 28/35 changed lines (80.0%) (90 changed lines)
  • CustomEventOperationExecutor.kt: 26/33 changed lines (78.8%) (71 changed lines)
    • ⚠️ Below threshold: 7 uncovered changed lines
  • SubscriptionOperationExecutor.kt: 0/9 changed lines (0.0%) (10 changed lines)
    • ⚠️ Below threshold: 9 uncovered changed lines
  • InAppMessagesManager.kt: 14/28 changed lines (50.0%) (48 changed lines)
    • ⚠️ Below threshold: 14 uncovered changed lines
  • InAppBackendService.kt: 1/1 changed lines (100.0%) (1 changed lines)
  • InAppDisplayer.kt: 0/1 changed lines (0.0%) (1 changed lines)
    • ⚠️ Below threshold: 1 uncovered changed lines
  • InAppMessageView.kt: 0/3 changed lines (0.0%) (3 changed lines)
    • ⚠️ Below threshold: 3 uncovered changed lines
  • OneSignalBounceInterpolator.kt: 0/1 changed lines (0.0%) (1 changed lines)
    • ⚠️ Below threshold: 1 uncovered changed lines
  • InAppHydrator.kt: 1/1 changed lines (100.0%) (1 changed lines)
  • TriggerController.kt: 1/1 changed lines (100.0%) (4 changed lines)
  • LocationManager.kt: 0/1 changed lines (0.0%) (1 changed lines)
    • ⚠️ Below threshold: 1 uncovered changed lines
  • GmsLocationController.kt: 0/4 changed lines (0.0%) (5 changed lines)
    • ⚠️ Below threshold: 4 uncovered changed lines
  • HmsLocationController.kt: 0/7 changed lines (0.0%) (8 changed lines)
    • ⚠️ Below threshold: 7 uncovered changed lines
  • OneSignalHmsEventBridge.kt: 0/1 changed lines (0.0%) (1 changed lines)
    • ⚠️ Below threshold: 1 uncovered changed lines
  • BadgeCountUpdater.kt: 0/2 changed lines (0.0%) (5 changed lines)
    • ⚠️ Below threshold: 2 uncovered changed lines
  • NotificationChannelManager.kt: 0/2 changed lines (0.0%) (2 changed lines)
    • ⚠️ Below threshold: 2 uncovered changed lines
  • OSWorkManagerHelper.kt: 0/2 changed lines (0.0%) (2 changed lines)
    • ⚠️ Below threshold: 2 uncovered changed lines
  • NotificationRepository.kt: 0/4 changed lines (0.0%) (10 changed lines)
    • ⚠️ Below threshold: 4 uncovered changed lines
  • NotificationGenerationProcessor.kt: 0/3 changed lines (0.0%) (4 changed lines)
    • ⚠️ Below threshold: 3 uncovered changed lines
  • NotificationLifecycleService.kt: 0/8 changed lines (0.0%) (9 changed lines)
    • ⚠️ Below threshold: 8 uncovered changed lines
  • PushTokenManager.kt: 2/2 changed lines (100.0%) (3 changed lines)
  • ReceiveReceiptProcessor.kt: 0/1 changed lines (0.0%) (1 changed lines)
    • ⚠️ Below threshold: 1 uncovered changed lines
  • PushRegistratorADM.kt: 0/2 changed lines (0.0%) (2 changed lines)
    • ⚠️ Below threshold: 2 uncovered changed lines
  • PushRegistratorAbstractGoogle.kt: 0/7 changed lines (0.0%) (7 changed lines)
    • ⚠️ Below threshold: 7 uncovered changed lines
  • PushRegistratorHMS.kt: 0/2 changed lines (0.0%) (2 changed lines)
    • ⚠️ Below threshold: 2 uncovered changed lines
  • NotificationRestoreProcessor.kt: 0/1 changed lines (0.0%) (1 changed lines)
    • ⚠️ Below threshold: 1 uncovered changed lines
  • NotificationRestoreWorkManager.kt: 0/2 changed lines (0.0%) (2 changed lines)
    • ⚠️ Below threshold: 2 uncovered changed lines
  • ADMMessageHandler.kt: 0/2 changed lines (0.0%) (2 changed lines)
    • ⚠️ Below threshold: 2 uncovered changed lines
  • ADMMessageHandlerJob.kt: 0/2 changed lines (0.0%) (2 changed lines)
    • ⚠️ Below threshold: 2 uncovered changed lines
  • OneSignalOpenTelemetry.kt: 0/75 changed lines (0.0%) (148 changed lines)
    • ⚠️ Below threshold: 75 uncovered changed lines
  • OtelFactory.kt: 0/23 changed lines (0.0%) (112 changed lines)
    • ⚠️ Below threshold: 23 uncovered changed lines
  • OtelLoggingHelper.kt: 0/31 changed lines (0.0%) (65 changed lines)
    • ⚠️ Below threshold: 31 uncovered changed lines
  • OtelFieldsPerEvent.kt: 0/13 changed lines (0.0%) (35 changed lines)
    • ⚠️ Below threshold: 13 uncovered changed lines
  • OtelFieldsTopLevel.kt: 0/21 changed lines (0.0%) (42 changed lines)
    • ⚠️ Below threshold: 21 uncovered changed lines
  • OtelConfigCrashFile.kt: 0/19 changed lines (0.0%) (50 changed lines)
    • ⚠️ Below threshold: 19 uncovered changed lines
  • OtelConfigRemoteOneSignal.kt: 0/18 changed lines (0.0%) (57 changed lines)
    • ⚠️ Below threshold: 18 uncovered changed lines
  • OtelConfigShared.kt: 0/18 changed lines (0.0%) (58 changed lines)
    • ⚠️ Below threshold: 18 uncovered changed lines
  • OtelCrashHandler.kt: 0/46 changed lines (0.0%) (127 changed lines)
    • ⚠️ Below threshold: 46 uncovered changed lines
  • OtelCrashReporter.kt: 0/33 changed lines (0.0%) (63 changed lines)
    • ⚠️ Below threshold: 33 uncovered changed lines
  • OtelCrashUploader.kt: 0/29 changed lines (0.0%) (91 changed lines)
    • ⚠️ Below threshold: 29 uncovered changed lines
  • ⚠️ MockHelper.kt: Not in coverage report (may not be compiled/tested)

Overall Coverage (Changed Lines Only)

270/1208 changed lines covered (22.4%)

❌ Coverage Check Failed

Files below 80% threshold:

  • SyncJobService.kt: 0.0% (4 uncovered changed lines)

  • AndroidUtils.kt: 0.0% (4 uncovered changed lines)

  • IParamsBackendService.kt: 0.0% (8 uncovered changed lines)

  • ParamsBackendService.kt: 0.0% (8 uncovered changed lines)

  • BackgroundManager.kt: 0.0% (1 uncovered changed lines)

  • ConfigModel.kt: 0.0% (14 uncovered changed lines)

  • ConfigModelStore.kt: 0.0% (1 uncovered changed lines)

  • ConfigModelStoreListener.kt: 0.0% (2 uncovered changed lines)

  • OperationModelStore.kt: 0.0% (1 uncovered changed lines)

  • Time.kt: 0.0% (1 uncovered changed lines)

  • LogLevel.kt: 0.0% (1 uncovered changed lines)

  • OneSignalCrashHandlerFactory.kt: 0.0% (5 uncovered changed lines)

  • OneSignalCrashUploaderWrapper.kt: 0.0% (17 uncovered changed lines)

  • OtelAnrDetector.kt: 0.0% (100 uncovered changed lines)

  • OtelSdkSupport.kt: 0.0% (4 uncovered changed lines)

  • Logging.kt: 16.7% (20 uncovered changed lines)

  • OtelIdResolver.kt: 0.0% (96 uncovered changed lines)

  • OtelPlatformProvider.kt: 0.0% (76 uncovered changed lines)

  • OneSignalImp.kt: 0.0% (5 uncovered changed lines)

  • OtelLifecycleManager.kt: 0.0% (117 uncovered changed lines)

  • ChannelTracker.kt: 77.8% (18 uncovered changed lines)

  • OutcomeSourceBody.kt: 25.0% (6 uncovered changed lines)

  • SessionListener.kt: 75.0% (1 uncovered changed lines)

  • IUserManager.kt: 0.0% (3 uncovered changed lines)

  • UserManager.kt: 66.7% (2 uncovered changed lines)

  • IdentityModelStore.kt: 0.0% (1 uncovered changed lines)

  • CustomEventOperationExecutor.kt: 78.8% (7 uncovered changed lines)

  • SubscriptionOperationExecutor.kt: 0.0% (9 uncovered changed lines)

  • InAppMessagesManager.kt: 50.0% (14 uncovered changed lines)

  • InAppDisplayer.kt: 0.0% (1 uncovered changed lines)

  • InAppMessageView.kt: 0.0% (3 uncovered changed lines)

  • OneSignalBounceInterpolator.kt: 0.0% (1 uncovered changed lines)

  • LocationManager.kt: 0.0% (1 uncovered changed lines)

  • GmsLocationController.kt: 0.0% (4 uncovered changed lines)

  • HmsLocationController.kt: 0.0% (7 uncovered changed lines)

  • OneSignalHmsEventBridge.kt: 0.0% (1 uncovered changed lines)

  • BadgeCountUpdater.kt: 0.0% (2 uncovered changed lines)

  • NotificationChannelManager.kt: 0.0% (2 uncovered changed lines)

  • OSWorkManagerHelper.kt: 0.0% (2 uncovered changed lines)

  • NotificationRepository.kt: 0.0% (4 uncovered changed lines)

  • NotificationGenerationProcessor.kt: 0.0% (3 uncovered changed lines)

  • NotificationLifecycleService.kt: 0.0% (8 uncovered changed lines)

  • ReceiveReceiptProcessor.kt: 0.0% (1 uncovered changed lines)

  • PushRegistratorADM.kt: 0.0% (2 uncovered changed lines)

  • PushRegistratorAbstractGoogle.kt: 0.0% (7 uncovered changed lines)

  • PushRegistratorHMS.kt: 0.0% (2 uncovered changed lines)

  • NotificationRestoreProcessor.kt: 0.0% (1 uncovered changed lines)

  • NotificationRestoreWorkManager.kt: 0.0% (2 uncovered changed lines)

  • ADMMessageHandler.kt: 0.0% (2 uncovered changed lines)

  • ADMMessageHandlerJob.kt: 0.0% (2 uncovered changed lines)

  • OneSignalOpenTelemetry.kt: 0.0% (75 uncovered changed lines)

  • OtelFactory.kt: 0.0% (23 uncovered changed lines)

  • OtelLoggingHelper.kt: 0.0% (31 uncovered changed lines)

  • OtelFieldsPerEvent.kt: 0.0% (13 uncovered changed lines)

  • OtelFieldsTopLevel.kt: 0.0% (21 uncovered changed lines)

  • OtelConfigCrashFile.kt: 0.0% (19 uncovered changed lines)

  • OtelConfigRemoteOneSignal.kt: 0.0% (18 uncovered changed lines)

  • OtelConfigShared.kt: 0.0% (18 uncovered changed lines)

  • OtelCrashHandler.kt: 0.0% (46 uncovered changed lines)

  • OtelCrashReporter.kt: 0.0% (33 uncovered changed lines)

  • OtelCrashUploader.kt: 0.0% (29 uncovered changed lines)

📥 View workflow run

On Android 8+ (API 26), notification channels handle app icon badges
natively, making ShortcutBadger unnecessary. ShortcutBadger's
DefaultBadger fallback causes native SIGSEGV crashes on certain Xiaomi
devices (Redmi 10C, Redmi 9A) where MIUI's broadcast receiver has
buggy native code that cannot be caught at the Java level.

Fixes OneSignal/react-native-onesignal#1766

Made-with: Cursor
@fadi-george fadi-george force-pushed the fix/shortcutbadger-sigsegv-api26 branch from 905aefb to 5139ef3 Compare March 11, 2026 21:05
@fadi-george fadi-george requested a review from nan-li March 12, 2026 18:36
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