permissions-dispatcher / PermissionsDispatcher

A declarative API to handle Android runtime permissions.
https://github.com/permissions-dispatcher/PermissionsDispatcher
Apache License 2.0
11.22k stars 1.44k forks source link

Target lost on screen rotation when request with additional parameters #538

Closed uladzimirsorokin closed 5 years ago

uladzimirsorokin commented 5 years ago

Target lost on screen rotation when request with additional parameters

when we get permission dialog and then rotate phone we will get our old target lost, and new target wont be reassigned because PENDING_HANDLEWRITESTORAGEACTION != null while target == null. So permission will be granted but bundle lost and target.handleWriteStorageAction(bundle); never called

version: 3.3.1

Approximate steps:

@NeedsPermission(WRITE_EXTERNAL_STORAGE) 
protected abstract void handleWriteStorageAction(@Nullable Bundle bundle)

PermissionWriteStorageFragmentPermissionsDispatcher.handleWriteStorageActionWithPermissionCheck(fragment, bundle);

//This leads to generation following:

 private static GrantableRequest PENDING_HANDLEWRITESTORAGEACTION;

//here, if we rotate phone, we can get non-null PENDING_HANDLEWRITESTORAGEACTION 
  while target == null  and i assume here we should check something like target != null
  and set new target here instead of directly grant() on nothing

static void onRequestPermissionsResult(PermissionWriteStorageFragment target, int requestCode,
      int[] grantResults) {
    switch (requestCode) {
      case REQUEST_HANDLEWRITESTORAGEACTION:
      if (PermissionUtils.verifyPermissions(grantResults)) {
        if (PENDING_HANDLEWRITESTORAGEACTION != null) {
          PENDING_HANDLEWRITESTORAGEACTION.grant();
        }

  private static final class PermissionWriteStorageFragmentHandleWriteStorageActionPermissionRequest implements GrantableRequest {
    private final WeakReference<PermissionWriteStorageFragment> weakTarget;

    private final Bundle bundle;

        @Override
    public void grant() {
      PermissionWriteStorageFragment target = weakTarget.get();
      if (target == null) return;
      target.handleWriteStorageAction(bundle);
    }
hotchemi commented 5 years ago

thx. it can be happened and quite difficult to fix since we're using WeakReference.. 🤔 I suppose workaround for the issue is make Activity/Fragment un-recreatable.