Update location CTS tests
-Add new classes to capture results from LocationListener,
PendingIntent, and GetCurrentLocation APIs
-Add new tests for a variety of untested LM methods
-Simplify GNSS tests which don't test much except that there isn't a
crash when invoked.
-Add tests around edge cases with null arguments.
-Add tests for new getCurrentLocation API
-Rewrite tests for requestLocationUpdates APIs to cover a larger segment
of use cases
-Add tests for minTime and minDistance paramters in location request
APIs
-Add more tests for getProvider* APIs
-Make CTS test less flaky by properly setting up and tearing down test
providers.
-Added more tests for Criteria APIs.
Test: LocationManagerTest
Change-Id: I9227d0bb3c5af17bc060b7eaf6bd95b362618f4d
diff --git a/tests/tests/location/src/android/location/cts/LocationManagerTest.java b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
index a46b19c..286fbb7 100644
--- a/tests/tests/location/src/android/location/cts/LocationManagerTest.java
+++ b/tests/tests/location/src/android/location/cts/LocationManagerTest.java
@@ -16,6 +16,16 @@
package android.location.cts;
+import static android.location.LocationManager.FUSED_PROVIDER;
+import static android.location.LocationManager.GPS_PROVIDER;
+import static android.location.LocationManager.KEY_LOCATION_CHANGED;
+import static android.location.LocationManager.KEY_PROVIDER_ENABLED;
+import static android.location.LocationManager.KEY_PROXIMITY_ENTERING;
+import static android.location.LocationManager.NETWORK_PROVIDER;
+import static android.location.LocationManager.PASSIVE_PROVIDER;
+
+import static org.junit.Assert.assertNotEquals;
+
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
@@ -23,22 +33,32 @@
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.location.Criteria;
+import android.location.GnssMeasurementsEvent;
+import android.location.GnssNavigationMessage;
import android.location.GnssStatus;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
+import android.location.LocationRequest;
import android.location.OnNmeaMessageListener;
import android.os.Bundle;
-import android.os.Handler;
+import android.os.CancellationSignal;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.SystemClock;
import android.os.UserManager;
-import android.test.UiThreadTest;
import android.util.Log;
+import com.android.internal.util.Preconditions;
+
import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Executors;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
/**
* Requires the permissions
@@ -51,815 +71,98 @@
private static final String TAG = "LocationManagerTest";
- private static final long TEST_TIME_OUT = 5000;
+ private static final long TIMEOUT_MS = 5000;
+ private static final long FAILURE_TIMEOUT_MS = 200;
- private static final String TEST_MOCK_PROVIDER_NAME = "test_provider";
-
- private static final String UNKNOWN_PROVIDER_NAME = "unknown_provider";
-
- private static final String FUSED_PROVIDER_NAME = "fused";
-
- private LocationManager mManager;
+ private static final String TEST_PROVIDER = "test_provider";
private Context mContext;
+ private LocationManager mManager;
- private PendingIntent mPendingIntent;
+ private static Location createLocation(String provider, double latitude, double longitude) {
+ Location location = new Location(provider);
+ location.setLatitude(latitude);
+ location.setLongitude(longitude);
+ location.setAccuracy(1.0f);
+ location.setTime(System.currentTimeMillis());
+ location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
+ return location;
+ }
- private TestIntentReceiver mIntentReceiver;
+ private static Executor directExecutor() {
+ return Runnable::run;
+ }
+
+ private static void assertLocationEquals(Location expected, Location actual) {
+ if (expected == actual) {
+ return;
+ }
+
+ if (expected == null || actual == null) {
+ // gives nicer error message
+ assertEquals(expected, actual);
+ return;
+ }
+
+ assertEquals(expected.getProvider(), actual.getProvider());
+ assertEquals(expected.getLatitude(), actual.getLatitude());
+ assertEquals(expected.getLongitude(), actual.getLongitude());
+ assertEquals(expected.getTime(), actual.getTime());
+ assertEquals(expected.getElapsedRealtimeNanos(), actual.getElapsedRealtimeNanos());
+ }
@Override
protected void setUp() throws Exception {
super.setUp();
mContext = getInstrumentation().getTargetContext();
+ mManager = mContext.getSystemService(LocationManager.class);
- mManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
+ assertNotNull(mManager);
- // remove test provider if left over from an aborted run
- LocationProvider lp = mManager.getProvider(TEST_MOCK_PROVIDER_NAME);
- if (lp != null) {
- mManager.removeTestProvider(TEST_MOCK_PROVIDER_NAME);
+ for (String provider : mManager.getAllProviders()) {
+ if (PASSIVE_PROVIDER.equals(provider)) {
+ continue;
+ }
+ mManager.removeTestProvider(provider);
}
- addTestProvider(TEST_MOCK_PROVIDER_NAME);
- }
-
- /**
- * Helper method to add a test provider with given name.
- */
- private void addTestProvider(final String providerName) {
- mManager.addTestProvider(providerName, true, //requiresNetwork,
- false, // requiresSatellite,
- true, // requiresCell,
- false, // hasMonetaryCost,
- false, // supportsAltitude,
- false, // supportsSpeed,
- false, // supportsBearing,
- Criteria.POWER_MEDIUM, // powerRequirement
- Criteria.ACCURACY_FINE); // accuracy
- mManager.setTestProviderEnabled(providerName, true);
+ mManager.addTestProvider(TEST_PROVIDER,
+ true,
+ false,
+ true,
+ false,
+ false,
+ false,
+ false,
+ Criteria.POWER_MEDIUM,
+ Criteria.ACCURACY_FINE);
+ mManager.setTestProviderEnabled(TEST_PROVIDER, true);
}
@Override
protected void tearDown() throws Exception {
- LocationProvider provider = mManager.getProvider(TEST_MOCK_PROVIDER_NAME);
- if (provider != null) {
- mManager.removeTestProvider(TEST_MOCK_PROVIDER_NAME);
+ for (String provider : mManager.getAllProviders()) {
+ if (PASSIVE_PROVIDER.equals(provider)) {
+ continue;
+ }
+ mManager.removeTestProvider(provider);
}
- if (mPendingIntent != null) {
- mManager.removeProximityAlert(mPendingIntent);
- }
- if (mIntentReceiver != null) {
- mContext.unregisterReceiver(mIntentReceiver);
- }
+
super.tearDown();
}
- public void testRemoveTestProvider() {
- // this test assumes TEST_MOCK_PROVIDER_NAME was created in setUp.
- LocationProvider provider = mManager.getProvider(TEST_MOCK_PROVIDER_NAME);
- assertNotNull(provider);
-
- try {
- mManager.addTestProvider(TEST_MOCK_PROVIDER_NAME, true, //requiresNetwork,
- false, // requiresSatellite,
- true, // requiresCell,
- false, // hasMonetaryCost,
- false, // supportsAltitude,
- false, // supportsSpeed,
- false, // supportsBearing,
- Criteria.POWER_MEDIUM, // powerRequirement
- Criteria.ACCURACY_FINE); // accuracy
- fail("Should throw IllegalArgumentException when provider already exists!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- mManager.removeTestProvider(TEST_MOCK_PROVIDER_NAME);
- provider = mManager.getProvider(TEST_MOCK_PROVIDER_NAME);
- assertNull(provider);
-
- try {
- mManager.removeTestProvider(UNKNOWN_PROVIDER_NAME);
- fail("Should throw IllegalArgumentException when no provider exists!");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- public void testGetProviders() {
- List<String> providers = mManager.getAllProviders();
- assertTrue(providers.size() >= 2);
- assertTrue(hasTestProvider(providers));
-
- assertEquals(hasGpsFeature(), hasGpsProvider(providers));
-
- int oldSizeAllProviders = providers.size();
-
- providers = mManager.getProviders(false);
- assertEquals(oldSizeAllProviders, providers.size());
- assertTrue(hasTestProvider(providers));
-
- providers = mManager.getProviders(true);
- assertTrue(providers.size() >= 1);
- assertTrue(hasTestProvider(providers));
- int oldSizeTrueProviders = providers.size();
-
- mManager.setTestProviderEnabled(TEST_MOCK_PROVIDER_NAME, false);
- providers = mManager.getProviders(true);
- assertEquals(oldSizeTrueProviders - 1, providers.size());
- assertFalse(hasTestProvider(providers));
-
- providers = mManager.getProviders(false);
- assertEquals(oldSizeAllProviders, providers.size());
- assertTrue(hasTestProvider(providers));
-
- mManager.removeTestProvider(TEST_MOCK_PROVIDER_NAME);
- providers = mManager.getAllProviders();
- assertEquals(oldSizeAllProviders - 1, providers.size());
- assertFalse(hasTestProvider(providers));
- }
-
- private boolean hasTestProvider(List<String> providers) {
- return hasProvider(providers, TEST_MOCK_PROVIDER_NAME);
- }
-
- private boolean hasGpsProvider(List<String> providers) {
- return hasProvider(providers, LocationManager.GPS_PROVIDER);
- }
-
- private boolean hasGpsFeature() {
- return mContext.getPackageManager().hasSystemFeature(
- PackageManager.FEATURE_LOCATION_GPS);
- }
-
- private boolean hasProvider(List<String> providers, String providerName) {
- for (String provider : providers) {
- if (provider != null && provider.equals(providerName)) {
- return true;
- }
- }
- return false;
- }
-
- public void testGetProvider() {
- LocationProvider p = mManager.getProvider(TEST_MOCK_PROVIDER_NAME);
- assertNotNull(p);
- assertEquals(TEST_MOCK_PROVIDER_NAME, p.getName());
-
- p = mManager.getProvider(LocationManager.GPS_PROVIDER);
- if (hasGpsFeature()) {
- assertNotNull(p);
- assertEquals(LocationManager.GPS_PROVIDER, p.getName());
- } else {
- assertNull(p);
- }
-
- p = mManager.getProvider(UNKNOWN_PROVIDER_NAME);
- assertNull(p);
-
- try {
- mManager.getProvider(null);
- fail("Should throw IllegalArgumentException when provider is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- public void testGetProvidersWithCriteria() {
- Criteria criteria = new Criteria();
- List<String> providers = mManager.getProviders(criteria, true);
- assertTrue(providers.size() >= 1);
- assertTrue(hasTestProvider(providers));
-
- criteria = new Criteria();
- criteria.setPowerRequirement(Criteria.POWER_HIGH);
- String p = mManager.getBestProvider(criteria, true);
- if (p != null) { // we may not have any enabled providers
- assertTrue(mManager.isProviderEnabled(p));
- }
-
- criteria.setPowerRequirement(Criteria.POWER_MEDIUM);
- p = mManager.getBestProvider(criteria, false);
- assertNotNull(p);
-
- criteria.setPowerRequirement(Criteria.POWER_LOW);
- p = mManager.getBestProvider(criteria, true);
- if (p != null) { // we may not have any enabled providers
- assertTrue(mManager.isProviderEnabled(p));
- }
-
- criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
- p = mManager.getBestProvider(criteria, false);
- assertNotNull(p);
- }
-
- /**
- * Returns true if the {@link LocationManager} reports that the device includes this flavor
- * of location provider.
- */
- private boolean deviceHasProvider(String provider) {
- List<String> providers = mManager.getAllProviders();
- for (String aProvider : providers) {
- if (aProvider.equals(provider)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Ensures the test provider is removed. {@link LocationManager#removeTestProvider(String)}
- * throws an {@link java.lang.IllegalArgumentException} if there is no such test provider,
- * so we have to add it before we clear it.
- */
- private void forceRemoveTestProvider(String provider) {
- addTestProvider(provider);
- mManager.removeTestProvider(provider);
- }
-
- public void testLocationUpdatesWithLocationListener() throws InterruptedException {
- doLocationUpdatesWithLocationListener(TEST_MOCK_PROVIDER_NAME);
-
- try {
- mManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
- (LocationListener) null);
- fail("Should throw IllegalArgumentException if param listener is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.requestLocationUpdates(null, 0, 0, new MockLocationListener());
- fail("Should throw IllegalArgumentException if param provider is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.removeUpdates( (LocationListener) null );
- fail("Should throw IllegalArgumentException if listener is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- /**
- * Helper method to test a location update with given mock location provider
- *
- * @param providerName name of provider to test. Must already exist.
- * @throws InterruptedException
- */
- private void doLocationUpdatesWithLocationListener(final String providerName)
- throws InterruptedException {
- final double latitude1 = 10;
- final double longitude1 = 40;
- final double latitude2 = 35;
- final double longitude2 = 80;
- final MockLocationListener listener = new MockLocationListener();
-
- // update location and notify listener
- new Thread(new Runnable() {
- public void run() {
- Looper.prepare();
- mManager.requestLocationUpdates(providerName, 0, 0, listener);
- listener.setLocationRequested();
- Looper.loop();
- }
- }).start();
- // wait for location requested to be called first, otherwise setLocation can be called
- // before there is a listener attached
- assertTrue(listener.hasCalledLocationRequested(TEST_TIME_OUT));
- updateLocation(providerName, latitude1, longitude1);
- assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
- Location location = listener.getLocation();
- assertEquals(providerName, location.getProvider());
- assertEquals(latitude1, location.getLatitude());
- assertEquals(longitude1, location.getLongitude());
- assertEquals(true, location.isFromMockProvider());
-
- // update location without notifying listener
- listener.reset();
- assertFalse(listener.hasCalledOnLocationChanged(0));
- mManager.removeUpdates(listener);
- updateLocation(providerName, latitude2, longitude2);
- assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
- }
-
- /**
- * Verifies that all real location providers can be replaced by a mock provider.
- * <p/>
- * This feature is quite useful for developer automated testing.
- * This test may fail if another unknown test provider already exists, because there is no
- * known way to determine if a given provider is a test provider.
- * @throws InterruptedException
- */
- public void testReplaceRealProvidersWithMocks() throws InterruptedException {
- for (String providerName : mManager.getAllProviders()) {
- if (!providerName.equals(TEST_MOCK_PROVIDER_NAME) &&
- !providerName.equals(LocationManager.PASSIVE_PROVIDER)) {
- addTestProvider(providerName);
- try {
- // run the update location test logic to ensure location updates can be injected
- doLocationUpdatesWithLocationListener(providerName);
- } finally {
- mManager.removeTestProvider(providerName);
- }
- }
- }
- }
-
- public void testLocationUpdatesWithLocationListenerAndLooper() throws InterruptedException {
- double latitude1 = 60;
- double longitude1 = 20;
- double latitude2 = 40;
- double longitude2 = 30;
- final MockLocationListener listener = new MockLocationListener();
-
- // update location and notify listener
- HandlerThread handlerThread = new HandlerThread("testLocationUpdates");
- handlerThread.start();
- mManager.requestLocationUpdates(TEST_MOCK_PROVIDER_NAME, 0, 0, listener,
- handlerThread.getLooper());
-
- updateLocation(latitude1, longitude1);
- assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
- Location location = listener.getLocation();
- assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider());
- assertEquals(latitude1, location.getLatitude());
- assertEquals(longitude1, location.getLongitude());
- assertEquals(true, location.isFromMockProvider());
-
- // update location without notifying listener
- mManager.removeUpdates(listener);
- listener.reset();
- updateLocation(latitude2, longitude2);
- assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
-
- try {
- mManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
- (LocationListener) null, Looper.myLooper());
- fail("Should throw IllegalArgumentException if param listener is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.requestLocationUpdates(null, 0, 0, listener, Looper.myLooper());
- fail("Should throw IllegalArgumentException if param provider is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.removeUpdates((LocationListener) null );
- fail("Should throw IllegalArgumentException if listener is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- public void testLocationUpdatesWithPendingIntent() throws InterruptedException {
- double latitude1 = 20;
- double longitude1 = 40;
- double latitude2 = 30;
- double longitude2 = 50;
-
- // update location and receive broadcast.
- registerIntentReceiver();
- mManager.requestLocationUpdates(TEST_MOCK_PROVIDER_NAME, 0, 0, mPendingIntent);
- updateLocation(latitude1, longitude1);
- waitForReceiveBroadcast();
-
- assertNotNull(mIntentReceiver.getLastReceivedIntent());
- Location location = mManager.getLastKnownLocation(TEST_MOCK_PROVIDER_NAME);
- assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider());
- assertEquals(latitude1, location.getLatitude());
- assertEquals(longitude1, location.getLongitude());
- assertEquals(true, location.isFromMockProvider());
-
- // update location without receiving broadcast.
- mManager.removeUpdates(mPendingIntent);
- mIntentReceiver.clearReceivedIntents();
- updateLocation(latitude2, longitude2);
- waitForReceiveBroadcast();
- assertNull(mIntentReceiver.getLastReceivedIntent());
-
- try {
- mManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
- (PendingIntent) null);
- fail("Should throw IllegalArgumentException if param intent is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.requestLocationUpdates(null, 0, 0, mPendingIntent);
- fail("Should throw IllegalArgumentException if param provider is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.removeUpdates( (PendingIntent) null );
- fail("Should throw IllegalArgumentException if intent is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- public void testSingleUpdateWithLocationListenerAndLooper() throws InterruptedException {
- double latitude1 = 60;
- double longitude1 = 20;
- double latitude2 = 40;
- double longitude2 = 30;
- double latitude3 = 10;
- double longitude3 = 50;
- final MockLocationListener listener = new MockLocationListener();
-
- // update location and notify listener
- HandlerThread handlerThread = new HandlerThread("testLocationUpdates4");
- handlerThread.start();
- mManager.requestSingleUpdate(TEST_MOCK_PROVIDER_NAME, listener, handlerThread.getLooper());
-
- updateLocation(latitude1, longitude1);
- assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
- Location location = listener.getLocation();
- assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider());
- assertEquals(latitude1, location.getLatitude());
- assertEquals(longitude1, location.getLongitude());
- assertEquals(true, location.isFromMockProvider());
-
- // Any further location change doesn't trigger an update.
- updateLocation(latitude2, longitude2);
- assertEquals(latitude1, location.getLatitude());
- assertEquals(longitude1, location.getLongitude());
-
- // update location without notifying listener
- mManager.removeUpdates(listener);
- listener.reset();
- updateLocation(latitude3, longitude3);
- assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
-
- try {
- mManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, mPendingIntent);
- fail("Should throw IllegalArgumentException if PendingIntent is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, (LocationListener) null,
- Looper.myLooper());
- fail("Should throw IllegalArgumentException if param listener is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.requestSingleUpdate((String) null, listener, Looper.myLooper());
- fail("Should throw IllegalArgumentException if param provider is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.removeUpdates((LocationListener) null );
- fail("Should throw IllegalArgumentException if listener is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- public void testLocationUpdatesWithCriteriaAndPendingIntent() throws InterruptedException {
- double latitude1 = 10;
- double longitude1 = 20;
- double latitude2 = 30;
- double longitude2 = 40;
-
- registerIntentReceiver();
- mockFusedLocation();
-
- // Update location and receive broadcast.
- Criteria criteria = createLocationCriteria();
- mManager.requestLocationUpdates(0, 0 , criteria, mPendingIntent);
- updateFusedLocation(latitude1, longitude1);
- waitForReceiveBroadcast();
-
- assertNotNull(mIntentReceiver.getLastReceivedIntent());
- Location location = (Location) mIntentReceiver.getLastReceivedIntent().getExtras()
- .get(LocationManager.KEY_LOCATION_CHANGED);
- assertEquals(latitude1, location.getLatitude());
- assertEquals(longitude1, location.getLongitude());
- assertTrue(location.hasAccuracy());
- assertEquals(1.0f, location.getAccuracy());
- assertEquals(true, location.isFromMockProvider());
-
- // Update location without receiving broadcast.
- mManager.removeUpdates(mPendingIntent);
- mIntentReceiver.clearReceivedIntents();
- updateFusedLocation(latitude2, longitude2);
- waitForReceiveBroadcast();
- assertNull(mIntentReceiver.getLastReceivedIntent());
-
- // Missing arguments throw exceptions.
- try {
- mManager.requestLocationUpdates(0, 0, criteria, (PendingIntent) null);
- fail("Should throw IllegalArgumentException if param intent is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.requestLocationUpdates(0, 0, null, mPendingIntent);
- fail("Should throw IllegalArgumentException if param criteria is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.removeUpdates( (PendingIntent) null );
- fail("Should throw IllegalArgumentException if param PendingIntent is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- unmockFusedLocation();
- }
-
- public void testSingleUpdateWithCriteriaAndPendingIntent() throws InterruptedException {
- double latitude1 = 10;
- double longitude1 = 20;
- double latitude2 = 30;
- double longitude2 = 40;
- double latitude3 = 50;
- double longitude3 = 60;
-
- registerIntentReceiver();
- mockFusedLocation();
-
- // Update location and receive broadcast.
- Criteria criteria = createLocationCriteria();
- mManager.requestSingleUpdate(criteria, mPendingIntent);
- updateFusedLocation(latitude1, longitude1);
- waitForReceiveBroadcast();
-
- assertNotNull(mIntentReceiver.getLastReceivedIntent());
- Location location = (Location) mIntentReceiver.getLastReceivedIntent().getExtras()
- .get(LocationManager.KEY_LOCATION_CHANGED);
- assertEquals(latitude1, location.getLatitude());
- assertEquals(longitude1, location.getLongitude());
- assertTrue(location.hasAccuracy());
- assertEquals(1.0f, location.getAccuracy());
- assertEquals(true, location.isFromMockProvider());
-
- // Any further location change doesn't trigger an update.
- updateFusedLocation(latitude2, longitude2);
- assertEquals(latitude1, location.getLatitude());
- assertEquals(longitude1, location.getLongitude());
-
- // Update location without receiving broadcast.
- mManager.removeUpdates(mPendingIntent);
- mIntentReceiver.clearReceivedIntents();
- updateFusedLocation(latitude3, longitude3);
- waitForReceiveBroadcast();
- assertNull(mIntentReceiver.getLastReceivedIntent());
-
- // Missing arguments throw exceptions.
- try {
- mManager.requestSingleUpdate(criteria, (PendingIntent) null);
- fail("Should throw IllegalArgumentException if param intent is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.requestSingleUpdate((Criteria) null, mPendingIntent);
- fail("Should throw IllegalArgumentException if param criteria is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.removeUpdates( (PendingIntent) null );
- fail("Should throw IllegalArgumentException if param PendingIntent is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- unmockFusedLocation();
- }
-
- public void testLocationUpdatesWithCriteriaAndLocationListenerAndLooper()
- throws InterruptedException {
- double latitude1 = 40;
- double longitude1 = 10;
- double latitude2 = 20;
- double longitude2 = 30;
- final MockLocationListener listener = new MockLocationListener();
- mockFusedLocation();
-
- // update location and notify listener
- HandlerThread handlerThread = new HandlerThread("testLocationUpdates1");
- handlerThread.start();
- Criteria criteria = createLocationCriteria();
- mManager.requestLocationUpdates(0, 0, criteria, listener, handlerThread.getLooper());
-
- updateFusedLocation(latitude1, longitude1);
- assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
- Location location = listener.getLocation();
- assertEquals(latitude1, location.getLatitude());
- assertEquals(longitude1, location.getLongitude());
- assertTrue(location.hasAccuracy());
- assertEquals(1.0f, location.getAccuracy());
- assertEquals(true, location.isFromMockProvider());
-
- // update location without notifying listener
- mManager.removeUpdates(listener);
- listener.reset();
- updateFusedLocation(latitude2, longitude2);
- assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
-
- // Missing arguments throw exceptions.
- try {
- mManager.requestLocationUpdates(0, 0, criteria, (LocationListener) null,
- Looper.myLooper());
- fail("Should throw IllegalArgumentException if param listener is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.requestLocationUpdates(0, 0, null, listener, Looper.myLooper());
- fail("Should throw IllegalArgumentException if param criteria is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.removeUpdates( (LocationListener) null );
- fail("Should throw IllegalArgumentException if listener is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- unmockFusedLocation();
- }
-
- public void testSingleUpdateWithCriteriaAndLocationListenerAndLooper()
- throws InterruptedException {
- double latitude1 = 40;
- double longitude1 = 10;
- double latitude2 = 20;
- double longitude2 = 30;
- double latitude3 = 60;
- double longitude3 = 50;
- final MockLocationListener listener = new MockLocationListener();
- mockFusedLocation();
-
- // update location and notify listener
- HandlerThread handlerThread = new HandlerThread("testLocationUpdates2");
- handlerThread.start();
- Criteria criteria = createLocationCriteria();
- mManager.requestSingleUpdate(criteria, listener, handlerThread.getLooper());
-
- updateFusedLocation(latitude1, longitude1);
- assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
- Location location = listener.getLocation();
- assertEquals(FUSED_PROVIDER_NAME, location.getProvider());
- assertEquals(latitude1, location.getLatitude());
- assertEquals(longitude1, location.getLongitude());
- assertTrue(location.hasAccuracy());
- assertEquals(1.0f, location.getAccuracy());
- assertEquals(true, location.isFromMockProvider());
-
- // Any further location change doesn't trigger an update.
- updateFusedLocation(latitude2, longitude2);
- assertEquals(latitude1, location.getLatitude());
- assertEquals(longitude1, location.getLongitude());
-
- // update location without notifying listener
- mManager.removeUpdates(listener);
- listener.reset();
- updateFusedLocation(latitude3, longitude3);
- assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
-
- // Missing arguments throw exceptions.
- try {
- mManager.requestLocationUpdates(0, 0, criteria, (LocationListener) null,
- Looper.myLooper());
- fail("Should throw IllegalArgumentException if param listener is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.requestLocationUpdates(0, 0, null, listener, Looper.myLooper());
- fail("Should throw IllegalArgumentException if param criteria is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.removeUpdates( (LocationListener) null );
- fail("Should throw IllegalArgumentException if listener is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- unmockFusedLocation();
- }
-
- public void testSingleUpdateWithPendingIntent() throws InterruptedException {
- double latitude1 = 20;
- double longitude1 = 40;
- double latitude2 = 30;
- double longitude2 = 50;
- double latitude3 = 10;
- double longitude3 = 60;
-
- // update location and receive broadcast.
- registerIntentReceiver();
- mManager.requestLocationUpdates(TEST_MOCK_PROVIDER_NAME, 0, 0, mPendingIntent);
- updateLocation(latitude1, longitude1);
- waitForReceiveBroadcast();
-
- assertNotNull(mIntentReceiver.getLastReceivedIntent());
- Location location = mManager.getLastKnownLocation(TEST_MOCK_PROVIDER_NAME);
- assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider());
- assertEquals(latitude1, location.getLatitude());
- assertEquals(longitude1, location.getLongitude());
- assertEquals(true, location.isFromMockProvider());
-
- // Any further location change doesn't trigger an update.
- updateLocation(latitude2, longitude2);
- assertEquals(latitude1, location.getLatitude());
- assertEquals(longitude1, location.getLongitude());
-
- // update location without receiving broadcast.
- mManager.removeUpdates(mPendingIntent);
- mIntentReceiver.clearReceivedIntents();
- updateLocation(latitude3, longitude3);
- waitForReceiveBroadcast();
- assertEquals(latitude1, location.getLatitude());
- assertEquals(longitude1, location.getLongitude());
-
- try {
- mManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
- (PendingIntent) null);
- fail("Should throw IllegalArgumentException if param intent is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.requestLocationUpdates(null, 0, 0, mPendingIntent);
- fail("Should throw IllegalArgumentException if param provider is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
-
- try {
- mManager.removeUpdates( (PendingIntent) null );
- fail("Should throw IllegalArgumentException if intent is null!");
- } catch (IllegalArgumentException e) {
- // expected
- }
- }
-
- public void testAddProximityAlert() {
- Intent i = new Intent();
- i.setAction("android.location.cts.TEST_GET_GPS_STATUS_ACTION");
- PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, PendingIntent.FLAG_ONE_SHOT);
-
- mManager.addProximityAlert(0, 0, 1.0f, 5000, pi);
- mManager.removeProximityAlert(pi);
- }
-
- @UiThreadTest
- public void testNmeaListener() {
- MockGnssNmeaListener gnssListener = new MockGnssNmeaListener();
- mManager.addNmeaListener(gnssListener);
- mManager.removeNmeaListener(gnssListener);
-
- HandlerThread handlerThread = new HandlerThread("testNmeaListener");
- handlerThread.start();
- mManager.addNmeaListener(gnssListener, new Handler(handlerThread.getLooper()));
- mManager.removeNmeaListener(gnssListener);
-
- mManager.addNmeaListener((OnNmeaMessageListener) null);
- mManager.removeNmeaListener((OnNmeaMessageListener) null);
+ public void testIsLocationEnabled() {
+ assertTrue(mManager.isLocationEnabled());
}
public void testIsProviderEnabled() {
- // this test assumes enabled TEST_MOCK_PROVIDER_NAME was created in setUp.
- assertNotNull(mManager.getProvider(TEST_MOCK_PROVIDER_NAME));
- assertTrue(mManager.isProviderEnabled(TEST_MOCK_PROVIDER_NAME));
+ assertTrue(mManager.isProviderEnabled(TEST_PROVIDER));
- mManager.clearTestProviderEnabled(TEST_MOCK_PROVIDER_NAME);
- assertFalse(mManager.isProviderEnabled(TEST_MOCK_PROVIDER_NAME));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, false);
+ assertFalse(mManager.isProviderEnabled(TEST_PROVIDER));
- mManager.setTestProviderEnabled(TEST_MOCK_PROVIDER_NAME, true);
- assertTrue(mManager.isProviderEnabled(TEST_MOCK_PROVIDER_NAME));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, true);
+ assertTrue(mManager.isProviderEnabled(TEST_PROVIDER));
try {
mManager.isProviderEnabled(null);
@@ -867,43 +170,20 @@
} catch (IllegalArgumentException e) {
// expected
}
-
- try {
- mManager.setTestProviderEnabled(UNKNOWN_PROVIDER_NAME, false);
- fail("Should throw IllegalArgumentException if provider is unknown!");
- } catch (IllegalArgumentException e) {
- // expected
- }
}
- public void testGetLastKnownLocation() throws InterruptedException {
- double latitude1 = 20;
- double longitude1 = 40;
- double latitude2 = 10;
- double longitude2 = 70;
+ public void testGetLastKnownLocation() {
+ Location loc1 = createLocation(TEST_PROVIDER, 6, 5);
+ Location loc2 = createLocation(TEST_PROVIDER, 10, 7);
- registerIntentReceiver();
- mManager.requestLocationUpdates(TEST_MOCK_PROVIDER_NAME, 0, 0, mPendingIntent);
- updateLocation(latitude1, longitude1);
- waitForReceiveBroadcast();
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc1);
+ assertLocationEquals(loc1, mManager.getLastKnownLocation(TEST_PROVIDER));
- assertNotNull(mIntentReceiver.getLastReceivedIntent());
- Location location = mManager.getLastKnownLocation(TEST_MOCK_PROVIDER_NAME);
- assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider());
- assertEquals(latitude1, location.getLatitude());
- assertEquals(longitude1, location.getLongitude());
- assertEquals(true, location.isFromMockProvider());
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc2);
+ assertLocationEquals(loc2, mManager.getLastKnownLocation(TEST_PROVIDER));
- mIntentReceiver.clearReceivedIntents();
- updateLocation(latitude2, longitude2);
- waitForReceiveBroadcast();
-
- assertNotNull(mIntentReceiver.getLastReceivedIntent());
- location = mManager.getLastKnownLocation(TEST_MOCK_PROVIDER_NAME);
- assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider());
- assertEquals(latitude2, location.getLatitude());
- assertEquals(longitude2, location.getLongitude());
- assertEquals(true, location.isFromMockProvider());
+ mManager.setTestProviderEnabled(TEST_PROVIDER, false);
+ assertNull(mManager.getLastKnownLocation(TEST_PROVIDER));
try {
mManager.getLastKnownLocation(null);
@@ -913,462 +193,984 @@
}
}
- /**
- * Test case for bug 33091107, where a malicious app used to be able to fool a real provider
- * into providing a mock location that isn't marked as being mock.
- */
- public void testLocationShouldStillBeMarkedMockWhenProvidersDoNotMatch()
- throws InterruptedException {
- double latitude = 20;
- double longitude = 40;
+ public void testGetCurrentLocation() throws Exception {
+ Location loc = createLocation(TEST_PROVIDER, 5, 6);
- List<String> providers = mManager.getAllProviders();
- if (providers.isEmpty()) {
- // Device doesn't have any providers. Can't perform this test, and no need to do so:
- // no providers that malicious app could fool
- return;
+ try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) {
+ mManager.getCurrentLocation(TEST_PROVIDER, capture.getCancellationSignal(),
+ Executors.newSingleThreadExecutor(), capture);
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc);
+ assertLocationEquals(loc, capture.getNextLocation(TIMEOUT_MS));
}
- String realProviderToFool = providers.get(0);
- // Register for location updates, then set a mock location and ensure it is marked "mock"
- updateLocationAndWait(TEST_MOCK_PROVIDER_NAME, realProviderToFool, latitude, longitude);
- }
+ // TODO: test timeout case
- @UiThreadTest
- public void testGnssStatusListener() {
- MockGnssStatusCallback callback = new MockGnssStatusCallback();
- mManager.registerGnssStatusCallback(callback);
- mManager.unregisterGnssStatusCallback(callback);
-
- mManager.registerGnssStatusCallback(null);
- mManager.unregisterGnssStatusCallback(null);
-
- HandlerThread handlerThread = new HandlerThread("testStatusUpdates");
- handlerThread.start();
-
- mManager.registerGnssStatusCallback(callback, new Handler(handlerThread.getLooper()));
- mManager.unregisterGnssStatusCallback(callback);
- }
-
- /**
- * Tests basic proximity alert when entering proximity
- */
- public void testEnterProximity() throws Exception {
- if (!isSystemUser()) {
- Log.i(TAG, "Skipping test on secondary user");
- return;
- }
- // need to mock the fused location provider for proximity tests
- mockFusedLocation();
-
- doTestEnterProximity(10000);
-
- unmockFusedLocation();
- }
-
- /**
- * Tests proximity alert when entering proximity, with no expiration
- */
- public void testEnterProximity_noexpire() throws Exception {
- if (!isSystemUser()) {
- Log.i(TAG, "Skipping test on secondary user");
- return;
- }
- // need to mock the fused location provider for proximity tests
- mockFusedLocation();
-
- doTestEnterProximity(-1);
-
- unmockFusedLocation();
- }
-
- /**
- * Tests basic proximity alert when exiting proximity
- */
- public void testExitProximity() throws Exception {
- if (!isSystemUser()) {
- Log.i(TAG, "Skipping test on secondary user");
- return;
- }
- // need to mock the fused location provider for proximity tests
- mockFusedLocation();
-
- // first do enter proximity scenario
- doTestEnterProximity(-1);
-
- // now update to trigger exit proximity proximity
- mIntentReceiver.clearReceivedIntents();
- updateLocationAndWait(FUSED_PROVIDER_NAME, 20, 20);
- waitForReceiveBroadcast();
- assertProximityType(false);
-
- unmockFusedLocation();
- }
-
- /**
- * Tests basic proximity alert when initially within proximity
- */
- public void testInitiallyWithinProximity() throws Exception {
- if (!isSystemUser()) {
- Log.i(TAG, "Skipping test on secondary user");
- return;
- }
- // need to mock the fused location provider for proximity tests
- mockFusedLocation();
-
- updateLocationAndWait(FUSED_PROVIDER_NAME, 0, 0);
- registerProximityListener(0, 0, 1000, 10000);
- waitForReceiveBroadcast();
- assertProximityType(true);
-
- unmockFusedLocation();
- }
-
- /**
- * Helper variant for testing enter proximity scenario
- * TODO: add additional parameters as more scenarios are added
- *
- * @param expiration - expiration of proximity alert
- */
- private void doTestEnterProximity(long expiration) throws Exception {
- // update location to outside proximity range
- updateLocationAndWait(FUSED_PROVIDER_NAME, 30, 30);
- registerProximityListener(0, 0, 1000, expiration);
-
- // Adding geofences is asynchronous, the return of LocationManager.addProximityAlert
- // doesn't mean that geofences are already being monitored. Wait for a few milliseconds
- // so that GeofenceManager is actively monitoring locations before we send the mock
- // location to avoid flaky tests.
- Thread.sleep(500);
-
- updateLocationAndWait(FUSED_PROVIDER_NAME, 0, 0);
- waitForReceiveBroadcast();
- assertProximityType(true);
- }
-
-
- private void updateLocationAndWait(String providerName, double latitude, double longitude)
- throws InterruptedException {
- updateLocationAndWait(providerName, providerName, latitude, longitude);
- }
-
- /**
- * Like {@link #updateLocationAndWait(String, double, double)}, but allows inconsistent providers
- * to be used in the calls to {@link Location#Location(String)} and {@link
- * LocationManager#setTestProviderLocation(String, Location)}
- *
- * @param testProviderName used in {@link LocationManager#setTestProviderLocation(String,
- * Location)}
- * @param locationProviderName used in {@link Location#Location(String)}
- */
- private void updateLocationAndWait(String testProviderName, String locationProviderName,
- double latitude, double longitude) throws InterruptedException {
-
- // Register a listener for the location we are about to set.
- MockLocationListener listener = new MockLocationListener();
- HandlerThread handlerThread = new HandlerThread("updateLocationAndWait");
- handlerThread.start();
- mManager.requestLocationUpdates(locationProviderName, 0, 0, listener,
- handlerThread.getLooper());
-
- // Set the location.
- updateLocation(testProviderName, locationProviderName, latitude, longitude);
-
- // Make sure we received the location, and it is the right one.
- assertTrue("Listener not called", listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
- Location location = listener.getLocation();
- assertEquals("Bad provider name", locationProviderName, location.getProvider());
- assertEquals("Bad latitude", latitude, location.getLatitude());
- assertEquals("Bad longitude", longitude, location.getLongitude());
- assertTrue("Bad isMock", location.isFromMockProvider());
-
- // Remove the listener.
- mManager.removeUpdates(listener);
- }
-
- private void registerIntentReceiver() {
- String intentKey = "LocationManagerTest";
- Intent proximityIntent = new Intent(intentKey);
- mPendingIntent = PendingIntent.getBroadcast(mContext, 0, proximityIntent,
- PendingIntent.FLAG_CANCEL_CURRENT);
- mIntentReceiver = new TestIntentReceiver(intentKey);
- mContext.registerReceiver(mIntentReceiver, mIntentReceiver.getFilter());
- }
-
- /**
- * Registers the proximity intent receiver
- */
- private void registerProximityListener(double latitude, double longitude, float radius,
- long expiration) {
- registerIntentReceiver();
- mManager.addProximityAlert(latitude, longitude, radius, expiration, mPendingIntent);
- }
-
- /**
- * Blocks until receive intent notification or time out.
- *
- * @throws InterruptedException
- */
- private void waitForReceiveBroadcast() throws InterruptedException {
- synchronized (mIntentReceiver) {
- mIntentReceiver.wait(TEST_TIME_OUT);
+ try {
+ mManager.getCurrentLocation((String) null, null, Executors.newSingleThreadExecutor(),
+ (location) -> {
+ });
+ fail("Should throw IllegalArgumentException if provider is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
}
}
- /**
- * Asserts that the received intent had the enter proximity property set as
- * expected
- *
- * @param expectedEnterProximity - true if enter proximity expected, false
- * if exit expected
- */
- private void assertProximityType(boolean expectedEnterProximity) throws Exception {
- Intent intent = mIntentReceiver.getLastReceivedIntent();
- assertNotNull("Did not receive any intent", intent);
- boolean proximityTest = intent.getBooleanExtra(
- LocationManager.KEY_PROXIMITY_ENTERING, !expectedEnterProximity);
- assertEquals("proximity alert not set to expected enter proximity value",
- expectedEnterProximity, proximityTest);
+ public void testGetCurrentLocation_DirectExecutor() throws Exception {
+ Location loc = createLocation(TEST_PROVIDER, 2, 1);
+
+ try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) {
+ mManager.getCurrentLocation(TEST_PROVIDER, capture.getCancellationSignal(),
+ directExecutor(), capture);
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc);
+ assertLocationEquals(loc, capture.getNextLocation(TIMEOUT_MS));
+ }
}
- private void updateLocation(final String providerName, final double latitude,
- final double longitude) {
- updateLocation(providerName, providerName, latitude, longitude);
+ public void testGetCurrentLocation_Cancellation() throws Exception {
+ Location loc = createLocation(TEST_PROVIDER, 1, 2);
+
+ try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) {
+ mManager.getCurrentLocation(TEST_PROVIDER, capture.getCancellationSignal(),
+ directExecutor(),
+ capture);
+ capture.getCancellationSignal().cancel();
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc);
+ assertNull(capture.getNextLocation(FAILURE_TIMEOUT_MS));
+ }
}
- /**
- * Like {@link #updateLocation(String, double, double)}, but allows inconsistent providers to be
- * used in the calls to {@link Location#Location(String)} and
- * {@link LocationManager#setTestProviderLocation(String, Location)}.
- */
- private void updateLocation(String testProviderName, String locationProviderName,
- double latitude, double longitude) {
- Location location = new Location(locationProviderName);
- location.setLatitude(latitude);
- location.setLongitude(longitude);
- location.setAccuracy(1.0f);
- location.setTime(System.currentTimeMillis());
- location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
- mManager.setTestProviderLocation(testProviderName, location);
+ public void testGetCurrentLocation_ProviderDisabled() throws Exception {
+ try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) {
+ mManager.setTestProviderEnabled(TEST_PROVIDER, false);
+ mManager.getCurrentLocation(TEST_PROVIDER, capture.getCancellationSignal(),
+ directExecutor(),
+ capture);
+ assertNull(capture.getNextLocation(FAILURE_TIMEOUT_MS));
+ }
+
+ try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) {
+ mManager.getCurrentLocation(TEST_PROVIDER, capture.getCancellationSignal(),
+ directExecutor(),
+ capture);
+ mManager.setTestProviderEnabled(TEST_PROVIDER, false);
+ assertNull(capture.getNextLocation(FAILURE_TIMEOUT_MS));
+ }
}
- private void updateLocation(final double latitude, final double longitude) {
- updateLocation(TEST_MOCK_PROVIDER_NAME, latitude, longitude);
+ public void testRequestLocationUpdates() throws Exception {
+ Location loc1 = createLocation(TEST_PROVIDER, 1, 4);
+ Location loc2 = createLocation(TEST_PROVIDER, 2, 5);
+
+ try (LocationListenerCapture capture = new LocationListenerCapture(mManager)) {
+ mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0,
+ Executors.newSingleThreadExecutor(), capture);
+
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc1);
+ assertLocationEquals(loc1, capture.getNextLocation(TIMEOUT_MS));
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc2);
+ assertLocationEquals(loc2, capture.getNextLocation(TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, false);
+ assertEquals(Boolean.FALSE, capture.getNextProviderChange(TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, true);
+ assertEquals(Boolean.TRUE, capture.getNextProviderChange(TIMEOUT_MS));
+
+ mManager.removeUpdates(capture);
+
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc1);
+ assertNull(capture.getNextLocation(FAILURE_TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, false);
+ assertNull(capture.getNextProviderChange(FAILURE_TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, true);
+ assertNull(capture.getNextProviderChange(FAILURE_TIMEOUT_MS));
+ }
+
+ try {
+ mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, (LocationListener) null);
+ fail("Should throw IllegalArgumentException if listener is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try (LocationListenerCapture capture = new LocationListenerCapture(mManager)) {
+ mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, null, capture);
+ fail("Should throw IllegalArgumentException if executor is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try (LocationListenerCapture capture = new LocationListenerCapture(mManager)) {
+ mManager.requestLocationUpdates(null, 0, 0, capture);
+ fail("Should throw IllegalArgumentException if provider is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ mManager.removeUpdates((LocationListener) null);
+ fail("Should throw IllegalArgumentException if listener is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
}
- private void updateFusedLocation(final double latitude, final double longitude) {
- updateLocation(FUSED_PROVIDER_NAME, latitude, longitude);
- }
+ public void testRequestLocationUpdates_PendingIntent() throws Exception {
+ Location loc1 = createLocation(TEST_PROVIDER, 1, 4);
+ Location loc2 = createLocation(TEST_PROVIDER, 2, 5);
- private Criteria createLocationCriteria() {
+ try (LocationPendingIntentCapture capture = new LocationPendingIntentCapture(mContext)) {
+ mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, capture.getPendingIntent());
+
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc1);
+ assertLocationEquals(loc1, capture.getNextLocation(TIMEOUT_MS));
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc2);
+ assertLocationEquals(loc2, capture.getNextLocation(TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, false);
+ assertEquals(Boolean.FALSE, capture.getNextProviderChange(TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, true);
+ assertEquals(Boolean.TRUE, capture.getNextProviderChange(TIMEOUT_MS));
+
+ mManager.removeUpdates(capture.getPendingIntent());
+
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc1);
+ assertNull(capture.getNextLocation(FAILURE_TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, false);
+ assertNull(capture.getNextProviderChange(FAILURE_TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, true);
+ assertNull(capture.getNextProviderChange(FAILURE_TIMEOUT_MS));
+ }
+
+ try {
+ mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, (PendingIntent) null);
+ fail("Should throw IllegalArgumentException if pending intent is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try (LocationPendingIntentCapture capture = new LocationPendingIntentCapture(mContext)) {
+ mManager.requestLocationUpdates(null, 0, 0, capture.getPendingIntent());
+ fail("Should throw IllegalArgumentException if provider is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ mManager.removeUpdates((PendingIntent) null);
+ fail("Should throw IllegalArgumentException if pending intent is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testRequestLocationUpdates_DirectExecutor() throws Exception {
+ Location loc1 = createLocation(TEST_PROVIDER, 1, 4);
+ Location loc2 = createLocation(TEST_PROVIDER, 2, 5);
+
+ try (LocationListenerCapture capture = new LocationListenerCapture(mManager)) {
+ mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, directExecutor(), capture);
+
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc1);
+ assertLocationEquals(loc1, capture.getNextLocation(TIMEOUT_MS));
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc2);
+ assertLocationEquals(loc2, capture.getNextLocation(TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, false);
+ assertEquals(Boolean.FALSE, capture.getNextProviderChange(TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, true);
+ assertEquals(Boolean.TRUE, capture.getNextProviderChange(TIMEOUT_MS));
+ }
+ }
+
+ public void testRequestLocationUpdates_Looper() throws Exception {
+ HandlerThread thread = new HandlerThread("locationTestThread");
+ thread.start();
+ Looper looper = thread.getLooper();
+ try {
+
+ Location loc1 = createLocation(TEST_PROVIDER, 1, 4);
+ Location loc2 = createLocation(TEST_PROVIDER, 2, 5);
+
+ try (LocationListenerCapture capture = new LocationListenerCapture(mManager)) {
+ mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, capture, looper);
+
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc1);
+ assertLocationEquals(loc1, capture.getNextLocation(TIMEOUT_MS));
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc2);
+ assertLocationEquals(loc2, capture.getNextLocation(TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, false);
+ assertEquals(Boolean.FALSE, capture.getNextProviderChange(TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, true);
+ assertEquals(Boolean.TRUE, capture.getNextProviderChange(TIMEOUT_MS));
+ }
+
+ } finally {
+ looper.quit();
+ }
+ }
+
+ public void testRequestLocationUpdates_Criteria() throws Exception {
+ // make the test provider the "perfect" provider
+ mManager.addTestProvider(TEST_PROVIDER,
+ false,
+ false,
+ false,
+ false,
+ true,
+ true,
+ true,
+ Criteria.POWER_LOW,
+ Criteria.ACCURACY_FINE);
+
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
- criteria.setPowerRequirement(Criteria.POWER_MEDIUM);
- criteria.setAltitudeRequired(false);
- criteria.setBearingRequired(false);
- criteria.setCostAllowed(false);
- criteria.setSpeedRequired(false);
- return criteria;
- }
+ criteria.setPowerRequirement(Criteria.POWER_LOW);
- private void mockFusedLocation() {
- addTestProvider(FUSED_PROVIDER_NAME);
- }
+ Location loc1 = createLocation(TEST_PROVIDER, 1, 4);
+ Location loc2 = createLocation(TEST_PROVIDER, 2, 5);
- private void unmockFusedLocation() {
- mManager.removeTestProvider(FUSED_PROVIDER_NAME);
- }
+ try (LocationListenerCapture capture = new LocationListenerCapture(mManager)) {
+ mManager.requestLocationUpdates(0, 0, criteria, directExecutor(), capture);
- /**
- * Helper class that receives a proximity intent and notifies the main class
- * when received
- */
- private static class TestIntentReceiver extends BroadcastReceiver {
- private String mExpectedAction;
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc1);
+ assertLocationEquals(loc1, capture.getNextLocation(TIMEOUT_MS));
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc2);
+ assertLocationEquals(loc2, capture.getNextLocation(TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, false);
+ assertEquals(Boolean.FALSE, capture.getNextProviderChange(TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, true);
+ assertEquals(Boolean.TRUE, capture.getNextProviderChange(TIMEOUT_MS));
- private Intent mLastReceivedIntent;
+ mManager.removeUpdates(capture);
- public TestIntentReceiver(String expectedAction) {
- mExpectedAction = expectedAction;
- mLastReceivedIntent = null;
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc1);
+ assertNull(capture.getNextLocation(FAILURE_TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, false);
+ assertNull(capture.getNextProviderChange(FAILURE_TIMEOUT_MS));
+ mManager.setTestProviderEnabled(TEST_PROVIDER, true);
+ assertNull(capture.getNextProviderChange(FAILURE_TIMEOUT_MS));
}
- public IntentFilter getFilter() {
- IntentFilter filter = new IntentFilter(mExpectedAction);
- return filter;
+
+ try {
+ mManager.requestLocationUpdates(0, 0, criteria, null, Looper.getMainLooper());
+ fail("Should throw IllegalArgumentException if listener is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try (LocationListenerCapture capture = new LocationListenerCapture(mManager)) {
+ mManager.requestLocationUpdates(0, 0, criteria, null, capture);
+ fail("Should throw IllegalArgumentException if executor is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try (LocationListenerCapture capture = new LocationListenerCapture(mManager)) {
+ mManager.requestLocationUpdates(0, 0, null, directExecutor(), capture);
+ fail("Should throw IllegalArgumentException if criteria is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testRequestLocationUpdates_ReplaceRequest() throws Exception {
+ Location loc1 = createLocation(TEST_PROVIDER, 1, 4);
+ Location loc2 = createLocation(TEST_PROVIDER, 2, 5);
+
+ try (LocationListenerCapture capture = new LocationListenerCapture(mManager)) {
+ mManager.requestLocationUpdates(TEST_PROVIDER, 1000, 1000, directExecutor(), capture);
+ mManager.requestLocationUpdates(TEST_PROVIDER, 0, 0, directExecutor(), capture);
+
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc1);
+ assertLocationEquals(loc1, capture.getNextLocation(TIMEOUT_MS));
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc2);
+ assertLocationEquals(loc2, capture.getNextLocation(TIMEOUT_MS));
+ }
+ }
+
+ public void testRequestLocationUpdates_NumUpdates() throws Exception {
+ Location loc1 = createLocation(TEST_PROVIDER, 10, 3);
+ Location loc2 = createLocation(TEST_PROVIDER, 2, 8);
+
+ LocationRequest request = LocationRequest.createFromDeprecatedProvider(TEST_PROVIDER, 0, 0,
+ false);
+ request.setNumUpdates(1);
+
+ try (LocationListenerCapture capture = new LocationListenerCapture(mManager)) {
+ mManager.requestLocationUpdates(request, directExecutor(), capture);
+
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc1);
+ assertLocationEquals(loc1, capture.getNextLocation(TIMEOUT_MS));
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc2);
+ assertNull(capture.getNextLocation(FAILURE_TIMEOUT_MS));
+ }
+ }
+
+ public void testRequestLocationUpdates_MinTime() throws Exception {
+ Location loc1 = createLocation(TEST_PROVIDER, 0, 0);
+ Location loc2 = createLocation(TEST_PROVIDER, 1, 1);
+
+ LocationRequest request = LocationRequest.createFromDeprecatedProvider(TEST_PROVIDER, 5000,
+ 0, false);
+
+ try (LocationListenerCapture capture = new LocationListenerCapture(mManager)) {
+ mManager.requestLocationUpdates(request, directExecutor(), capture);
+
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc1);
+ assertLocationEquals(loc1, capture.getNextLocation(TIMEOUT_MS));
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc2);
+ assertNull(capture.getNextLocation(FAILURE_TIMEOUT_MS));
+ }
+ }
+
+ public void testRequestLocationUpdates_MinDistance() throws Exception {
+ Location loc1 = createLocation(TEST_PROVIDER, 0, 0);
+ Location loc2 = createLocation(TEST_PROVIDER, 0, 1);
+
+ LocationRequest request = LocationRequest.createFromDeprecatedProvider(TEST_PROVIDER, 0,
+ 10000, false);
+
+ try (LocationListenerCapture capture = new LocationListenerCapture(mManager)) {
+ mManager.requestLocationUpdates(request, directExecutor(), capture);
+
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc1);
+ assertLocationEquals(loc1, capture.getNextLocation(TIMEOUT_MS));
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc2);
+ assertNull(capture.getNextLocation(FAILURE_TIMEOUT_MS));
+ }
+ }
+
+ public void testGetAllProviders() {
+ List<String> providers = mManager.getAllProviders();
+ if (hasGpsFeature()) {
+ assertTrue(providers.contains(LocationManager.GPS_PROVIDER));
+ }
+ assertTrue(providers.contains(PASSIVE_PROVIDER));
+ assertTrue(providers.contains(TEST_PROVIDER));
+
+ mManager.removeTestProvider(TEST_PROVIDER);
+
+ providers = mManager.getAllProviders();
+ assertTrue(providers.contains(PASSIVE_PROVIDER));
+ assertFalse(providers.contains(TEST_PROVIDER));
+ }
+
+ public void testGetProviders() {
+ List<String> providers = mManager.getProviders(false);
+ assertTrue(providers.contains(TEST_PROVIDER));
+
+ providers = mManager.getProviders(true);
+ assertTrue(providers.contains(TEST_PROVIDER));
+
+ mManager.setTestProviderEnabled(TEST_PROVIDER, false);
+
+ providers = mManager.getProviders(false);
+ assertTrue(providers.contains(TEST_PROVIDER));
+
+ providers = mManager.getProviders(true);
+ assertFalse(providers.contains(TEST_PROVIDER));
+ }
+
+ public void testGetProviders_Criteria() {
+ Criteria criteria = new Criteria();
+
+ List<String> providers = mManager.getProviders(criteria, false);
+ assertTrue(providers.contains(TEST_PROVIDER));
+
+ providers = mManager.getProviders(criteria, true);
+ assertTrue(providers.contains(TEST_PROVIDER));
+
+ criteria.setPowerRequirement(Criteria.POWER_LOW);
+
+ providers = mManager.getProviders(criteria, false);
+ assertFalse(providers.contains(TEST_PROVIDER));
+
+ providers = mManager.getProviders(criteria, true);
+ assertFalse(providers.contains(TEST_PROVIDER));
+ }
+
+ public void testGetBestProvider() {
+ List<String> allProviders = mManager.getAllProviders();
+ Criteria criteria = new Criteria();
+
+ String bestProvider = mManager.getBestProvider(criteria, false);
+ if (allProviders.contains(GPS_PROVIDER)) {
+ assertEquals(GPS_PROVIDER, bestProvider);
+ } else if (allProviders.contains(NETWORK_PROVIDER)) {
+ assertEquals(NETWORK_PROVIDER, bestProvider);
+ } else {
+ assertEquals(TEST_PROVIDER, bestProvider);
+ }
+
+ // the "perfect" provider - this test case only works if there is no real provider on the
+ // device with the same "perfect" properties
+ mManager.addTestProvider(TEST_PROVIDER,
+ false,
+ false,
+ false,
+ false,
+ true,
+ true,
+ true,
+ Criteria.POWER_LOW,
+ Criteria.ACCURACY_FINE);
+
+ criteria.setAccuracy(Criteria.ACCURACY_FINE);
+ criteria.setPowerRequirement(Criteria.POWER_LOW);
+ assertEquals(TEST_PROVIDER, mManager.getBestProvider(criteria, false));
+
+ mManager.setTestProviderEnabled(TEST_PROVIDER, false);
+ assertNotEquals(TEST_PROVIDER, mManager.getBestProvider(criteria, true));
+ }
+
+ public void testGetProvider() {
+ LocationProvider provider = mManager.getProvider(TEST_PROVIDER);
+ assertNotNull(provider);
+ assertEquals(TEST_PROVIDER, provider.getName());
+
+ provider = mManager.getProvider(LocationManager.GPS_PROVIDER);
+ if (hasGpsFeature()) {
+ assertNotNull(provider);
+ assertEquals(LocationManager.GPS_PROVIDER, provider.getName());
+ } else {
+ assertNull(provider);
+ }
+
+ try {
+ mManager.getProvider(null);
+ fail("Should throw IllegalArgumentException when provider is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testSendExtraCommand() {
+ for (String provider : mManager.getAllProviders()) {
+ boolean res = mManager.sendExtraCommand(provider, "dontCrash", null);
+ assertTrue(res);
+
+ try {
+ mManager.sendExtraCommand(provider, null, null);
+ fail("Should throw IllegalArgumentException if command is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ try {
+ mManager.sendExtraCommand(null, "crash", null);
+ fail("Should throw IllegalArgumentException if provider is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testAddTestProvider() {
+ // overwriting providers should not crash
+ for (String provider : mManager.getAllProviders()) {
+ if (PASSIVE_PROVIDER.equals(provider)) {
+ continue;
+ }
+
+ mManager.addTestProvider(provider, true,
+ false,
+ true,
+ false,
+ false,
+ false,
+ false,
+ Criteria.POWER_MEDIUM,
+ Criteria.ACCURACY_FINE);
+ mManager.setTestProviderLocation(provider, createLocation(provider, 0, 0));
+ }
+
+ try {
+ mManager.addTestProvider("passive",
+ true,
+ false,
+ true,
+ false,
+ false,
+ false,
+ false,
+ Criteria.POWER_MEDIUM,
+ Criteria.ACCURACY_FINE);
+ fail("Should throw IllegalArgumentException if provider is passive!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ mManager.addTestProvider(null,
+ true,
+ false,
+ true,
+ false,
+ false,
+ false,
+ false,
+ Criteria.POWER_MEDIUM,
+ Criteria.ACCURACY_FINE);
+ fail("Should throw IllegalArgumentException if provider is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testSetTestProviderLocation() throws Exception {
+ Location loc1 = createLocation(TEST_PROVIDER, 1, 2);
+ Location loc2 = createLocation(TEST_PROVIDER, 2, 1);
+
+ for (String provider : mManager.getAllProviders()) {
+ if (TEST_PROVIDER.equals(provider)) {
+ try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) {
+ mManager.getCurrentLocation(provider, capture.getCancellationSignal(),
+ directExecutor(), capture);
+ mManager.setTestProviderLocation(provider, loc1);
+
+ Location received = capture.getNextLocation(TIMEOUT_MS);
+ assertLocationEquals(loc1, received);
+ assertTrue(received.isFromMockProvider());
+ assertLocationEquals(loc1, mManager.getLastKnownLocation(provider));
+
+ mManager.setTestProviderEnabled(provider, false);
+ mManager.setTestProviderLocation(provider, loc2);
+ assertNull(mManager.getLastKnownLocation(provider));
+ }
+ } else {
+ try {
+ mManager.setTestProviderLocation(provider, loc1);
+ fail("Should throw IllegalArgumentException since " + provider
+ + " is not a test provider!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+ }
+
+ try {
+ mManager.setTestProviderLocation(TEST_PROVIDER, null);
+ fail("Should throw IllegalArgumentException since location is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ mManager.removeTestProvider(TEST_PROVIDER);
+ try {
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc1);
+ fail("Should throw IllegalArgumentException since " + TEST_PROVIDER
+ + " is not a test provider!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ mManager.setTestProviderLocation(null, loc1);
+ fail("Should throw IllegalArgumentException since provider is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+
+ public void testSetTestProviderLocation_B33091107() throws Exception {
+ // test for b/33091107, where a malicious app could fool a real provider into providing a
+ // mock location that isn't marked as being mock
+
+ List<String> providers = mManager.getAllProviders();
+ if (providers.size() <= 2) {
+ // can't perform the test without any real providers, and no need to do so since there
+ // are no providers a malicious app could fool
+ assertTrue(providers.contains(TEST_PROVIDER));
+ assertTrue(providers.contains(PASSIVE_PROVIDER));
+ return;
+ }
+
+ providers.remove(TEST_PROVIDER);
+ providers.remove(PASSIVE_PROVIDER);
+
+ String realProvider = providers.get(0);
+ Location loc = createLocation(realProvider, 2, 2);
+
+ try (GetCurrentLocationCapture capture = new GetCurrentLocationCapture()) {
+ mManager.getCurrentLocation(TEST_PROVIDER, capture.getCancellationSignal(),
+ directExecutor(), capture);
+ mManager.setTestProviderLocation(TEST_PROVIDER, loc);
+
+ Location received = capture.getNextLocation(TIMEOUT_MS);
+ assertLocationEquals(loc, received);
+ assertTrue(received.isFromMockProvider());
+
+ Location realProvideLocation = mManager.getLastKnownLocation(realProvider);
+ if (realProvideLocation != null) {
+ try {
+ assertLocationEquals(loc, realProvideLocation);
+ fail("real provider saw " + TEST_PROVIDER + " location!");
+ } catch (AssertionError e) {
+ // pass
+ }
+ }
+ }
+ }
+
+ public void testRemoveTestProvider() {
+ // removing providers should not crash
+ for (String provider : mManager.getAllProviders()) {
+ mManager.removeTestProvider(provider);
+ }
+ }
+
+ public void testAddProximityAlert() throws Exception {
+ if (isNotSystemUser()) {
+ Log.i(TAG, "Skipping test on secondary user");
+ return;
+ }
+
+ mManager.addTestProvider(FUSED_PROVIDER,
+ true,
+ false,
+ true,
+ false,
+ false,
+ false,
+ false,
+ Criteria.POWER_MEDIUM,
+ Criteria.ACCURACY_FINE);
+ mManager.setTestProviderEnabled(FUSED_PROVIDER, true);
+ mManager.setTestProviderLocation(FUSED_PROVIDER, createLocation(FUSED_PROVIDER, 30, 30));
+
+ try (ProximityPendingIntentCapture capture = new ProximityPendingIntentCapture(mContext)) {
+ mManager.addProximityAlert(0, 0, 1000, -1, capture.getPendingIntent());
+
+ // adding a proximity alert is asynchronous for no good reason, so we have to wait and
+ // hope the alert is added in the mean time.
+ Thread.sleep(500);
+
+ mManager.setTestProviderLocation(FUSED_PROVIDER, createLocation(FUSED_PROVIDER, 0, 0));
+ assertEquals(Boolean.TRUE, capture.getNextProximityChange(TIMEOUT_MS));
+
+ mManager.setTestProviderLocation(FUSED_PROVIDER,
+ createLocation(FUSED_PROVIDER, 30, 30));
+ assertEquals(Boolean.FALSE, capture.getNextProximityChange(TIMEOUT_MS));
+ }
+
+ try {
+ mManager.addProximityAlert(0, 0, 1000, -1, null);
+ fail("Should throw IllegalArgumentException if pending intent is null!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try (ProximityPendingIntentCapture capture = new ProximityPendingIntentCapture(mContext)) {
+ try {
+ mManager.addProximityAlert(0, 0, 0, -1, capture.getPendingIntent());
+ fail("Should throw IllegalArgumentException if radius == 0!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ mManager.addProximityAlert(0, 0, -1, -1, capture.getPendingIntent());
+ fail("Should throw IllegalArgumentException if radius < 0!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+
+ try {
+ mManager.addProximityAlert(1000, 1000, 1000, -1, capture.getPendingIntent());
+ fail("Should throw IllegalArgumentException if lat/lon are illegal!");
+ } catch (IllegalArgumentException e) {
+ // expected
+ }
+ }
+ }
+
+ public void testAddProximityAlert_StartProximate() throws Exception {
+ if (isNotSystemUser()) {
+ Log.i(TAG, "Skipping test on secondary user");
+ return;
+ }
+
+ mManager.addTestProvider(FUSED_PROVIDER,
+ true,
+ false,
+ true,
+ false,
+ false,
+ false,
+ false,
+ Criteria.POWER_MEDIUM,
+ Criteria.ACCURACY_FINE);
+ mManager.setTestProviderEnabled(FUSED_PROVIDER, true);
+ mManager.setTestProviderLocation(FUSED_PROVIDER, createLocation(FUSED_PROVIDER, 0, 0));
+
+ try (ProximityPendingIntentCapture capture = new ProximityPendingIntentCapture(mContext)) {
+ mManager.addProximityAlert(0, 0, 1000, -1, capture.getPendingIntent());
+ assertEquals(Boolean.TRUE, capture.getNextProximityChange(TIMEOUT_MS));
+ }
+ }
+
+ public void testAddProximityAlert_Expires() throws Exception {
+ if (isNotSystemUser()) {
+ Log.i(TAG, "Skipping test on secondary user");
+ return;
+ }
+
+ mManager.addTestProvider(FUSED_PROVIDER,
+ true,
+ false,
+ true,
+ false,
+ false,
+ false,
+ false,
+ Criteria.POWER_MEDIUM,
+ Criteria.ACCURACY_FINE);
+ mManager.setTestProviderEnabled(FUSED_PROVIDER, true);
+ mManager.setTestProviderLocation(FUSED_PROVIDER, createLocation(FUSED_PROVIDER, 30, 30));
+
+ try (ProximityPendingIntentCapture capture = new ProximityPendingIntentCapture(mContext)) {
+ mManager.addProximityAlert(0, 0, 1000, 1, capture.getPendingIntent());
+
+ // adding a proximity alert is asynchronous for no good reason, so we have to wait and
+ // hope the alert is added in the mean time.
+ Thread.sleep(500);
+
+ mManager.setTestProviderLocation(FUSED_PROVIDER, createLocation(FUSED_PROVIDER, 0, 0));
+ assertNull(capture.getNextProximityChange(FAILURE_TIMEOUT_MS));
+ }
+ }
+
+ public void testGetGnssYearOfHardware() {
+ mManager.getGnssYearOfHardware();
+ }
+
+ public void testGetGnssHardwareModelName() {
+ mManager.getGnssHardwareModelName();
+ }
+
+ public void testRegisterGnssStatusCallback() {
+ GnssStatus.Callback callback = new GnssStatus.Callback() {
+ };
+
+ mManager.registerGnssStatusCallback(directExecutor(), callback);
+ mManager.unregisterGnssStatusCallback(callback);
+ }
+
+ public void testAddNmeaListener() {
+ OnNmeaMessageListener listener = (message, timestamp) -> {
+ };
+
+ mManager.addNmeaListener(directExecutor(), listener);
+ mManager.removeNmeaListener(listener);
+ }
+
+ public void testRegisterGnssMeasurementsCallback() {
+ GnssMeasurementsEvent.Callback callback = new GnssMeasurementsEvent.Callback() {
+ };
+
+ mManager.registerGnssMeasurementsCallback(directExecutor(), callback);
+ mManager.unregisterGnssMeasurementsCallback(callback);
+ }
+
+ public void testRegisterGnssNavigationMessageCallback() {
+ GnssNavigationMessage.Callback callback = new GnssNavigationMessage.Callback() {
+ };
+
+ mManager.registerGnssNavigationMessageCallback(directExecutor(), callback);
+ mManager.unregisterGnssNavigationMessageCallback(callback);
+ }
+
+ private boolean hasGpsFeature() {
+ return mContext.getPackageManager().hasSystemFeature(
+ PackageManager.FEATURE_LOCATION_GPS);
+ }
+
+ private boolean isNotSystemUser() {
+ return !mContext.getSystemService(UserManager.class).isSystemUser();
+ }
+
+ private static class LocationListenerCapture implements LocationListener, AutoCloseable {
+
+ private final LocationManager mLocationManager;
+ private final LinkedBlockingQueue<Location> mLocations;
+ private final LinkedBlockingQueue<Boolean> mProviderChanges;
+
+ public LocationListenerCapture(LocationManager locationManager) {
+ mLocationManager = locationManager;
+ mLocations = new LinkedBlockingQueue<>();
+ mProviderChanges = new LinkedBlockingQueue<>();
+ }
+
+ public Location getNextLocation(long timeoutMs) throws InterruptedException {
+ return mLocations.poll(timeoutMs, TimeUnit.MILLISECONDS);
+ }
+
+ public Boolean getNextProviderChange(long timeoutMs) throws InterruptedException {
+ return mProviderChanges.poll(timeoutMs, TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ public void onLocationChanged(Location location) {
+ mLocations.add(location);
+ }
+
+ @Override
+ public void onStatusChanged(String provider, int status, Bundle extras) {
+ }
+
+ @Override
+ public void onProviderEnabled(String provider) {
+ mProviderChanges.add(true);
+ }
+
+ @Override
+ public void onProviderDisabled(String provider) {
+ mProviderChanges.add(false);
+ }
+
+ @Override
+ public void close() {
+ mLocationManager.removeUpdates(this);
+ }
+ }
+
+ private static class LocationPendingIntentCapture extends BroadcastReceiver implements
+ AutoCloseable {
+
+ private static final String ACTION = "android.location.cts.LOCATION_BROADCAST";
+ private static final AtomicInteger sRequestCode = new AtomicInteger(0);
+
+ private final Context mContext;
+ private final LocationManager mLocationManager;
+ private final PendingIntent mPendingIntent;
+ private final LinkedBlockingQueue<Location> mLocations;
+ private final LinkedBlockingQueue<Boolean> mProviderChanges;
+
+ public LocationPendingIntentCapture(Context context) {
+ mContext = context;
+ mLocationManager = context.getSystemService(LocationManager.class);
+ mPendingIntent = PendingIntent.getBroadcast(context, sRequestCode.getAndIncrement(),
+ new Intent(ACTION).setPackage(context.getPackageName()),
+ PendingIntent.FLAG_CANCEL_CURRENT);
+ mLocations = new LinkedBlockingQueue<>();
+ mProviderChanges = new LinkedBlockingQueue<>();
+
+ context.registerReceiver(this, new IntentFilter(ACTION));
+ }
+
+ public PendingIntent getPendingIntent() {
+ return mPendingIntent;
+ }
+
+ /**
+ * May not be called from the main thread. Tests do not run on the main thread so this
+ * generally shouldn't be a problem.
+ */
+ public Location getNextLocation(long timeoutMs) throws InterruptedException {
+ Preconditions.checkState(Looper.myLooper() != Looper.getMainLooper());
+ return mLocations.poll(timeoutMs, TimeUnit.MILLISECONDS);
+ }
+
+ /**
+ * May not be called from the main thread. Tests do not run on the main thread so this
+ * generally shouldn't be a problem.
+ */
+ public Boolean getNextProviderChange(long timeoutMs) throws InterruptedException {
+ Preconditions.checkState(Looper.myLooper() != Looper.getMainLooper());
+ return mProviderChanges.poll(timeoutMs, TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ public void close() {
+ mLocationManager.removeUpdates(mPendingIntent);
+ mContext.unregisterReceiver(this);
+ mPendingIntent.cancel();
}
@Override
public void onReceive(Context context, Intent intent) {
- if (intent != null && mExpectedAction.equals(intent.getAction())) {
- synchronized (this) {
- mLastReceivedIntent = intent;
- notify();
- }
+ if (intent.hasExtra(KEY_PROVIDER_ENABLED)) {
+ mProviderChanges.add(intent.getBooleanExtra(KEY_PROVIDER_ENABLED, false));
+ } else if (intent.hasExtra(KEY_LOCATION_CHANGED)) {
+ mLocations.add(intent.getParcelableExtra(KEY_LOCATION_CHANGED));
}
}
-
- public Intent getLastReceivedIntent() {
- return mLastReceivedIntent;
- }
-
- public void clearReceivedIntents() {
- mLastReceivedIntent = null;
- }
}
- private static class MockLocationListener implements LocationListener {
- private String mProvider;
- private int mStatus;
- private Location mLocation;
- private Object mStatusLock = new Object();
- private Object mLocationLock = new Object();
- private Object mLocationRequestLock = new Object();
+ private static class ProximityPendingIntentCapture extends BroadcastReceiver implements
+ AutoCloseable {
- private boolean mHasCalledOnLocationChanged;
+ private static final String ACTION = "android.location.cts.LOCATION_BROADCAST";
+ private static final AtomicInteger sRequestCode = new AtomicInteger(0);
- private boolean mHasCalledOnProviderDisabled;
+ private final Context mContext;
+ private final LocationManager mLocationManager;
+ private final PendingIntent mPendingIntent;
+ private final LinkedBlockingQueue<Boolean> mProximityChanges;
- private boolean mHasCalledOnProviderEnabled;
+ public ProximityPendingIntentCapture(Context context) {
+ mContext = context;
+ mLocationManager = context.getSystemService(LocationManager.class);
+ mPendingIntent = PendingIntent.getBroadcast(context, sRequestCode.getAndIncrement(),
+ new Intent(ACTION).setPackage(context.getPackageName()),
+ PendingIntent.FLAG_CANCEL_CURRENT);
+ mProximityChanges = new LinkedBlockingQueue<>();
- private boolean mHasCalledOnStatusChanged;
+ context.registerReceiver(this, new IntentFilter(ACTION));
+ }
- private boolean mHasCalledRequestLocation;
-
- public void reset(){
- mHasCalledOnLocationChanged = false;
- mHasCalledOnProviderDisabled = false;
- mHasCalledOnProviderEnabled = false;
- mHasCalledOnStatusChanged = false;
- mHasCalledRequestLocation = false;
- mProvider = null;
- mStatus = 0;
+ public PendingIntent getPendingIntent() {
+ return mPendingIntent;
}
/**
- * Call to inform listener that location has been updates have been requested
+ * May not be called from the main thread. Tests do not run on the main thread so this
+ * generally shouldn't be a problem.
*/
- public void setLocationRequested() {
- synchronized (mLocationRequestLock) {
- mHasCalledRequestLocation = true;
- mLocationRequestLock.notify();
- }
+ public Boolean getNextProximityChange(long timeoutMs) throws InterruptedException {
+ Preconditions.checkState(Looper.myLooper() != Looper.getMainLooper());
+ return mProximityChanges.poll(timeoutMs, TimeUnit.MILLISECONDS);
}
- public boolean hasCalledLocationRequested(long timeout) throws InterruptedException {
- synchronized (mLocationRequestLock) {
- if (timeout > 0 && !mHasCalledRequestLocation) {
- mLocationRequestLock.wait(timeout);
- }
- }
- return mHasCalledRequestLocation;
- }
-
- /**
- * Check whether onLocationChanged() has been called. Wait up to timeout milliseconds
- * for the callback.
- * @param timeout Maximum time to wait for the callback, 0 to return immediately.
- */
- public boolean hasCalledOnLocationChanged(long timeout) throws InterruptedException {
- synchronized (mLocationLock) {
- if (timeout > 0 && !mHasCalledOnLocationChanged) {
- mLocationLock.wait(timeout);
- }
- }
- return mHasCalledOnLocationChanged;
- }
-
- public boolean hasCalledOnProviderDisabled() {
- return mHasCalledOnProviderDisabled;
- }
-
- public boolean hasCalledOnProviderEnabled() {
- return mHasCalledOnProviderEnabled;
- }
-
- public boolean hasCalledOnStatusChanged(long timeout) throws InterruptedException {
- synchronized(mStatusLock) {
- // wait(0) would wait forever
- if (timeout > 0 && !mHasCalledOnStatusChanged) {
- mStatusLock.wait(timeout);
- }
- }
- return mHasCalledOnStatusChanged;
- }
-
- public void onLocationChanged(Location location) {
- mLocation = location;
- synchronized (mLocationLock) {
- mHasCalledOnLocationChanged = true;
- mLocationLock.notify();
- }
- }
-
- public void onProviderDisabled(String provider) {
- mHasCalledOnProviderDisabled = true;
- }
-
- public void onProviderEnabled(String provider) {
- mHasCalledOnProviderEnabled = true;
- }
-
- public void onStatusChanged(String provider, int status, Bundle extras) {
- mProvider = provider;
- mStatus = status;
- synchronized (mStatusLock) {
- mHasCalledOnStatusChanged = true;
- mStatusLock.notify();
- }
- }
-
- public String getProvider() {
- return mProvider;
- }
-
- public int getStatus() {
- return mStatus;
- }
-
- public Location getLocation() {
- return mLocation;
- }
- }
-
- private static class MockGnssNmeaListener implements OnNmeaMessageListener {
- private boolean mIsNmeaReceived;
-
@Override
- public void onNmeaMessage(String name, long timestamp) {
- mIsNmeaReceived = true;
+ public void close() {
+ mLocationManager.removeProximityAlert(mPendingIntent);
+ mContext.unregisterReceiver(this);
+ mPendingIntent.cancel();
}
- public boolean isNmeaRecevied() {
- return mIsNmeaReceived;
- }
-
- public void reset() {
- mIsNmeaReceived = false;
- }
- }
-
- private static class MockGnssStatusCallback extends GnssStatus.Callback {
@Override
- public void onSatelliteStatusChanged(GnssStatus status) {
- for (int i = 0; i < status.getSatelliteCount(); ++i) {
- status.getAzimuthDegrees(i);
- status.getCn0DbHz(i);
- status.getConstellationType(i);
- status.getElevationDegrees(i);
- status.getSvid(i);
- status.hasAlmanacData(i);
- status.hasEphemerisData(i);
- status.usedInFix(i);
+ public void onReceive(Context context, Intent intent) {
+ if (intent.hasExtra(KEY_PROXIMITY_ENTERING)) {
+ mProximityChanges.add(intent.getBooleanExtra(KEY_PROXIMITY_ENTERING, false));
}
}
}
- private boolean isSystemUser() {
- UserManager userManager = mContext.getSystemService(UserManager.class);
- return userManager.isSystemUser();
+ private static class GetCurrentLocationCapture implements Consumer<Location>, AutoCloseable {
+
+ private final CancellationSignal mCancellationSignal;
+ private final LinkedBlockingQueue<Location> locations;
+
+ public GetCurrentLocationCapture() {
+ locations = new LinkedBlockingQueue<>();
+ mCancellationSignal = new CancellationSignal();
+ }
+
+ public CancellationSignal getCancellationSignal() {
+ return mCancellationSignal;
+ }
+
+ public Location getNextLocation(long timeoutMs) throws InterruptedException {
+ return locations.poll(timeoutMs, TimeUnit.MILLISECONDS);
+ }
+
+ @Override
+ public void accept(Location location) {
+ locations.add(location);
+ }
+
+ @Override
+ public void close() {
+ mCancellationSignal.cancel();
+ }
}
}