Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.location.cts;
     18 
     19 import android.app.PendingIntent;
     20 import android.content.BroadcastReceiver;
     21 import android.content.Context;
     22 import android.content.Intent;
     23 import android.content.IntentFilter;
     24 import android.content.pm.PackageManager;
     25 import android.location.Criteria;
     26 import android.location.GnssStatus;
     27 import android.location.Location;
     28 import android.location.LocationListener;
     29 import android.location.LocationManager;
     30 import android.location.LocationProvider;
     31 import android.location.OnNmeaMessageListener;
     32 import android.os.Bundle;
     33 import android.os.Handler;
     34 import android.os.HandlerThread;
     35 import android.os.Looper;
     36 import android.os.SystemClock;
     37 import android.os.UserManager;
     38 import android.test.UiThreadTest;
     39 import android.util.Log;
     40 
     41 import java.util.List;
     42 
     43 /**
     44  * Requires the permissions
     45  * android.permission.ACCESS_MOCK_LOCATION to mock provider
     46  * android.permission.ACCESS_COARSE_LOCATION to access network provider
     47  * android.permission.ACCESS_FINE_LOCATION to access GPS provider
     48  * android.permission.ACCESS_LOCATION_EXTRA_COMMANDS to send extra commands to GPS provider
     49  */
     50 public class LocationManagerTest extends BaseMockLocationTest {
     51 
     52     private static final String TAG = "LocationManagerTest";
     53 
     54     private static final long TEST_TIME_OUT = 5000;
     55 
     56     private static final String TEST_MOCK_PROVIDER_NAME = "test_provider";
     57 
     58     private static final String UNKNOWN_PROVIDER_NAME = "unknown_provider";
     59 
     60     private static final String FUSED_PROVIDER_NAME = "fused";
     61 
     62     private LocationManager mManager;
     63 
     64     private Context mContext;
     65 
     66     private PendingIntent mPendingIntent;
     67 
     68     private TestIntentReceiver mIntentReceiver;
     69 
     70     @Override
     71     protected void setUp() throws Exception {
     72         super.setUp();
     73         mContext = getInstrumentation().getTargetContext();
     74 
     75         mManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
     76 
     77         // remove test provider if left over from an aborted run
     78         LocationProvider lp = mManager.getProvider(TEST_MOCK_PROVIDER_NAME);
     79         if (lp != null) {
     80             mManager.removeTestProvider(TEST_MOCK_PROVIDER_NAME);
     81         }
     82 
     83         addTestProvider(TEST_MOCK_PROVIDER_NAME);
     84     }
     85 
     86     /**
     87      * Helper method to add a test provider with given name.
     88      */
     89     private void addTestProvider(final String providerName) {
     90         mManager.addTestProvider(providerName, true, //requiresNetwork,
     91                 false, // requiresSatellite,
     92                 true,  // requiresCell,
     93                 false, // hasMonetaryCost,
     94                 false, // supportsAltitude,
     95                 false, // supportsSpeed,
     96                 false, // supportsBearing,
     97                 Criteria.POWER_MEDIUM, // powerRequirement
     98                 Criteria.ACCURACY_FINE); // accuracy
     99         mManager.setTestProviderEnabled(providerName, true);
    100     }
    101 
    102     @Override
    103     protected void tearDown() throws Exception {
    104         LocationProvider provider = mManager.getProvider(TEST_MOCK_PROVIDER_NAME);
    105         if (provider != null) {
    106             mManager.removeTestProvider(TEST_MOCK_PROVIDER_NAME);
    107         }
    108         if (mPendingIntent != null) {
    109             mManager.removeProximityAlert(mPendingIntent);
    110         }
    111         if (mIntentReceiver != null) {
    112             mContext.unregisterReceiver(mIntentReceiver);
    113         }
    114         super.tearDown();
    115     }
    116 
    117     public void testRemoveTestProvider() {
    118         // this test assumes TEST_MOCK_PROVIDER_NAME was created in setUp.
    119         LocationProvider provider = mManager.getProvider(TEST_MOCK_PROVIDER_NAME);
    120         assertNotNull(provider);
    121 
    122         try {
    123             mManager.addTestProvider(TEST_MOCK_PROVIDER_NAME, true, //requiresNetwork,
    124                     false, // requiresSatellite,
    125                     true,  // requiresCell,
    126                     false, // hasMonetaryCost,
    127                     false, // supportsAltitude,
    128                     false, // supportsSpeed,
    129                     false, // supportsBearing,
    130                     Criteria.POWER_MEDIUM, // powerRequirement
    131                     Criteria.ACCURACY_FINE); // accuracy
    132             fail("Should throw IllegalArgumentException when provider already exists!");
    133         } catch (IllegalArgumentException e) {
    134             // expected
    135         }
    136 
    137         mManager.removeTestProvider(TEST_MOCK_PROVIDER_NAME);
    138         provider = mManager.getProvider(TEST_MOCK_PROVIDER_NAME);
    139         assertNull(provider);
    140 
    141         try {
    142             mManager.removeTestProvider(UNKNOWN_PROVIDER_NAME);
    143             fail("Should throw IllegalArgumentException when no provider exists!");
    144         } catch (IllegalArgumentException e) {
    145             // expected
    146         }
    147     }
    148 
    149     public void testGetProviders() {
    150         List<String> providers = mManager.getAllProviders();
    151         assertTrue(providers.size() >= 2);
    152         assertTrue(hasTestProvider(providers));
    153 
    154         assertEquals(hasGpsFeature(), hasGpsProvider(providers));
    155 
    156         int oldSizeAllProviders = providers.size();
    157 
    158         providers = mManager.getProviders(false);
    159         assertEquals(oldSizeAllProviders, providers.size());
    160         assertTrue(hasTestProvider(providers));
    161 
    162         providers = mManager.getProviders(true);
    163         assertTrue(providers.size() >= 1);
    164         assertTrue(hasTestProvider(providers));
    165         int oldSizeTrueProviders = providers.size();
    166 
    167         mManager.setTestProviderEnabled(TEST_MOCK_PROVIDER_NAME, false);
    168         providers = mManager.getProviders(true);
    169         assertEquals(oldSizeTrueProviders - 1, providers.size());
    170         assertFalse(hasTestProvider(providers));
    171 
    172         providers = mManager.getProviders(false);
    173         assertEquals(oldSizeAllProviders, providers.size());
    174         assertTrue(hasTestProvider(providers));
    175 
    176         mManager.removeTestProvider(TEST_MOCK_PROVIDER_NAME);
    177         providers = mManager.getAllProviders();
    178         assertEquals(oldSizeAllProviders - 1, providers.size());
    179         assertFalse(hasTestProvider(providers));
    180     }
    181 
    182     private boolean hasTestProvider(List<String> providers) {
    183         return hasProvider(providers, TEST_MOCK_PROVIDER_NAME);
    184     }
    185 
    186     private boolean hasGpsProvider(List<String> providers) {
    187         return hasProvider(providers, LocationManager.GPS_PROVIDER);
    188     }
    189 
    190     private boolean hasGpsFeature() {
    191         return mContext.getPackageManager().hasSystemFeature(
    192                 PackageManager.FEATURE_LOCATION_GPS);
    193     }
    194 
    195     private boolean hasProvider(List<String> providers, String providerName) {
    196         for (String provider : providers) {
    197             if (provider != null && provider.equals(providerName)) {
    198                 return true;
    199             }
    200         }
    201         return false;
    202     }
    203 
    204     public void testGetProvider() {
    205         LocationProvider p = mManager.getProvider(TEST_MOCK_PROVIDER_NAME);
    206         assertNotNull(p);
    207         assertEquals(TEST_MOCK_PROVIDER_NAME, p.getName());
    208 
    209         p = mManager.getProvider(LocationManager.GPS_PROVIDER);
    210         if (hasGpsFeature()) {
    211             assertNotNull(p);
    212             assertEquals(LocationManager.GPS_PROVIDER, p.getName());
    213         } else {
    214             assertNull(p);
    215         }
    216 
    217         p = mManager.getProvider(UNKNOWN_PROVIDER_NAME);
    218         assertNull(p);
    219 
    220         try {
    221             mManager.getProvider(null);
    222             fail("Should throw IllegalArgumentException when provider is null!");
    223         } catch (IllegalArgumentException e) {
    224             // expected
    225         }
    226     }
    227 
    228     public void testGetProvidersWithCriteria() {
    229         Criteria criteria = new Criteria();
    230         List<String> providers = mManager.getProviders(criteria, true);
    231         assertTrue(providers.size() >= 1);
    232         assertTrue(hasTestProvider(providers));
    233 
    234         criteria = new Criteria();
    235         criteria.setPowerRequirement(Criteria.POWER_HIGH);
    236         String p = mManager.getBestProvider(criteria, true);
    237         if (p != null) { // we may not have any enabled providers
    238             assertTrue(mManager.isProviderEnabled(p));
    239         }
    240 
    241         criteria.setPowerRequirement(Criteria.POWER_MEDIUM);
    242         p = mManager.getBestProvider(criteria, false);
    243         assertNotNull(p);
    244 
    245         criteria.setPowerRequirement(Criteria.POWER_LOW);
    246         p = mManager.getBestProvider(criteria, true);
    247         if (p != null) { // we may not have any enabled providers
    248             assertTrue(mManager.isProviderEnabled(p));
    249         }
    250 
    251         criteria.setPowerRequirement(Criteria.NO_REQUIREMENT);
    252         p = mManager.getBestProvider(criteria, false);
    253         assertNotNull(p);
    254     }
    255 
    256     /**
    257      * Returns true if the {@link LocationManager} reports that the device includes this flavor
    258      * of location provider.
    259      */
    260     private boolean deviceHasProvider(String provider) {
    261         List<String> providers = mManager.getAllProviders();
    262         for (String aProvider : providers) {
    263             if (aProvider.equals(provider)) {
    264                 return true;
    265             }
    266         }
    267         return false;
    268     }
    269 
    270     /**
    271      * Ensures the test provider is removed. {@link LocationManager#removeTestProvider(String)}
    272      * throws an {@link java.lang.IllegalArgumentException} if there is no such test provider,
    273      * so we have to add it before we clear it.
    274      */
    275     private void forceRemoveTestProvider(String provider) {
    276         addTestProvider(provider);
    277         mManager.removeTestProvider(provider);
    278     }
    279 
    280     public void testLocationUpdatesWithLocationListener() throws InterruptedException {
    281         doLocationUpdatesWithLocationListener(TEST_MOCK_PROVIDER_NAME);
    282 
    283         try {
    284             mManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
    285                     (LocationListener) null);
    286             fail("Should throw IllegalArgumentException if param listener is null!");
    287         } catch (IllegalArgumentException e) {
    288             // expected
    289         }
    290 
    291         try {
    292             mManager.requestLocationUpdates(null, 0, 0, new MockLocationListener());
    293             fail("Should throw IllegalArgumentException if param provider is null!");
    294         } catch (IllegalArgumentException e) {
    295             // expected
    296         }
    297 
    298         try {
    299             mManager.removeUpdates( (LocationListener) null );
    300             fail("Should throw IllegalArgumentException if listener is null!");
    301         } catch (IllegalArgumentException e) {
    302             // expected
    303         }
    304     }
    305 
    306     /**
    307      * Helper method to test a location update with given mock location provider
    308      *
    309      * @param providerName name of provider to test. Must already exist.
    310      * @throws InterruptedException
    311      */
    312     private void doLocationUpdatesWithLocationListener(final String providerName)
    313             throws InterruptedException {
    314         final double latitude1 = 10;
    315         final double longitude1 = 40;
    316         final double latitude2 = 35;
    317         final double longitude2 = 80;
    318         final MockLocationListener listener = new MockLocationListener();
    319 
    320         // update location and notify listener
    321         new Thread(new Runnable() {
    322             public void run() {
    323                 Looper.prepare();
    324                 mManager.requestLocationUpdates(providerName, 0, 0, listener);
    325                 listener.setLocationRequested();
    326                 Looper.loop();
    327             }
    328         }).start();
    329         // wait for location requested to be called first, otherwise setLocation can be called
    330         // before there is a listener attached
    331         assertTrue(listener.hasCalledLocationRequested(TEST_TIME_OUT));
    332         updateLocation(providerName, latitude1, longitude1);
    333         assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
    334         Location location = listener.getLocation();
    335         assertEquals(providerName, location.getProvider());
    336         assertEquals(latitude1, location.getLatitude());
    337         assertEquals(longitude1, location.getLongitude());
    338         assertEquals(true, location.isFromMockProvider());
    339 
    340         // update location without notifying listener
    341         listener.reset();
    342         assertFalse(listener.hasCalledOnLocationChanged(0));
    343         mManager.removeUpdates(listener);
    344         updateLocation(providerName, latitude2, longitude2);
    345         assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
    346     }
    347 
    348     /**
    349      * Verifies that all real location providers can be replaced by a mock provider.
    350      * <p/>
    351      * This feature is quite useful for developer automated testing.
    352      * This test may fail if another unknown test provider already exists, because there is no
    353      * known way to determine if a given provider is a test provider.
    354      * @throws InterruptedException
    355      */
    356     public void testReplaceRealProvidersWithMocks() throws InterruptedException {
    357         for (String providerName : mManager.getAllProviders()) {
    358             if (!providerName.equals(TEST_MOCK_PROVIDER_NAME) &&
    359                 !providerName.equals(LocationManager.PASSIVE_PROVIDER)) {
    360                 addTestProvider(providerName);
    361                 try {
    362                     // run the update location test logic to ensure location updates can be injected
    363                     doLocationUpdatesWithLocationListener(providerName);
    364                 } finally {
    365                     mManager.removeTestProvider(providerName);
    366                 }
    367             }
    368         }
    369     }
    370 
    371     public void testLocationUpdatesWithLocationListenerAndLooper() throws InterruptedException {
    372         double latitude1 = 60;
    373         double longitude1 = 20;
    374         double latitude2 = 40;
    375         double longitude2 = 30;
    376         final MockLocationListener listener = new MockLocationListener();
    377 
    378         // update location and notify listener
    379         HandlerThread handlerThread = new HandlerThread("testLocationUpdates");
    380         handlerThread.start();
    381         mManager.requestLocationUpdates(TEST_MOCK_PROVIDER_NAME, 0, 0, listener,
    382                 handlerThread.getLooper());
    383 
    384         updateLocation(latitude1, longitude1);
    385         assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
    386         Location location = listener.getLocation();
    387         assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider());
    388         assertEquals(latitude1, location.getLatitude());
    389         assertEquals(longitude1, location.getLongitude());
    390         assertEquals(true, location.isFromMockProvider());
    391 
    392         // update location without notifying listener
    393         mManager.removeUpdates(listener);
    394         listener.reset();
    395         updateLocation(latitude2, longitude2);
    396         assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
    397 
    398         try {
    399             mManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
    400                     (LocationListener) null, Looper.myLooper());
    401             fail("Should throw IllegalArgumentException if param listener is null!");
    402         } catch (IllegalArgumentException e) {
    403             // expected
    404         }
    405 
    406         try {
    407             mManager.requestLocationUpdates(null, 0, 0, listener, Looper.myLooper());
    408             fail("Should throw IllegalArgumentException if param provider is null!");
    409         } catch (IllegalArgumentException e) {
    410             // expected
    411         }
    412 
    413         try {
    414             mManager.removeUpdates((LocationListener) null );
    415             fail("Should throw IllegalArgumentException if listener is null!");
    416         } catch (IllegalArgumentException e) {
    417             // expected
    418         }
    419     }
    420 
    421     public void testLocationUpdatesWithPendingIntent() throws InterruptedException {
    422         double latitude1 = 20;
    423         double longitude1 = 40;
    424         double latitude2 = 30;
    425         double longitude2 = 50;
    426 
    427         // update location and receive broadcast.
    428         registerIntentReceiver();
    429         mManager.requestLocationUpdates(TEST_MOCK_PROVIDER_NAME, 0, 0, mPendingIntent);
    430         updateLocation(latitude1, longitude1);
    431         waitForReceiveBroadcast();
    432 
    433         assertNotNull(mIntentReceiver.getLastReceivedIntent());
    434         Location location = mManager.getLastKnownLocation(TEST_MOCK_PROVIDER_NAME);
    435         assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider());
    436         assertEquals(latitude1, location.getLatitude());
    437         assertEquals(longitude1, location.getLongitude());
    438         assertEquals(true, location.isFromMockProvider());
    439 
    440         // update location without receiving broadcast.
    441         mManager.removeUpdates(mPendingIntent);
    442         mIntentReceiver.clearReceivedIntents();
    443         updateLocation(latitude2, longitude2);
    444         waitForReceiveBroadcast();
    445         assertNull(mIntentReceiver.getLastReceivedIntent());
    446 
    447         try {
    448             mManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
    449                     (PendingIntent) null);
    450             fail("Should throw IllegalArgumentException if param intent is null!");
    451         } catch (IllegalArgumentException e) {
    452             // expected
    453         }
    454 
    455         try {
    456             mManager.requestLocationUpdates(null, 0, 0, mPendingIntent);
    457             fail("Should throw IllegalArgumentException if param provider is null!");
    458         } catch (IllegalArgumentException e) {
    459             // expected
    460         }
    461 
    462         try {
    463             mManager.removeUpdates( (PendingIntent) null );
    464             fail("Should throw IllegalArgumentException if intent is null!");
    465         } catch (IllegalArgumentException e) {
    466             // expected
    467         }
    468     }
    469 
    470     public void testSingleUpdateWithLocationListenerAndLooper() throws InterruptedException {
    471         double latitude1 = 60;
    472         double longitude1 = 20;
    473         double latitude2 = 40;
    474         double longitude2 = 30;
    475         double latitude3 = 10;
    476         double longitude3 = 50;
    477         final MockLocationListener listener = new MockLocationListener();
    478 
    479         // update location and notify listener
    480         HandlerThread handlerThread = new HandlerThread("testLocationUpdates4");
    481         handlerThread.start();
    482         mManager.requestSingleUpdate(TEST_MOCK_PROVIDER_NAME, listener, handlerThread.getLooper());
    483 
    484         updateLocation(latitude1, longitude1);
    485         assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
    486         Location location = listener.getLocation();
    487         assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider());
    488         assertEquals(latitude1, location.getLatitude());
    489         assertEquals(longitude1, location.getLongitude());
    490         assertEquals(true, location.isFromMockProvider());
    491 
    492         // Any further location change doesn't trigger an update.
    493         updateLocation(latitude2, longitude2);
    494         assertEquals(latitude1, location.getLatitude());
    495         assertEquals(longitude1, location.getLongitude());
    496 
    497         // update location without notifying listener
    498         mManager.removeUpdates(listener);
    499         listener.reset();
    500         updateLocation(latitude3, longitude3);
    501         assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
    502 
    503         try {
    504             mManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, mPendingIntent);
    505             fail("Should throw IllegalArgumentException if PendingIntent is null!");
    506         } catch (IllegalArgumentException e) {
    507             // expected
    508         }
    509 
    510         try {
    511             mManager.requestSingleUpdate(LocationManager.GPS_PROVIDER, (LocationListener) null,
    512                     Looper.myLooper());
    513             fail("Should throw IllegalArgumentException if param listener is null!");
    514         } catch (IllegalArgumentException e) {
    515             // expected
    516         }
    517 
    518         try {
    519             mManager.requestSingleUpdate((String) null, listener, Looper.myLooper());
    520             fail("Should throw IllegalArgumentException if param provider is null!");
    521         } catch (IllegalArgumentException e) {
    522             // expected
    523         }
    524 
    525         try {
    526             mManager.removeUpdates((LocationListener) null );
    527             fail("Should throw IllegalArgumentException if listener is null!");
    528         } catch (IllegalArgumentException e) {
    529             // expected
    530         }
    531     }
    532 
    533     public void testLocationUpdatesWithCriteriaAndPendingIntent() throws InterruptedException {
    534         double latitude1 = 10;
    535         double longitude1 = 20;
    536         double latitude2 = 30;
    537         double longitude2 = 40;
    538 
    539         registerIntentReceiver();
    540         mockFusedLocation();
    541 
    542         // Update location and receive broadcast.
    543         Criteria criteria = createLocationCriteria();
    544         mManager.requestLocationUpdates(0, 0 , criteria, mPendingIntent);
    545         updateFusedLocation(latitude1, longitude1);
    546         waitForReceiveBroadcast();
    547 
    548         assertNotNull(mIntentReceiver.getLastReceivedIntent());
    549         Location location = (Location) mIntentReceiver.getLastReceivedIntent().getExtras()
    550                 .get(LocationManager.KEY_LOCATION_CHANGED);
    551         assertEquals(latitude1, location.getLatitude());
    552         assertEquals(longitude1, location.getLongitude());
    553         assertTrue(location.hasAccuracy());
    554         assertEquals(1.0f, location.getAccuracy());
    555         assertEquals(true, location.isFromMockProvider());
    556 
    557         // Update location without receiving broadcast.
    558         mManager.removeUpdates(mPendingIntent);
    559         mIntentReceiver.clearReceivedIntents();
    560         updateFusedLocation(latitude2, longitude2);
    561         waitForReceiveBroadcast();
    562         assertNull(mIntentReceiver.getLastReceivedIntent());
    563 
    564         // Missing arguments throw exceptions.
    565         try {
    566             mManager.requestLocationUpdates(0, 0, criteria, (PendingIntent) null);
    567             fail("Should throw IllegalArgumentException if param intent is null!");
    568         } catch (IllegalArgumentException e) {
    569             // expected
    570         }
    571 
    572         try {
    573             mManager.requestLocationUpdates(0, 0, null, mPendingIntent);
    574             fail("Should throw IllegalArgumentException if param criteria is null!");
    575         } catch (IllegalArgumentException e) {
    576             // expected
    577         }
    578 
    579         try {
    580             mManager.removeUpdates( (PendingIntent) null );
    581             fail("Should throw IllegalArgumentException if param PendingIntent is null!");
    582         } catch (IllegalArgumentException e) {
    583             // expected
    584         }
    585 
    586         unmockFusedLocation();
    587     }
    588 
    589     public void testSingleUpdateWithCriteriaAndPendingIntent() throws InterruptedException {
    590         double latitude1 = 10;
    591         double longitude1 = 20;
    592         double latitude2 = 30;
    593         double longitude2 = 40;
    594         double latitude3 = 50;
    595         double longitude3 = 60;
    596 
    597         registerIntentReceiver();
    598         mockFusedLocation();
    599 
    600         // Update location and receive broadcast.
    601         Criteria criteria = createLocationCriteria();
    602         mManager.requestSingleUpdate(criteria, mPendingIntent);
    603         updateFusedLocation(latitude1, longitude1);
    604         waitForReceiveBroadcast();
    605 
    606         assertNotNull(mIntentReceiver.getLastReceivedIntent());
    607         Location location = (Location) mIntentReceiver.getLastReceivedIntent().getExtras()
    608                 .get(LocationManager.KEY_LOCATION_CHANGED);
    609         assertEquals(latitude1, location.getLatitude());
    610         assertEquals(longitude1, location.getLongitude());
    611         assertTrue(location.hasAccuracy());
    612         assertEquals(1.0f, location.getAccuracy());
    613         assertEquals(true, location.isFromMockProvider());
    614 
    615         // Any further location change doesn't trigger an update.
    616         updateFusedLocation(latitude2, longitude2);
    617         assertEquals(latitude1, location.getLatitude());
    618         assertEquals(longitude1, location.getLongitude());
    619 
    620         // Update location without receiving broadcast.
    621         mManager.removeUpdates(mPendingIntent);
    622         mIntentReceiver.clearReceivedIntents();
    623         updateFusedLocation(latitude3, longitude3);
    624         waitForReceiveBroadcast();
    625         assertNull(mIntentReceiver.getLastReceivedIntent());
    626 
    627         // Missing arguments throw exceptions.
    628         try {
    629             mManager.requestSingleUpdate(criteria, (PendingIntent) null);
    630             fail("Should throw IllegalArgumentException if param intent is null!");
    631         } catch (IllegalArgumentException e) {
    632             // expected
    633         }
    634 
    635         try {
    636             mManager.requestSingleUpdate((Criteria) null, mPendingIntent);
    637             fail("Should throw IllegalArgumentException if param criteria is null!");
    638         } catch (IllegalArgumentException e) {
    639             // expected
    640         }
    641 
    642         try {
    643             mManager.removeUpdates( (PendingIntent) null );
    644             fail("Should throw IllegalArgumentException if param PendingIntent is null!");
    645         } catch (IllegalArgumentException e) {
    646             // expected
    647         }
    648 
    649         unmockFusedLocation();
    650     }
    651 
    652     public void testLocationUpdatesWithCriteriaAndLocationListenerAndLooper()
    653             throws InterruptedException {
    654         double latitude1 = 40;
    655         double longitude1 = 10;
    656         double latitude2 = 20;
    657         double longitude2 = 30;
    658        final MockLocationListener listener = new MockLocationListener();
    659         mockFusedLocation();
    660 
    661         // update location and notify listener
    662         HandlerThread handlerThread = new HandlerThread("testLocationUpdates1");
    663         handlerThread.start();
    664         Criteria criteria = createLocationCriteria();
    665         mManager.requestLocationUpdates(0, 0, criteria, listener, handlerThread.getLooper());
    666 
    667         updateFusedLocation(latitude1, longitude1);
    668         assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
    669         Location location = listener.getLocation();
    670         assertEquals(latitude1, location.getLatitude());
    671         assertEquals(longitude1, location.getLongitude());
    672         assertTrue(location.hasAccuracy());
    673         assertEquals(1.0f, location.getAccuracy());
    674         assertEquals(true, location.isFromMockProvider());
    675 
    676         // update location without notifying listener
    677         mManager.removeUpdates(listener);
    678         listener.reset();
    679         updateFusedLocation(latitude2, longitude2);
    680         assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
    681 
    682         // Missing arguments throw exceptions.
    683         try {
    684             mManager.requestLocationUpdates(0, 0, criteria, (LocationListener) null,
    685                     Looper.myLooper());
    686             fail("Should throw IllegalArgumentException if param listener is null!");
    687         } catch (IllegalArgumentException e) {
    688             // expected
    689         }
    690 
    691         try {
    692             mManager.requestLocationUpdates(0, 0, null, listener, Looper.myLooper());
    693             fail("Should throw IllegalArgumentException if param criteria is null!");
    694         } catch (IllegalArgumentException e) {
    695             // expected
    696         }
    697 
    698         try {
    699             mManager.removeUpdates( (LocationListener) null );
    700             fail("Should throw IllegalArgumentException if listener is null!");
    701         } catch (IllegalArgumentException e) {
    702             // expected
    703         }
    704 
    705         unmockFusedLocation();
    706     }
    707 
    708     public void testSingleUpdateWithCriteriaAndLocationListenerAndLooper()
    709             throws InterruptedException {
    710         double latitude1 = 40;
    711         double longitude1 = 10;
    712         double latitude2 = 20;
    713         double longitude2 = 30;
    714         double latitude3 = 60;
    715         double longitude3 = 50;
    716         final MockLocationListener listener = new MockLocationListener();
    717         mockFusedLocation();
    718 
    719         // update location and notify listener
    720         HandlerThread handlerThread = new HandlerThread("testLocationUpdates2");
    721         handlerThread.start();
    722         Criteria criteria = createLocationCriteria();
    723         mManager.requestSingleUpdate(criteria, listener, handlerThread.getLooper());
    724 
    725         updateFusedLocation(latitude1, longitude1);
    726         assertTrue(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
    727         Location location = listener.getLocation();
    728         assertEquals(FUSED_PROVIDER_NAME, location.getProvider());
    729         assertEquals(latitude1, location.getLatitude());
    730         assertEquals(longitude1, location.getLongitude());
    731         assertTrue(location.hasAccuracy());
    732         assertEquals(1.0f, location.getAccuracy());
    733         assertEquals(true, location.isFromMockProvider());
    734 
    735         // Any further location change doesn't trigger an update.
    736         updateFusedLocation(latitude2, longitude2);
    737         assertEquals(latitude1, location.getLatitude());
    738         assertEquals(longitude1, location.getLongitude());
    739 
    740         // update location without notifying listener
    741         mManager.removeUpdates(listener);
    742         listener.reset();
    743         updateFusedLocation(latitude3, longitude3);
    744         assertFalse(listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
    745 
    746         // Missing arguments throw exceptions.
    747         try {
    748             mManager.requestLocationUpdates(0, 0, criteria, (LocationListener) null,
    749                     Looper.myLooper());
    750             fail("Should throw IllegalArgumentException if param listener is null!");
    751         } catch (IllegalArgumentException e) {
    752             // expected
    753         }
    754 
    755         try {
    756             mManager.requestLocationUpdates(0, 0, null, listener, Looper.myLooper());
    757             fail("Should throw IllegalArgumentException if param criteria is null!");
    758         } catch (IllegalArgumentException e) {
    759             // expected
    760         }
    761 
    762         try {
    763             mManager.removeUpdates( (LocationListener) null );
    764             fail("Should throw IllegalArgumentException if listener is null!");
    765         } catch (IllegalArgumentException e) {
    766             // expected
    767         }
    768 
    769         unmockFusedLocation();
    770     }
    771 
    772     public void testSingleUpdateWithPendingIntent() throws InterruptedException {
    773         double latitude1 = 20;
    774         double longitude1 = 40;
    775         double latitude2 = 30;
    776         double longitude2 = 50;
    777         double latitude3 = 10;
    778         double longitude3 = 60;
    779 
    780         // update location and receive broadcast.
    781         registerIntentReceiver();
    782         mManager.requestLocationUpdates(TEST_MOCK_PROVIDER_NAME, 0, 0, mPendingIntent);
    783         updateLocation(latitude1, longitude1);
    784         waitForReceiveBroadcast();
    785 
    786         assertNotNull(mIntentReceiver.getLastReceivedIntent());
    787         Location location = mManager.getLastKnownLocation(TEST_MOCK_PROVIDER_NAME);
    788         assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider());
    789         assertEquals(latitude1, location.getLatitude());
    790         assertEquals(longitude1, location.getLongitude());
    791         assertEquals(true, location.isFromMockProvider());
    792 
    793         // Any further location change doesn't trigger an update.
    794         updateLocation(latitude2, longitude2);
    795         assertEquals(latitude1, location.getLatitude());
    796         assertEquals(longitude1, location.getLongitude());
    797 
    798         // update location without receiving broadcast.
    799         mManager.removeUpdates(mPendingIntent);
    800         mIntentReceiver.clearReceivedIntents();
    801         updateLocation(latitude3, longitude3);
    802         waitForReceiveBroadcast();
    803         assertEquals(latitude1, location.getLatitude());
    804         assertEquals(longitude1, location.getLongitude());
    805 
    806         try {
    807             mManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0,
    808                     (PendingIntent) null);
    809             fail("Should throw IllegalArgumentException if param intent is null!");
    810         } catch (IllegalArgumentException e) {
    811             // expected
    812         }
    813 
    814         try {
    815             mManager.requestLocationUpdates(null, 0, 0, mPendingIntent);
    816             fail("Should throw IllegalArgumentException if param provider is null!");
    817         } catch (IllegalArgumentException e) {
    818             // expected
    819         }
    820 
    821         try {
    822             mManager.removeUpdates( (PendingIntent) null );
    823             fail("Should throw IllegalArgumentException if intent is null!");
    824         } catch (IllegalArgumentException e) {
    825             // expected
    826         }
    827     }
    828 
    829     public void testAddProximityAlert() {
    830         Intent i = new Intent();
    831         i.setAction("android.location.cts.TEST_GET_GPS_STATUS_ACTION");
    832         PendingIntent pi = PendingIntent.getBroadcast(mContext, 0, i, PendingIntent.FLAG_ONE_SHOT);
    833 
    834         mManager.addProximityAlert(0, 0, 1.0f, 5000, pi);
    835         mManager.removeProximityAlert(pi);
    836     }
    837 
    838     @UiThreadTest
    839     public void testNmeaListener() {
    840         MockGnssNmeaListener gnssListener = new MockGnssNmeaListener();
    841         mManager.addNmeaListener(gnssListener);
    842         mManager.removeNmeaListener(gnssListener);
    843 
    844         HandlerThread handlerThread = new HandlerThread("testNmeaListener");
    845         handlerThread.start();
    846         mManager.addNmeaListener(gnssListener, new Handler(handlerThread.getLooper()));
    847         mManager.removeNmeaListener(gnssListener);
    848 
    849         mManager.addNmeaListener((OnNmeaMessageListener) null);
    850         mManager.removeNmeaListener((OnNmeaMessageListener) null);
    851     }
    852 
    853     public void testIsProviderEnabled() {
    854         // this test assumes enabled TEST_MOCK_PROVIDER_NAME was created in setUp.
    855         assertNotNull(mManager.getProvider(TEST_MOCK_PROVIDER_NAME));
    856         assertTrue(mManager.isProviderEnabled(TEST_MOCK_PROVIDER_NAME));
    857 
    858         mManager.clearTestProviderEnabled(TEST_MOCK_PROVIDER_NAME);
    859         assertFalse(mManager.isProviderEnabled(TEST_MOCK_PROVIDER_NAME));
    860 
    861         mManager.setTestProviderEnabled(TEST_MOCK_PROVIDER_NAME, true);
    862         assertTrue(mManager.isProviderEnabled(TEST_MOCK_PROVIDER_NAME));
    863 
    864         try {
    865             mManager.isProviderEnabled(null);
    866             fail("Should throw IllegalArgumentException if provider is null!");
    867         } catch (IllegalArgumentException e) {
    868             // expected
    869         }
    870 
    871         try {
    872             mManager.setTestProviderEnabled(UNKNOWN_PROVIDER_NAME, false);
    873             fail("Should throw IllegalArgumentException if provider is unknown!");
    874         } catch (IllegalArgumentException e) {
    875             // expected
    876         }
    877     }
    878 
    879     public void testGetLastKnownLocation() throws InterruptedException {
    880         double latitude1 = 20;
    881         double longitude1 = 40;
    882         double latitude2 = 10;
    883         double longitude2 = 70;
    884 
    885         registerIntentReceiver();
    886         mManager.requestLocationUpdates(TEST_MOCK_PROVIDER_NAME, 0, 0, mPendingIntent);
    887         updateLocation(latitude1, longitude1);
    888         waitForReceiveBroadcast();
    889 
    890         assertNotNull(mIntentReceiver.getLastReceivedIntent());
    891         Location location = mManager.getLastKnownLocation(TEST_MOCK_PROVIDER_NAME);
    892         assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider());
    893         assertEquals(latitude1, location.getLatitude());
    894         assertEquals(longitude1, location.getLongitude());
    895         assertEquals(true, location.isFromMockProvider());
    896 
    897         mIntentReceiver.clearReceivedIntents();
    898         updateLocation(latitude2, longitude2);
    899         waitForReceiveBroadcast();
    900 
    901         assertNotNull(mIntentReceiver.getLastReceivedIntent());
    902         location = mManager.getLastKnownLocation(TEST_MOCK_PROVIDER_NAME);
    903         assertEquals(TEST_MOCK_PROVIDER_NAME, location.getProvider());
    904         assertEquals(latitude2, location.getLatitude());
    905         assertEquals(longitude2, location.getLongitude());
    906         assertEquals(true, location.isFromMockProvider());
    907 
    908         try {
    909             mManager.getLastKnownLocation(null);
    910             fail("Should throw IllegalArgumentException if provider is null!");
    911         } catch (IllegalArgumentException e) {
    912             // expected
    913         }
    914     }
    915 
    916     /**
    917      * Test case for bug 33091107, where a malicious app used to be able to fool a real provider
    918      * into providing a mock location that isn't marked as being mock.
    919      */
    920     public void testLocationShouldStillBeMarkedMockWhenProvidersDoNotMatch()
    921             throws InterruptedException {
    922         double latitude = 20;
    923         double longitude = 40;
    924 
    925         List<String> providers = mManager.getAllProviders();
    926         if (providers.isEmpty()) {
    927             // Device doesn't have any providers. Can't perform this test, and no need to do so:
    928             // no providers that malicious app could fool
    929             return;
    930         }
    931         String realProviderToFool = providers.get(0);
    932 
    933         // Register for location updates, then set a mock location and ensure it is marked "mock"
    934         updateLocationAndWait(TEST_MOCK_PROVIDER_NAME, realProviderToFool, latitude, longitude);
    935     }
    936 
    937     @UiThreadTest
    938     public void testGnssStatusListener() {
    939         MockGnssStatusCallback callback = new MockGnssStatusCallback();
    940         mManager.registerGnssStatusCallback(callback);
    941         mManager.unregisterGnssStatusCallback(callback);
    942 
    943         mManager.registerGnssStatusCallback(null);
    944         mManager.unregisterGnssStatusCallback(null);
    945 
    946         HandlerThread handlerThread = new HandlerThread("testStatusUpdates");
    947         handlerThread.start();
    948 
    949         mManager.registerGnssStatusCallback(callback, new Handler(handlerThread.getLooper()));
    950         mManager.unregisterGnssStatusCallback(callback);
    951     }
    952 
    953     /**
    954      * Tests basic proximity alert when entering proximity
    955      */
    956     public void testEnterProximity() throws Exception {
    957         if (!isSystemUser()) {
    958             Log.i(TAG, "Skipping test on secondary user");
    959             return;
    960         }
    961         // need to mock the fused location provider for proximity tests
    962         mockFusedLocation();
    963 
    964         doTestEnterProximity(10000);
    965 
    966         unmockFusedLocation();
    967     }
    968 
    969     /**
    970      * Tests proximity alert when entering proximity, with no expiration
    971      */
    972     public void testEnterProximity_noexpire() throws Exception {
    973         if (!isSystemUser()) {
    974             Log.i(TAG, "Skipping test on secondary user");
    975             return;
    976         }
    977         // need to mock the fused location provider for proximity tests
    978         mockFusedLocation();
    979 
    980         doTestEnterProximity(-1);
    981 
    982         unmockFusedLocation();
    983     }
    984 
    985     /**
    986      * Tests basic proximity alert when exiting proximity
    987      */
    988     public void testExitProximity() throws Exception {
    989         if (!isSystemUser()) {
    990             Log.i(TAG, "Skipping test on secondary user");
    991             return;
    992         }
    993         // need to mock the fused location provider for proximity tests
    994         mockFusedLocation();
    995 
    996         // first do enter proximity scenario
    997         doTestEnterProximity(-1);
    998 
    999         // now update to trigger exit proximity proximity
   1000         mIntentReceiver.clearReceivedIntents();
   1001         updateLocationAndWait(FUSED_PROVIDER_NAME, 20, 20);
   1002         waitForReceiveBroadcast();
   1003         assertProximityType(false);
   1004 
   1005         unmockFusedLocation();
   1006     }
   1007 
   1008     /**
   1009      * Tests basic proximity alert when initially within proximity
   1010      */
   1011     public void testInitiallyWithinProximity() throws Exception {
   1012         if (!isSystemUser()) {
   1013             Log.i(TAG, "Skipping test on secondary user");
   1014             return;
   1015         }
   1016         // need to mock the fused location provider for proximity tests
   1017         mockFusedLocation();
   1018 
   1019         updateLocationAndWait(FUSED_PROVIDER_NAME, 0, 0);
   1020         registerProximityListener(0, 0, 1000, 10000);
   1021         waitForReceiveBroadcast();
   1022         assertProximityType(true);
   1023 
   1024         unmockFusedLocation();
   1025     }
   1026 
   1027     /**
   1028      * Helper variant for testing enter proximity scenario
   1029      * TODO: add additional parameters as more scenarios are added
   1030      *
   1031      * @param expiration - expiration of proximity alert
   1032      */
   1033     private void doTestEnterProximity(long expiration) throws Exception {
   1034         // update location to outside proximity range
   1035         updateLocationAndWait(FUSED_PROVIDER_NAME, 30, 30);
   1036         registerProximityListener(0, 0, 1000, expiration);
   1037 
   1038         // Adding geofences is asynchronous, the return of LocationManager.addProximityAlert
   1039         // doesn't mean that geofences are already being monitored. Wait for a few milliseconds
   1040         // so that GeofenceManager is actively monitoring locations before we send the mock
   1041         // location to avoid flaky tests.
   1042         Thread.sleep(500);
   1043 
   1044         updateLocationAndWait(FUSED_PROVIDER_NAME, 0, 0);
   1045         waitForReceiveBroadcast();
   1046         assertProximityType(true);
   1047     }
   1048 
   1049 
   1050     private void updateLocationAndWait(String providerName, double latitude, double longitude)
   1051             throws InterruptedException {
   1052         updateLocationAndWait(providerName, providerName, latitude, longitude);
   1053     }
   1054 
   1055     /**
   1056      * Like {@link #updateLocationAndWait(String, double, double)}, but allows inconsistent providers
   1057      * to be used in the calls to {@link Location#Location(String)} and {@link
   1058      * LocationManager#setTestProviderLocation(String, Location)}
   1059      *
   1060      * @param testProviderName used in {@link LocationManager#setTestProviderLocation(String,
   1061      * Location)}
   1062      * @param locationProviderName used in {@link Location#Location(String)}
   1063      */
   1064     private void updateLocationAndWait(String testProviderName, String locationProviderName,
   1065         double latitude, double longitude) throws InterruptedException {
   1066 
   1067         // Register a listener for the location we are about to set.
   1068         MockLocationListener listener = new MockLocationListener();
   1069         HandlerThread handlerThread = new HandlerThread("updateLocationAndWait");
   1070         handlerThread.start();
   1071         mManager.requestLocationUpdates(locationProviderName, 0, 0, listener,
   1072                 handlerThread.getLooper());
   1073 
   1074         // Set the location.
   1075         updateLocation(testProviderName, locationProviderName, latitude, longitude);
   1076 
   1077         // Make sure we received the location, and it is the right one.
   1078         assertTrue("Listener not called", listener.hasCalledOnLocationChanged(TEST_TIME_OUT));
   1079         Location location = listener.getLocation();
   1080         assertEquals("Bad provider name", locationProviderName, location.getProvider());
   1081         assertEquals("Bad latitude", latitude, location.getLatitude());
   1082         assertEquals("Bad longitude", longitude, location.getLongitude());
   1083         assertTrue("Bad isMock", location.isFromMockProvider());
   1084 
   1085         // Remove the listener.
   1086         mManager.removeUpdates(listener);
   1087     }
   1088 
   1089     private void registerIntentReceiver() {
   1090         String intentKey = "LocationManagerTest";
   1091         Intent proximityIntent = new Intent(intentKey);
   1092         mPendingIntent = PendingIntent.getBroadcast(mContext, 0, proximityIntent,
   1093                 PendingIntent.FLAG_CANCEL_CURRENT);
   1094         mIntentReceiver = new TestIntentReceiver(intentKey);
   1095         mContext.registerReceiver(mIntentReceiver, mIntentReceiver.getFilter());
   1096     }
   1097 
   1098     /**
   1099      * Registers the proximity intent receiver
   1100      */
   1101     private void registerProximityListener(double latitude, double longitude, float radius,
   1102             long expiration) {
   1103         registerIntentReceiver();
   1104         mManager.addProximityAlert(latitude, longitude, radius, expiration, mPendingIntent);
   1105     }
   1106 
   1107     /**
   1108      * Blocks until receive intent notification or time out.
   1109      *
   1110      * @throws InterruptedException
   1111      */
   1112     private void waitForReceiveBroadcast() throws InterruptedException {
   1113         synchronized (mIntentReceiver) {
   1114             mIntentReceiver.wait(TEST_TIME_OUT);
   1115         }
   1116     }
   1117 
   1118     /**
   1119      * Asserts that the received intent had the enter proximity property set as
   1120      * expected
   1121      *
   1122      * @param expectedEnterProximity - true if enter proximity expected, false
   1123      *            if exit expected
   1124      */
   1125     private void assertProximityType(boolean expectedEnterProximity) throws Exception {
   1126         Intent intent = mIntentReceiver.getLastReceivedIntent();
   1127         assertNotNull("Did not receive any intent", intent);
   1128         boolean proximityTest = intent.getBooleanExtra(
   1129                 LocationManager.KEY_PROXIMITY_ENTERING, !expectedEnterProximity);
   1130         assertEquals("proximity alert not set to expected enter proximity value",
   1131                 expectedEnterProximity, proximityTest);
   1132     }
   1133 
   1134     private void updateLocation(final String providerName, final double latitude,
   1135             final double longitude) {
   1136         updateLocation(providerName, providerName, latitude, longitude);
   1137     }
   1138 
   1139     /**
   1140      * Like {@link #updateLocation(String, double, double)}, but allows inconsistent providers to be
   1141      * used in the calls to {@link Location#Location(String)} and
   1142      * {@link LocationManager#setTestProviderLocation(String, Location)}.
   1143      */
   1144     private void updateLocation(String testProviderName, String locationProviderName,
   1145         double latitude, double longitude) {
   1146         Location location = new Location(locationProviderName);
   1147         location.setLatitude(latitude);
   1148         location.setLongitude(longitude);
   1149         location.setAccuracy(1.0f);
   1150         location.setTime(System.currentTimeMillis());
   1151         location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
   1152         mManager.setTestProviderLocation(testProviderName, location);
   1153     }
   1154 
   1155     private void updateLocation(final double latitude, final double longitude) {
   1156         updateLocation(TEST_MOCK_PROVIDER_NAME, latitude, longitude);
   1157     }
   1158 
   1159     private void updateFusedLocation(final double latitude, final double longitude) {
   1160       updateLocation(FUSED_PROVIDER_NAME, latitude, longitude);
   1161  }
   1162 
   1163     private Criteria createLocationCriteria() {
   1164         Criteria criteria = new Criteria();
   1165         criteria.setAccuracy(Criteria.ACCURACY_FINE);
   1166         criteria.setPowerRequirement(Criteria.POWER_MEDIUM);
   1167         criteria.setAltitudeRequired(false);
   1168         criteria.setBearingRequired(false);
   1169         criteria.setCostAllowed(false);
   1170         criteria.setSpeedRequired(false);
   1171         return criteria;
   1172      }
   1173 
   1174     private void mockFusedLocation() {
   1175         addTestProvider(FUSED_PROVIDER_NAME);
   1176     }
   1177 
   1178     private void unmockFusedLocation() {
   1179         mManager.removeTestProvider(FUSED_PROVIDER_NAME);
   1180     }
   1181 
   1182     /**
   1183      * Helper class that receives a proximity intent and notifies the main class
   1184      * when received
   1185      */
   1186     private static class TestIntentReceiver extends BroadcastReceiver {
   1187         private String mExpectedAction;
   1188 
   1189         private Intent mLastReceivedIntent;
   1190 
   1191         public TestIntentReceiver(String expectedAction) {
   1192             mExpectedAction = expectedAction;
   1193             mLastReceivedIntent = null;
   1194         }
   1195 
   1196         public IntentFilter getFilter() {
   1197             IntentFilter filter = new IntentFilter(mExpectedAction);
   1198             return filter;
   1199         }
   1200 
   1201         @Override
   1202         public void onReceive(Context context, Intent intent) {
   1203             if (intent != null && mExpectedAction.equals(intent.getAction())) {
   1204                 synchronized (this) {
   1205                     mLastReceivedIntent = intent;
   1206                     notify();
   1207                 }
   1208             }
   1209         }
   1210 
   1211         public Intent getLastReceivedIntent() {
   1212             return mLastReceivedIntent;
   1213         }
   1214 
   1215         public void clearReceivedIntents() {
   1216             mLastReceivedIntent = null;
   1217         }
   1218     }
   1219 
   1220     private static class MockLocationListener implements LocationListener {
   1221         private String mProvider;
   1222         private int mStatus;
   1223         private Location mLocation;
   1224         private Object mStatusLock = new Object();
   1225         private Object mLocationLock = new Object();
   1226         private Object mLocationRequestLock = new Object();
   1227 
   1228         private boolean mHasCalledOnLocationChanged;
   1229 
   1230         private boolean mHasCalledOnProviderDisabled;
   1231 
   1232         private boolean mHasCalledOnProviderEnabled;
   1233 
   1234         private boolean mHasCalledOnStatusChanged;
   1235 
   1236         private boolean mHasCalledRequestLocation;
   1237 
   1238         public void reset(){
   1239             mHasCalledOnLocationChanged = false;
   1240             mHasCalledOnProviderDisabled = false;
   1241             mHasCalledOnProviderEnabled = false;
   1242             mHasCalledOnStatusChanged = false;
   1243             mHasCalledRequestLocation = false;
   1244             mProvider = null;
   1245             mStatus = 0;
   1246         }
   1247 
   1248         /**
   1249          * Call to inform listener that location has been updates have been requested
   1250          */
   1251         public void setLocationRequested() {
   1252             synchronized (mLocationRequestLock) {
   1253                 mHasCalledRequestLocation = true;
   1254                 mLocationRequestLock.notify();
   1255             }
   1256         }
   1257 
   1258         public boolean hasCalledLocationRequested(long timeout) throws InterruptedException {
   1259             synchronized (mLocationRequestLock) {
   1260                 if (timeout > 0 && !mHasCalledRequestLocation) {
   1261                     mLocationRequestLock.wait(timeout);
   1262                 }
   1263             }
   1264             return mHasCalledRequestLocation;
   1265         }
   1266 
   1267         /**
   1268          * Check whether onLocationChanged() has been called. Wait up to timeout milliseconds
   1269          * for the callback.
   1270          * @param timeout Maximum time to wait for the callback, 0 to return immediately.
   1271          */
   1272         public boolean hasCalledOnLocationChanged(long timeout) throws InterruptedException {
   1273             synchronized (mLocationLock) {
   1274                 if (timeout > 0 && !mHasCalledOnLocationChanged) {
   1275                     mLocationLock.wait(timeout);
   1276                 }
   1277             }
   1278             return mHasCalledOnLocationChanged;
   1279         }
   1280 
   1281         public boolean hasCalledOnProviderDisabled() {
   1282             return mHasCalledOnProviderDisabled;
   1283         }
   1284 
   1285         public boolean hasCalledOnProviderEnabled() {
   1286             return mHasCalledOnProviderEnabled;
   1287         }
   1288 
   1289         public boolean hasCalledOnStatusChanged(long timeout) throws InterruptedException {
   1290             synchronized(mStatusLock) {
   1291                 // wait(0) would wait forever
   1292                 if (timeout > 0 && !mHasCalledOnStatusChanged) {
   1293                     mStatusLock.wait(timeout);
   1294                 }
   1295             }
   1296             return mHasCalledOnStatusChanged;
   1297         }
   1298 
   1299         public void onLocationChanged(Location location) {
   1300             mLocation = location;
   1301             synchronized (mLocationLock) {
   1302                 mHasCalledOnLocationChanged = true;
   1303                 mLocationLock.notify();
   1304             }
   1305         }
   1306 
   1307         public void onProviderDisabled(String provider) {
   1308             mHasCalledOnProviderDisabled = true;
   1309         }
   1310 
   1311         public void onProviderEnabled(String provider) {
   1312             mHasCalledOnProviderEnabled = true;
   1313         }
   1314 
   1315         public void onStatusChanged(String provider, int status, Bundle extras) {
   1316             mProvider = provider;
   1317             mStatus = status;
   1318             synchronized (mStatusLock) {
   1319                 mHasCalledOnStatusChanged = true;
   1320                 mStatusLock.notify();
   1321             }
   1322         }
   1323 
   1324         public String getProvider() {
   1325             return mProvider;
   1326         }
   1327 
   1328         public int getStatus() {
   1329             return mStatus;
   1330         }
   1331 
   1332         public Location getLocation() {
   1333             return mLocation;
   1334         }
   1335     }
   1336 
   1337     private static class MockGnssNmeaListener implements OnNmeaMessageListener {
   1338         private boolean mIsNmeaReceived;
   1339 
   1340         @Override
   1341         public void onNmeaMessage(String name, long timestamp) {
   1342             mIsNmeaReceived = true;
   1343         }
   1344 
   1345         public boolean isNmeaRecevied() {
   1346             return mIsNmeaReceived;
   1347         }
   1348 
   1349         public void reset() {
   1350             mIsNmeaReceived = false;
   1351         }
   1352     }
   1353 
   1354     private static class MockGnssStatusCallback extends GnssStatus.Callback {
   1355         @Override
   1356         public void onSatelliteStatusChanged(GnssStatus status) {
   1357             for (int i = 0; i < status.getSatelliteCount(); ++i) {
   1358                 status.getAzimuthDegrees(i);
   1359                 status.getCn0DbHz(i);
   1360                 status.getConstellationType(i);
   1361                 status.getElevationDegrees(i);
   1362                 status.getSvid(i);
   1363                 status.hasAlmanacData(i);
   1364                 status.hasEphemerisData(i);
   1365                 status.usedInFix(i);
   1366             }
   1367         }
   1368     }
   1369 
   1370     private boolean isSystemUser() {
   1371         UserManager userManager = mContext.getSystemService(UserManager.class);
   1372         return userManager.isSystemUser();
   1373     }
   1374 }
   1375