Throttle location update rate in proximity alert

Bug: 36197768
Test: manual
Change-Id: I2427ed7e77e9153c20e7c65e8f861de4c7ffeac6
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 89c0963..78a7ea3 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -7717,6 +7717,14 @@
                 "location_background_throttle_interval_ms";
 
         /**
+         * Most frequent location update interval in milliseconds that proximity alert is allowed
+         * to request.
+         * @hide
+         */
+        public static final String LOCATION_BACKGROUND_THROTTLE_PROXIMITY_ALERT_INTERVAL_MS =
+                "location_background_throttle_proximity_alert_interval_ms";
+
+        /**
          * Packages that are whitelisted for background throttling (throttling will not be applied).
          * @hide
          */
diff --git a/core/tests/coretests/src/android/provider/SettingsBackupTest.java b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
index ba24eec..a4b1378 100644
--- a/core/tests/coretests/src/android/provider/SettingsBackupTest.java
+++ b/core/tests/coretests/src/android/provider/SettingsBackupTest.java
@@ -213,6 +213,7 @@
                     Settings.Global.LANG_ID_UPDATE_CONTENT_URL,
                     Settings.Global.LANG_ID_UPDATE_METADATA_URL,
                     Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS,
+                    Settings.Global.LOCATION_BACKGROUND_THROTTLE_PROXIMITY_ALERT_INTERVAL_MS,
                     Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST,
                     Settings.Global.LOCATION_SETTINGS_LINK_TO_PERMISSIONS_ENABLED,
                     Settings.Global.LOCK_SOUND,
diff --git a/services/core/java/com/android/server/location/GeofenceManager.java b/services/core/java/com/android/server/location/GeofenceManager.java
index e24bf76..2493dfb 100644
--- a/services/core/java/com/android/server/location/GeofenceManager.java
+++ b/services/core/java/com/android/server/location/GeofenceManager.java
@@ -23,8 +23,10 @@
 
 import android.app.AppOpsManager;
 import android.app.PendingIntent;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.database.ContentObserver;
 import android.location.Geofence;
 import android.location.Location;
 import android.location.LocationListener;
@@ -35,6 +37,8 @@
 import android.os.Message;
 import android.os.PowerManager;
 import android.os.SystemClock;
+import android.os.UserHandle;
+import android.provider.Settings;
 import android.util.Slog;
 
 import com.android.server.LocationManagerService;
@@ -58,9 +62,9 @@
     private static final long MAX_AGE_NANOS = 5 * 60 * 1000000000L; // five minutes
 
     /**
-     * Most frequent update interval allowed.
+     * The default value of most frequent update interval allowed.
      */
-    private static final long MIN_INTERVAL_MS = 1 * 60 * 1000; // one minute
+    private static final long DEFAULT_MIN_INTERVAL_MS = 30 * 60 * 1000; // 30 minutes
 
     /**
      * Least frequent update interval allowed.
@@ -106,6 +110,12 @@
      */
     private boolean mPendingUpdate;
 
+    /**
+     * The actual value of most frequent update interval allowed.
+     */
+    private long mEffectiveMinIntervalMs;
+    private ContentResolver mResolver;
+
     public GeofenceManager(Context context, LocationBlacklist blacklist) {
         mContext = context;
         mLocationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
@@ -114,6 +124,28 @@
         mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
         mHandler = new GeofenceHandler();
         mBlacklist = blacklist;
+        mResolver = mContext.getContentResolver();
+        updateMinInterval();
+        mResolver.registerContentObserver(
+            Settings.Global.getUriFor(
+                    Settings.Global.LOCATION_BACKGROUND_THROTTLE_PROXIMITY_ALERT_INTERVAL_MS),
+            true,
+            new ContentObserver(mHandler) {
+                @Override
+                public void onChange(boolean selfChange) {
+                    synchronized (mLock) {
+                        updateMinInterval();
+                    }
+                }
+            }, UserHandle.USER_ALL);
+    }
+
+    /**
+     * Updates the minimal location request frequency.
+     */
+    private void updateMinInterval() {
+        mEffectiveMinIntervalMs = Settings.Global.getLong(mResolver,
+                Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS, DEFAULT_MIN_INTERVAL_MS);
     }
 
     public void addFence(LocationRequest request, Geofence geofence, PendingIntent intent,
@@ -301,10 +333,10 @@
                 // Compute a location update interval based on the distance to the nearest fence.
                 long intervalMs;
                 if (location != null && Double.compare(minFenceDistance, Double.MAX_VALUE) != 0) {
-                    intervalMs = (long)Math.min(MAX_INTERVAL_MS, Math.max(MIN_INTERVAL_MS,
+                    intervalMs = (long)Math.min(MAX_INTERVAL_MS, Math.max(mEffectiveMinIntervalMs,
                             minFenceDistance * 1000 / MAX_SPEED_M_S));
                 } else {
-                    intervalMs = MIN_INTERVAL_MS;
+                    intervalMs = mEffectiveMinIntervalMs;
                 }
                 if (!mReceivingLocationUpdates || mLocationUpdateInterval != intervalMs) {
                     mReceivingLocationUpdates = true;