You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cordova.apache.org by da...@apache.org on 2022/10/18 13:33:10 UTC

[cordova-plugin-geolocation] branch master updated: (android) fix: respect requested location accuracy when checking/requesting permissions on Android 12+ Handle bug on API < 32 when requesting COARSE permission results in TIMEOUT error.

This is an automated email from the ASF dual-hosted git repository.

davealden pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cordova-plugin-geolocation.git


The following commit(s) were added to refs/heads/master by this push:
     new 73719d9  (android) fix: respect requested location accuracy when checking/requesting permissions on Android 12+ Handle bug on API < 32 when requesting COARSE permission results in TIMEOUT error.
     new 9187204  Merge pull request #250 from dpa99c/android_permission_types
73719d9 is described below

commit 73719d94e37cc6ba83dac0a35b18ae7ff8ab884c
Author: Dave Alden <dp...@gmail.com>
AuthorDate: Mon Aug 1 14:19:01 2022 +0100

    (android) fix: respect requested location accuracy when checking/requesting permissions on Android 12+
    Handle bug on API < 32 when requesting COARSE permission results in TIMEOUT error.
---
 src/android/Geolocation.java | 45 ++++++++++++++++++++++++++++++++++----------
 www/android/geolocation.js   | 30 ++++++++++++++++++-----------
 2 files changed, 54 insertions(+), 21 deletions(-)

diff --git a/src/android/Geolocation.java b/src/android/Geolocation.java
index 6452170..d8cae0e 100644
--- a/src/android/Geolocation.java
+++ b/src/android/Geolocation.java
@@ -23,7 +23,6 @@ import android.Manifest;
 import android.os.Build;
 
 import org.apache.cordova.CallbackContext;
-import org.apache.cordova.CordovaArgs;
 import org.apache.cordova.CordovaPlugin;
 import org.apache.cordova.PermissionHelper;
 import org.apache.cordova.PluginResult;
@@ -31,14 +30,17 @@ import org.apache.cordova.LOG;
 import org.json.JSONArray;
 import org.json.JSONException;
 
