Last updated: 2026-05-15 | Current stable: v2.1.0 | Next major: v2.1.0
Focus: Opt-in handler DSL, Wearables, Large Screens, and Fine-grained UX control.
1. Opt-in Handler Registration DSL (from PR #39 by @RoryKelly)
-
GrantFactory.create { }block API — per-permissionexpect/actualextension functions (location(),bluetooth(),camera(), …) so K/N DCE can strip any unused handler, not just the three covered by v2.1.0 module isolation. Apps that only use Bluetooth + Notification will no longer linkAVFoundation,Photos, orCoreLocationeither. - Layer the DSL on top of v2.1.0 module split — unconditional safety by default, optional granular control for consumers who want to minimize binary size further.
- Backward-compatible:
create()no-arg stays functional viaregisterAll()shim.
2. Platform Expansion
- Wear OS support — minimal permission surface, sensor-only grants.
- Android TV / Large screen —
requestWithCustomUi()examples for non-phone form factors.
3. UX & Analytics
- Analytics hooks — optional
GrantEventListenerfor tracking permission funnel drop-off. - iOS XCTest snapshot tests for
GrantDialogCompose UI.
4. Maintenance
- Android 16 photo picker (
PICK_IMAGESintent) — full library integration. Recipe is shipped atdocs/recipes/photo-picker-fallback.md; turning it into a built-inAppGrant-level surface.
- iOS Framework Isolation:
Contacts.framework,EventKit.framework,CoreMotion.frameworkmoved to opt-in modules (grant-contacts,grant-calendar,grant-motion). Apps that don't add these modules never link these frameworks — Apple's static scanner no longer requires the correspondingNSUsageDescriptionkeys. - New modules:
grant-contacts,grant-calendar,grant-motionas separate Gradle/Maven artifacts. IosPermissionHandlerRegistry: Registry fix —checkStatus()forRawPermissionnow correctly dispatches to registered custom handlers.- Test suite expanded: 1131 tests across 6 modules (Android JVM + iOS Simulator), 100% pass rate.
- Breaking change: iOS apps using Contacts/Calendar/Motion permissions must add the new optional module and call
initialize()once. Android is unaffected.
- FINAL FIX: Resolved 60s timeout in
LOCATION_ALWAYSflow (Issue #33). - Hardening: Immediate state reset in
GrantRequestActivityand 10s fail-safe guard. - Logic: Corrected
PARTIAL_GRANTEDupgrade path to allow system dialogs. - Android 15: Optimized transitions and lifecycle handling.
- HOTFIX: Initial mitigation for duplicate background location requests.
- Process Death Recovery:
SavedStateHandleintegration inGrantRequestActivity. - Activity Launch Guard: Prevented overlapping Activity instances.
- IosPermissionHandlerRegistry: Custom handlers for
RawPermissionon iOS. - NEARBY_WIFI_DEVICES: Full Android 13+ support.
- Material 3: Upgraded all Compose dialogs to
BasicAlertDialog. - New APIs:
requestSuspend()andrequestFlow().
- HOTFIX: iOS
request()mutex deadlock resolution (Issue #29). - Regression tests for non-reentrant mutex patterns.