arnaucube
arnaucube/openEventsPlatformAppPublic Self-hosted repository
openEventsPlatformApp/plugins/cordova-plugin-compat/src/android/PermissionHelper.java
plugins/cordova-plugin-compat/src/android/PermissionHelper.javaRaw
  1/*
  2       Licensed to the Apache Software Foundation (ASF) under one
  3       or more contributor license agreements.  See the NOTICE file
  4       distributed with this work for additional information
  5       regarding copyright ownership.  The ASF licenses this file
  6       to you under the Apache License, Version 2.0 (the
  7       "License"); you may not use this file except in compliance
  8       with the License.  You may obtain a copy of the License at
  9
 10         http://www.apache.org/licenses/LICENSE-2.0
 11
 12       Unless required by applicable law or agreed to in writing,
 13       software distributed under the License is distributed on an
 14       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 15       KIND, either express or implied.  See the License for the
 16       specific language governing permissions and limitations
 17       under the License.
 18*/
 19package org.apache.cordova;
 20
 21import java.lang.reflect.InvocationTargetException;
 22import java.lang.reflect.Method;
 23import java.util.Arrays;
 24
 25import org.apache.cordova.CordovaInterface;
 26import org.apache.cordova.CordovaPlugin;
 27import org.apache.cordova.LOG;
 28
 29import android.content.pm.PackageManager;
 30
 31/**
 32 * This class provides reflective methods for permission requesting and checking so that plugins
 33 * written for cordova-android 5.0.0+ can still compile with earlier cordova-android versions.
 34 */
 35public class PermissionHelper {
 36    private static final String LOG_TAG = "CordovaPermissionHelper";
 37
 38    /**
 39     * Requests a "dangerous" permission for the application at runtime. This is a helper method
 40     * alternative to cordovaInterface.requestPermission() that does not require the project to be
 41     * built with cordova-android 5.0.0+
 42     *
 43     * @param plugin        The plugin the permission is being requested for
 44     * @param requestCode   A requestCode to be passed to the plugin's onRequestPermissionResult()
 45     *                      along with the result of the permission request
 46     * @param permission    The permission to be requested
 47     */
 48    public static void requestPermission(CordovaPlugin plugin, int requestCode, String permission) {
 49        PermissionHelper.requestPermissions(plugin, requestCode, new String[] {permission});
 50    }
 51
 52    /**
 53     * Requests "dangerous" permissions for the application at runtime. This is a helper method
 54     * alternative to cordovaInterface.requestPermissions() that does not require the project to be
 55     * built with cordova-android 5.0.0+
 56     *
 57     * @param plugin        The plugin the permissions are being requested for
 58     * @param requestCode   A requestCode to be passed to the plugin's onRequestPermissionResult()
 59     *                      along with the result of the permissions request
 60     * @param permissions   The permissions to be requested
 61     */
 62    public static void requestPermissions(CordovaPlugin plugin, int requestCode, String[] permissions) {
 63        try {
 64            Method requestPermission = CordovaInterface.class.getDeclaredMethod(
 65                    "requestPermissions", CordovaPlugin.class, int.class, String[].class);
 66
 67            // If there is no exception, then this is cordova-android 5.0.0+
 68            requestPermission.invoke(plugin.cordova, plugin, requestCode, permissions);
 69        } catch (NoSuchMethodException noSuchMethodException) {
 70            // cordova-android version is less than 5.0.0, so permission is implicitly granted
 71            LOG.d(LOG_TAG, "No need to request permissions " + Arrays.toString(permissions));
 72
 73            // Notify the plugin that all were granted by using more reflection
 74            deliverPermissionResult(plugin, requestCode, permissions);
 75        } catch (IllegalAccessException illegalAccessException) {
 76            // Should never be caught; this is a public method
 77            LOG.e(LOG_TAG, "IllegalAccessException when requesting permissions " + Arrays.toString(permissions), illegalAccessException);
 78        } catch(InvocationTargetException invocationTargetException) {
 79            // This method does not throw any exceptions, so this should never be caught
 80            LOG.e(LOG_TAG, "invocationTargetException when requesting permissions " + Arrays.toString(permissions), invocationTargetException);
 81        }
 82    }
 83
 84    /**
 85     * Checks at runtime to see if the application has been granted a permission. This is a helper
 86     * method alternative to cordovaInterface.hasPermission() that does not require the project to
 87     * be built with cordova-android 5.0.0+
 88     *
 89     * @param plugin        The plugin the permission is being checked against
 90     * @param permission    The permission to be checked
 91     *
 92     * @return              True if the permission has already been granted and false otherwise
 93     */
 94    public static boolean hasPermission(CordovaPlugin plugin, String permission) {
 95        try {
 96            Method hasPermission = CordovaInterface.class.getDeclaredMethod("hasPermission", String.class);
 97
 98            // If there is no exception, then this is cordova-android 5.0.0+
 99            return (Boolean) hasPermission.invoke(plugin.cordova, permission);
100        } catch (NoSuchMethodException noSuchMethodException) {
101            // cordova-android version is less than 5.0.0, so permission is implicitly granted
102            LOG.d(LOG_TAG, "No need to check for permission " + permission);
103            return true;
104        } catch (IllegalAccessException illegalAccessException) {
105            // Should never be caught; this is a public method
106            LOG.e(LOG_TAG, "IllegalAccessException when checking permission " + permission, illegalAccessException);
107        } catch(InvocationTargetException invocationTargetException) {
108            // This method does not throw any exceptions, so this should never be caught
109            LOG.e(LOG_TAG, "invocationTargetException when checking permission " + permission, invocationTargetException);
110        }
111        return false;
112    }
113
114    private static void deliverPermissionResult(CordovaPlugin plugin, int requestCode, String[] permissions) {
115        // Generate the request results
116        int[] requestResults = new int[permissions.length];
117        Arrays.fill(requestResults, PackageManager.PERMISSION_GRANTED);
118
119        try {
120            Method onRequestPermissionResult = CordovaPlugin.class.getDeclaredMethod(
121                    "onRequestPermissionResult", int.class, String[].class, int[].class);
122
123            onRequestPermissionResult.invoke(plugin, requestCode, permissions, requestResults);
124        } catch (NoSuchMethodException noSuchMethodException) {
125            // Should never be caught since the plugin must be written for cordova-android 5.0.0+ if it
126            // made it to this point
127            LOG.e(LOG_TAG, "NoSuchMethodException when delivering permissions results", noSuchMethodException);
128        } catch (IllegalAccessException illegalAccessException) {
129            // Should never be caught; this is a public method
130            LOG.e(LOG_TAG, "IllegalAccessException when delivering permissions results", illegalAccessException);
131        } catch(InvocationTargetException invocationTargetException) {
132            // This method may throw a JSONException. We are just duplicating cordova-android's
133            // exception handling behavior here; all it does is log the exception in CordovaActivity,
134            // print the stacktrace, and ignore it
135            LOG.e(LOG_TAG, "InvocationTargetException when delivering permissions results", invocationTargetException);
136        }
137    }
138}