• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 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 com.android.server.location.provider;
18 
19 import static android.Manifest.permission.ACCESS_COARSE_LOCATION;
20 import static android.Manifest.permission.ACCESS_FINE_LOCATION;
21 import static android.Manifest.permission.LOCATION_BYPASS;
22 import static android.app.AppOpsManager.OP_FINE_LOCATION;
23 import static android.app.AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION;
24 import static android.app.AppOpsManager.OP_MONITOR_LOCATION;
25 import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
26 import static android.location.LocationManager.GPS_PROVIDER;
27 import static android.location.LocationRequest.PASSIVE_INTERVAL;
28 import static android.location.provider.ProviderProperties.POWER_USAGE_HIGH;
29 import static android.os.PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF;
30 
31 import static androidx.test.ext.truth.location.LocationSubject.assertThat;
32 
33 import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
34 import static com.android.server.location.LocationPermissions.PERMISSION_COARSE;
35 import static com.android.server.location.LocationPermissions.PERMISSION_FINE;
36 import static com.android.server.location.LocationUtils.createLocation;
37 import static com.android.server.location.LocationUtils.createLocationResult;
38 
39 import static com.google.common.truth.Truth.assertThat;
40 
41 import static org.mockito.ArgumentMatchers.any;
42 import static org.mockito.ArgumentMatchers.anyBoolean;
43 import static org.mockito.ArgumentMatchers.anyDouble;
44 import static org.mockito.ArgumentMatchers.anyInt;
45 import static org.mockito.ArgumentMatchers.anyLong;
46 import static org.mockito.ArgumentMatchers.anyString;
47 import static org.mockito.ArgumentMatchers.eq;
48 import static org.mockito.ArgumentMatchers.isNull;
49 import static org.mockito.ArgumentMatchers.nullable;
50 import static org.mockito.Mockito.after;
51 import static org.mockito.Mockito.doReturn;
52 import static org.mockito.Mockito.inOrder;
53 import static org.mockito.Mockito.mock;
54 import static org.mockito.Mockito.never;
55 import static org.mockito.Mockito.spy;
56 import static org.mockito.Mockito.timeout;
57 import static org.mockito.Mockito.times;
58 import static org.mockito.Mockito.verify;
59 import static org.mockito.Mockito.verifyNoMoreInteractions;
60 import static org.mockito.MockitoAnnotations.initMocks;
61 import static org.testng.Assert.assertThrows;
62 
63 import android.content.Context;
64 import android.content.pm.PackageManager;
65 import android.content.res.Resources;
66 import android.location.ILocationCallback;
67 import android.location.ILocationListener;
68 import android.location.LastLocationRequest;
69 import android.location.Location;
70 import android.location.LocationManagerInternal;
71 import android.location.LocationManagerInternal.ProviderEnabledListener;
72 import android.location.LocationRequest;
73 import android.location.LocationResult;
74 import android.location.flags.Flags;
75 import android.location.provider.IProviderRequestListener;
76 import android.location.provider.IS2LevelCallback;
77 import android.location.provider.ProviderProperties;
78 import android.location.provider.ProviderRequest;
79 import android.location.util.identity.CallerIdentity;
80 import android.os.Bundle;
81 import android.os.ICancellationSignal;
82 import android.os.IRemoteCallback;
83 import android.os.PackageTagsList;
84 import android.os.PowerManager;
85 import android.os.Process;
86 import android.os.RemoteException;
87 import android.os.SystemClock;
88 import android.os.WorkSource;
89 import android.platform.test.annotations.Presubmit;
90 import android.platform.test.flag.junit.SetFlagsRule;
91 import android.provider.DeviceConfig;
92 import android.provider.Settings;
93 import android.util.Log;
94 
95 import androidx.test.core.app.ApplicationProvider;
96 import androidx.test.filters.MediumTest;
97 import androidx.test.filters.SmallTest;
98 import androidx.test.runner.AndroidJUnit4;
99 
100 import com.android.internal.R;
101 import com.android.server.FgThread;
102 import com.android.server.LocalServices;
103 import com.android.server.location.fudger.LocationFudgerCache;
104 import com.android.server.location.injector.FakeUserInfoHelper;
105 import com.android.server.location.injector.TestInjector;
106 import com.android.server.location.provider.proxy.ProxyPopulationDensityProvider;
107 
108 import org.junit.After;
109 import org.junit.Before;
110 import org.junit.Rule;
111 import org.junit.Test;
112 import org.junit.runner.RunWith;
113 import org.mockito.ArgumentCaptor;
114 import org.mockito.InOrder;
115 import org.mockito.Mock;
116 
117 import java.io.FileDescriptor;
118 import java.io.PrintWriter;
119 import java.util.ArrayList;
120 import java.util.Collection;
121 import java.util.Collections;
122 import java.util.List;
123 import java.util.Random;
124 import java.util.concurrent.CountDownLatch;
125 import java.util.concurrent.TimeUnit;
126 
127 @Presubmit
128 @SmallTest
129 @RunWith(AndroidJUnit4.class)
130 public class LocationProviderManagerTest {
131 
132     private static final String TAG = "LocationProviderManagerTest";
133 
134     private static final long TIMEOUT_MS = 1000;
135 
136     private static final int CURRENT_USER = FakeUserInfoHelper.DEFAULT_USERID;
137     private static final int OTHER_USER = CURRENT_USER + 10;
138 
139     private static final String NAME = "test";
140     private static final ProviderProperties PROPERTIES = new ProviderProperties.Builder()
141             .setHasAltitudeSupport(true)
142             .setHasSpeedSupport(true)
143             .setHasBearingSupport(true)
144             .setPowerUsage(POWER_USAGE_HIGH)
145             .setAccuracy(ProviderProperties.ACCURACY_FINE)
146             .build();
147     private static final CallerIdentity PROVIDER_IDENTITY = CallerIdentity.forTest(CURRENT_USER, 1,
148             "mypackage", "attribution");
149     private static final CallerIdentity IDENTITY = CallerIdentity.forTest(CURRENT_USER, 1,
150             "mypackage", "attribution", "listener");
151     private static final WorkSource WORK_SOURCE = new WorkSource(IDENTITY.getUid());
152     private static final String MISSING_PERMISSION = "missing_permission";
153 
154     @Rule
155     public final SetFlagsRule mSetFlagsRule = new SetFlagsRule();
156 
157     private Random mRandom;
158 
159     @Mock
160     private LocationProviderManager.StateChangedListener mStateChangedListener;
161     @Mock
162     private LocationManagerInternal mInternal;
163     @Mock
164     private Context mContext;
165     @Mock
166     private Resources mResources;
167     @Mock
168     private PackageManager mPackageManager;
169     @Mock
170     private PowerManager mPowerManager;
171     @Mock
172     private PowerManager.WakeLock mWakeLock;
173 
174     private TestInjector mInjector;
175     private PassiveLocationProviderManager mPassive;
176     private TestProvider mProvider;
177 
178     private LocationProviderManager mManager;
179 
180     @Before
setUp()181     public void setUp() {
182         initMocks(this);
183 
184         long seed = System.currentTimeMillis();
185         Log.i(TAG, "location random seed: " + seed);
186 
187         mRandom = new Random(seed);
188 
189         LocalServices.addService(LocationManagerInternal.class, mInternal);
190 
191         doReturn("android").when(mContext).getPackageName();
192         doReturn(mResources).when(mContext).getResources();
193         doReturn(mPackageManager).when(mContext).getPackageManager();
194         doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class);
195         doReturn(ApplicationProvider.getApplicationContext()).when(
196                 mContext).getApplicationContext();
197         doReturn(mWakeLock).when(mPowerManager).newWakeLock(anyInt(), anyString());
198         doReturn(PackageManager.PERMISSION_DENIED)
199                 .when(mContext)
200                 .checkCallingOrSelfPermission(MISSING_PERMISSION);
201 
202         mInjector = new TestInjector(mContext);
203         mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
204         mInjector.getUserInfoHelper().startUser(OTHER_USER);
205         mInjector.getUserInfoHelper().setUserVisible(OTHER_USER, true);
206 
207         mPassive = new PassiveLocationProviderManager(mContext, mInjector);
208         mPassive.startManager(null);
209         mPassive.setRealProvider(new PassiveLocationProvider(mContext));
210 
211         createManager(NAME);
212     }
213 
createManager(String name)214     private void createManager(String name) {
215         createManager(name, Collections.emptyList());
216     }
217 
createManager(String name, Collection<String> requiredPermissions)218     private void createManager(String name, Collection<String> requiredPermissions) {
219         mStateChangedListener = mock(LocationProviderManager.StateChangedListener.class);
220 
221         mProvider = new TestProvider(PROPERTIES, PROVIDER_IDENTITY);
222         mProvider.setProviderAllowed(true);
223 
224         mManager =
225                 new LocationProviderManager(
226                         mContext, mInjector, name, mPassive, requiredPermissions);
227         mManager.startManager(mStateChangedListener);
228         mManager.setRealProvider(mProvider);
229     }
230 
231     @After
tearDown()232     public void tearDown() throws Exception {
233         DeviceConfig.resetToDefaults(Settings.RESET_MODE_PACKAGE_DEFAULTS,
234                 DeviceConfig.NAMESPACE_LOCATION);
235         LocalServices.removeServiceForTest(LocationManagerInternal.class);
236 
237         // some test failures may leave the fg thread stuck, interrupt until we get out of it
238         CountDownLatch latch = new CountDownLatch(1);
239         FgThread.getExecutor().execute(latch::countDown);
240         int count = 0;
241         while (++count < 10 && !latch.await(10, TimeUnit.MILLISECONDS)) {
242             FgThread.get().getLooper().getThread().interrupt();
243         }
244     }
245 
246     @Test
testProperties()247     public void testProperties() {
248         assertThat(mManager.getName()).isEqualTo(NAME);
249         assertThat(mManager.getProperties()).isEqualTo(PROPERTIES);
250         assertThat(mManager.getProviderIdentity()).isEqualTo(IDENTITY);
251         assertThat(mManager.hasProvider()).isTrue();
252 
253         ProviderProperties newProperties = new ProviderProperties.Builder()
254                 .setHasNetworkRequirement(true)
255                 .setHasSatelliteRequirement(true)
256                 .setHasCellRequirement(true)
257                 .setHasMonetaryCost(true)
258                 .setPowerUsage(POWER_USAGE_HIGH)
259                 .setAccuracy(ProviderProperties.ACCURACY_COARSE)
260                 .build();
261         mProvider.setProperties(newProperties);
262         assertThat(mManager.getProperties()).isEqualTo(newProperties);
263 
264         CallerIdentity newIdentity = CallerIdentity.forTest(OTHER_USER, 1, "otherpackage",
265                 "otherattribution");
266         mProvider.setIdentity(newIdentity);
267         assertThat(mManager.getProviderIdentity()).isEqualTo(newIdentity);
268 
269         mManager.setRealProvider(null);
270         assertThat(mManager.hasProvider()).isFalse();
271     }
272 
273     @Test
testStateChangedListener()274     public void testStateChangedListener() {
275         mProvider.setExtraAttributionTags(Collections.singleton("extra"));
276 
277         ArgumentCaptor<AbstractLocationProvider.State> captorOld = ArgumentCaptor.forClass(
278                 AbstractLocationProvider.State.class);
279         ArgumentCaptor<AbstractLocationProvider.State> captorNew = ArgumentCaptor.forClass(
280                 AbstractLocationProvider.State.class);
281         verify(mStateChangedListener, timeout(TIMEOUT_MS).times(2)).onStateChanged(eq(NAME),
282                 captorOld.capture(), captorNew.capture());
283 
284         assertThat(captorOld.getAllValues().get(1).extraAttributionTags).isEmpty();
285         assertThat(captorNew.getAllValues().get(1).extraAttributionTags).containsExactly("extra");
286     }
287 
288     @Test
testRemoveProvider()289     public void testRemoveProvider() {
290         mManager.setRealProvider(null);
291         assertThat(mManager.hasProvider()).isFalse();
292     }
293 
294     @Test
testIsEnabled()295     public void testIsEnabled() {
296         assertThat(mManager.isEnabled(CURRENT_USER)).isTrue();
297         assertThat(mManager.isEnabled(OTHER_USER)).isTrue();
298 
299         mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER);
300         assertThat(mManager.isEnabled(CURRENT_USER)).isFalse();
301         assertThat(mManager.isEnabled(OTHER_USER)).isTrue();
302 
303         mInjector.getSettingsHelper().setLocationEnabled(true, CURRENT_USER);
304         mProvider.setAllowed(false);
305         assertThat(mManager.isEnabled(CURRENT_USER)).isFalse();
306         assertThat(mManager.isEnabled(OTHER_USER)).isFalse();
307 
308         mProvider.setAllowed(true);
309         assertThat(mManager.isEnabled(CURRENT_USER)).isTrue();
310         assertThat(mManager.isEnabled(OTHER_USER)).isTrue();
311     }
312 
313     @Test
testIsEnabledListener()314     public void testIsEnabledListener() {
315         ProviderEnabledListener listener = mock(ProviderEnabledListener.class);
316         mManager.addEnabledListener(listener);
317         verify(listener, never()).onProviderEnabledChanged(anyString(), anyInt(), anyBoolean());
318 
319         mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER);
320         verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, CURRENT_USER,
321                 false);
322 
323         mInjector.getSettingsHelper().setLocationEnabled(true, CURRENT_USER);
324         verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, CURRENT_USER,
325                 true);
326 
327         mProvider.setAllowed(false);
328         verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, CURRENT_USER,
329                 false);
330         verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, OTHER_USER,
331                 false);
332 
333         mProvider.setAllowed(true);
334         verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, CURRENT_USER,
335                 true);
336         verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, OTHER_USER,
337                 true);
338 
339         mManager.removeEnabledListener(listener);
340         mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER);
341         verifyNoMoreInteractions(listener);
342     }
343 
344     @Test
testGetLastLocation_Fine()345     public void testGetLastLocation_Fine() {
346         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
347                 PERMISSION_FINE)).isNull();
348 
349         Location loc = createLocation(NAME, mRandom);
350         mProvider.setProviderLocation(loc);
351         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
352                 PERMISSION_FINE)).isEqualTo(loc);
353     }
354 
355     @Test
testGetLastLocation_Coarse()356     public void testGetLastLocation_Coarse() {
357         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
358                 PERMISSION_FINE)).isNull();
359 
360         Location loc = createLocation(NAME, mRandom);
361         mProvider.setProviderLocation(loc);
362         Location coarse = mManager.getLastLocation(new LastLocationRequest.Builder().build(),
363                 IDENTITY, PERMISSION_COARSE);
364         assertThat(coarse).isNotEqualTo(loc);
365         assertThat(coarse).isNearby(loc, 5000);
366     }
367 
368     @Test
testGetLastLocation_InvisibleUser()369     public void testGetLastLocation_InvisibleUser() {
370         Location loc = createLocation(NAME, mRandom);
371         mProvider.setProviderLocation(loc);
372 
373         mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
374         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
375                 PERMISSION_FINE)).isNull();
376 
377         mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
378         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
379                 PERMISSION_FINE)).isEqualTo(loc);
380     }
381 
382     @Test
testGetLastLocation_Bypass()383     public void testGetLastLocation_Bypass() {
384         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
385                 new PackageTagsList.Builder().add(
386                         IDENTITY.getPackageName()).build());
387 
388         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
389                 PERMISSION_FINE)).isNull();
390         assertThat(mManager.getLastLocation(
391                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
392                 IDENTITY, PERMISSION_FINE)).isNull();
393 
394         Location loc = createLocation(NAME, mRandom);
395         mProvider.setProviderLocation(loc);
396         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
397                 PERMISSION_FINE)).isEqualTo(loc);
398         assertThat(mManager.getLastLocation(
399                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
400                 IDENTITY, PERMISSION_FINE)).isEqualTo(
401                 loc);
402 
403         mProvider.setProviderAllowed(false);
404         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
405                 PERMISSION_FINE)).isNull();
406         assertThat(mManager.getLastLocation(
407                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
408                 IDENTITY, PERMISSION_FINE)).isEqualTo(
409                 loc);
410 
411         loc = createLocation(NAME, mRandom);
412         mProvider.setProviderLocation(loc);
413         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
414                 PERMISSION_FINE)).isNull();
415         assertThat(mManager.getLastLocation(
416                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
417                 IDENTITY, PERMISSION_FINE)).isEqualTo(
418                 loc);
419 
420         mProvider.setProviderAllowed(true);
421         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
422                 PERMISSION_FINE)).isNull();
423         assertThat(mManager.getLastLocation(
424                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
425                 IDENTITY, PERMISSION_FINE)).isEqualTo(
426                 loc);
427 
428         loc = createLocation(NAME, mRandom);
429         mProvider.setProviderLocation(loc);
430         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
431                 PERMISSION_FINE)).isEqualTo(loc);
432         assertThat(mManager.getLastLocation(
433                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
434                 IDENTITY, PERMISSION_FINE)).isEqualTo(
435                 loc);
436 
437         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
438                 new PackageTagsList.Builder().build());
439         mProvider.setProviderAllowed(false);
440 
441         assertThat(mManager.getLastLocation(
442                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
443                 IDENTITY, PERMISSION_FINE)).isNull();
444     }
445 
446     @Test
testGetLastLocation_ClearOnMockRemoval()447     public void testGetLastLocation_ClearOnMockRemoval() {
448         MockLocationProvider mockProvider = new MockLocationProvider(PROPERTIES, PROVIDER_IDENTITY,
449                 Collections.emptySet());
450         mockProvider.setAllowed(true);
451         mManager.setMockProvider(mockProvider);
452 
453         Location loc = createLocation(NAME, mRandom);
454         mockProvider.setProviderLocation(loc);
455         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
456                 PERMISSION_FINE)).isEqualTo(loc);
457 
458         mManager.setMockProvider(null);
459         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
460                 PERMISSION_FINE)).isNull();
461     }
462 
463     @Test
testInjectLastLocation()464     public void testInjectLastLocation() {
465         Location loc1 = createLocation(NAME, mRandom);
466         mManager.injectLastLocation(loc1, CURRENT_USER);
467 
468         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
469                 PERMISSION_FINE)).isEqualTo(loc1);
470 
471         Location loc2 = createLocation(NAME, mRandom);
472         mManager.injectLastLocation(loc2, CURRENT_USER);
473 
474         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
475                 PERMISSION_FINE)).isEqualTo(loc1);
476     }
477 
478     @Test
testPassive_Listener()479     public void testPassive_Listener() throws Exception {
480         ILocationListener listener = createMockLocationListener();
481         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
482         mPassive.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
483 
484         LocationResult loc = createLocationResult(NAME, mRandom);
485         mProvider.setProviderLocation(loc);
486         verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class));
487     }
488 
489     @Test
testPassive_LastLocation()490     public void testPassive_LastLocation() {
491         Location loc = createLocation(NAME, mRandom);
492         mProvider.setProviderLocation(loc);
493 
494         assertThat(mPassive.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
495                 PERMISSION_FINE)).isEqualTo(loc);
496     }
497 
498     @Test
testRegisterListener()499     public void testRegisterListener() throws Exception {
500         ILocationListener listener = createMockLocationListener();
501         mManager.registerLocationRequest(
502                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
503                 IDENTITY,
504                 PERMISSION_FINE,
505                 listener);
506 
507         LocationResult loc = createLocationResult(NAME, mRandom);
508         mProvider.setProviderLocation(loc);
509         verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class));
510 
511         mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER);
512         verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, false);
513         loc = createLocationResult(NAME, mRandom);
514         mProvider.setProviderLocation(loc);
515         verify(listener, times(1)).onLocationChanged(any(List.class),
516                 nullable(IRemoteCallback.class));
517 
518         mInjector.getSettingsHelper().setLocationEnabled(true, CURRENT_USER);
519         verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, true);
520 
521         mProvider.setAllowed(false);
522         verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, false);
523         loc = createLocationResult(NAME, mRandom);
524         mProvider.setProviderLocation(loc);
525         verify(listener, times(1)).onLocationChanged(any(List.class),
526                 nullable(IRemoteCallback.class));
527 
528         mProvider.setAllowed(true);
529         verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, true);
530 
531         loc = createLocationResult(NAME, mRandom);
532         mProvider.setProviderLocation(loc);
533         verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class));
534     }
535 
536     @Test
testRegisterListener_SameProcess()537     public void testRegisterListener_SameProcess() throws Exception {
538         CallerIdentity identity = CallerIdentity.forTest(CURRENT_USER, Process.myPid(), "mypackage",
539                 "attribution", "listener");
540 
541         ILocationListener listener = createMockLocationListener();
542         mManager.registerLocationRequest(
543                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
544                 identity,
545                 PERMISSION_FINE,
546                 listener);
547 
548         LocationResult loc = createLocationResult(NAME, mRandom);
549         mProvider.setProviderLocation(loc);
550         verify(listener, timeout(TIMEOUT_MS).times(1)).onLocationChanged(eq(loc.asList()),
551                 nullable(IRemoteCallback.class));
552     }
553 
554     @Test
testRegisterListener_Unregister()555     public void testRegisterListener_Unregister() throws Exception {
556         ILocationListener listener = createMockLocationListener();
557         mManager.registerLocationRequest(
558                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
559                 IDENTITY,
560                 PERMISSION_FINE,
561                 listener);
562         mManager.unregisterLocationRequest(listener);
563 
564         mProvider.setProviderLocation(createLocation(NAME, mRandom));
565         verify(listener, never()).onLocationChanged(any(List.class),
566                 nullable(IRemoteCallback.class));
567 
568         mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER);
569         verify(listener, after(TIMEOUT_MS).never()).onProviderEnabledChanged(NAME, false);
570     }
571 
572     @Test
testRegisterListener_Unregister_SameProcess()573     public void testRegisterListener_Unregister_SameProcess() throws Exception {
574         CallerIdentity identity = CallerIdentity.forTest(CURRENT_USER, Process.myPid(), "mypackage",
575                 "attribution", "listener");
576 
577         ILocationListener listener = createMockLocationListener();
578         mManager.registerLocationRequest(
579                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
580                 identity,
581                 PERMISSION_FINE,
582                 listener);
583 
584         CountDownLatch blocker = new CountDownLatch(1);
585         FgThread.getExecutor().execute(() -> {
586             try {
587                 blocker.await();
588             } catch (InterruptedException e) {
589                 // do nothing
590             }
591         });
592 
593         mProvider.setProviderLocation(createLocation(NAME, mRandom));
594         mManager.unregisterLocationRequest(listener);
595         blocker.countDown();
596         verify(listener, after(TIMEOUT_MS).never()).onLocationChanged(any(List.class),
597                 nullable(IRemoteCallback.class));
598     }
599 
600     @Test
testRegisterListener_NumUpdates()601     public void testRegisterListener_NumUpdates() throws Exception {
602         ILocationListener listener = createMockLocationListener();
603         LocationRequest request = new LocationRequest.Builder(0)
604                 .setMaxUpdates(5)
605                 .setWorkSource(WORK_SOURCE)
606                 .build();
607         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
608 
609         mProvider.setProviderLocation(createLocation(NAME, mRandom));
610         mProvider.setProviderLocation(createLocation(NAME, mRandom));
611         mProvider.setProviderLocation(createLocation(NAME, mRandom));
612         mProvider.setProviderLocation(createLocation(NAME, mRandom));
613         mProvider.setProviderLocation(createLocation(NAME, mRandom));
614         mProvider.setProviderLocation(createLocation(NAME, mRandom));
615 
616         verify(listener, times(5)).onLocationChanged(any(List.class),
617                 nullable(IRemoteCallback.class));
618     }
619 
620     @Test
testRegisterListener_InvisibleUser()621     public void testRegisterListener_InvisibleUser() throws Exception {
622         ILocationListener listener = createMockLocationListener();
623         LocationRequest request = new LocationRequest.Builder(0)
624                 .setWorkSource(WORK_SOURCE)
625                 .build();
626         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
627 
628         mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
629         mProvider.setProviderLocation(createLocationResult(NAME, mRandom));
630         verify(listener, never()).onLocationChanged(any(List.class),
631                 nullable(IRemoteCallback.class));
632 
633         mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
634         LocationResult loc = createLocationResult(NAME, mRandom);
635         mProvider.setProviderLocation(loc);
636         verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class));
637     }
638 
639     @Test
testRegisterListener_ExpiringAlarm()640     public void testRegisterListener_ExpiringAlarm() throws Exception {
641         ILocationListener listener = createMockLocationListener();
642         LocationRequest request = new LocationRequest.Builder(0)
643                 .setDurationMillis(5000)
644                 .setWorkSource(WORK_SOURCE)
645                 .build();
646         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
647 
648         mInjector.getAlarmHelper().incrementAlarmTime(5000);
649         mProvider.setProviderLocation(createLocation(NAME, mRandom));
650         verify(listener, never()).onLocationChanged(any(List.class),
651                 nullable(IRemoteCallback.class));
652     }
653 
654     @Test
testRegisterListener_ExpiringNoAlarm()655     public void testRegisterListener_ExpiringNoAlarm() throws Exception {
656         ILocationListener listener = createMockLocationListener();
657         LocationRequest request = new LocationRequest.Builder(0)
658                 .setDurationMillis(25)
659                 .setWorkSource(WORK_SOURCE)
660                 .build();
661         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
662 
663         Thread.sleep(25);
664 
665         mProvider.setProviderLocation(createLocation(NAME, mRandom));
666         verify(listener, never()).onLocationChanged(any(List.class),
667                 nullable(IRemoteCallback.class));
668     }
669 
670     @Test
testRegisterListener_FastestInterval()671     public void testRegisterListener_FastestInterval() throws Exception {
672         ILocationListener listener = createMockLocationListener();
673         LocationRequest request = new LocationRequest.Builder(5000)
674                 .setMinUpdateIntervalMillis(5000)
675                 .setWorkSource(WORK_SOURCE)
676                 .build();
677         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
678 
679         mProvider.setProviderLocation(createLocation(NAME, mRandom));
680         mProvider.setProviderLocation(createLocation(NAME, mRandom));
681 
682         verify(listener, times(1)).onLocationChanged(
683                 any(List.class), nullable(IRemoteCallback.class));
684     }
685 
686     @Test
testRegisterListener_SmallestDisplacement()687     public void testRegisterListener_SmallestDisplacement() throws Exception {
688         ILocationListener listener = createMockLocationListener();
689         LocationRequest request = new LocationRequest.Builder(5000)
690                 .setMinUpdateDistanceMeters(1f)
691                 .setWorkSource(WORK_SOURCE)
692                 .build();
693         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
694 
695         Location loc = createLocation(NAME, mRandom);
696         mProvider.setProviderLocation(loc);
697         mProvider.setProviderLocation(loc);
698 
699         verify(listener, times(1)).onLocationChanged(
700                 any(List.class), nullable(IRemoteCallback.class));
701     }
702 
703     @Test
testRegisterListener_NoteOpFailure()704     public void testRegisterListener_NoteOpFailure() throws Exception {
705         ILocationListener listener = createMockLocationListener();
706         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
707         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
708 
709         mInjector.getAppOpsHelper().setAppOpAllowed(OP_FINE_LOCATION, IDENTITY.getPackageName(),
710                 false);
711 
712         mProvider.setProviderLocation(createLocation(NAME, mRandom));
713 
714         verify(listener, never()).onLocationChanged(any(List.class),
715                 nullable(IRemoteCallback.class));
716     }
717 
718     @Test
testRegisterListener_Wakelock()719     public void testRegisterListener_Wakelock() throws Exception {
720         CallerIdentity identity = CallerIdentity.forTest(CURRENT_USER, Process.myPid(), "mypackage",
721                 "attribution", "listener");
722 
723         ILocationListener listener = createMockLocationListener();
724         mManager.registerLocationRequest(
725                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
726                 identity,
727                 PERMISSION_FINE,
728                 listener);
729 
730         CountDownLatch blocker = new CountDownLatch(1);
731         FgThread.getExecutor().execute(() -> {
732             try {
733                 blocker.await();
734             } catch (InterruptedException e) {
735                 // do nothing
736             }
737         });
738 
739         mProvider.setProviderLocation(createLocation(NAME, mRandom));
740         verify(mWakeLock).acquire(anyLong());
741         verify(mWakeLock, never()).release();
742 
743         blocker.countDown();
744         verify(listener, timeout(TIMEOUT_MS)).onLocationChanged(any(List.class),
745                 nullable(IRemoteCallback.class));
746         verify(mWakeLock).acquire(anyLong());
747         verify(mWakeLock, timeout(TIMEOUT_MS)).release();
748     }
749 
750     @Test
testRegisterListener_Coarse()751     public void testRegisterListener_Coarse() throws Exception {
752         ILocationListener listener = createMockLocationListener();
753         mManager.registerLocationRequest(
754                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
755                 IDENTITY,
756                 PERMISSION_COARSE,
757                 listener);
758 
759         mProvider.setProviderLocation(createLocation(NAME, mRandom));
760         mProvider.setProviderLocation(createLocation(NAME, mRandom));
761         verify(listener, times(1))
762                 .onLocationChanged(any(List.class), nullable(IRemoteCallback.class));
763     }
764 
765     @Test
testRegisterListener_Coarse_Passive()766     public void testRegisterListener_Coarse_Passive() throws Exception {
767         ILocationListener listener = createMockLocationListener();
768         mManager.registerLocationRequest(
769                 new LocationRequest.Builder(PASSIVE_INTERVAL)
770                         .setMinUpdateIntervalMillis(0)
771                         .setWorkSource(WORK_SOURCE).build(),
772                 IDENTITY,
773                 PERMISSION_COARSE,
774                 listener);
775 
776         mProvider.setProviderLocation(createLocation(NAME, mRandom));
777         mProvider.setProviderLocation(createLocation(NAME, mRandom));
778         verify(listener, times(1))
779                 .onLocationChanged(any(List.class), nullable(IRemoteCallback.class));
780     }
781 
782     @Test
testProviderRequestListener()783     public void testProviderRequestListener() throws Exception {
784         IProviderRequestListener requestListener = mock(IProviderRequestListener.class);
785         mManager.addProviderRequestListener(requestListener);
786 
787         ILocationListener locationListener = createMockLocationListener();
788         LocationRequest request = new LocationRequest.Builder(1).setWorkSource(
789                 WORK_SOURCE).build();
790         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, locationListener);
791 
792         verify(requestListener, timeout(TIMEOUT_MS).times(1)).onProviderRequestChanged(anyString(),
793                 any(ProviderRequest.class));
794 
795         mManager.unregisterLocationRequest(locationListener);
796         mManager.removeProviderRequestListener(requestListener);
797     }
798 
799     @Test
testGetCurrentLocation()800     public void testGetCurrentLocation() throws Exception {
801         ILocationCallback listener = createMockGetCurrentLocationListener();
802         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
803         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
804 
805         Location loc = createLocation(NAME, mRandom);
806         mProvider.setProviderLocation(loc);
807         mProvider.setProviderLocation(createLocation(NAME, mRandom));
808         verify(listener, times(1)).onLocation(loc);
809     }
810 
811     @Test
testGetCurrentLocation_Cancel()812     public void testGetCurrentLocation_Cancel() throws Exception {
813         ILocationCallback listener = createMockGetCurrentLocationListener();
814         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
815         ICancellationSignal cancellationSignal = mManager.getCurrentLocation(request,
816                 IDENTITY, PERMISSION_FINE, listener);
817 
818         cancellationSignal.cancel();
819         mProvider.setProviderLocation(createLocation(NAME, mRandom));
820         verify(listener, never()).onLocation(nullable(Location.class));
821     }
822 
823     @Test
testGetCurrentLocation_ProviderDisabled()824     public void testGetCurrentLocation_ProviderDisabled() throws Exception {
825         ILocationCallback listener = createMockGetCurrentLocationListener();
826         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
827         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
828 
829         mProvider.setProviderAllowed(false);
830         mProvider.setProviderAllowed(true);
831         mProvider.setProviderLocation(createLocation(NAME, mRandom));
832         verify(listener, times(1)).onLocation(isNull());
833     }
834 
835     @Test
testGetCurrentLocation_ProviderAlreadyDisabled()836     public void testGetCurrentLocation_ProviderAlreadyDisabled() throws Exception {
837         mProvider.setProviderAllowed(false);
838 
839         ILocationCallback listener = createMockGetCurrentLocationListener();
840         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
841         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
842 
843         mProvider.setProviderAllowed(true);
844         mProvider.setProviderLocation(createLocation(NAME, mRandom));
845         verify(listener, times(1)).onLocation(isNull());
846     }
847 
848     @Test
testGetCurrentLocation_LastLocation()849     public void testGetCurrentLocation_LastLocation() throws Exception {
850         Location loc = createLocation(NAME, mRandom);
851         mProvider.setProviderLocation(loc);
852 
853         ILocationCallback listener = createMockGetCurrentLocationListener();
854         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
855         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
856         verify(listener, times(1)).onLocation(eq(loc));
857     }
858 
859     @Test
testGetCurrentLocation_Timeout()860     public void testGetCurrentLocation_Timeout() throws Exception {
861         ILocationCallback listener = createMockGetCurrentLocationListener();
862         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
863         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
864 
865         mInjector.getAlarmHelper().incrementAlarmTime(60000);
866         verify(listener, times(1)).onLocation(isNull());
867     }
868 
869     @Test
testGetCurrentLocation_InvisibleUser()870     public void testGetCurrentLocation_InvisibleUser() throws Exception {
871         mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
872 
873         ILocationCallback listener = createMockGetCurrentLocationListener();
874         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
875         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
876 
877         verify(listener).onLocation(isNull());
878     }
879 
880     @Test
testFlush()881     public void testFlush() throws Exception {
882         ILocationListener listener = createMockLocationListener();
883         mManager.registerLocationRequest(
884                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
885                 IDENTITY,
886                 PERMISSION_FINE,
887                 listener);
888 
889         mManager.flush(listener, 99);
890 
891         LocationResult loc = createLocationResult(NAME, mRandom);
892         mProvider.setProviderLocation(loc);
893         mProvider.completeFlushes();
894 
895         InOrder inOrder = inOrder(listener);
896         inOrder.verify(listener).onLocationChanged(eq(loc.asList()), any(IRemoteCallback.class));
897         inOrder.verify(listener).onFlushComplete(99);
898     }
899 
900     @Test
testFlush_UnknownKey()901     public void testFlush_UnknownKey() {
902         assertThrows(IllegalArgumentException.class,
903                 () -> mManager.flush(createMockLocationListener(), 0));
904     }
905 
906     @Test
testLocationMonitoring()907     public void testLocationMonitoring() {
908         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
909                 IDENTITY.getPackageName())).isFalse();
910         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
911                 IDENTITY.getPackageName())).isFalse();
912 
913         ILocationListener listener = createMockLocationListener();
914         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
915         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
916 
917         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
918                 IDENTITY.getPackageName())).isTrue();
919         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
920                 IDENTITY.getPackageName())).isTrue();
921 
922         mInjector.getAppForegroundHelper().setAppForeground(IDENTITY.getUid(), false);
923 
924         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
925                 IDENTITY.getPackageName())).isTrue();
926         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
927                 IDENTITY.getPackageName())).isFalse();
928 
929         mManager.unregisterLocationRequest(listener);
930 
931         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
932                 IDENTITY.getPackageName())).isFalse();
933         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
934                 IDENTITY.getPackageName())).isFalse();
935     }
936 
937     @Test
testLocationMonitoring_multipleIdentities()938     public void testLocationMonitoring_multipleIdentities() {
939         CallerIdentity identity1 = CallerIdentity.forTest(CURRENT_USER, 1,
940                 "mypackage", "attribution", "listener1");
941         CallerIdentity identity2 = CallerIdentity.forTest(CURRENT_USER, 1,
942                 "mypackage", "attribution", "listener2");
943 
944         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
945                 IDENTITY.getPackageName())).isFalse();
946         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
947                 IDENTITY.getPackageName())).isFalse();
948 
949         ILocationListener listener1 = createMockLocationListener();
950         LocationRequest request1 = new LocationRequest.Builder(0).setWorkSource(
951                 WORK_SOURCE).build();
952         mManager.registerLocationRequest(request1, identity1, PERMISSION_FINE, listener1);
953 
954         ILocationListener listener2 = createMockLocationListener();
955         LocationRequest request2 = new LocationRequest.Builder(0).setWorkSource(
956                 WORK_SOURCE).build();
957         mManager.registerLocationRequest(request2, identity2, PERMISSION_FINE, listener2);
958 
959         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
960                 "mypackage")).isTrue();
961         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
962                 "mypackage")).isTrue();
963 
964         mManager.unregisterLocationRequest(listener2);
965 
966         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
967                 "mypackage")).isTrue();
968         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
969                 "mypackage")).isTrue();
970 
971         mManager.unregisterLocationRequest(listener1);
972 
973         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
974                 "mypackage")).isFalse();
975         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
976                 "mypackage")).isFalse();
977     }
978 
979     @Test
testProviderRequest()980     public void testProviderRequest() {
981         assertThat(mProvider.getRequest().isActive()).isFalse();
982 
983         ILocationListener listener1 = createMockLocationListener();
984         LocationRequest request1 = new LocationRequest.Builder(5).setWorkSource(
985                 WORK_SOURCE).build();
986         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
987 
988         assertThat(mProvider.getRequest().isActive()).isTrue();
989         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse();
990         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
991         assertThat(mProvider.getRequest().isLowPower()).isFalse();
992         assertThat(mProvider.getRequest().getWorkSource()).isNotNull();
993 
994         ILocationListener listener2 = createMockLocationListener();
995         LocationRequest request2 = new LocationRequest.Builder(1)
996                 .setLowPower(true)
997                 .setWorkSource(WORK_SOURCE)
998                 .build();
999         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
1000 
1001         assertThat(mProvider.getRequest().isActive()).isTrue();
1002         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse();
1003         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
1004         assertThat(mProvider.getRequest().isLowPower()).isFalse();
1005         assertThat(mProvider.getRequest().getWorkSource()).isNotNull();
1006 
1007         mManager.unregisterLocationRequest(listener1);
1008 
1009         assertThat(mProvider.getRequest().isActive()).isTrue();
1010         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse();
1011         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
1012         assertThat(mProvider.getRequest().isLowPower()).isTrue();
1013         assertThat(mProvider.getRequest().getWorkSource()).isNotNull();
1014 
1015         mManager.unregisterLocationRequest(listener2);
1016 
1017         assertThat(mProvider.getRequest().isActive()).isFalse();
1018     }
1019 
1020     @Test
testProviderRequest_DelayedRequest()1021     public void testProviderRequest_DelayedRequest() throws Exception {
1022         mProvider.setProviderLocation(createLocation(NAME, mRandom));
1023 
1024         ILocationListener listener1 = createMockLocationListener();
1025         LocationRequest request1 = new LocationRequest.Builder(60000)
1026                 .setWorkSource(WORK_SOURCE)
1027                 .build();
1028         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1029 
1030         verify(listener1).onLocationChanged(any(List.class),
1031                 nullable(IRemoteCallback.class));
1032 
1033         assertThat(mProvider.getRequest().isActive()).isFalse();
1034 
1035         mInjector.getAlarmHelper().incrementAlarmTime(60000);
1036         assertThat(mProvider.getRequest().isActive()).isTrue();
1037         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(60000);
1038     }
1039 
1040     @Test
testProviderRequest_DelayedRequest_Remove()1041     public void testProviderRequest_DelayedRequest_Remove() {
1042         mProvider.setProviderLocation(createLocation(NAME, mRandom));
1043 
1044         ILocationListener listener1 = createMockLocationListener();
1045         LocationRequest request1 = new LocationRequest.Builder(60000)
1046                 .setWorkSource(WORK_SOURCE)
1047                 .build();
1048         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1049         mManager.unregisterLocationRequest(listener1);
1050 
1051         mInjector.getAlarmHelper().incrementAlarmTime(60000);
1052         assertThat(mProvider.getRequest().isActive()).isFalse();
1053     }
1054 
1055     @Test
testProviderRequest_SpamRequesting()1056     public void testProviderRequest_SpamRequesting() {
1057         mProvider.setProviderLocation(createLocation(NAME, mRandom));
1058 
1059         ILocationListener listener1 = createMockLocationListener();
1060         LocationRequest request1 = new LocationRequest.Builder(60000)
1061                 .setWorkSource(WORK_SOURCE)
1062                 .build();
1063 
1064         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1065         assertThat(mProvider.getRequest().isActive()).isFalse();
1066         mManager.unregisterLocationRequest(listener1);
1067         assertThat(mProvider.getRequest().isActive()).isFalse();
1068         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1069         assertThat(mProvider.getRequest().isActive()).isFalse();
1070         mManager.unregisterLocationRequest(listener1);
1071         assertThat(mProvider.getRequest().isActive()).isFalse();
1072     }
1073 
1074     @Test
testProviderRequest_BackgroundThrottle()1075     public void testProviderRequest_BackgroundThrottle() {
1076         ILocationListener listener1 = createMockLocationListener();
1077         LocationRequest request1 = new LocationRequest.Builder(5)
1078                 .setWorkSource(WORK_SOURCE)
1079                 .build();
1080         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1081 
1082         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1083 
1084         mInjector.getAppForegroundHelper().setAppForeground(IDENTITY.getUid(), false);
1085         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(
1086                 mInjector.getSettingsHelper().getBackgroundThrottleIntervalMs());
1087     }
1088 
1089     @Test
testProviderRequest_InvisibleUser()1090     public void testProviderRequest_InvisibleUser() {
1091         ILocationListener listener = createMockLocationListener();
1092         LocationRequest request = new LocationRequest.Builder(5)
1093                 .setWorkSource(WORK_SOURCE)
1094                 .build();
1095         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
1096 
1097         mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, false);
1098         assertThat(mProvider.getRequest().isActive()).isFalse();
1099 
1100         mInjector.getUserInfoHelper().setUserVisible(CURRENT_USER, true);
1101         assertThat(mProvider.getRequest().isActive()).isTrue();
1102     }
1103 
1104     @Test
testProviderRequest_IgnoreLocationSettings()1105     public void testProviderRequest_IgnoreLocationSettings() {
1106         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
1107                 new PackageTagsList.Builder().add(
1108                         IDENTITY.getPackageName()).build());
1109 
1110         ILocationListener listener1 = createMockLocationListener();
1111         LocationRequest request1 = new LocationRequest.Builder(5)
1112                 .setWorkSource(WORK_SOURCE)
1113                 .build();
1114         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1115 
1116         assertThat(mProvider.getRequest().isActive()).isTrue();
1117         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1118         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse();
1119 
1120         ILocationListener listener2 = createMockLocationListener();
1121         LocationRequest request2 = new LocationRequest.Builder(1)
1122                 .setLocationSettingsIgnored(true)
1123                 .setWorkSource(WORK_SOURCE)
1124                 .build();
1125         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
1126 
1127         assertThat(mProvider.getRequest().isActive()).isTrue();
1128         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
1129         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isTrue();
1130     }
1131 
1132     @Test
testProviderRequest_IgnoreLocationSettings_ProviderDisabled()1133     public void testProviderRequest_IgnoreLocationSettings_ProviderDisabled() {
1134         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
1135                 new PackageTagsList.Builder().add(
1136                         IDENTITY.getPackageName()).build());
1137 
1138         ILocationListener listener1 = createMockLocationListener();
1139         LocationRequest request1 = new LocationRequest.Builder(1)
1140                 .setWorkSource(WORK_SOURCE)
1141                 .build();
1142         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1143 
1144         ILocationListener listener2 = createMockLocationListener();
1145         LocationRequest request2 = new LocationRequest.Builder(5)
1146                 .setLocationSettingsIgnored(true)
1147                 .setWorkSource(WORK_SOURCE)
1148                 .build();
1149         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
1150 
1151         mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId());
1152 
1153         assertThat(mProvider.getRequest().isActive()).isTrue();
1154         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1155         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isTrue();
1156     }
1157 
1158     @Test
testProviderRequest_IgnoreLocationSettings_NoAllowlist()1159     public void testProviderRequest_IgnoreLocationSettings_NoAllowlist() {
1160         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
1161                 new PackageTagsList.Builder().add(
1162                         IDENTITY.getPackageName()).build());
1163 
1164         ILocationListener listener = createMockLocationListener();
1165         LocationRequest request = new LocationRequest.Builder(1)
1166                 .setLocationSettingsIgnored(true)
1167                 .setWorkSource(WORK_SOURCE)
1168                 .build();
1169         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
1170 
1171         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
1172                 new PackageTagsList.Builder().build());
1173 
1174         assertThat(mProvider.getRequest().isActive()).isTrue();
1175         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
1176         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse();
1177     }
1178 
1179     @Test
testProviderRequest_IgnoreLocationSettings_LocationBypass()1180     public void testProviderRequest_IgnoreLocationSettings_LocationBypass() {
1181         mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LOCATION_BYPASS);
1182 
1183         doReturn(PackageManager.PERMISSION_GRANTED)
1184                 .when(mContext)
1185                 .checkPermission(LOCATION_BYPASS, IDENTITY.getPid(), IDENTITY.getUid());
1186         mInjector.getLocationPermissionsHelper()
1187                 .revokePermission(IDENTITY.getPackageName(), ACCESS_FINE_LOCATION);
1188         mInjector.getLocationPermissionsHelper()
1189                 .revokePermission(IDENTITY.getPackageName(), ACCESS_COARSE_LOCATION);
1190         mInjector
1191                 .getSettingsHelper()
1192                 .setIgnoreSettingsAllowlist(
1193                         new PackageTagsList.Builder().add(IDENTITY.getPackageName()).build());
1194 
1195         ILocationListener listener = createMockLocationListener();
1196         LocationRequest request =
1197                 new LocationRequest.Builder(1)
1198                         .setLocationSettingsIgnored(true)
1199                         .setWorkSource(WORK_SOURCE)
1200                         .build();
1201         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
1202 
1203         assertThat(mProvider.getRequest().isActive()).isFalse();
1204     }
1205 
1206     @Test
testProviderRequest_IgnoreLocationSettings_LocationBypass_EmergencyCall()1207     public void testProviderRequest_IgnoreLocationSettings_LocationBypass_EmergencyCall() {
1208         mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_LOCATION_BYPASS);
1209 
1210         doReturn(PackageManager.PERMISSION_GRANTED)
1211                 .when(mContext)
1212                 .checkPermission(LOCATION_BYPASS, IDENTITY.getPid(), IDENTITY.getUid());
1213         mInjector.getLocationPermissionsHelper()
1214                 .revokePermission(IDENTITY.getPackageName(), ACCESS_FINE_LOCATION);
1215         mInjector.getLocationPermissionsHelper()
1216                 .revokePermission(IDENTITY.getPackageName(), ACCESS_COARSE_LOCATION);
1217         mInjector.getEmergencyHelper().setInEmergency(true);
1218         mInjector
1219                 .getSettingsHelper()
1220                 .setIgnoreSettingsAllowlist(
1221                         new PackageTagsList.Builder().add(IDENTITY.getPackageName()).build());
1222 
1223         ILocationListener listener = createMockLocationListener();
1224         LocationRequest request =
1225                 new LocationRequest.Builder(1)
1226                         .setLocationSettingsIgnored(true)
1227                         .setWorkSource(WORK_SOURCE)
1228                         .build();
1229         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
1230 
1231         assertThat(mProvider.getRequest().isActive()).isTrue();
1232         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
1233         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isTrue();
1234     }
1235 
1236     @Test
testProviderRequest_BackgroundThrottle_IgnoreLocationSettings()1237     public void testProviderRequest_BackgroundThrottle_IgnoreLocationSettings() {
1238         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
1239                 new PackageTagsList.Builder().add(
1240                         IDENTITY.getPackageName()).build());
1241 
1242         ILocationListener listener1 = createMockLocationListener();
1243         LocationRequest request1 = new LocationRequest.Builder(5)
1244                 .setLocationSettingsIgnored(true)
1245                 .setWorkSource(WORK_SOURCE)
1246                 .build();
1247         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1248 
1249         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1250 
1251         mInjector.getAppForegroundHelper().setAppForeground(IDENTITY.getUid(), false);
1252         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1253     }
1254 
1255     @Test
testProviderRequest_AdasGnssBypass()1256     public void testProviderRequest_AdasGnssBypass() {
1257         doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
1258         doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
1259 
1260         mInjector.getSettingsHelper().setAdasSettingsAllowlist(
1261                 new PackageTagsList.Builder().add(
1262                         IDENTITY.getPackageName()).build());
1263 
1264         createManager(GPS_PROVIDER);
1265 
1266         ILocationListener listener1 = createMockLocationListener();
1267         LocationRequest request1 = new LocationRequest.Builder(5)
1268                 .setWorkSource(WORK_SOURCE)
1269                 .build();
1270         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1271 
1272         assertThat(mProvider.getRequest().isActive()).isTrue();
1273         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1274         assertThat(mProvider.getRequest().isAdasGnssBypass()).isFalse();
1275 
1276         ILocationListener listener2 = createMockLocationListener();
1277         LocationRequest request2 = new LocationRequest.Builder(1)
1278                 .setAdasGnssBypass(true)
1279                 .setWorkSource(WORK_SOURCE)
1280                 .build();
1281         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
1282 
1283         assertThat(mProvider.getRequest().isActive()).isTrue();
1284         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
1285         assertThat(mProvider.getRequest().isAdasGnssBypass()).isTrue();
1286     }
1287 
1288     @Test
testProviderRequest_AdasGnssBypass_ProviderDisabled()1289     public void testProviderRequest_AdasGnssBypass_ProviderDisabled() {
1290         doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
1291         doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
1292 
1293         mInjector.getSettingsHelper().setAdasSettingsAllowlist(
1294                 new PackageTagsList.Builder().add(
1295                         IDENTITY.getPackageName()).build());
1296 
1297         createManager(GPS_PROVIDER);
1298 
1299         ILocationListener listener1 = createMockLocationListener();
1300         LocationRequest request1 = new LocationRequest.Builder(1)
1301                 .setWorkSource(WORK_SOURCE)
1302                 .build();
1303         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1304 
1305         ILocationListener listener2 = createMockLocationListener();
1306         LocationRequest request2 = new LocationRequest.Builder(5)
1307                 .setAdasGnssBypass(true)
1308                 .setWorkSource(WORK_SOURCE)
1309                 .build();
1310         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
1311 
1312         mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId());
1313 
1314         assertThat(mProvider.getRequest().isActive()).isTrue();
1315         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1316         assertThat(mProvider.getRequest().isAdasGnssBypass()).isTrue();
1317     }
1318 
1319     @Test
testProviderRequest_AdasGnssBypass_ProviderDisabled_AdasDisabled()1320     public void testProviderRequest_AdasGnssBypass_ProviderDisabled_AdasDisabled() {
1321         doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
1322         doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
1323 
1324         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
1325                 new PackageTagsList.Builder().add(
1326                         IDENTITY.getPackageName()).build());
1327 
1328         mInjector.getSettingsHelper().setAdasSettingsAllowlist(
1329                 new PackageTagsList.Builder().add(
1330                         IDENTITY.getPackageName()).build());
1331 
1332         createManager(GPS_PROVIDER);
1333 
1334         ILocationListener listener1 = createMockLocationListener();
1335         LocationRequest request1 = new LocationRequest.Builder(5)
1336                 .setLocationSettingsIgnored(true)
1337                 .setWorkSource(WORK_SOURCE)
1338                 .build();
1339         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1340 
1341         ILocationListener listener2 = createMockLocationListener();
1342         LocationRequest request2 = new LocationRequest.Builder(1)
1343                 .setAdasGnssBypass(true)
1344                 .setWorkSource(WORK_SOURCE)
1345                 .build();
1346         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
1347 
1348         mInjector.getLocationSettings().updateUserSettings(IDENTITY.getUserId(),
1349                 settings -> settings.withAdasGnssLocationEnabled(false));
1350         mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId());
1351 
1352         assertThat(mProvider.getRequest().isActive()).isTrue();
1353         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1354         assertThat(mProvider.getRequest().isAdasGnssBypass()).isFalse();
1355     }
1356 
1357     @Test
testProviderRequest_BatterySaver_ScreenOnOff()1358     public void testProviderRequest_BatterySaver_ScreenOnOff() {
1359         mInjector.getLocationPowerSaveModeHelper().setLocationPowerSaveMode(
1360                 LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF);
1361 
1362         ILocationListener listener = createMockLocationListener();
1363         LocationRequest request = new LocationRequest.Builder(5).setWorkSource(WORK_SOURCE).build();
1364         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
1365 
1366         assertThat(mProvider.getRequest().isActive()).isTrue();
1367 
1368         mInjector.getScreenInteractiveHelper().setScreenInteractive(false);
1369         assertThat(mProvider.getRequest().isActive()).isFalse();
1370     }
1371 
1372     @Test
testQueryPackageReset()1373     public void testQueryPackageReset() {
1374         assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isFalse();
1375 
1376         ILocationListener listener1 = createMockLocationListener();
1377         mManager.registerLocationRequest(new LocationRequest.Builder(0).setWorkSource(
1378                 WORK_SOURCE).build(), IDENTITY, PERMISSION_FINE, listener1);
1379         assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isTrue();
1380 
1381         ILocationListener listener2 = createMockLocationListener();
1382         mManager.registerLocationRequest(new LocationRequest.Builder(0).setWorkSource(
1383                 WORK_SOURCE).build(), IDENTITY, PERMISSION_FINE, listener2);
1384         assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isTrue();
1385 
1386         mManager.unregisterLocationRequest(listener1);
1387         assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isTrue();
1388 
1389         mManager.unregisterLocationRequest(listener2);
1390         assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isFalse();
1391     }
1392 
1393     @Test
testPackageReset()1394     public void testPackageReset() {
1395         ILocationListener listener1 = createMockLocationListener();
1396         mManager.registerLocationRequest(new LocationRequest.Builder(0).setWorkSource(
1397                 WORK_SOURCE).build(), IDENTITY, PERMISSION_FINE, listener1);
1398         ILocationListener listener2 = createMockLocationListener();
1399         mManager.registerLocationRequest(new LocationRequest.Builder(0).setWorkSource(
1400                 WORK_SOURCE).build(), IDENTITY, PERMISSION_FINE, listener2);
1401 
1402         assertThat(mProvider.getRequest().isActive()).isTrue();
1403         assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isTrue();
1404 
1405         mInjector.getPackageResetHelper().reset("mypackage");
1406         assertThat(mProvider.getRequest().isActive()).isFalse();
1407         assertThat(mInjector.getPackageResetHelper().isResetableForPackage("mypackage")).isFalse();
1408     }
1409 
1410     @Test
testIsVisibleToCaller()1411     public void testIsVisibleToCaller() {
1412         assertThat(mManager.isVisibleToCaller()).isTrue();
1413     }
1414 
1415     @Test
testIsVisibleToCaller_noPermissions()1416     public void testIsVisibleToCaller_noPermissions() {
1417         createManager("any_name", Collections.singletonList(MISSING_PERMISSION));
1418         assertThat(mManager.isVisibleToCaller()).isFalse();
1419     }
1420 
1421     @Test
testValidateLocation_futureLocation()1422     public void testValidateLocation_futureLocation() {
1423         mSetFlagsRule.enableFlags(Flags.FLAG_LOCATION_VALIDATION);
1424         Location location = createLocation(NAME, mRandom);
1425         mProvider.setProviderLocation(location);
1426 
1427         assertThat(mPassive.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
1428                 PERMISSION_FINE)).isEqualTo(location);
1429 
1430         Location futureLocation = createLocation(NAME, mRandom);
1431         futureLocation.setElapsedRealtimeNanos(
1432                 SystemClock.elapsedRealtimeNanos() + TimeUnit.SECONDS.toNanos(2));
1433         mProvider.setProviderLocation(futureLocation);
1434 
1435         assertThat(mPassive.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
1436                 PERMISSION_FINE)).isEqualTo(location);
1437     }
1438 
1439     @Test
testLocationFudger_withFlagDisabled_cacheIsNotSetAndOldAlgoIsUsed()1440     public void testLocationFudger_withFlagDisabled_cacheIsNotSetAndOldAlgoIsUsed() {
1441         mSetFlagsRule.disableFlags(Flags.FLAG_DENSITY_BASED_COARSE_LOCATIONS);
1442         createManager("some-name");
1443         ProxyPopulationDensityProvider provider = mock(ProxyPopulationDensityProvider.class);
1444         LocationFudgerCache cache = new LocationFudgerCache(provider);
1445 
1446         mManager.setLocationFudgerCache(cache);
1447 
1448         Location test = new Location("any-provider");
1449         mManager.getPermittedLocation(test, PERMISSION_COARSE);
1450 
1451         verify(provider, never()).getCoarsenedS2Cells(anyDouble(), anyDouble(), anyInt(), any());
1452     }
1453 
1454     @Test
testLocationFudger_withFlagEnabledButNoDefaults_oldAlgoIsUsed()1455     public void testLocationFudger_withFlagEnabledButNoDefaults_oldAlgoIsUsed()
1456             throws RemoteException {
1457         mSetFlagsRule.enableFlags(Flags.FLAG_DENSITY_BASED_COARSE_LOCATIONS);
1458         createManager("some-other-name");
1459         ProxyPopulationDensityProvider provider = mock(ProxyPopulationDensityProvider.class);
1460         LocationFudgerCache cache = new LocationFudgerCache(provider);
1461 
1462         mManager.setLocationFudgerCache(cache);
1463 
1464         ArgumentCaptor<IS2LevelCallback> captor = ArgumentCaptor.forClass(IS2LevelCallback.class);
1465         verify(provider).getDefaultCoarseningLevel(captor.capture());
1466 
1467         IS2LevelCallback cb = captor.getValue();
1468 
1469         // Act: the provider didn't provide a default
1470         cb.onError();
1471 
1472         Location test = new Location("any-provider");
1473         mManager.getPermittedLocation(test, PERMISSION_COARSE);
1474 
1475         verify(provider, never()).getCoarsenedS2Cells(anyDouble(), anyDouble(), anyInt(), any());
1476     }
1477 
1478     @Test
testLocationFudger_withFlagEnabled_cacheIsSetAndNewAlgoIsUsed()1479     public void testLocationFudger_withFlagEnabled_cacheIsSetAndNewAlgoIsUsed()
1480             throws RemoteException {
1481         mSetFlagsRule.enableFlags(Flags.FLAG_DENSITY_BASED_COARSE_LOCATIONS);
1482         createManager("some-other-name");
1483         ProxyPopulationDensityProvider provider = mock(ProxyPopulationDensityProvider.class);
1484         LocationFudgerCache cache = new LocationFudgerCache(provider);
1485         int defaultLevel = 2;
1486 
1487         mManager.setLocationFudgerCache(cache);
1488 
1489         ArgumentCaptor<IS2LevelCallback> captor = ArgumentCaptor.forClass(IS2LevelCallback.class);
1490         verify(provider).getDefaultCoarseningLevel(captor.capture());
1491 
1492         IS2LevelCallback cb = captor.getValue();
1493         cb.onResult(defaultLevel);
1494 
1495         Location test = new Location("any-provider");
1496         test.setLatitude(10.0);
1497         test.setLongitude(20.0);
1498         mManager.getPermittedLocation(test, PERMISSION_COARSE);
1499 
1500         // We can't test that 10.0, 20.0 was passed due to the offset. We only test that a call
1501         // happened.
1502         verify(provider).getCoarsenedS2Cells(anyDouble(), anyDouble(), anyInt(), any());
1503     }
1504 
1505     @MediumTest
1506     @Test
testEnableMsl_expectedBehavior()1507     public void testEnableMsl_expectedBehavior() throws Exception {
1508         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LOCATION,
1509                 "enable_location_provider_manager_msl", Boolean.toString(true), false);
1510 
1511         // Create a random location and set provider location to cache necessary MSL assets.
1512         Location loc = createLocation(NAME, mRandom);
1513         loc.setAltitude(mRandom.nextDouble());
1514         loc.setVerticalAccuracyMeters(mRandom.nextFloat());
1515         mProvider.setProviderLocation(LocationResult.wrap(loc));
1516         Thread.sleep(1000);
1517 
1518         // Register listener and reset provider location to capture.
1519         ILocationListener listener = createMockLocationListener();
1520         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
1521         mPassive.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
1522         mProvider.setProviderLocation(LocationResult.wrap(loc));
1523         ArgumentCaptor<List<Location>> captor = ArgumentCaptor.forClass(List.class);
1524         verify(listener).onLocationChanged(captor.capture(), nullable(IRemoteCallback.class));
1525 
1526         // Assert that MSL fields are populated.
1527         Location actual = captor.getValue().get(0);
1528         assertThat(actual.hasMslAltitude()).isTrue();
1529         assertThat(actual.hasMslAltitudeAccuracy()).isTrue();
1530     }
1531 
1532     @MediumTest
1533     @Test
testEnableMsl_noVerticalAccuracy()1534     public void testEnableMsl_noVerticalAccuracy() throws Exception {
1535         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LOCATION,
1536                 "enable_location_provider_manager_msl", Boolean.toString(true), false);
1537 
1538         // Create a random location and set provider location to cache necessary MSL assets.
1539         Location loc = createLocation(NAME, mRandom);
1540         loc.setAltitude(mRandom.nextDouble());
1541         loc.setVerticalAccuracyMeters(mRandom.nextFloat());
1542         mProvider.setProviderLocation(LocationResult.wrap(loc));
1543         Thread.sleep(1000);
1544 
1545         // Register listener and reset provider location with no vertical accuracy to capture.
1546         ILocationListener listener = createMockLocationListener();
1547         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
1548         mPassive.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
1549         loc.removeVerticalAccuracy();
1550         mProvider.setProviderLocation(LocationResult.wrap(loc));
1551         ArgumentCaptor<List<Location>> captor = ArgumentCaptor.forClass(List.class);
1552         verify(listener).onLocationChanged(captor.capture(), nullable(IRemoteCallback.class));
1553 
1554         // Assert that only the MSL accuracy field is populated.
1555         Location actual = captor.getValue().get(0);
1556         assertThat(actual.hasMslAltitude()).isTrue();
1557         assertThat(actual.hasMslAltitudeAccuracy()).isFalse();
1558     }
1559 
1560     @MediumTest
1561     @Test
testEnableMsl_noAltitude()1562     public void testEnableMsl_noAltitude() throws Exception {
1563         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LOCATION,
1564                 "enable_location_provider_manager_msl", Boolean.toString(true), false);
1565 
1566         // Create a random location and set provider location to cache necessary MSL assets.
1567         Location loc = createLocation(NAME, mRandom);
1568         loc.setAltitude(mRandom.nextDouble());
1569         loc.setVerticalAccuracyMeters(mRandom.nextFloat());
1570         mProvider.setProviderLocation(LocationResult.wrap(loc));
1571         Thread.sleep(1000);
1572 
1573         // Register listener and reset provider location with no altitude to capture.
1574         ILocationListener listener = createMockLocationListener();
1575         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
1576         mPassive.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
1577         loc.removeAltitude();
1578         mProvider.setProviderLocation(LocationResult.wrap(loc));
1579         ArgumentCaptor<List<Location>> captor = ArgumentCaptor.forClass(List.class);
1580         verify(listener).onLocationChanged(captor.capture(), nullable(IRemoteCallback.class));
1581 
1582         // Assert that no MSL fields are populated.
1583         Location actual = captor.getValue().get(0);
1584         assertThat(actual.hasMslAltitude()).isFalse();
1585         assertThat(actual.hasMslAltitudeAccuracy()).isFalse();
1586     }
1587 
1588     @MediumTest
1589     @Test
testEnableMsl_invalidAltitude()1590     public void testEnableMsl_invalidAltitude() throws Exception {
1591         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LOCATION,
1592                 "enable_location_provider_manager_msl", Boolean.toString(true), false);
1593 
1594         // Create a random location and set provider location to cache necessary MSL assets.
1595         Location loc = createLocation(NAME, mRandom);
1596         loc.setAltitude(mRandom.nextDouble());
1597         loc.setVerticalAccuracyMeters(mRandom.nextFloat());
1598         mProvider.setProviderLocation(LocationResult.wrap(loc));
1599         Thread.sleep(1000);
1600 
1601         // Register listener and reset provider location with invalid altitude to capture.
1602         ILocationListener listener = createMockLocationListener();
1603         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
1604         mPassive.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
1605         loc.setAltitude(Double.POSITIVE_INFINITY);
1606         mProvider.setProviderLocation(LocationResult.wrap(loc));
1607         ArgumentCaptor<List<Location>> captor = ArgumentCaptor.forClass(List.class);
1608         verify(listener).onLocationChanged(captor.capture(), nullable(IRemoteCallback.class));
1609 
1610         // Assert that no MSL fields are populated.
1611         Location actual = captor.getValue().get(0);
1612         assertThat(actual.hasMslAltitude()).isFalse();
1613         assertThat(actual.hasMslAltitudeAccuracy()).isFalse();
1614     }
1615 
1616     @MediumTest
1617     @Test
testDisableMsl_expectedBehavior()1618     public void testDisableMsl_expectedBehavior() throws Exception {
1619         DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LOCATION,
1620                 "enable_location_provider_manager_msl", Boolean.toString(false), false);
1621 
1622         // Create a random location and set provider location to cache necessary MSL assets.
1623         Location loc = createLocation(NAME, mRandom);
1624         loc.setAltitude(mRandom.nextDouble());
1625         loc.setVerticalAccuracyMeters(mRandom.nextFloat());
1626         mProvider.setProviderLocation(LocationResult.wrap(loc));
1627         Thread.sleep(1000);
1628 
1629         // Register listener and reset provider location to capture.
1630         ILocationListener listener = createMockLocationListener();
1631         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
1632         mPassive.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
1633         mProvider.setProviderLocation(LocationResult.wrap(loc));
1634         ArgumentCaptor<List<Location>> captor = ArgumentCaptor.forClass(List.class);
1635         verify(listener).onLocationChanged(captor.capture(), nullable(IRemoteCallback.class));
1636 
1637         // Assert that no MSL fields are populated.
1638         Location actual = captor.getValue().get(0);
1639         assertThat(actual.hasMslAltitude()).isFalse();
1640         assertThat(actual.hasMslAltitudeAccuracy()).isFalse();
1641     }
1642 
createMockLocationListener()1643     private ILocationListener createMockLocationListener() {
1644         return spy(new ILocationListener.Stub() {
1645             @Override
1646             public void onLocationChanged(List<Location> locations,
1647                     IRemoteCallback onCompleteCallback) {
1648                 if (onCompleteCallback != null) {
1649                     try {
1650                         onCompleteCallback.sendResult(null);
1651                     } catch (RemoteException e) {
1652                         e.rethrowFromSystemServer();
1653                     }
1654                 }
1655             }
1656 
1657             @Override
1658             public void onFlushComplete(int requestCode) {
1659             }
1660 
1661             @Override
1662             public void onProviderEnabledChanged(String provider, boolean enabled) {
1663             }
1664         });
1665     }
1666 
1667     private ILocationCallback createMockGetCurrentLocationListener() {
1668         return spy(new ILocationCallback.Stub() {
1669             @Override
1670             public void onLocation(Location location) {
1671             }
1672         });
1673     }
1674 
1675     private static class TestProvider extends AbstractLocationProvider {
1676 
1677         private ProviderRequest mProviderRequest = ProviderRequest.EMPTY_REQUEST;
1678 
1679         private final ArrayList<Runnable> mFlushCallbacks = new ArrayList<>();
1680 
1681         TestProvider(ProviderProperties properties, CallerIdentity identity) {
1682             super(DIRECT_EXECUTOR, identity, properties, Collections.emptySet());
1683         }
1684 
1685         public void setProviderAllowed(boolean allowed) {
1686             setAllowed(allowed);
1687         }
1688 
1689         public void setProviderLocation(Location l) {
1690             reportLocation(LocationResult.create(new Location(l)));
1691         }
1692 
1693         public void setProviderLocation(LocationResult l) {
1694             reportLocation(l);
1695         }
1696 
1697         public void completeFlushes() {
1698             for (Runnable r : mFlushCallbacks) {
1699                 r.run();
1700             }
1701             mFlushCallbacks.clear();
1702         }
1703 
1704         public ProviderRequest getRequest() {
1705             return mProviderRequest;
1706         }
1707 
1708         @Override
1709         public void onSetRequest(ProviderRequest request) {
1710             mProviderRequest = request;
1711         }
1712 
1713         @Override
1714         protected void onFlush(Runnable callback) {
1715             mFlushCallbacks.add(callback);
1716         }
1717 
1718         @Override
1719         protected void onExtraCommand(int uid, int pid, String command, Bundle extras) {
1720         }
1721 
1722         @Override
1723         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1724         }
1725     }
1726 }
1727