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}