moko-permissions
moko-permissions copied to clipboard
Permission requests synchronization
If couple of permission requests run in different scopes in parallel, at least one request will fail with an exception.
W/Activity: Can request only one set of permissions at a time
E/AndroidRuntime: FATAL EXCEPTION: main
Process: dev.icerock.moko.samples.permissions.debug, PID: 27897
java.util.NoSuchElementException: Array is empty.
at kotlin.collections.ArraysKt___ArraysKt.first(_Arrays.kt:1013)
at dev.icerock.moko.permissions.ResolverFragment.onRequestPermissionsResult(ResolverFragment.kt:54)
at androidx.fragment.app.FragmentActivity.onRequestPermissionsResult(FragmentActivity.java:769)
...
Simpliest example of such case may look like that:
SampleViewModel.kt
private fun requestPermission() {
viewModelScope.launch {
try {
// Calls suspend function in a coroutine to request some permission.
permissionsController.providePermission(Permission.RECORD_AUDIO)
// If there are no exceptions, permission has been granted successfully.
eventsDispatcher.dispatchEvent { onSuccess() }
} catch (deniedAlwaysException: DeniedAlwaysException) {
eventsDispatcher.dispatchEvent { onDeniedAlways(deniedAlwaysException) }
} catch (deniedException: DeniedException) {
eventsDispatcher.dispatchEvent { onDenied(deniedException) }
}
}
viewModelScope.launch {
try {
// Calls suspend function in a coroutine to request some permission.
permissionsController.providePermission(Permission.CAMERA)
// If there are no exceptions, permission has been granted successfully.
eventsDispatcher.dispatchEvent { onSuccess() }
} catch (deniedAlwaysException: DeniedAlwaysException) {
eventsDispatcher.dispatchEvent { onDeniedAlways(deniedAlwaysException) }
} catch (deniedException: DeniedException) {
eventsDispatcher.dispatchEvent { onDenied(deniedException) }
}
}
}
In real-world cases this may be caused, for example, by requesting couple of different permissions in separate application modules. Moreover, LocationTracker
from moko-geo
is affected too.
Although problem can be solved by providing synchronization manually, it wold be nice to implement this in library. I think the best possible option is synchronize request across all PermissionController
instances, but it will be great to have such thing for at least one instance.