diff options
7 files changed, 47 insertions, 29 deletions
diff --git a/location/api/system-current.txt b/location/api/system-current.txt index 8cd08d3aad6c..9478e350de57 100644 --- a/location/api/system-current.txt +++ b/location/api/system-current.txt @@ -645,7 +645,7 @@ package android.location.provider { @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 9b5cb5ae8c7a..41fe5006983d 100644 --- a/location/java/android/location/provider/IPopulationDensityProvider.aidl +++ b/location/java/android/location/provider/IPopulationDensityProvider.aidl @@ -35,11 +35,11 @@ oneway interface IPopulationDensityProvider { 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 3907516f6aaa..0177cf8694df 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 @@ public abstract class PopulationDensityProviderBase { * 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 @@ public abstract class PopulationDensityProviderBase { } @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 3670c1f5c51b..ce8bec8f0147 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 @@ public class LocationFudgerCache { 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 b0a0f0b0c83b..7b454e481dda 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 @@ public class ProxyPopulationDensityProvider { /** 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 04b82c4890af..6b7eda26b945 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 com.google.common.truth.Truth.assertThat; 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 @@ public class LocationFudgerCacheTest { 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 @@ public class LocationFudgerCacheTest { 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 @@ public class LocationFudgerCacheTest { 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 cd1990407806..6d78defe2943 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 @@ public class LocationProviderManagerTest { 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 @@ public class LocationProviderManagerTest { 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 @@ public class LocationProviderManagerTest { // 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 |