-import javax.security.auth.callback.Callback;
 
 public class Geolocation extends CordovaPlugin {
 
     String TAG = "GeolocationPlugin";
     CallbackContext context;
 
-    String [] permissions = { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION };
+
+    String [] highAccuracyPermissions = { Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION };
+    String [] lowAccuracyPermissions = { Manifest.permission.ACCESS_COARSE_LOCATION };
+    String [] permissionsToRequest;
+    String[] permissionsToCheck;
 
 
     public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
@@ -46,14 +48,21 @@ public class Geolocation extends CordovaPlugin {
         context = callbackContext;
         if(action.equals("getPermission"))
         {
-            if(hasPermisssion())
+            boolean highAccuracy = args.getBoolean(0);
+            permissionsToCheck = highAccuracy ? highAccuracyPermissions : lowAccuracyPermissions;
+
+            // Always request both FINE & COARSE permissions on API <= 31 due to bug in WebView that manifests on these versions
+            // See https://bugs.chromium.org/p/chromium/issues/detail?id=1269362
+            permissionsToRequest = Build.VERSION.SDK_INT <= 31 ? highAccuracyPermissions : permissionsToCheck;
+
+            if(hasPermisssion(permissionsToCheck))
             {
-                PluginResult r = new PluginResult(PluginResult.Status.OK);
+                PluginResult r = new PluginResult(PluginResult.Status.OK, Build.VERSION.SDK_INT);
                 context.sendPluginResult(r);
                 return true;
             }
             else {
-                PermissionHelper.requestPermissions(this, 0, permissions);
+                PermissionHelper.requestPermissions(this, 0, permissionsToRequest);
             }
             return true;
         }
@@ -67,8 +76,10 @@ public class Geolocation extends CordovaPlugin {
         PluginResult result;
         //This is important if we're using Cordova without using Cordova, but we have the geolocation plugin installed
         if(context != null) {
-            for (int r : grantResults) {
-                if (r == PackageManager.PERMISSION_DENIED) {
+            for (int i=0; i<grantResults.length; i++) {
+                int r = grantResults[i];
+                String p = permissions[i];
+                if (r == PackageManager.PERMISSION_DENIED && arrayContains(permissionsToCheck, p)) {
                     LOG.d(TAG, "Permission Denied!");
                     result = new PluginResult(PluginResult.Status.ILLEGAL_ACCESS_EXCEPTION);
                     context.sendPluginResult(result);
@@ -81,7 +92,7 @@ public class Geolocation extends CordovaPlugin {
         }
     }
 
-    public boolean hasPermisssion() {
+    public boolean hasPermisssion(String[] permissions) {
         for(String p : permissions)
         {
             if(!PermissionHelper.hasPermission(this, p))
@@ -99,9 +110,23 @@ public class Geolocation extends CordovaPlugin {
 
     public void requestPermissions(int requestCode)
     {
-        PermissionHelper.requestPermissions(this, requestCode, permissions);
+        PermissionHelper.requestPermissions(this, requestCode, permissionsToRequest);
     }
 
+    //https://stackoverflow.com/a/12635769/777265
+    private <T> boolean arrayContains(final T[] array, final T v) {
+        if (v == null) {
+            for (final T e : array)
+                if (e == null)
+                    return true;
+        }
+        else {
+            for (final T e : array)
+                if (e == v || v.equals(e))
+                    return true;
+        }
 
+        return false;
+    }
 
 }
diff --git a/www/android/geolocation.js b/www/android/geolocation.js
index c02940b..2d66809 100644
--- a/www/android/geolocation.js
+++ b/www/android/geolocation.js
@@ -29,7 +29,12 @@ var pluginToNativeWatchMap = {};
 
 module.exports = {
     getCurrentPosition: function (success, error, args) {
-        var win = function () {
+        var win = function (deviceApiLevel) {
+            // Workaround for bug specific to API 31 where requesting `enableHighAccuracy: false` results in TIMEOUT error.
+            if (deviceApiLevel === 31) {
+                if (typeof args === 'undefined') args = {};
+                args.enableHighAccuracy = true;
+            }
             var geo = cordova.require('cordova/modulemapper').getOriginalSymbol(window, 'navigator.geolocation'); // eslint-disable-line no-undef
             geo.getCurrentPosition(success, error, args);
         };
@@ -38,13 +43,19 @@ module.exports = {
                 error(new PositionError(PositionError.PERMISSION_DENIED, 'Illegal Access'));
             }
         };
-        exec(win, fail, 'Geolocation', 'getPermission', []);
+        var enableHighAccuracy = typeof args === 'object' && !!args.enableHighAccuracy;
+        exec(win, fail, 'Geolocation', 'getPermission', [enableHighAccuracy]);
     },
 
     watchPosition: function (success, error, args) {
         var pluginWatchId = utils.createUUID();
 
-        var win = function () {
+        var win = function (deviceApiLevel) {
+            // Workaround for bug specific to API 31 where requesting `enableHighAccuracy: false` results in TIMEOUT error.
+            if (deviceApiLevel === 31) {
+                if (typeof args === 'undefined') args = {};
+                args.enableHighAccuracy = true;
+            }
             var geo = cordova.require('cordova/modulemapper').getOriginalSymbol(window, 'navigator.geolocation'); // eslint-disable-line no-undef
             pluginToNativeWatchMap[pluginWatchId] = geo.watchPosition(success, error, args);
         };
@@ -54,18 +65,15 @@ module.exports = {
                 error(new PositionError(PositionError.PERMISSION_DENIED, 'Illegal Access'));
             }
         };
-        exec(win, fail, 'Geolocation', 'getPermission', []);
+        var enableHighAccuracy = typeof args === 'object' && !!args.enableHighAccuracy;
+        exec(win, fail, 'Geolocation', 'getPermission', [enableHighAccuracy]);
 
         return pluginWatchId;
     },
 
     clearWatch: function (pluginWatchId) {
-        var win = function () {
-            var nativeWatchId = pluginToNativeWatchMap[pluginWatchId];
-            var geo = cordova.require('cordova/modulemapper').getOriginalSymbol(window, 'navigator.geolocation'); // eslint-disable-line no-undef
-            geo.clearWatch(nativeWatchId);
-        };
-
-        exec(win, null, 'Geolocation', 'getPermission', []);
+        var nativeWatchId = pluginToNativeWatchMap[pluginWatchId];
+        var geo = cordova.require('cordova/modulemapper').getOriginalSymbol(window, 'navigator.geolocation'); // eslint-disable-line no-undef
+        geo.clearWatch(nativeWatchId);
     }
 };


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cordova.apache.org
For additional commands, e-mail: commits-help@cordova.apache.org