Merge "Population Density Provider: add cache hint" into main
diff --git a/location/api/system-current.txt b/location/api/system-current.txt
index 8cd08d3..9478e35 100644
--- a/location/api/system-current.txt
+++ b/location/api/system-current.txt
@@ -645,7 +645,7 @@
@FlaggedApi("android.location.flags.population_density_provider") public abstract class PopulationDensityProviderBase {
ctor public PopulationDensityProviderBase(@NonNull android.content.Context, @NonNull String);
method @Nullable public final android.os.IBinder getBinder();
- method public abstract void onGetCoarsenedS2Cell(double, double, @NonNull android.os.OutcomeReceiver<long[],java.lang.Throwable>);
+ method public abstract void onGetCoarsenedS2Cells(double, double, @IntRange(from=0) int, @NonNull android.os.OutcomeReceiver<long[],java.lang.Throwable>);
method public abstract void onGetDefaultCoarseningLevel(@NonNull android.os.OutcomeReceiver<java.lang.Integer,java.lang.Throwable>);
field public static final String ACTION_POPULATION_DENSITY_PROVIDER = "com.android.location.service.PopulationDensityProvider";
}
diff --git a/location/java/android/location/provider/IPopulationDensityProvider.aidl b/location/java/android/location/provider/IPopulationDensityProvider.aidl
index 9b5cb5a..41fe500 100644
--- a/location/java/android/location/provider/IPopulationDensityProvider.aidl
+++ b/location/java/android/location/provider/IPopulationDensityProvider.aidl
@@ -35,11 +35,11 @@
void getDefaultCoarseningLevel(in IS2LevelCallback callback);
/**
- * Returns a list of IDs of the S2 cells to be used to coarsen a location. The answer should
+ * Requests a list of IDs of the S2 cells to be used to coarsen a location. The answer should
* contain at least one S2 cell, which should contain the requested location. Its level
- * represents the population density. Optionally, additional nearby cells can be also returned,
- * to assist in coarsening nearby locations.
+ * represents the population density. Optionally, if numAdditionalCells is greater than 0,
+ * additional nearby cells can be also returned, to assist in coarsening nearby locations.
*/
- void getCoarsenedS2Cell(double latitudeDegrees, double longitudeDegrees, in IS2CellIdsCallback
- callback);
+ void getCoarsenedS2Cells(double latitudeDegrees, double longitudeDegrees,
+ int numAdditionalCells, in IS2CellIdsCallback callback);
}
diff --git a/location/java/android/location/provider/PopulationDensityProviderBase.java b/location/java/android/location/provider/PopulationDensityProviderBase.java
index 3907516..0177cf8 100644
--- a/location/java/android/location/provider/PopulationDensityProviderBase.java
+++ b/location/java/android/location/provider/PopulationDensityProviderBase.java
@@ -17,6 +17,7 @@
package android.location.provider;
import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SuppressLint;
@@ -89,17 +90,18 @@
* Called upon receiving a new request for population density at a specific latitude/longitude,
* expressed in degrees.
* The answer is at least one S2CellId corresponding to the coarsening level at the specified
- * location. This must be the first element of the result array. Optionally, additional nearby
- * S2CellIds can be returned. One use for the optional nearby cells is when the client has a
- * local cache that needs to be filled with the local area around a certain latitude/longitude.
- * The callback {@link OutcomeReceiver#onResult} should be called with the result; or, in case
- * an error occurs, {@link OutcomeReceiver#onError} should be called.
- * The callback is single-use, calling more than any one of these two methods throws an
- * AssertionException.
+ * location. This must be the first element of the result array. Optionally, if
+ * numAdditionalCells is greater than zero, additional nearby S2CellIds can be returned. One use
+ * for the optional nearby cells is when the client has a local cache that needs to be filled
+ * with the local area around a certain latitude/longitude. The callback
+ * {@link OutcomeReceiver#onResult} should be called with the result; or, in case an error
+ * occurs, {@link OutcomeReceiver#onError} should be called. The callback is single-use, calling
+ * more than any one of these two methods throws an AssertionException.
*
* @param callback A single-use callback that either returns S2CellIds, or an error.
*/
- public abstract void onGetCoarsenedS2Cell(double latitudeDegrees, double longitudeDegrees,
+ public abstract void onGetCoarsenedS2Cells(double latitudeDegrees, double longitudeDegrees,
+ @IntRange(from = 0) int numAdditionalCells,
@NonNull OutcomeReceiver<long[], Throwable> callback);
private final class Service extends IPopulationDensityProvider.Stub {
@@ -119,10 +121,10 @@
}
@Override
- public void getCoarsenedS2Cell(double latitudeDegrees, double longitudeDegrees,
- @NonNull IS2CellIdsCallback callback) {
+ public void getCoarsenedS2Cells(double latitudeDegrees, double longitudeDegrees,
+ int numAdditionalCells, @NonNull IS2CellIdsCallback callback) {
try {
- onGetCoarsenedS2Cell(latitudeDegrees, longitudeDegrees,
+ onGetCoarsenedS2Cells(latitudeDegrees, longitudeDegrees, numAdditionalCells,
new SingleUseS2CellIdsCallback(callback));
} catch (RuntimeException e) {
// exceptions on one-way binder threads are dropped - move to a different thread
diff --git a/services/core/java/com/android/server/location/fudger/LocationFudgerCache.java b/services/core/java/com/android/server/location/fudger/LocationFudgerCache.java
index 3670c1f..ce8bec8 100644
--- a/services/core/java/com/android/server/location/fudger/LocationFudgerCache.java
+++ b/services/core/java/com/android/server/location/fudger/LocationFudgerCache.java
@@ -180,7 +180,8 @@
Log.e(sTAG, "could not get population density");
}
};
- mPopulationDensityProvider.getCoarsenedS2Cell(latitude, longitude, callback);
+ mPopulationDensityProvider.getCoarsenedS2Cells(latitude, longitude, MAX_CACHE_SIZE - 1,
+ callback);
}
/**
diff --git a/services/core/java/com/android/server/location/provider/proxy/ProxyPopulationDensityProvider.java b/services/core/java/com/android/server/location/provider/proxy/ProxyPopulationDensityProvider.java
index b0a0f0b..7b454e4 100644
--- a/services/core/java/com/android/server/location/provider/proxy/ProxyPopulationDensityProvider.java
+++ b/services/core/java/com/android/server/location/provider/proxy/ProxyPopulationDensityProvider.java
@@ -96,14 +96,15 @@
/** Gets the population density at the requested location. */
- public void getCoarsenedS2Cell(double latitudeDegrees, double longitudeDegrees,
- IS2CellIdsCallback callback) {
+ public void getCoarsenedS2Cells(double latitudeDegrees, double longitudeDegrees,
+ int numAdditionalCells, IS2CellIdsCallback callback) {
mServiceWatcher.runOnBinder(
new ServiceWatcher.BinderOperation() {
@Override
public void run(IBinder binder) throws RemoteException {
IPopulationDensityProvider.Stub.asInterface(binder)
- .getCoarsenedS2Cell(latitudeDegrees, longitudeDegrees, callback);
+ .getCoarsenedS2Cells(latitudeDegrees, longitudeDegrees,
+ numAdditionalCells, callback);
}
@Override
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/fudger/LocationFudgerCacheTest.java b/services/tests/mockingservicestests/src/com/android/server/location/fudger/LocationFudgerCacheTest.java
index 04b82c4..6b7eda2 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/fudger/LocationFudgerCacheTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/fudger/LocationFudgerCacheTest.java
@@ -20,6 +20,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyDouble;
+import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -226,8 +227,8 @@
cache.getCoarseningLevel(POINT_IN_TIMES_SQUARE[0], POINT_IN_TIMES_SQUARE[1]);
- verify(provider).getCoarsenedS2Cell(eq(POINT_IN_TIMES_SQUARE[0]),
- eq(POINT_IN_TIMES_SQUARE[1]), any());
+ verify(provider).getCoarsenedS2Cells(eq(POINT_IN_TIMES_SQUARE[0]),
+ eq(POINT_IN_TIMES_SQUARE[1]), anyInt(), any());
}
@Test
@@ -242,8 +243,8 @@
ArgumentCaptor<IS2CellIdsCallback> argumentCaptor = ArgumentCaptor.forClass(
IS2CellIdsCallback.class);
- verify(provider).getCoarsenedS2Cell(eq(POINT_IN_TIMES_SQUARE[0]),
- eq(POINT_IN_TIMES_SQUARE[1]), argumentCaptor.capture());
+ verify(provider).getCoarsenedS2Cells(eq(POINT_IN_TIMES_SQUARE[0]),
+ eq(POINT_IN_TIMES_SQUARE[1]), anyInt(), argumentCaptor.capture());
// Results from the proxy should set the cache
int expectedLevel = 4;
@@ -264,10 +265,23 @@
cache.addToCache(TIMES_SQUARE_S2_ID);
- verify(provider, never()).getCoarsenedS2Cell(anyDouble(), anyDouble(), any());
+ verify(provider, never()).getCoarsenedS2Cells(anyDouble(), anyDouble(), anyInt(), any());
}
@Test
+ public void locationFudgerCache_whenQueryIsCached_askForMaxCacheSizeElems() {
+ ProxyPopulationDensityProvider provider = mock(ProxyPopulationDensityProvider.class);
+ LocationFudgerCache cache = new LocationFudgerCache(provider);
+ int numAdditionalCells = cache.MAX_CACHE_SIZE - 1;
+
+ cache.getCoarseningLevel(POINT_IN_TIMES_SQUARE[0], POINT_IN_TIMES_SQUARE[1]);
+
+ verify(provider).getCoarsenedS2Cells(eq(POINT_IN_TIMES_SQUARE[0]),
+ eq(POINT_IN_TIMES_SQUARE[1]), eq(numAdditionalCells), any());
+ }
+
+
+ @Test
public void locationFudgerCache_canContainUpToMaxSizeItems() {
// This test has two sequences of arrange-act-assert.
// The first checks that the cache correctly store up to MAX_CACHE_SIZE items.
diff --git a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
index cd19904..6d78def 100644
--- a/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/location/provider/LocationProviderManagerTest.java
@@ -1448,7 +1448,7 @@
Location test = new Location("any-provider");
mManager.getPermittedLocation(test, PERMISSION_COARSE);
- verify(provider, never()).getCoarsenedS2Cell(anyDouble(), anyDouble(), any());
+ verify(provider, never()).getCoarsenedS2Cells(anyDouble(), anyDouble(), anyInt(), any());
}
@Test
@@ -1472,7 +1472,7 @@
Location test = new Location("any-provider");
mManager.getPermittedLocation(test, PERMISSION_COARSE);
- verify(provider, never()).getCoarsenedS2Cell(anyDouble(), anyDouble(), any());
+ verify(provider, never()).getCoarsenedS2Cells(anyDouble(), anyDouble(), anyInt(), any());
}
@Test
@@ -1499,7 +1499,7 @@
// We can't test that 10.0, 20.0 was passed due to the offset. We only test that a call
// happened.
- verify(provider).getCoarsenedS2Cell(anyDouble(), anyDouble(), any());
+ verify(provider).getCoarsenedS2Cells(anyDouble(), anyDouble(), anyInt(), any());
}
@MediumTest