Skip to content

release: v1.3.1 — iOS Hotfix & Quality Audit#30

Merged
vietnguyentuan2019 merged 5 commits intomainfrom
hotfix/ios-request-mutex-deadlock
May 5, 2026
Merged

release: v1.3.1 — iOS Hotfix & Quality Audit#30
vietnguyentuan2019 merged 5 commits intomainfrom
hotfix/ios-request-mutex-deadlock

Conversation

@vietnguyentuan2019
Copy link
Copy Markdown
Contributor

Description

This PR addresses critical Issue #29 (iOS Mutex Deadlock) and prepares the project for the v1.3.1 hotfix release.

Key Changes

  • fix(ios): Resolved a deadlock in PlatformGrantDelegate.ios.kt by using internal status checks within request(), avoiding non-reentrant mutex acquisition.
  • version: Synchronized all modules and documentation to 1.3.1.
  • test:
    • Added Issue29IosMutexDeadlockTest (iOS regression).
    • Added GlobalHardeningTest (Performance, Stress, and Security).
    • Verified 100% pass rate on iOS Simulator and Android.
  • docs: Updated README, CHANGELOG, and migration guides. Fixed Xcode build configuration to exclude macOS targets for the demo app.

Verification Results

  • GlobalHardeningTest: Passed (28ms refresh latency)
  • Issue29IosMutexDeadlockTest: Passed (No hangs detected)
  • iOS Demo App: Build & Launch successful on iPhone 17 Simulator.

vietnguyentuan2019 added 5 commits May 5, 2026 23:06
PlatformGrantDelegate.requestInternal() was calling the public checkStatus()
while already holding the per-permission Mutex acquired by request(). Since
Kotlin's Mutex is non-reentrant, the coroutine suspended indefinitely —
no permission dialog appeared and a CancellationException fired on app minimize.

Fix: requestInternal() now calls checkStatusInternal() directly, matching the
pattern already used by the Android implementation.

Adds Issue29IosMutexDeadlockTest to regression/ to prevent recurrence.
- IosGrantDelegateTest: add Group F — 9 withTimeout-wrapped tests calling
  request() through the real PlatformGrantDelegate on simulator. Any future
  deadlock regression will fail these tests instead of hanging silently.

- Bump grant-compose and grant-core-koin to v1.3.1 for hotfix release.

Root cause of the test gap: IosGrantDelegateTest previously only tested
checkStatus(). request() had zero coverage through the real delegate on iOS.
SimulatorDetector guards on Bluetooth/Motion also masked the bug for those
permissions on simulator.
@vietnguyentuan2019 vietnguyentuan2019 merged commit f41745a into main May 5, 2026
11 checks passed
@vietnguyentuan2019 vietnguyentuan2019 deleted the hotfix/ios-request-mutex-deadlock branch May 5, 2026 23:35
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

✅ CI Build passed

Build Status: success
Commit: 79e68c4

View full build log

Artifacts

  • Build reports
  • Coverage reports
  • Demo APK (if successful)

Automated comment by GitHub Actions

Comment on lines +67 to +75
val jobs = (0 until 50).map { index ->
launch {
val grant = permissions[index % permissions.size]
val handler = GrantHandler(mockGrantManager, grant, this)
handler.request {
results.add(handler.status.value)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants