• 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.app.AppOpsManager.OP_FINE_LOCATION;
20 import static android.app.AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION;
21 import static android.app.AppOpsManager.OP_MONITOR_LOCATION;
22 import static android.content.pm.PackageManager.FEATURE_AUTOMOTIVE;
23 import static android.location.LocationManager.GPS_PROVIDER;
24 import static android.location.LocationRequest.PASSIVE_INTERVAL;
25 import static android.location.provider.ProviderProperties.POWER_USAGE_HIGH;
26 import static android.os.PowerManager.LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF;
27 
28 import static androidx.test.ext.truth.location.LocationSubject.assertThat;
29 
30 import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
31 import static com.android.server.location.LocationPermissions.PERMISSION_COARSE;
32 import static com.android.server.location.LocationPermissions.PERMISSION_FINE;
33 import static com.android.server.location.LocationUtils.createLocation;
34 import static com.android.server.location.LocationUtils.createLocationResult;
35 import static com.android.server.location.listeners.RemoteListenerRegistration.IN_PROCESS_EXECUTOR;
36 
37 import static com.google.common.truth.Truth.assertThat;
38 
39 import static org.mockito.ArgumentMatchers.any;
40 import static org.mockito.ArgumentMatchers.anyBoolean;
41 import static org.mockito.ArgumentMatchers.anyInt;
42 import static org.mockito.ArgumentMatchers.anyLong;
43 import static org.mockito.ArgumentMatchers.anyString;
44 import static org.mockito.ArgumentMatchers.eq;
45 import static org.mockito.ArgumentMatchers.isNull;
46 import static org.mockito.ArgumentMatchers.nullable;
47 import static org.mockito.Mockito.after;
48 import static org.mockito.Mockito.doReturn;
49 import static org.mockito.Mockito.inOrder;
50 import static org.mockito.Mockito.mock;
51 import static org.mockito.Mockito.never;
52 import static org.mockito.Mockito.spy;
53 import static org.mockito.Mockito.timeout;
54 import static org.mockito.Mockito.times;
55 import static org.mockito.Mockito.verify;
56 import static org.mockito.Mockito.verifyNoMoreInteractions;
57 import static org.mockito.MockitoAnnotations.initMocks;
58 import static org.testng.Assert.assertThrows;
59 
60 import android.content.Context;
61 import android.content.pm.PackageManager;
62 import android.content.res.Resources;
63 import android.location.ILocationCallback;
64 import android.location.ILocationListener;
65 import android.location.LastLocationRequest;
66 import android.location.Location;
67 import android.location.LocationManagerInternal;
68 import android.location.LocationManagerInternal.ProviderEnabledListener;
69 import android.location.LocationRequest;
70 import android.location.LocationResult;
71 import android.location.provider.IProviderRequestListener;
72 import android.location.provider.ProviderProperties;
73 import android.location.provider.ProviderRequest;
74 import android.location.util.identity.CallerIdentity;
75 import android.os.Bundle;
76 import android.os.ICancellationSignal;
77 import android.os.IRemoteCallback;
78 import android.os.PackageTagsList;
79 import android.os.PowerManager;
80 import android.os.Process;
81 import android.os.RemoteException;
82 import android.os.WorkSource;
83 import android.platform.test.annotations.Presubmit;
84 import android.util.Log;
85 
86 import androidx.test.filters.SmallTest;
87 import androidx.test.runner.AndroidJUnit4;
88 
89 import com.android.internal.R;
90 import com.android.server.FgThread;
91 import com.android.server.LocalServices;
92 import com.android.server.location.injector.FakeUserInfoHelper;
93 import com.android.server.location.injector.TestInjector;
94 
95 import org.junit.After;
96 import org.junit.Before;
97 import org.junit.Test;
98 import org.junit.runner.RunWith;
99 import org.mockito.ArgumentCaptor;
100 import org.mockito.InOrder;
101 import org.mockito.Mock;
102 
103 import java.io.FileDescriptor;
104 import java.io.PrintWriter;
105 import java.util.ArrayList;
106 import java.util.Collections;
107 import java.util.List;
108 import java.util.Random;
109 import java.util.concurrent.CountDownLatch;
110 import java.util.concurrent.TimeUnit;
111 
112 @Presubmit
113 @SmallTest
114 @RunWith(AndroidJUnit4.class)
115 public class LocationProviderManagerTest {
116 
117     private static final String TAG = "LocationProviderManagerTest";
118 
119     private static final long TIMEOUT_MS = 1000;
120 
121     private static final int CURRENT_USER = FakeUserInfoHelper.DEFAULT_USERID;
122     private static final int OTHER_USER = CURRENT_USER + 10;
123 
124     private static final String NAME = "test";
125     private static final ProviderProperties PROPERTIES = new ProviderProperties.Builder()
126             .setHasAltitudeSupport(true)
127             .setHasSpeedSupport(true)
128             .setHasBearingSupport(true)
129             .setPowerUsage(POWER_USAGE_HIGH)
130             .setAccuracy(ProviderProperties.ACCURACY_FINE)
131             .build();
132     private static final CallerIdentity PROVIDER_IDENTITY = CallerIdentity.forTest(CURRENT_USER, 1,
133             "mypackage", "attribution");
134     private static final CallerIdentity IDENTITY = CallerIdentity.forTest(CURRENT_USER, 1,
135             "mypackage", "attribution", "listener");
136     private static final WorkSource WORK_SOURCE = new WorkSource(IDENTITY.getUid());
137 
138     private Random mRandom;
139 
140     @Mock
141     private LocationProviderManager.StateChangedListener mStateChangedListener;
142     @Mock
143     private LocationManagerInternal mInternal;
144     @Mock
145     private Context mContext;
146     @Mock
147     private Resources mResources;
148     @Mock
149     private PackageManager mPackageManager;
150     @Mock
151     private PowerManager mPowerManager;
152     @Mock
153     private PowerManager.WakeLock mWakeLock;
154 
155     private TestInjector mInjector;
156     private PassiveLocationProviderManager mPassive;
157     private TestProvider mProvider;
158 
159     private LocationProviderManager mManager;
160 
161     @Before
setUp()162     public void setUp() {
163         initMocks(this);
164 
165         long seed = System.currentTimeMillis();
166         Log.i(TAG, "location random seed: " + seed);
167 
168         mRandom = new Random(seed);
169 
170         LocalServices.addService(LocationManagerInternal.class, mInternal);
171 
172         doReturn("android").when(mContext).getPackageName();
173         doReturn(mResources).when(mContext).getResources();
174         doReturn(mPackageManager).when(mContext).getPackageManager();
175         doReturn(mPowerManager).when(mContext).getSystemService(PowerManager.class);
176         doReturn(mWakeLock).when(mPowerManager).newWakeLock(anyInt(), anyString());
177 
178         mInjector = new TestInjector(mContext);
179         mInjector.getUserInfoHelper().startUser(OTHER_USER);
180 
181         mPassive = new PassiveLocationProviderManager(mContext, mInjector);
182         mPassive.startManager(null);
183         mPassive.setRealProvider(new PassiveLocationProvider(mContext));
184 
185         createManager(NAME);
186     }
187 
createManager(String name)188     private void createManager(String name) {
189         mStateChangedListener = mock(LocationProviderManager.StateChangedListener.class);
190 
191         mProvider = new TestProvider(PROPERTIES, PROVIDER_IDENTITY);
192         mProvider.setProviderAllowed(true);
193 
194         mManager = new LocationProviderManager(mContext, mInjector, name, mPassive);
195         mManager.startManager(mStateChangedListener);
196         mManager.setRealProvider(mProvider);
197     }
198 
199     @After
tearDown()200     public void tearDown() throws Exception {
201         LocalServices.removeServiceForTest(LocationManagerInternal.class);
202 
203         // some test failures may leave the fg thread stuck, interrupt until we get out of it
204         CountDownLatch latch = new CountDownLatch(1);
205         FgThread.getExecutor().execute(latch::countDown);
206         int count = 0;
207         while (++count < 10 && !latch.await(10, TimeUnit.MILLISECONDS)) {
208             FgThread.get().getLooper().getThread().interrupt();
209         }
210     }
211 
212     @Test
testProperties()213     public void testProperties() {
214         assertThat(mManager.getName()).isEqualTo(NAME);
215         assertThat(mManager.getProperties()).isEqualTo(PROPERTIES);
216         assertThat(mManager.getProviderIdentity()).isEqualTo(IDENTITY);
217         assertThat(mManager.hasProvider()).isTrue();
218 
219         ProviderProperties newProperties = new ProviderProperties.Builder()
220                 .setHasNetworkRequirement(true)
221                 .setHasSatelliteRequirement(true)
222                 .setHasCellRequirement(true)
223                 .setHasMonetaryCost(true)
224                 .setPowerUsage(POWER_USAGE_HIGH)
225                 .setAccuracy(ProviderProperties.ACCURACY_COARSE)
226                 .build();
227         mProvider.setProperties(newProperties);
228         assertThat(mManager.getProperties()).isEqualTo(newProperties);
229 
230         CallerIdentity newIdentity = CallerIdentity.forTest(OTHER_USER, 1, "otherpackage",
231                 "otherattribution");
232         mProvider.setIdentity(newIdentity);
233         assertThat(mManager.getProviderIdentity()).isEqualTo(newIdentity);
234 
235         mManager.setRealProvider(null);
236         assertThat(mManager.hasProvider()).isFalse();
237     }
238 
239     @Test
testStateChangedListener()240     public void testStateChangedListener() {
241         mProvider.setExtraAttributionTags(Collections.singleton("extra"));
242 
243         ArgumentCaptor<AbstractLocationProvider.State> captorOld = ArgumentCaptor.forClass(
244                 AbstractLocationProvider.State.class);
245         ArgumentCaptor<AbstractLocationProvider.State> captorNew = ArgumentCaptor.forClass(
246                 AbstractLocationProvider.State.class);
247         verify(mStateChangedListener, timeout(TIMEOUT_MS).times(2)).onStateChanged(eq(NAME),
248                 captorOld.capture(), captorNew.capture());
249 
250         assertThat(captorOld.getAllValues().get(1).extraAttributionTags).isEmpty();
251         assertThat(captorNew.getAllValues().get(1).extraAttributionTags).containsExactly("extra");
252     }
253 
254     @Test
testRemoveProvider()255     public void testRemoveProvider() {
256         mManager.setRealProvider(null);
257         assertThat(mManager.hasProvider()).isFalse();
258     }
259 
260     @Test
testIsEnabled()261     public void testIsEnabled() {
262         assertThat(mManager.isEnabled(CURRENT_USER)).isTrue();
263         assertThat(mManager.isEnabled(OTHER_USER)).isTrue();
264 
265         mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER);
266         assertThat(mManager.isEnabled(CURRENT_USER)).isFalse();
267         assertThat(mManager.isEnabled(OTHER_USER)).isTrue();
268 
269         mInjector.getSettingsHelper().setLocationEnabled(true, CURRENT_USER);
270         mProvider.setAllowed(false);
271         assertThat(mManager.isEnabled(CURRENT_USER)).isFalse();
272         assertThat(mManager.isEnabled(OTHER_USER)).isFalse();
273 
274         mProvider.setAllowed(true);
275         assertThat(mManager.isEnabled(CURRENT_USER)).isTrue();
276         assertThat(mManager.isEnabled(OTHER_USER)).isTrue();
277     }
278 
279     @Test
testIsEnabledListener()280     public void testIsEnabledListener() {
281         ProviderEnabledListener listener = mock(ProviderEnabledListener.class);
282         mManager.addEnabledListener(listener);
283         verify(listener, never()).onProviderEnabledChanged(anyString(), anyInt(), anyBoolean());
284 
285         mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER);
286         verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, CURRENT_USER,
287                 false);
288 
289         mInjector.getSettingsHelper().setLocationEnabled(true, CURRENT_USER);
290         verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, CURRENT_USER,
291                 true);
292 
293         mProvider.setAllowed(false);
294         verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, CURRENT_USER,
295                 false);
296         verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, OTHER_USER,
297                 false);
298 
299         mProvider.setAllowed(true);
300         verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, CURRENT_USER,
301                 true);
302         verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, OTHER_USER,
303                 true);
304 
305         mManager.removeEnabledListener(listener);
306         mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER);
307         verifyNoMoreInteractions(listener);
308     }
309 
310     @Test
testGetLastLocation_Fine()311     public void testGetLastLocation_Fine() {
312         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
313                 PERMISSION_FINE)).isNull();
314 
315         Location loc = createLocation(NAME, mRandom);
316         mProvider.setProviderLocation(loc);
317         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
318                 PERMISSION_FINE)).isEqualTo(loc);
319     }
320 
321     @Test
testGetLastLocation_Coarse()322     public void testGetLastLocation_Coarse() {
323         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
324                 PERMISSION_FINE)).isNull();
325 
326         Location loc = createLocation(NAME, mRandom);
327         mProvider.setProviderLocation(loc);
328         Location coarse = mManager.getLastLocation(new LastLocationRequest.Builder().build(),
329                 IDENTITY, PERMISSION_COARSE);
330         assertThat(coarse).isNotEqualTo(loc);
331         assertThat(coarse).isNearby(loc, 5000);
332     }
333 
334     @Test
testGetLastLocation_Bypass()335     public void testGetLastLocation_Bypass() {
336         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
337                 new PackageTagsList.Builder().add(
338                         IDENTITY.getPackageName()).build());
339 
340         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
341                 PERMISSION_FINE)).isNull();
342         assertThat(mManager.getLastLocation(
343                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
344                 IDENTITY, PERMISSION_FINE)).isNull();
345 
346         Location loc = createLocation(NAME, mRandom);
347         mProvider.setProviderLocation(loc);
348         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
349                 PERMISSION_FINE)).isEqualTo(loc);
350         assertThat(mManager.getLastLocation(
351                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
352                 IDENTITY, PERMISSION_FINE)).isEqualTo(
353                 loc);
354 
355         mProvider.setProviderAllowed(false);
356         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
357                 PERMISSION_FINE)).isNull();
358         assertThat(mManager.getLastLocation(
359                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
360                 IDENTITY, PERMISSION_FINE)).isEqualTo(
361                 loc);
362 
363         loc = createLocation(NAME, mRandom);
364         mProvider.setProviderLocation(loc);
365         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
366                 PERMISSION_FINE)).isNull();
367         assertThat(mManager.getLastLocation(
368                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
369                 IDENTITY, PERMISSION_FINE)).isEqualTo(
370                 loc);
371 
372         mProvider.setProviderAllowed(true);
373         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
374                 PERMISSION_FINE)).isNull();
375         assertThat(mManager.getLastLocation(
376                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
377                 IDENTITY, PERMISSION_FINE)).isEqualTo(
378                 loc);
379 
380         loc = createLocation(NAME, mRandom);
381         mProvider.setProviderLocation(loc);
382         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
383                 PERMISSION_FINE)).isEqualTo(loc);
384         assertThat(mManager.getLastLocation(
385                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
386                 IDENTITY, PERMISSION_FINE)).isEqualTo(
387                 loc);
388 
389         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
390                 new PackageTagsList.Builder().build());
391         mProvider.setProviderAllowed(false);
392 
393         assertThat(mManager.getLastLocation(
394                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
395                 IDENTITY, PERMISSION_FINE)).isNull();
396     }
397 
398     @Test
testGetLastLocation_ClearOnMockRemoval()399     public void testGetLastLocation_ClearOnMockRemoval() {
400         MockLocationProvider mockProvider = new MockLocationProvider(PROPERTIES, PROVIDER_IDENTITY,
401                 Collections.emptySet());
402         mockProvider.setAllowed(true);
403         mManager.setMockProvider(mockProvider);
404 
405         Location loc = createLocation(NAME, mRandom);
406         mockProvider.setProviderLocation(loc);
407         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
408                 PERMISSION_FINE)).isEqualTo(loc);
409 
410         mManager.setMockProvider(null);
411         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
412                 PERMISSION_FINE)).isNull();
413     }
414 
415     @Test
testInjectLastLocation()416     public void testInjectLastLocation() {
417         Location loc1 = createLocation(NAME, mRandom);
418         mManager.injectLastLocation(loc1, CURRENT_USER);
419 
420         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
421                 PERMISSION_FINE)).isEqualTo(loc1);
422 
423         Location loc2 = createLocation(NAME, mRandom);
424         mManager.injectLastLocation(loc2, CURRENT_USER);
425 
426         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
427                 PERMISSION_FINE)).isEqualTo(loc1);
428     }
429 
430     @Test
testPassive_Listener()431     public void testPassive_Listener() throws Exception {
432         ILocationListener listener = createMockLocationListener();
433         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
434         mPassive.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
435 
436         LocationResult loc = createLocationResult(NAME, mRandom);
437         mProvider.setProviderLocation(loc);
438         verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class));
439     }
440 
441     @Test
testPassive_LastLocation()442     public void testPassive_LastLocation() {
443         Location loc = createLocation(NAME, mRandom);
444         mProvider.setProviderLocation(loc);
445 
446         assertThat(mPassive.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
447                 PERMISSION_FINE)).isEqualTo(loc);
448     }
449 
450     @Test
testRegisterListener()451     public void testRegisterListener() throws Exception {
452         ILocationListener listener = createMockLocationListener();
453         mManager.registerLocationRequest(
454                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
455                 IDENTITY,
456                 PERMISSION_FINE,
457                 listener);
458 
459         LocationResult loc = createLocationResult(NAME, mRandom);
460         mProvider.setProviderLocation(loc);
461         verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class));
462 
463         mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER);
464         verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, false);
465         loc = createLocationResult(NAME, mRandom);
466         mProvider.setProviderLocation(loc);
467         verify(listener, times(1)).onLocationChanged(any(List.class),
468                 nullable(IRemoteCallback.class));
469 
470         mInjector.getSettingsHelper().setLocationEnabled(true, CURRENT_USER);
471         verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, true);
472 
473         mProvider.setAllowed(false);
474         verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, false);
475         loc = createLocationResult(NAME, mRandom);
476         mProvider.setProviderLocation(loc);
477         verify(listener, times(1)).onLocationChanged(any(List.class),
478                 nullable(IRemoteCallback.class));
479 
480         mProvider.setAllowed(true);
481         verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, true);
482 
483         loc = createLocationResult(NAME, mRandom);
484         mProvider.setProviderLocation(loc);
485         verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class));
486     }
487 
488     @Test
testRegisterListener_SameProcess()489     public void testRegisterListener_SameProcess() throws Exception {
490         CallerIdentity identity = CallerIdentity.forTest(CURRENT_USER, Process.myPid(), "mypackage",
491                 "attribution", "listener");
492 
493         ILocationListener listener = createMockLocationListener();
494         mManager.registerLocationRequest(
495                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
496                 identity,
497                 PERMISSION_FINE,
498                 listener);
499 
500         LocationResult loc = createLocationResult(NAME, mRandom);
501         mProvider.setProviderLocation(loc);
502         verify(listener, timeout(TIMEOUT_MS).times(1)).onLocationChanged(eq(loc.asList()),
503                 nullable(IRemoteCallback.class));
504     }
505 
506     @Test
testRegisterListener_Unregister()507     public void testRegisterListener_Unregister() throws Exception {
508         ILocationListener listener = createMockLocationListener();
509         mManager.registerLocationRequest(
510                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
511                 IDENTITY,
512                 PERMISSION_FINE,
513                 listener);
514         mManager.unregisterLocationRequest(listener);
515 
516         mProvider.setProviderLocation(createLocation(NAME, mRandom));
517         verify(listener, never()).onLocationChanged(any(List.class),
518                 nullable(IRemoteCallback.class));
519 
520         mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER);
521         verify(listener, after(TIMEOUT_MS).never()).onProviderEnabledChanged(NAME, false);
522     }
523 
524     @Test
testRegisterListener_Unregister_SameProcess()525     public void testRegisterListener_Unregister_SameProcess() throws Exception {
526         CallerIdentity identity = CallerIdentity.forTest(CURRENT_USER, Process.myPid(), "mypackage",
527                 "attribution", "listener");
528 
529         ILocationListener listener = createMockLocationListener();
530         mManager.registerLocationRequest(
531                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
532                 identity,
533                 PERMISSION_FINE,
534                 listener);
535 
536         CountDownLatch blocker = new CountDownLatch(1);
537         IN_PROCESS_EXECUTOR.execute(() -> {
538             try {
539                 blocker.await();
540             } catch (InterruptedException e) {
541                 // do nothing
542             }
543         });
544 
545         mProvider.setProviderLocation(createLocation(NAME, mRandom));
546         mManager.unregisterLocationRequest(listener);
547         blocker.countDown();
548         verify(listener, after(TIMEOUT_MS).never()).onLocationChanged(any(List.class),
549                 nullable(IRemoteCallback.class));
550     }
551 
552     @Test
testRegisterListener_NumUpdates()553     public void testRegisterListener_NumUpdates() throws Exception {
554         ILocationListener listener = createMockLocationListener();
555         LocationRequest request = new LocationRequest.Builder(0)
556                 .setMaxUpdates(5)
557                 .setWorkSource(WORK_SOURCE)
558                 .build();
559         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
560 
561         mProvider.setProviderLocation(createLocation(NAME, mRandom));
562         mProvider.setProviderLocation(createLocation(NAME, mRandom));
563         mProvider.setProviderLocation(createLocation(NAME, mRandom));
564         mProvider.setProviderLocation(createLocation(NAME, mRandom));
565         mProvider.setProviderLocation(createLocation(NAME, mRandom));
566         mProvider.setProviderLocation(createLocation(NAME, mRandom));
567 
568         verify(listener, times(5)).onLocationChanged(any(List.class),
569                 nullable(IRemoteCallback.class));
570     }
571 
572     @Test
testRegisterListener_ExpiringAlarm()573     public void testRegisterListener_ExpiringAlarm() throws Exception {
574         ILocationListener listener = createMockLocationListener();
575         LocationRequest request = new LocationRequest.Builder(0)
576                 .setDurationMillis(5000)
577                 .setWorkSource(WORK_SOURCE)
578                 .build();
579         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
580 
581         mInjector.getAlarmHelper().incrementAlarmTime(5000);
582         mProvider.setProviderLocation(createLocation(NAME, mRandom));
583         verify(listener, never()).onLocationChanged(any(List.class),
584                 nullable(IRemoteCallback.class));
585     }
586 
587     @Test
testRegisterListener_ExpiringNoAlarm()588     public void testRegisterListener_ExpiringNoAlarm() throws Exception {
589         ILocationListener listener = createMockLocationListener();
590         LocationRequest request = new LocationRequest.Builder(0)
591                 .setDurationMillis(25)
592                 .setWorkSource(WORK_SOURCE)
593                 .build();
594         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
595 
596         Thread.sleep(25);
597 
598         mProvider.setProviderLocation(createLocation(NAME, mRandom));
599         verify(listener, never()).onLocationChanged(any(List.class),
600                 nullable(IRemoteCallback.class));
601     }
602 
603     @Test
testRegisterListener_FastestInterval()604     public void testRegisterListener_FastestInterval() throws Exception {
605         ILocationListener listener = createMockLocationListener();
606         LocationRequest request = new LocationRequest.Builder(5000)
607                 .setMinUpdateIntervalMillis(5000)
608                 .setWorkSource(WORK_SOURCE)
609                 .build();
610         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
611 
612         mProvider.setProviderLocation(createLocation(NAME, mRandom));
613         mProvider.setProviderLocation(createLocation(NAME, mRandom));
614 
615         verify(listener, times(1)).onLocationChanged(
616                 any(List.class), nullable(IRemoteCallback.class));
617     }
618 
619     @Test
testRegisterListener_SmallestDisplacement()620     public void testRegisterListener_SmallestDisplacement() throws Exception {
621         ILocationListener listener = createMockLocationListener();
622         LocationRequest request = new LocationRequest.Builder(5000)
623                 .setMinUpdateDistanceMeters(1f)
624                 .setWorkSource(WORK_SOURCE)
625                 .build();
626         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
627 
628         Location loc = createLocation(NAME, mRandom);
629         mProvider.setProviderLocation(loc);
630         mProvider.setProviderLocation(loc);
631 
632         verify(listener, times(1)).onLocationChanged(
633                 any(List.class), nullable(IRemoteCallback.class));
634     }
635 
636     @Test
testRegisterListener_NoteOpFailure()637     public void testRegisterListener_NoteOpFailure() throws Exception {
638         ILocationListener listener = createMockLocationListener();
639         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
640         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
641 
642         mInjector.getAppOpsHelper().setAppOpAllowed(OP_FINE_LOCATION, IDENTITY.getPackageName(),
643                 false);
644 
645         mProvider.setProviderLocation(createLocation(NAME, mRandom));
646 
647         verify(listener, never()).onLocationChanged(any(List.class),
648                 nullable(IRemoteCallback.class));
649     }
650 
651     @Test
testRegisterListener_Wakelock()652     public void testRegisterListener_Wakelock() throws Exception {
653         CallerIdentity identity = CallerIdentity.forTest(CURRENT_USER, Process.myPid(), "mypackage",
654                 "attribution", "listener");
655 
656         ILocationListener listener = createMockLocationListener();
657         mManager.registerLocationRequest(
658                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
659                 identity,
660                 PERMISSION_FINE,
661                 listener);
662 
663         CountDownLatch blocker = new CountDownLatch(1);
664         IN_PROCESS_EXECUTOR.execute(() -> {
665             try {
666                 blocker.await();
667             } catch (InterruptedException e) {
668                 // do nothing
669             }
670         });
671 
672         mProvider.setProviderLocation(createLocation(NAME, mRandom));
673         verify(mWakeLock).acquire(anyLong());
674         verify(mWakeLock, never()).release();
675 
676         blocker.countDown();
677         verify(listener, timeout(TIMEOUT_MS)).onLocationChanged(any(List.class),
678                 nullable(IRemoteCallback.class));
679         verify(mWakeLock).acquire(anyLong());
680         verify(mWakeLock, timeout(TIMEOUT_MS)).release();
681     }
682 
683     @Test
testRegisterListener_Coarse()684     public void testRegisterListener_Coarse() throws Exception {
685         ILocationListener listener = createMockLocationListener();
686         mManager.registerLocationRequest(
687                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
688                 IDENTITY,
689                 PERMISSION_COARSE,
690                 listener);
691 
692         mProvider.setProviderLocation(createLocation(NAME, mRandom));
693         mProvider.setProviderLocation(createLocation(NAME, mRandom));
694         verify(listener, times(1))
695                 .onLocationChanged(any(List.class), nullable(IRemoteCallback.class));
696     }
697 
698     @Test
testRegisterListener_Coarse_Passive()699     public void testRegisterListener_Coarse_Passive() throws Exception {
700         ILocationListener listener = createMockLocationListener();
701         mManager.registerLocationRequest(
702                 new LocationRequest.Builder(PASSIVE_INTERVAL)
703                         .setMinUpdateIntervalMillis(0)
704                         .setWorkSource(WORK_SOURCE).build(),
705                 IDENTITY,
706                 PERMISSION_COARSE,
707                 listener);
708 
709         mProvider.setProviderLocation(createLocation(NAME, mRandom));
710         mProvider.setProviderLocation(createLocation(NAME, mRandom));
711         verify(listener, times(1))
712                 .onLocationChanged(any(List.class), nullable(IRemoteCallback.class));
713     }
714 
715     @Test
testProviderRequestListener()716     public void testProviderRequestListener() throws Exception {
717         IProviderRequestListener requestListener = mock(IProviderRequestListener.class);
718         mManager.addProviderRequestListener(requestListener);
719 
720         ILocationListener locationListener = createMockLocationListener();
721         LocationRequest request = new LocationRequest.Builder(1).setWorkSource(
722                 WORK_SOURCE).build();
723         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, locationListener);
724 
725         verify(requestListener, timeout(TIMEOUT_MS).times(1)).onProviderRequestChanged(anyString(),
726                 any(ProviderRequest.class));
727 
728         mManager.unregisterLocationRequest(locationListener);
729         mManager.removeProviderRequestListener(requestListener);
730     }
731 
732     @Test
testGetCurrentLocation()733     public void testGetCurrentLocation() throws Exception {
734         ILocationCallback listener = createMockGetCurrentLocationListener();
735         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
736         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
737 
738         Location loc = createLocation(NAME, mRandom);
739         mProvider.setProviderLocation(loc);
740         mProvider.setProviderLocation(createLocation(NAME, mRandom));
741         verify(listener, times(1)).onLocation(loc);
742     }
743 
744     @Test
testGetCurrentLocation_Cancel()745     public void testGetCurrentLocation_Cancel() throws Exception {
746         ILocationCallback listener = createMockGetCurrentLocationListener();
747         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
748         ICancellationSignal cancellationSignal = mManager.getCurrentLocation(request,
749                 IDENTITY, PERMISSION_FINE, listener);
750 
751         cancellationSignal.cancel();
752         mProvider.setProviderLocation(createLocation(NAME, mRandom));
753         verify(listener, never()).onLocation(nullable(Location.class));
754     }
755 
756     @Test
testGetCurrentLocation_ProviderDisabled()757     public void testGetCurrentLocation_ProviderDisabled() throws Exception {
758         ILocationCallback listener = createMockGetCurrentLocationListener();
759         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
760         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
761 
762         mProvider.setProviderAllowed(false);
763         mProvider.setProviderAllowed(true);
764         mProvider.setProviderLocation(createLocation(NAME, mRandom));
765         verify(listener, times(1)).onLocation(isNull());
766     }
767 
768     @Test
testGetCurrentLocation_ProviderAlreadyDisabled()769     public void testGetCurrentLocation_ProviderAlreadyDisabled() throws Exception {
770         mProvider.setProviderAllowed(false);
771 
772         ILocationCallback listener = createMockGetCurrentLocationListener();
773         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
774         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
775 
776         mProvider.setProviderAllowed(true);
777         mProvider.setProviderLocation(createLocation(NAME, mRandom));
778         verify(listener, times(1)).onLocation(isNull());
779     }
780 
781     @Test
testGetCurrentLocation_LastLocation()782     public void testGetCurrentLocation_LastLocation() throws Exception {
783         Location loc = createLocation(NAME, mRandom);
784         mProvider.setProviderLocation(loc);
785 
786         ILocationCallback listener = createMockGetCurrentLocationListener();
787         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
788         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
789         verify(listener, times(1)).onLocation(eq(loc));
790     }
791 
792     @Test
testGetCurrentLocation_Timeout()793     public void testGetCurrentLocation_Timeout() throws Exception {
794         ILocationCallback listener = createMockGetCurrentLocationListener();
795         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
796         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
797 
798         mInjector.getAlarmHelper().incrementAlarmTime(60000);
799         verify(listener, times(1)).onLocation(isNull());
800     }
801 
802     @Test
testFlush()803     public void testFlush() throws Exception {
804         ILocationListener listener = createMockLocationListener();
805         mManager.registerLocationRequest(
806                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
807                 IDENTITY,
808                 PERMISSION_FINE,
809                 listener);
810 
811         mManager.flush(listener, 99);
812 
813         LocationResult loc = createLocationResult(NAME, mRandom);
814         mProvider.setProviderLocation(loc);
815         mProvider.completeFlushes();
816 
817         InOrder inOrder = inOrder(listener);
818         inOrder.verify(listener).onLocationChanged(eq(loc.asList()), any(IRemoteCallback.class));
819         inOrder.verify(listener).onFlushComplete(99);
820     }
821 
822     @Test
testFlush_UnknownKey()823     public void testFlush_UnknownKey() {
824         assertThrows(IllegalArgumentException.class,
825                 () -> mManager.flush(createMockLocationListener(), 0));
826     }
827 
828     @Test
testLocationMonitoring()829     public void testLocationMonitoring() {
830         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
831                 IDENTITY.getPackageName())).isFalse();
832         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
833                 IDENTITY.getPackageName())).isFalse();
834 
835         ILocationListener listener = createMockLocationListener();
836         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
837         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
838 
839         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
840                 IDENTITY.getPackageName())).isTrue();
841         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
842                 IDENTITY.getPackageName())).isTrue();
843 
844         mInjector.getAppForegroundHelper().setAppForeground(IDENTITY.getUid(), false);
845 
846         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
847                 IDENTITY.getPackageName())).isTrue();
848         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
849                 IDENTITY.getPackageName())).isFalse();
850 
851         mManager.unregisterLocationRequest(listener);
852 
853         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
854                 IDENTITY.getPackageName())).isFalse();
855         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
856                 IDENTITY.getPackageName())).isFalse();
857     }
858 
859     @Test
testLocationMonitoring_multipleIdentities()860     public void testLocationMonitoring_multipleIdentities() {
861         CallerIdentity identity1 = CallerIdentity.forTest(CURRENT_USER, 1,
862                 "mypackage", "attribution", "listener1");
863         CallerIdentity identity2 = CallerIdentity.forTest(CURRENT_USER, 1,
864                 "mypackage", "attribution", "listener2");
865 
866         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
867                 IDENTITY.getPackageName())).isFalse();
868         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
869                 IDENTITY.getPackageName())).isFalse();
870 
871         ILocationListener listener1 = createMockLocationListener();
872         LocationRequest request1 = new LocationRequest.Builder(0).setWorkSource(
873                 WORK_SOURCE).build();
874         mManager.registerLocationRequest(request1, identity1, PERMISSION_FINE, listener1);
875 
876         ILocationListener listener2 = createMockLocationListener();
877         LocationRequest request2 = new LocationRequest.Builder(0).setWorkSource(
878                 WORK_SOURCE).build();
879         mManager.registerLocationRequest(request2, identity2, PERMISSION_FINE, listener2);
880 
881         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
882                 "mypackage")).isTrue();
883         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
884                 "mypackage")).isTrue();
885 
886         mManager.unregisterLocationRequest(listener2);
887 
888         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
889                 "mypackage")).isTrue();
890         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
891                 "mypackage")).isTrue();
892 
893         mManager.unregisterLocationRequest(listener1);
894 
895         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
896                 "mypackage")).isFalse();
897         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
898                 "mypackage")).isFalse();
899     }
900 
901     @Test
testProviderRequest()902     public void testProviderRequest() {
903         assertThat(mProvider.getRequest().isActive()).isFalse();
904 
905         ILocationListener listener1 = createMockLocationListener();
906         LocationRequest request1 = new LocationRequest.Builder(5).setWorkSource(
907                 WORK_SOURCE).build();
908         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
909 
910         assertThat(mProvider.getRequest().isActive()).isTrue();
911         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse();
912         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
913         assertThat(mProvider.getRequest().isLowPower()).isFalse();
914         assertThat(mProvider.getRequest().getWorkSource()).isNotNull();
915 
916         ILocationListener listener2 = createMockLocationListener();
917         LocationRequest request2 = new LocationRequest.Builder(1)
918                 .setLowPower(true)
919                 .setWorkSource(WORK_SOURCE)
920                 .build();
921         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
922 
923         assertThat(mProvider.getRequest().isActive()).isTrue();
924         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse();
925         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
926         assertThat(mProvider.getRequest().isLowPower()).isFalse();
927         assertThat(mProvider.getRequest().getWorkSource()).isNotNull();
928 
929         mManager.unregisterLocationRequest(listener1);
930 
931         assertThat(mProvider.getRequest().isActive()).isTrue();
932         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse();
933         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
934         assertThat(mProvider.getRequest().isLowPower()).isTrue();
935         assertThat(mProvider.getRequest().getWorkSource()).isNotNull();
936 
937         mManager.unregisterLocationRequest(listener2);
938 
939         assertThat(mProvider.getRequest().isActive()).isFalse();
940     }
941 
942     @Test
testProviderRequest_DelayedRequest()943     public void testProviderRequest_DelayedRequest() throws Exception {
944         mProvider.setProviderLocation(createLocation(NAME, mRandom));
945 
946         ILocationListener listener1 = createMockLocationListener();
947         LocationRequest request1 = new LocationRequest.Builder(60000)
948                 .setWorkSource(WORK_SOURCE)
949                 .build();
950         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
951 
952         verify(listener1).onLocationChanged(any(List.class),
953                 nullable(IRemoteCallback.class));
954 
955         assertThat(mProvider.getRequest().isActive()).isFalse();
956 
957         mInjector.getAlarmHelper().incrementAlarmTime(60000);
958         assertThat(mProvider.getRequest().isActive()).isTrue();
959         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(60000);
960     }
961 
962     @Test
testProviderRequest_DelayedRequest_Remove()963     public void testProviderRequest_DelayedRequest_Remove() {
964         mProvider.setProviderLocation(createLocation(NAME, mRandom));
965 
966         ILocationListener listener1 = createMockLocationListener();
967         LocationRequest request1 = new LocationRequest.Builder(60000)
968                 .setWorkSource(WORK_SOURCE)
969                 .build();
970         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
971         mManager.unregisterLocationRequest(listener1);
972 
973         mInjector.getAlarmHelper().incrementAlarmTime(60000);
974         assertThat(mProvider.getRequest().isActive()).isFalse();
975     }
976 
977     @Test
testProviderRequest_SpamRequesting()978     public void testProviderRequest_SpamRequesting() {
979         mProvider.setProviderLocation(createLocation(NAME, mRandom));
980 
981         ILocationListener listener1 = createMockLocationListener();
982         LocationRequest request1 = new LocationRequest.Builder(60000)
983                 .setWorkSource(WORK_SOURCE)
984                 .build();
985 
986         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
987         assertThat(mProvider.getRequest().isActive()).isFalse();
988         mManager.unregisterLocationRequest(listener1);
989         assertThat(mProvider.getRequest().isActive()).isFalse();
990         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
991         assertThat(mProvider.getRequest().isActive()).isFalse();
992         mManager.unregisterLocationRequest(listener1);
993         assertThat(mProvider.getRequest().isActive()).isFalse();
994     }
995 
996     @Test
testProviderRequest_BackgroundThrottle()997     public void testProviderRequest_BackgroundThrottle() {
998         ILocationListener listener1 = createMockLocationListener();
999         LocationRequest request1 = new LocationRequest.Builder(5)
1000                 .setWorkSource(WORK_SOURCE)
1001                 .build();
1002         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1003 
1004         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1005 
1006         mInjector.getAppForegroundHelper().setAppForeground(IDENTITY.getUid(), false);
1007         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(
1008                 mInjector.getSettingsHelper().getBackgroundThrottleIntervalMs());
1009     }
1010 
1011     @Test
testProviderRequest_IgnoreLocationSettings()1012     public void testProviderRequest_IgnoreLocationSettings() {
1013         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
1014                 new PackageTagsList.Builder().add(
1015                         IDENTITY.getPackageName()).build());
1016 
1017         ILocationListener listener1 = createMockLocationListener();
1018         LocationRequest request1 = new LocationRequest.Builder(5)
1019                 .setWorkSource(WORK_SOURCE)
1020                 .build();
1021         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1022 
1023         assertThat(mProvider.getRequest().isActive()).isTrue();
1024         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1025         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse();
1026 
1027         ILocationListener listener2 = createMockLocationListener();
1028         LocationRequest request2 = new LocationRequest.Builder(1)
1029                 .setLocationSettingsIgnored(true)
1030                 .setWorkSource(WORK_SOURCE)
1031                 .build();
1032         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
1033 
1034         assertThat(mProvider.getRequest().isActive()).isTrue();
1035         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
1036         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isTrue();
1037     }
1038 
1039     @Test
testProviderRequest_IgnoreLocationSettings_ProviderDisabled()1040     public void testProviderRequest_IgnoreLocationSettings_ProviderDisabled() {
1041         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
1042                 new PackageTagsList.Builder().add(
1043                         IDENTITY.getPackageName()).build());
1044 
1045         ILocationListener listener1 = createMockLocationListener();
1046         LocationRequest request1 = new LocationRequest.Builder(1)
1047                 .setWorkSource(WORK_SOURCE)
1048                 .build();
1049         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1050 
1051         ILocationListener listener2 = createMockLocationListener();
1052         LocationRequest request2 = new LocationRequest.Builder(5)
1053                 .setLocationSettingsIgnored(true)
1054                 .setWorkSource(WORK_SOURCE)
1055                 .build();
1056         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
1057 
1058         mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId());
1059 
1060         assertThat(mProvider.getRequest().isActive()).isTrue();
1061         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1062         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isTrue();
1063     }
1064 
1065     @Test
testProviderRequest_IgnoreLocationSettings_NoAllowlist()1066     public void testProviderRequest_IgnoreLocationSettings_NoAllowlist() {
1067         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
1068                 new PackageTagsList.Builder().add(
1069                         IDENTITY.getPackageName()).build());
1070 
1071         ILocationListener listener = createMockLocationListener();
1072         LocationRequest request = new LocationRequest.Builder(1)
1073                 .setLocationSettingsIgnored(true)
1074                 .setWorkSource(WORK_SOURCE)
1075                 .build();
1076         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
1077 
1078         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
1079                 new PackageTagsList.Builder().build());
1080 
1081         assertThat(mProvider.getRequest().isActive()).isTrue();
1082         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
1083         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse();
1084     }
1085 
1086     @Test
testProviderRequest_BackgroundThrottle_IgnoreLocationSettings()1087     public void testProviderRequest_BackgroundThrottle_IgnoreLocationSettings() {
1088         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
1089                 new PackageTagsList.Builder().add(
1090                         IDENTITY.getPackageName()).build());
1091 
1092         ILocationListener listener1 = createMockLocationListener();
1093         LocationRequest request1 = new LocationRequest.Builder(5)
1094                 .setLocationSettingsIgnored(true)
1095                 .setWorkSource(WORK_SOURCE)
1096                 .build();
1097         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1098 
1099         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1100 
1101         mInjector.getAppForegroundHelper().setAppForeground(IDENTITY.getUid(), false);
1102         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1103     }
1104 
1105     @Test
testProviderRequest_AdasGnssBypass()1106     public void testProviderRequest_AdasGnssBypass() {
1107         doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
1108         doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
1109 
1110         mInjector.getSettingsHelper().setAdasSettingsAllowlist(
1111                 new PackageTagsList.Builder().add(
1112                         IDENTITY.getPackageName()).build());
1113 
1114         createManager(GPS_PROVIDER);
1115 
1116         ILocationListener listener1 = createMockLocationListener();
1117         LocationRequest request1 = new LocationRequest.Builder(5)
1118                 .setWorkSource(WORK_SOURCE)
1119                 .build();
1120         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1121 
1122         assertThat(mProvider.getRequest().isActive()).isTrue();
1123         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1124         assertThat(mProvider.getRequest().isAdasGnssBypass()).isFalse();
1125 
1126         ILocationListener listener2 = createMockLocationListener();
1127         LocationRequest request2 = new LocationRequest.Builder(1)
1128                 .setAdasGnssBypass(true)
1129                 .setWorkSource(WORK_SOURCE)
1130                 .build();
1131         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
1132 
1133         assertThat(mProvider.getRequest().isActive()).isTrue();
1134         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
1135         assertThat(mProvider.getRequest().isAdasGnssBypass()).isTrue();
1136     }
1137 
1138     @Test
testProviderRequest_AdasGnssBypass_ProviderDisabled()1139     public void testProviderRequest_AdasGnssBypass_ProviderDisabled() {
1140         doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
1141         doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
1142 
1143         mInjector.getSettingsHelper().setAdasSettingsAllowlist(
1144                 new PackageTagsList.Builder().add(
1145                         IDENTITY.getPackageName()).build());
1146 
1147         createManager(GPS_PROVIDER);
1148 
1149         ILocationListener listener1 = createMockLocationListener();
1150         LocationRequest request1 = new LocationRequest.Builder(1)
1151                 .setWorkSource(WORK_SOURCE)
1152                 .build();
1153         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1154 
1155         ILocationListener listener2 = createMockLocationListener();
1156         LocationRequest request2 = new LocationRequest.Builder(5)
1157                 .setAdasGnssBypass(true)
1158                 .setWorkSource(WORK_SOURCE)
1159                 .build();
1160         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
1161 
1162         mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId());
1163 
1164         assertThat(mProvider.getRequest().isActive()).isTrue();
1165         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1166         assertThat(mProvider.getRequest().isAdasGnssBypass()).isTrue();
1167     }
1168 
1169     @Test
testProviderRequest_AdasGnssBypass_ProviderDisabled_AdasDisabled()1170     public void testProviderRequest_AdasGnssBypass_ProviderDisabled_AdasDisabled() {
1171         doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
1172         doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
1173 
1174         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
1175                 new PackageTagsList.Builder().add(
1176                         IDENTITY.getPackageName()).build());
1177 
1178         mInjector.getSettingsHelper().setAdasSettingsAllowlist(
1179                 new PackageTagsList.Builder().add(
1180                         IDENTITY.getPackageName()).build());
1181 
1182         createManager(GPS_PROVIDER);
1183 
1184         ILocationListener listener1 = createMockLocationListener();
1185         LocationRequest request1 = new LocationRequest.Builder(5)
1186                 .setLocationSettingsIgnored(true)
1187                 .setWorkSource(WORK_SOURCE)
1188                 .build();
1189         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1190 
1191         ILocationListener listener2 = createMockLocationListener();
1192         LocationRequest request2 = new LocationRequest.Builder(1)
1193                 .setAdasGnssBypass(true)
1194                 .setWorkSource(WORK_SOURCE)
1195                 .build();
1196         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
1197 
1198         mInjector.getLocationSettings().updateUserSettings(IDENTITY.getUserId(),
1199                 settings -> settings.withAdasGnssLocationEnabled(false));
1200         mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId());
1201 
1202         assertThat(mProvider.getRequest().isActive()).isTrue();
1203         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1204         assertThat(mProvider.getRequest().isAdasGnssBypass()).isFalse();
1205     }
1206 
1207     @Test
testProviderRequest_BatterySaver_ScreenOnOff()1208     public void testProviderRequest_BatterySaver_ScreenOnOff() {
1209         mInjector.getLocationPowerSaveModeHelper().setLocationPowerSaveMode(
1210                 LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF);
1211 
1212         ILocationListener listener = createMockLocationListener();
1213         LocationRequest request = new LocationRequest.Builder(5).setWorkSource(WORK_SOURCE).build();
1214         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
1215 
1216         assertThat(mProvider.getRequest().isActive()).isTrue();
1217 
1218         mInjector.getScreenInteractiveHelper().setScreenInteractive(false);
1219         assertThat(mProvider.getRequest().isActive()).isFalse();
1220     }
1221 
createMockLocationListener()1222     private ILocationListener createMockLocationListener() {
1223         return spy(new ILocationListener.Stub() {
1224             @Override
1225             public void onLocationChanged(List<Location> locations,
1226                     IRemoteCallback onCompleteCallback) {
1227                 if (onCompleteCallback != null) {
1228                     try {
1229                         onCompleteCallback.sendResult(null);
1230                     } catch (RemoteException e) {
1231                         e.rethrowFromSystemServer();
1232                     }
1233                 }
1234             }
1235 
1236             @Override
1237             public void onFlushComplete(int requestCode) {
1238             }
1239 
1240             @Override
1241             public void onProviderEnabledChanged(String provider, boolean enabled) {
1242             }
1243         });
1244     }
1245 
1246     private ILocationCallback createMockGetCurrentLocationListener() {
1247         return spy(new ILocationCallback.Stub() {
1248             @Override
1249             public void onLocation(Location location) {
1250             }
1251         });
1252     }
1253 
1254     private static class TestProvider extends AbstractLocationProvider {
1255 
1256         private ProviderRequest mProviderRequest = ProviderRequest.EMPTY_REQUEST;
1257 
1258         private final ArrayList<Runnable> mFlushCallbacks = new ArrayList<>();
1259 
1260         TestProvider(ProviderProperties properties, CallerIdentity identity) {
1261             super(DIRECT_EXECUTOR, identity, properties, Collections.emptySet());
1262         }
1263 
1264         public void setProviderAllowed(boolean allowed) {
1265             setAllowed(allowed);
1266         }
1267 
1268         public void setProviderLocation(Location l) {
1269             reportLocation(LocationResult.create(new Location(l)));
1270         }
1271 
1272         public void setProviderLocation(LocationResult l) {
1273             reportLocation(l);
1274         }
1275 
1276         public void completeFlushes() {
1277             for (Runnable r : mFlushCallbacks) {
1278                 r.run();
1279             }
1280             mFlushCallbacks.clear();
1281         }
1282 
1283         public ProviderRequest getRequest() {
1284             return mProviderRequest;
1285         }
1286 
1287         @Override
1288         public void onSetRequest(ProviderRequest request) {
1289             mProviderRequest = request;
1290         }
1291 
1292         @Override
1293         protected void onFlush(Runnable callback) {
1294             mFlushCallbacks.add(callback);
1295         }
1296 
1297         @Override
1298         protected void onExtraCommand(int uid, int pid, String command, Bundle extras) {
1299         }
1300 
1301         @Override
1302         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1303         }
1304     }
1305 }
1306