Require ACCESS_FINE_LOCATION for Geofence use.

Bug: 7153226
Change-Id: I49236379e739fcda66bbc9a31cfdca9a87122aec
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index bef363b..b127b53 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -994,6 +994,12 @@
      * <p> Internally, this method uses both {@link #NETWORK_PROVIDER}
      * and {@link #GPS_PROVIDER}.
      *
+     * <p>Before API version 17, this method could be used with
+     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+     * From API version 17 and onwards, this method requires
+     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission.
+     *
      * @param latitude the latitude of the central point of the
      * alert region
      * @param longitude the longitude of the central point of the
@@ -1005,7 +1011,8 @@
      * @param intent a PendingIntent that will be used to generate an Intent to
      * fire when entry to or exit from the alert region is detected
      *
-     * @throws SecurityException if no suitable permission is present
+     * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
+     * permission is not present
      *
      * @deprecated Use {@link LocationRequest} and {@link Geofence} instead
      */
@@ -1055,7 +1062,8 @@
      *
      * @throws IllegalArgumentException if fence is null
      * @throws IllegalArgumentException if intent is null
-     * @throws SecurityException if no suitable permission is present
+     * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
+     * permission is not present
      */
     public void addGeofence(LocationRequest request, Geofence fence, PendingIntent intent) {
         checkPendingIntent(intent);
@@ -1071,11 +1079,18 @@
     /**
      * Removes the proximity alert with the given PendingIntent.
      *
+     * <p>Before API version 17, this method could be used with
+     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or
+     * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}.
+     * From API version 17 and onwards, this method requires
+     * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission.
+     *
      * @param intent the PendingIntent that no longer needs to be notified of
      * proximity alerts
      *
      * @throws IllegalArgumentException if intent is null
-     * @throws SecurityException if no suitable permission is present
+     * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
+     * permission is not present
      *
      * @deprecated Use {@link LocationRequest} and {@link Geofence} instead
      */
@@ -1102,7 +1117,8 @@
      *
      * @throws IllegalArgumentException if fence is null
      * @throws IllegalArgumentException if intent is null
-     * @throws SecurityException if no suitable permission is present
+     * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
+     * permission is not present
      */
     public void removeGeofence(Geofence fence, PendingIntent intent) {
         checkPendingIntent(intent);
@@ -1122,7 +1138,8 @@
      * @param intent a pending intent previously passed to {@link #addGeofence}
      *
      * @throws IllegalArgumentException if intent is null
-     * @throws SecurityException if no suitable permission is present
+     * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION}
+     * permission is not present
      */
     public void removeAllGeofences(PendingIntent intent) {
         checkPendingIntent(intent);
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index c26448f..197f6ab 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -588,7 +588,17 @@
         }
 
         throw new SecurityException("Location requires either ACCESS_COARSE_LOCATION or" +
-                "ACCESS_FINE_LOCATION permission");
+                " ACCESS_FINE_LOCATION permission");
+    }
+
+    /**
+     * Throw SecurityException if caller lacks permission to use Geofences.
+     */
+    private void checkGeofencePermission() {
+        if (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) !=
+                PackageManager.PERMISSION_GRANTED) {
+            throw new SecurityException("Geofence usage requires ACCESS_FINE_LOCATION permission");
+        }
     }
 
     /**
@@ -1096,6 +1106,7 @@
     public void requestGeofence(LocationRequest request, Geofence geofence, PendingIntent intent,
             String packageName) {
         if (request == null) request = DEFAULT_LOCATION_REQUEST;
+        checkGeofencePermission();
         checkPermissionAndRequest(request);
         checkPendingIntent(intent);
         checkPackageName(packageName);
@@ -1114,7 +1125,7 @@
 
     @Override
     public void removeGeofence(Geofence geofence, PendingIntent intent, String packageName) {
-        checkPermission();
+        checkGeofencePermission();
         checkPendingIntent(intent);
         checkPackageName(packageName);