Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

onRequestPermissionResult deprecation issue #1388

Open
jacobg opened this issue Jan 5, 2022 · 8 comments · May be fixed by #1405
Open

onRequestPermissionResult deprecation issue #1388

jacobg opened this issue Jan 5, 2022 · 8 comments · May be fixed by #1405

Comments

@jacobg
Copy link

jacobg commented Jan 5, 2022

onRequestPermissionResult is marked as deprecated in favor of onRequestPermissionsResult:

* @deprecated Use {@link #onRequestPermissionsResult} instead.
*/
@Deprecated
public void onRequestPermissionResult(int requestCode, String[] permissions,
int[] grantResults) throws JSONException {
}

However, CordovaInterfaceImpl calls the deprecated method instead of the new one:

public void onRequestPermissionResult(int requestCode, String[] permissions,
int[] grantResults) throws JSONException {
Pair<CordovaPlugin, Integer> callback = permissionResultCallbacks.getAndRemoveCallback(requestCode);
if(callback != null) {
callback.first.onRequestPermissionResult(callback.second, permissions, grantResults);
}
}

Maybe should CordovaPlugin's default implementation of onRequestPermissionResult call the new onRequestPermissionsResult method until onRequestPermissionResult is removed?

@dpogue
Copy link
Member

dpogue commented Jan 5, 2022

They are both called by the PermissionsHelper:

private static void deliverPermissionResult(CordovaPlugin plugin, int requestCode, String[] permissions) {
// Generate the request results
int[] requestResults = new int[permissions.length];
Arrays.fill(requestResults, PackageManager.PERMISSION_GRANTED);
try {
// This one is deprecated - see https://github.com/apache/cordova-android/issues/592
plugin.onRequestPermissionResult(requestCode, permissions, requestResults);
plugin.onRequestPermissionsResult(requestCode, permissions, requestResults);
} catch (JSONException e) {
LOG.e(LOG_TAG, "JSONException when delivering permissions results", e);
}
}

We can't remove onRequestPermissionResult until the next major version because it will break existing plugins that haven't been updated to use onRequestPermissionsResult.

@dpogue dpogue added this to the 11.0.0 milestone Jan 5, 2022
@jacobg
Copy link
Author

jacobg commented Jan 5, 2022

Where does callback.first.onRequestPermissionResult in CordovaInterfaceImpl call to?

@Chuckytuh
Copy link
Contributor

CordovaInterfaceImpl is directly calling the deprecated method onRequestPermissionResult but the deprecation annotation is pushing developers to override the new method that is never executed.

Also, does it make sense for the PermissionHelper to execute both the deprecated and the new methods? That seems like a source of bugs lurking around for plugins as it isn't explicit that both will be executed and mainly because PermissionHelper is to provide back compatibility with potentially legacy code.

@andredestro andredestro linked a pull request Mar 11, 2022 that will close this issue
5 tasks
@breautek breautek added this to To Do in Release Plan - 11.0.0 via automation Mar 16, 2022
@erisu erisu removed this from the 11.0.0 milestone Jun 29, 2022
@erisu erisu removed this from To Do in Release Plan - 11.0.0 Jun 29, 2022
@gwynjudd
Copy link

@dpogue

They are both called by the PermissionsHelper:

This isn't really correct though, this method is private and never called by anything that I can see.

image

There's essentially no way to have onRequestPermissionResults be called.

@erisu
Copy link
Member

erisu commented Mar 27, 2023

@gwynjudd I think the deliverPermissionResult method is deprecated and can be removed.

If I remember correctly, this helper class originated from Apache's cordova-plugin-compat plugin. That plugin is deprecated long ago. Its version of the helper class had and used the deliverPermissionResult method.

I believe the class was copied to this repo to make it available for other plugins and was a part of Cordova-Android 5 backward compatibility support. #594

Removing onRequestPermissionResult may break existing plugins.

Even though Apache has added the deprecated flag and updated Apache core plugins to not use the method, many unmaintained third-party plugins works with the current version of Cordova-Android and could be calling the deprecated method. If we remove the method, then all those plugins will stop working.

There might have been some agreement that this step has to be taken either way, but when?

@gwynjudd
Copy link

gwynjudd commented Aug 3, 2023 via email

rmoehn added a commit to GuidedTrack/cordova-plugin-mindease that referenced this issue Oct 24, 2023
As noted in the comment, the former is deprecated in favour of the
latter, but the latter is never called. See also:

- apache/cordova-android#1388
- apache/cordova-android#1393

I hope the comment will help us fix the problem quickly when the Cordova
folks decide to remove the deprecated method. (And hopefully make sure
that the new method is called.)

Addresses: https://trello.com/c/zsmadleg/2549-mind-ease-notifications-probably-broken-on-android
rmoehn added a commit to GuidedTrack/cordova-plugin-mindease that referenced this issue Oct 24, 2023
As noted in the comment, the former is deprecated in favour of the
latter, but the latter is never called. See also:

- apache/cordova-android#1388
- apache/cordova-android#1393

I hope the comment will help us fix the problem quickly when the Cordova
folks decide to remove the deprecated method. (And hopefully make sure
that the new method is called.)

Addresses: https://trello.com/c/zsmadleg/2549-mind-ease-notifications-probably-broken-on-android
@MikeDimmickMnetics
Copy link

I've just spent a day adding POST_NOTIFICATIONS permission to a plugin that didn't previously need permissions, and have run across this issue.

If you override onRequestPermissionsResult (the new method) in your plugin, it does not work. That method is not called when the user picks an option on the permissions dialog (or swipes to dismiss).

To actually get called back, you have to override the deprecated method onRequestPermissionResult.

The documentation correctly tells you to use the old deprecated method name. I was surprised to find that Android Studio struck through the method name indicating that it was deprecated. I changed it to the new name, then wasted a lot of time wondering why it didn't work until I realised that the callback wasn't even called.

In my project, nothing calls PermissionsHelper.deliverPermissionResult. Indeed, since it is a private method in PermissionHelper, the only way it could be called is through reflection. It seems highly unlikely that anyone would do that, since you can simply call onRequestPermissionsResult yourself directly. The purpose of this code was to call the callback on Android versions that didn't support the requestPermissions API, but since the minimum supported Android version is now 7.0 (SDK 24), the requestPermission/s methods no longer need to implement a workaround.

Suggested fixes:

  1. Revert feat: Deprecated onRequestPermissionResult in favour for onRequestPermissionsResult for consistency #1047 and live with the inconsistency, OR
  2. Add a call to callback.first.onRequestPermissionsResult to CordovaInterfaceImpl.onRequestPermissionResult, after the call to callback.first.onRequestPermissionResult. Update the documentation to the new method.

I also suggest that PermissionsHelper.deliverPermissionResult is removed.

@MikeDimmickMnetics
Copy link

As an alternative, we could make CordovaPlugin.onRequestPermissionsResult (the new method's default implementation) call CordovaPlugin.onRequestPermissionResult (the old method, which may be overridden in plugins). Then change CordovaInterfaceImpl to only call callback.first.onRequestPermissionsResult (i.e. the new method).

// CordovaPlugin.java

    /**
     * Called by the system when the user grants permissions
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     * 
     * @deprecated Use {@link #onRequestPermissionsResult} instead.
     */
    @Deprecated
    public void onRequestPermissionResult(int requestCode, String[] permissions,
                                          int[] grantResults) throws JSONException {

    }

    /**
     * Called by the system when the user grants permissions
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    public void onRequestPermissionsResult(int requestCode, String[] permissions,
                                          int[] grantResults) throws JSONException {
        // Call the old method name for backward compatibility
        this.onRequestPermissionResult(requestCode, permissions, grantResults);
    }

/// CordovaInterfaceImpl.java

    /**
     * Called by the system when the user grants permissions
     *
     * @param requestCode
     * @param permissions
     * @param grantResults
     */
    public void onRequestPermissionResult(int requestCode, String[] permissions,
                                          int[] grantResults) throws JSONException {
        Pair<CordovaPlugin, Integer> callback = permissionResultCallbacks.getAndRemoveCallback(requestCode);
        if(callback != null) {
            callback.first.onRequestPermissionsResult(callback.second, permissions, grantResults);
        }
    }

It may be worth renaming the method in CordovaInterface (therefore also CordovaInterfaceImpl) for consistency.

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 a pull request may close this issue.

6 participants