• 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.getIdentity()).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.getIdentity()).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         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
337                 PERMISSION_FINE)).isNull();
338         assertThat(mManager.getLastLocation(
339                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
340                 IDENTITY, PERMISSION_FINE)).isNull();
341 
342         Location loc = createLocation(NAME, mRandom);
343         mProvider.setProviderLocation(loc);
344         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
345                 PERMISSION_FINE)).isEqualTo(loc);
346         assertThat(mManager.getLastLocation(
347                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
348                 IDENTITY, PERMISSION_FINE)).isEqualTo(
349                 loc);
350 
351         mProvider.setProviderAllowed(false);
352         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
353                 PERMISSION_FINE)).isNull();
354         assertThat(mManager.getLastLocation(
355                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
356                 IDENTITY, PERMISSION_FINE)).isEqualTo(
357                 loc);
358 
359         loc = createLocation(NAME, mRandom);
360         mProvider.setProviderLocation(loc);
361         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
362                 PERMISSION_FINE)).isNull();
363         assertThat(mManager.getLastLocation(
364                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
365                 IDENTITY, PERMISSION_FINE)).isEqualTo(
366                 loc);
367 
368         mProvider.setProviderAllowed(true);
369         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
370                 PERMISSION_FINE)).isNull();
371         assertThat(mManager.getLastLocation(
372                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
373                 IDENTITY, PERMISSION_FINE)).isEqualTo(
374                 loc);
375 
376         loc = createLocation(NAME, mRandom);
377         mProvider.setProviderLocation(loc);
378         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
379                 PERMISSION_FINE)).isEqualTo(loc);
380         assertThat(mManager.getLastLocation(
381                 new LastLocationRequest.Builder().setLocationSettingsIgnored(true).build(),
382                 IDENTITY, PERMISSION_FINE)).isEqualTo(
383                 loc);
384     }
385 
386     @Test
testGetLastLocation_ClearOnMockRemoval()387     public void testGetLastLocation_ClearOnMockRemoval() {
388         MockLocationProvider mockProvider = new MockLocationProvider(PROPERTIES, PROVIDER_IDENTITY,
389                 Collections.emptySet());
390         mockProvider.setAllowed(true);
391         mManager.setMockProvider(mockProvider);
392 
393         Location loc = createLocation(NAME, mRandom);
394         mockProvider.setProviderLocation(loc);
395         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
396                 PERMISSION_FINE)).isEqualTo(loc);
397 
398         mManager.setMockProvider(null);
399         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
400                 PERMISSION_FINE)).isNull();
401     }
402 
403     @Test
testInjectLastLocation()404     public void testInjectLastLocation() {
405         Location loc1 = createLocation(NAME, mRandom);
406         mManager.injectLastLocation(loc1, CURRENT_USER);
407 
408         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
409                 PERMISSION_FINE)).isEqualTo(loc1);
410 
411         Location loc2 = createLocation(NAME, mRandom);
412         mManager.injectLastLocation(loc2, CURRENT_USER);
413 
414         assertThat(mManager.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
415                 PERMISSION_FINE)).isEqualTo(loc1);
416     }
417 
418     @Test
testPassive_Listener()419     public void testPassive_Listener() throws Exception {
420         ILocationListener listener = createMockLocationListener();
421         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
422         mPassive.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
423 
424         LocationResult loc = createLocationResult(NAME, mRandom);
425         mProvider.setProviderLocation(loc);
426         verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class));
427     }
428 
429     @Test
testPassive_LastLocation()430     public void testPassive_LastLocation() {
431         Location loc = createLocation(NAME, mRandom);
432         mProvider.setProviderLocation(loc);
433 
434         assertThat(mPassive.getLastLocation(new LastLocationRequest.Builder().build(), IDENTITY,
435                 PERMISSION_FINE)).isEqualTo(loc);
436     }
437 
438     @Test
testRegisterListener()439     public void testRegisterListener() throws Exception {
440         ILocationListener listener = createMockLocationListener();
441         mManager.registerLocationRequest(
442                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
443                 IDENTITY,
444                 PERMISSION_FINE,
445                 listener);
446 
447         LocationResult loc = createLocationResult(NAME, mRandom);
448         mProvider.setProviderLocation(loc);
449         verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class));
450 
451         mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER);
452         verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, false);
453         loc = createLocationResult(NAME, mRandom);
454         mProvider.setProviderLocation(loc);
455         verify(listener, times(1)).onLocationChanged(any(List.class),
456                 nullable(IRemoteCallback.class));
457 
458         mInjector.getSettingsHelper().setLocationEnabled(true, CURRENT_USER);
459         verify(listener, timeout(TIMEOUT_MS).times(1)).onProviderEnabledChanged(NAME, true);
460 
461         mProvider.setAllowed(false);
462         verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, false);
463         loc = createLocationResult(NAME, mRandom);
464         mProvider.setProviderLocation(loc);
465         verify(listener, times(1)).onLocationChanged(any(List.class),
466                 nullable(IRemoteCallback.class));
467 
468         mProvider.setAllowed(true);
469         verify(listener, timeout(TIMEOUT_MS).times(2)).onProviderEnabledChanged(NAME, true);
470 
471         loc = createLocationResult(NAME, mRandom);
472         mProvider.setProviderLocation(loc);
473         verify(listener).onLocationChanged(eq(loc.asList()), nullable(IRemoteCallback.class));
474     }
475 
476     @Test
testRegisterListener_SameProcess()477     public void testRegisterListener_SameProcess() throws Exception {
478         CallerIdentity identity = CallerIdentity.forTest(CURRENT_USER, Process.myPid(), "mypackage",
479                 "attribution", "listener");
480 
481         ILocationListener listener = createMockLocationListener();
482         mManager.registerLocationRequest(
483                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
484                 identity,
485                 PERMISSION_FINE,
486                 listener);
487 
488         LocationResult loc = createLocationResult(NAME, mRandom);
489         mProvider.setProviderLocation(loc);
490         verify(listener, timeout(TIMEOUT_MS).times(1)).onLocationChanged(eq(loc.asList()),
491                 nullable(IRemoteCallback.class));
492     }
493 
494     @Test
testRegisterListener_Unregister()495     public void testRegisterListener_Unregister() throws Exception {
496         ILocationListener listener = createMockLocationListener();
497         mManager.registerLocationRequest(
498                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
499                 IDENTITY,
500                 PERMISSION_FINE,
501                 listener);
502         mManager.unregisterLocationRequest(listener);
503 
504         mProvider.setProviderLocation(createLocation(NAME, mRandom));
505         verify(listener, never()).onLocationChanged(any(List.class),
506                 nullable(IRemoteCallback.class));
507 
508         mInjector.getSettingsHelper().setLocationEnabled(false, CURRENT_USER);
509         verify(listener, after(TIMEOUT_MS).never()).onProviderEnabledChanged(NAME, false);
510     }
511 
512     @Test
testRegisterListener_Unregister_SameProcess()513     public void testRegisterListener_Unregister_SameProcess() throws Exception {
514         CallerIdentity identity = CallerIdentity.forTest(CURRENT_USER, Process.myPid(), "mypackage",
515                 "attribution", "listener");
516 
517         ILocationListener listener = createMockLocationListener();
518         mManager.registerLocationRequest(
519                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
520                 identity,
521                 PERMISSION_FINE,
522                 listener);
523 
524         CountDownLatch blocker = new CountDownLatch(1);
525         IN_PROCESS_EXECUTOR.execute(() -> {
526             try {
527                 blocker.await();
528             } catch (InterruptedException e) {
529                 // do nothing
530             }
531         });
532 
533         mProvider.setProviderLocation(createLocation(NAME, mRandom));
534         mManager.unregisterLocationRequest(listener);
535         blocker.countDown();
536         verify(listener, after(TIMEOUT_MS).never()).onLocationChanged(any(List.class),
537                 nullable(IRemoteCallback.class));
538     }
539 
540     @Test
testRegisterListener_NumUpdates()541     public void testRegisterListener_NumUpdates() throws Exception {
542         ILocationListener listener = createMockLocationListener();
543         LocationRequest request = new LocationRequest.Builder(0)
544                 .setMaxUpdates(5)
545                 .setWorkSource(WORK_SOURCE)
546                 .build();
547         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
548 
549         mProvider.setProviderLocation(createLocation(NAME, mRandom));
550         mProvider.setProviderLocation(createLocation(NAME, mRandom));
551         mProvider.setProviderLocation(createLocation(NAME, mRandom));
552         mProvider.setProviderLocation(createLocation(NAME, mRandom));
553         mProvider.setProviderLocation(createLocation(NAME, mRandom));
554         mProvider.setProviderLocation(createLocation(NAME, mRandom));
555 
556         verify(listener, times(5)).onLocationChanged(any(List.class),
557                 nullable(IRemoteCallback.class));
558     }
559 
560     @Test
testRegisterListener_ExpiringAlarm()561     public void testRegisterListener_ExpiringAlarm() throws Exception {
562         ILocationListener listener = createMockLocationListener();
563         LocationRequest request = new LocationRequest.Builder(0)
564                 .setDurationMillis(5000)
565                 .setWorkSource(WORK_SOURCE)
566                 .build();
567         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
568 
569         mInjector.getAlarmHelper().incrementAlarmTime(5000);
570         mProvider.setProviderLocation(createLocation(NAME, mRandom));
571         verify(listener, never()).onLocationChanged(any(List.class),
572                 nullable(IRemoteCallback.class));
573     }
574 
575     @Test
testRegisterListener_ExpiringNoAlarm()576     public void testRegisterListener_ExpiringNoAlarm() throws Exception {
577         ILocationListener listener = createMockLocationListener();
578         LocationRequest request = new LocationRequest.Builder(0)
579                 .setDurationMillis(25)
580                 .setWorkSource(WORK_SOURCE)
581                 .build();
582         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
583 
584         Thread.sleep(25);
585 
586         mProvider.setProviderLocation(createLocation(NAME, mRandom));
587         verify(listener, never()).onLocationChanged(any(List.class),
588                 nullable(IRemoteCallback.class));
589     }
590 
591     @Test
testRegisterListener_FastestInterval()592     public void testRegisterListener_FastestInterval() throws Exception {
593         ILocationListener listener = createMockLocationListener();
594         LocationRequest request = new LocationRequest.Builder(5000)
595                 .setMinUpdateIntervalMillis(5000)
596                 .setWorkSource(WORK_SOURCE)
597                 .build();
598         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
599 
600         mProvider.setProviderLocation(createLocation(NAME, mRandom));
601         mProvider.setProviderLocation(createLocation(NAME, mRandom));
602 
603         verify(listener, times(1)).onLocationChanged(
604                 any(List.class), nullable(IRemoteCallback.class));
605     }
606 
607     @Test
testRegisterListener_SmallestDisplacement()608     public void testRegisterListener_SmallestDisplacement() throws Exception {
609         ILocationListener listener = createMockLocationListener();
610         LocationRequest request = new LocationRequest.Builder(5000)
611                 .setMinUpdateDistanceMeters(1f)
612                 .setWorkSource(WORK_SOURCE)
613                 .build();
614         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
615 
616         Location loc = createLocation(NAME, mRandom);
617         mProvider.setProviderLocation(loc);
618         mProvider.setProviderLocation(loc);
619 
620         verify(listener, times(1)).onLocationChanged(
621                 any(List.class), nullable(IRemoteCallback.class));
622     }
623 
624     @Test
testRegisterListener_NoteOpFailure()625     public void testRegisterListener_NoteOpFailure() throws Exception {
626         ILocationListener listener = createMockLocationListener();
627         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
628         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
629 
630         mInjector.getAppOpsHelper().setAppOpAllowed(OP_FINE_LOCATION, IDENTITY.getPackageName(),
631                 false);
632 
633         mProvider.setProviderLocation(createLocation(NAME, mRandom));
634 
635         verify(listener, never()).onLocationChanged(any(List.class),
636                 nullable(IRemoteCallback.class));
637     }
638 
639     @Test
testRegisterListener_Wakelock()640     public void testRegisterListener_Wakelock() throws Exception {
641         CallerIdentity identity = CallerIdentity.forTest(CURRENT_USER, Process.myPid(), "mypackage",
642                 "attribution", "listener");
643 
644         ILocationListener listener = createMockLocationListener();
645         mManager.registerLocationRequest(
646                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
647                 identity,
648                 PERMISSION_FINE,
649                 listener);
650 
651         CountDownLatch blocker = new CountDownLatch(1);
652         IN_PROCESS_EXECUTOR.execute(() -> {
653             try {
654                 blocker.await();
655             } catch (InterruptedException e) {
656                 // do nothing
657             }
658         });
659 
660         mProvider.setProviderLocation(createLocation(NAME, mRandom));
661         verify(mWakeLock).acquire(anyLong());
662         verify(mWakeLock, never()).release();
663 
664         blocker.countDown();
665         verify(listener, timeout(TIMEOUT_MS)).onLocationChanged(any(List.class),
666                 nullable(IRemoteCallback.class));
667         verify(mWakeLock).acquire(anyLong());
668         verify(mWakeLock, timeout(TIMEOUT_MS)).release();
669     }
670 
671     @Test
testRegisterListener_Coarse()672     public void testRegisterListener_Coarse() throws Exception {
673         ILocationListener listener = createMockLocationListener();
674         mManager.registerLocationRequest(
675                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
676                 IDENTITY,
677                 PERMISSION_COARSE,
678                 listener);
679 
680         mProvider.setProviderLocation(createLocation(NAME, mRandom));
681         mProvider.setProviderLocation(createLocation(NAME, mRandom));
682         verify(listener, times(1))
683                 .onLocationChanged(any(List.class), nullable(IRemoteCallback.class));
684     }
685 
686     @Test
testRegisterListener_Coarse_Passive()687     public void testRegisterListener_Coarse_Passive() throws Exception {
688         ILocationListener listener = createMockLocationListener();
689         mManager.registerLocationRequest(
690                 new LocationRequest.Builder(PASSIVE_INTERVAL)
691                         .setMinUpdateIntervalMillis(0)
692                         .setWorkSource(WORK_SOURCE).build(),
693                 IDENTITY,
694                 PERMISSION_COARSE,
695                 listener);
696 
697         mProvider.setProviderLocation(createLocation(NAME, mRandom));
698         mProvider.setProviderLocation(createLocation(NAME, mRandom));
699         verify(listener, times(1))
700                 .onLocationChanged(any(List.class), nullable(IRemoteCallback.class));
701     }
702 
703     @Test
testProviderRequestListener()704     public void testProviderRequestListener() throws Exception {
705         IProviderRequestListener requestListener = mock(IProviderRequestListener.class);
706         mManager.addProviderRequestListener(requestListener);
707 
708         ILocationListener locationListener = createMockLocationListener();
709         LocationRequest request = new LocationRequest.Builder(1).setWorkSource(
710                 WORK_SOURCE).build();
711         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, locationListener);
712 
713         verify(requestListener, timeout(TIMEOUT_MS).times(1)).onProviderRequestChanged(anyString(),
714                 any(ProviderRequest.class));
715 
716         mManager.unregisterLocationRequest(locationListener);
717         mManager.removeProviderRequestListener(requestListener);
718     }
719 
720     @Test
testGetCurrentLocation()721     public void testGetCurrentLocation() throws Exception {
722         ILocationCallback listener = createMockGetCurrentLocationListener();
723         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
724         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
725 
726         Location loc = createLocation(NAME, mRandom);
727         mProvider.setProviderLocation(loc);
728         mProvider.setProviderLocation(createLocation(NAME, mRandom));
729         verify(listener, times(1)).onLocation(loc);
730     }
731 
732     @Test
testGetCurrentLocation_Cancel()733     public void testGetCurrentLocation_Cancel() throws Exception {
734         ILocationCallback listener = createMockGetCurrentLocationListener();
735         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
736         ICancellationSignal cancellationSignal = mManager.getCurrentLocation(request,
737                 IDENTITY, PERMISSION_FINE, listener);
738 
739         cancellationSignal.cancel();
740         mProvider.setProviderLocation(createLocation(NAME, mRandom));
741         verify(listener, never()).onLocation(nullable(Location.class));
742     }
743 
744     @Test
testGetCurrentLocation_ProviderDisabled()745     public void testGetCurrentLocation_ProviderDisabled() throws Exception {
746         ILocationCallback listener = createMockGetCurrentLocationListener();
747         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
748         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
749 
750         mProvider.setProviderAllowed(false);
751         mProvider.setProviderAllowed(true);
752         mProvider.setProviderLocation(createLocation(NAME, mRandom));
753         verify(listener, times(1)).onLocation(isNull());
754     }
755 
756     @Test
testGetCurrentLocation_ProviderAlreadyDisabled()757     public void testGetCurrentLocation_ProviderAlreadyDisabled() throws Exception {
758         mProvider.setProviderAllowed(false);
759 
760         ILocationCallback listener = createMockGetCurrentLocationListener();
761         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
762         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
763 
764         mProvider.setProviderAllowed(true);
765         mProvider.setProviderLocation(createLocation(NAME, mRandom));
766         verify(listener, times(1)).onLocation(isNull());
767     }
768 
769     @Test
testGetCurrentLocation_LastLocation()770     public void testGetCurrentLocation_LastLocation() throws Exception {
771         Location loc = createLocation(NAME, mRandom);
772         mProvider.setProviderLocation(loc);
773 
774         ILocationCallback listener = createMockGetCurrentLocationListener();
775         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
776         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
777         verify(listener, times(1)).onLocation(eq(loc));
778     }
779 
780     @Test
testGetCurrentLocation_Timeout()781     public void testGetCurrentLocation_Timeout() throws Exception {
782         ILocationCallback listener = createMockGetCurrentLocationListener();
783         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
784         mManager.getCurrentLocation(request, IDENTITY, PERMISSION_FINE, listener);
785 
786         mInjector.getAlarmHelper().incrementAlarmTime(60000);
787         verify(listener, times(1)).onLocation(isNull());
788     }
789 
790     @Test
testFlush()791     public void testFlush() throws Exception {
792         ILocationListener listener = createMockLocationListener();
793         mManager.registerLocationRequest(
794                 new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build(),
795                 IDENTITY,
796                 PERMISSION_FINE,
797                 listener);
798 
799         mManager.flush(listener, 99);
800 
801         LocationResult loc = createLocationResult(NAME, mRandom);
802         mProvider.setProviderLocation(loc);
803         mProvider.completeFlushes();
804 
805         InOrder inOrder = inOrder(listener);
806         inOrder.verify(listener).onLocationChanged(eq(loc.asList()), any(IRemoteCallback.class));
807         inOrder.verify(listener).onFlushComplete(99);
808     }
809 
810     @Test
testFlush_UnknownKey()811     public void testFlush_UnknownKey() {
812         assertThrows(IllegalArgumentException.class,
813                 () -> mManager.flush(createMockLocationListener(), 0));
814     }
815 
816     @Test
testLocationMonitoring()817     public void testLocationMonitoring() {
818         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
819                 IDENTITY.getPackageName())).isFalse();
820         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
821                 IDENTITY.getPackageName())).isFalse();
822 
823         ILocationListener listener = createMockLocationListener();
824         LocationRequest request = new LocationRequest.Builder(0).setWorkSource(WORK_SOURCE).build();
825         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
826 
827         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
828                 IDENTITY.getPackageName())).isTrue();
829         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
830                 IDENTITY.getPackageName())).isTrue();
831 
832         mInjector.getAppForegroundHelper().setAppForeground(IDENTITY.getUid(), false);
833 
834         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
835                 IDENTITY.getPackageName())).isTrue();
836         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
837                 IDENTITY.getPackageName())).isFalse();
838 
839         mManager.unregisterLocationRequest(listener);
840 
841         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_LOCATION,
842                 IDENTITY.getPackageName())).isFalse();
843         assertThat(mInjector.getAppOpsHelper().isAppOpStarted(OP_MONITOR_HIGH_POWER_LOCATION,
844                 IDENTITY.getPackageName())).isFalse();
845     }
846 
847     @Test
testProviderRequest()848     public void testProviderRequest() {
849         assertThat(mProvider.getRequest().isActive()).isFalse();
850 
851         ILocationListener listener1 = createMockLocationListener();
852         LocationRequest request1 = new LocationRequest.Builder(5).setWorkSource(
853                 WORK_SOURCE).build();
854         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
855 
856         assertThat(mProvider.getRequest().isActive()).isTrue();
857         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse();
858         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
859         assertThat(mProvider.getRequest().isLowPower()).isFalse();
860         assertThat(mProvider.getRequest().getWorkSource()).isNotNull();
861 
862         ILocationListener listener2 = createMockLocationListener();
863         LocationRequest request2 = new LocationRequest.Builder(1)
864                 .setLowPower(true)
865                 .setWorkSource(WORK_SOURCE)
866                 .build();
867         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
868 
869         assertThat(mProvider.getRequest().isActive()).isTrue();
870         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse();
871         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
872         assertThat(mProvider.getRequest().isLowPower()).isFalse();
873         assertThat(mProvider.getRequest().getWorkSource()).isNotNull();
874 
875         mManager.unregisterLocationRequest(listener1);
876 
877         assertThat(mProvider.getRequest().isActive()).isTrue();
878         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse();
879         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
880         assertThat(mProvider.getRequest().isLowPower()).isTrue();
881         assertThat(mProvider.getRequest().getWorkSource()).isNotNull();
882 
883         mManager.unregisterLocationRequest(listener2);
884 
885         assertThat(mProvider.getRequest().isActive()).isFalse();
886     }
887 
888     @Test
testProviderRequest_DelayedRequest()889     public void testProviderRequest_DelayedRequest() throws Exception {
890         mProvider.setProviderLocation(createLocation(NAME, mRandom));
891 
892         ILocationListener listener1 = createMockLocationListener();
893         LocationRequest request1 = new LocationRequest.Builder(60000)
894                 .setWorkSource(WORK_SOURCE)
895                 .build();
896         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
897 
898         verify(listener1).onLocationChanged(any(List.class),
899                 nullable(IRemoteCallback.class));
900 
901         assertThat(mProvider.getRequest().isActive()).isFalse();
902 
903         mInjector.getAlarmHelper().incrementAlarmTime(60000);
904         assertThat(mProvider.getRequest().isActive()).isTrue();
905         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(60000);
906     }
907 
908     @Test
testProviderRequest_SpamRequesting()909     public void testProviderRequest_SpamRequesting() {
910         mProvider.setProviderLocation(createLocation(NAME, mRandom));
911 
912         ILocationListener listener1 = createMockLocationListener();
913         LocationRequest request1 = new LocationRequest.Builder(60000)
914                 .setWorkSource(WORK_SOURCE)
915                 .build();
916 
917         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
918         assertThat(mProvider.getRequest().isActive()).isFalse();
919         mManager.unregisterLocationRequest(listener1);
920         assertThat(mProvider.getRequest().isActive()).isFalse();
921         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
922         assertThat(mProvider.getRequest().isActive()).isFalse();
923         mManager.unregisterLocationRequest(listener1);
924         assertThat(mProvider.getRequest().isActive()).isFalse();
925     }
926 
927     @Test
testProviderRequest_BackgroundThrottle()928     public void testProviderRequest_BackgroundThrottle() {
929         ILocationListener listener1 = createMockLocationListener();
930         LocationRequest request1 = new LocationRequest.Builder(5)
931                 .setWorkSource(WORK_SOURCE)
932                 .build();
933         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
934 
935         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
936 
937         mInjector.getAppForegroundHelper().setAppForeground(IDENTITY.getUid(), false);
938         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(
939                 mInjector.getSettingsHelper().getBackgroundThrottleIntervalMs());
940     }
941 
942     @Test
testProviderRequest_IgnoreLocationSettings()943     public void testProviderRequest_IgnoreLocationSettings() {
944         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
945                 new PackageTagsList.Builder().add(
946                         IDENTITY.getPackageName()).build());
947 
948         ILocationListener listener1 = createMockLocationListener();
949         LocationRequest request1 = new LocationRequest.Builder(5)
950                 .setWorkSource(WORK_SOURCE)
951                 .build();
952         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
953 
954         assertThat(mProvider.getRequest().isActive()).isTrue();
955         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
956         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse();
957 
958         ILocationListener listener2 = createMockLocationListener();
959         LocationRequest request2 = new LocationRequest.Builder(1)
960                 .setLocationSettingsIgnored(true)
961                 .setWorkSource(WORK_SOURCE)
962                 .build();
963         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
964 
965         assertThat(mProvider.getRequest().isActive()).isTrue();
966         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
967         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isTrue();
968     }
969 
970     @Test
testProviderRequest_IgnoreLocationSettings_ProviderDisabled()971     public void testProviderRequest_IgnoreLocationSettings_ProviderDisabled() {
972         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
973                 new PackageTagsList.Builder().add(
974                         IDENTITY.getPackageName()).build());
975 
976         ILocationListener listener1 = createMockLocationListener();
977         LocationRequest request1 = new LocationRequest.Builder(1)
978                 .setWorkSource(WORK_SOURCE)
979                 .build();
980         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
981 
982         ILocationListener listener2 = createMockLocationListener();
983         LocationRequest request2 = new LocationRequest.Builder(5)
984                 .setLocationSettingsIgnored(true)
985                 .setWorkSource(WORK_SOURCE)
986                 .build();
987         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
988 
989         mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId());
990 
991         assertThat(mProvider.getRequest().isActive()).isTrue();
992         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
993         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isTrue();
994     }
995 
996     @Test
testProviderRequest_IgnoreLocationSettings_NoAllowlist()997     public void testProviderRequest_IgnoreLocationSettings_NoAllowlist() {
998         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
999                 new PackageTagsList.Builder().add(
1000                         IDENTITY.getPackageName()).build());
1001 
1002         ILocationListener listener = createMockLocationListener();
1003         LocationRequest request = new LocationRequest.Builder(1)
1004                 .setLocationSettingsIgnored(true)
1005                 .setWorkSource(WORK_SOURCE)
1006                 .build();
1007         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
1008 
1009         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
1010                 new PackageTagsList.Builder().build());
1011 
1012         assertThat(mProvider.getRequest().isActive()).isTrue();
1013         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
1014         assertThat(mProvider.getRequest().isLocationSettingsIgnored()).isFalse();
1015     }
1016 
1017     @Test
testProviderRequest_BackgroundThrottle_IgnoreLocationSettings()1018     public void testProviderRequest_BackgroundThrottle_IgnoreLocationSettings() {
1019         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
1020                 new PackageTagsList.Builder().add(
1021                         IDENTITY.getPackageName()).build());
1022 
1023         ILocationListener listener1 = createMockLocationListener();
1024         LocationRequest request1 = new LocationRequest.Builder(5)
1025                 .setLocationSettingsIgnored(true)
1026                 .setWorkSource(WORK_SOURCE)
1027                 .build();
1028         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1029 
1030         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1031 
1032         mInjector.getAppForegroundHelper().setAppForeground(IDENTITY.getUid(), false);
1033         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1034     }
1035 
1036     @Test
testProviderRequest_AdasGnssBypass()1037     public void testProviderRequest_AdasGnssBypass() {
1038         doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
1039         doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
1040 
1041         createManager(GPS_PROVIDER);
1042 
1043         ILocationListener listener1 = createMockLocationListener();
1044         LocationRequest request1 = new LocationRequest.Builder(5)
1045                 .setWorkSource(WORK_SOURCE)
1046                 .build();
1047         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1048 
1049         assertThat(mProvider.getRequest().isActive()).isTrue();
1050         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1051         assertThat(mProvider.getRequest().isAdasGnssBypass()).isFalse();
1052 
1053         ILocationListener listener2 = createMockLocationListener();
1054         LocationRequest request2 = new LocationRequest.Builder(1)
1055                 .setAdasGnssBypass(true)
1056                 .setWorkSource(WORK_SOURCE)
1057                 .build();
1058         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
1059 
1060         assertThat(mProvider.getRequest().isActive()).isTrue();
1061         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(1);
1062         assertThat(mProvider.getRequest().isAdasGnssBypass()).isTrue();
1063     }
1064 
1065     @Test
testProviderRequest_AdasGnssBypass_ProviderDisabled()1066     public void testProviderRequest_AdasGnssBypass_ProviderDisabled() {
1067         doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
1068         doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
1069 
1070         createManager(GPS_PROVIDER);
1071 
1072         ILocationListener listener1 = createMockLocationListener();
1073         LocationRequest request1 = new LocationRequest.Builder(1)
1074                 .setWorkSource(WORK_SOURCE)
1075                 .build();
1076         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1077 
1078         ILocationListener listener2 = createMockLocationListener();
1079         LocationRequest request2 = new LocationRequest.Builder(5)
1080                 .setAdasGnssBypass(true)
1081                 .setWorkSource(WORK_SOURCE)
1082                 .build();
1083         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
1084 
1085         mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId());
1086 
1087         assertThat(mProvider.getRequest().isActive()).isTrue();
1088         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1089         assertThat(mProvider.getRequest().isAdasGnssBypass()).isTrue();
1090     }
1091 
1092     @Test
testProviderRequest_AdasGnssBypass_ProviderDisabled_AdasDisabled()1093     public void testProviderRequest_AdasGnssBypass_ProviderDisabled_AdasDisabled() {
1094         mInjector.getSettingsHelper().setIgnoreSettingsAllowlist(
1095                 new PackageTagsList.Builder().add(
1096                         IDENTITY.getPackageName()).build());
1097         doReturn(true).when(mPackageManager).hasSystemFeature(FEATURE_AUTOMOTIVE);
1098         doReturn(true).when(mResources).getBoolean(R.bool.config_defaultAdasGnssLocationEnabled);
1099 
1100         createManager(GPS_PROVIDER);
1101 
1102         ILocationListener listener1 = createMockLocationListener();
1103         LocationRequest request1 = new LocationRequest.Builder(5)
1104                 .setLocationSettingsIgnored(true)
1105                 .setWorkSource(WORK_SOURCE)
1106                 .build();
1107         mManager.registerLocationRequest(request1, IDENTITY, PERMISSION_FINE, listener1);
1108 
1109         ILocationListener listener2 = createMockLocationListener();
1110         LocationRequest request2 = new LocationRequest.Builder(1)
1111                 .setAdasGnssBypass(true)
1112                 .setWorkSource(WORK_SOURCE)
1113                 .build();
1114         mManager.registerLocationRequest(request2, IDENTITY, PERMISSION_FINE, listener2);
1115 
1116         mInjector.getLocationSettings().updateUserSettings(IDENTITY.getUserId(),
1117                 settings -> settings.withAdasGnssLocationEnabled(false));
1118         mInjector.getSettingsHelper().setLocationEnabled(false, IDENTITY.getUserId());
1119 
1120         assertThat(mProvider.getRequest().isActive()).isTrue();
1121         assertThat(mProvider.getRequest().getIntervalMillis()).isEqualTo(5);
1122         assertThat(mProvider.getRequest().isAdasGnssBypass()).isFalse();
1123     }
1124 
1125     @Test
testProviderRequest_BatterySaver_ScreenOnOff()1126     public void testProviderRequest_BatterySaver_ScreenOnOff() {
1127         mInjector.getLocationPowerSaveModeHelper().setLocationPowerSaveMode(
1128                 LOCATION_MODE_THROTTLE_REQUESTS_WHEN_SCREEN_OFF);
1129 
1130         ILocationListener listener = createMockLocationListener();
1131         LocationRequest request = new LocationRequest.Builder(5).setWorkSource(WORK_SOURCE).build();
1132         mManager.registerLocationRequest(request, IDENTITY, PERMISSION_FINE, listener);
1133 
1134         assertThat(mProvider.getRequest().isActive()).isTrue();
1135 
1136         mInjector.getScreenInteractiveHelper().setScreenInteractive(false);
1137         assertThat(mProvider.getRequest().isActive()).isFalse();
1138     }
1139 
createMockLocationListener()1140     private ILocationListener createMockLocationListener() {
1141         return spy(new ILocationListener.Stub() {
1142             @Override
1143             public void onLocationChanged(List<Location> locations,
1144                     IRemoteCallback onCompleteCallback) {
1145                 if (onCompleteCallback != null) {
1146                     try {
1147                         onCompleteCallback.sendResult(null);
1148                     } catch (RemoteException e) {
1149                         e.rethrowFromSystemServer();
1150                     }
1151                 }
1152             }
1153 
1154             @Override
1155             public void onFlushComplete(int requestCode) {
1156             }
1157 
1158             @Override
1159             public void onProviderEnabledChanged(String provider, boolean enabled) {
1160             }
1161         });
1162     }
1163 
1164     private ILocationCallback createMockGetCurrentLocationListener() {
1165         return spy(new ILocationCallback.Stub() {
1166             @Override
1167             public void onLocation(Location location) {
1168             }
1169         });
1170     }
1171 
1172     private static class TestProvider extends AbstractLocationProvider {
1173 
1174         private ProviderRequest mProviderRequest = ProviderRequest.EMPTY_REQUEST;
1175 
1176         private final ArrayList<Runnable> mFlushCallbacks = new ArrayList<>();
1177 
1178         TestProvider(ProviderProperties properties, CallerIdentity identity) {
1179             super(DIRECT_EXECUTOR, identity, properties, Collections.emptySet());
1180         }
1181 
1182         public void setProviderAllowed(boolean allowed) {
1183             setAllowed(allowed);
1184         }
1185 
1186         public void setProviderLocation(Location l) {
1187             reportLocation(LocationResult.create(new Location(l)));
1188         }
1189 
1190         public void setProviderLocation(LocationResult l) {
1191             reportLocation(l);
1192         }
1193 
1194         public void completeFlushes() {
1195             for (Runnable r : mFlushCallbacks) {
1196                 r.run();
1197             }
1198             mFlushCallbacks.clear();
1199         }
1200 
1201         public ProviderRequest getRequest() {
1202             return mProviderRequest;
1203         }
1204 
1205         @Override
1206         public void onSetRequest(ProviderRequest request) {
1207             mProviderRequest = request;
1208         }
1209 
1210         @Override
1211         protected void onFlush(Runnable callback) {
1212             mFlushCallbacks.add(callback);
1213         }
1214 
1215         @Override
1216         protected void onExtraCommand(int uid, int pid, String command, Bundle extras) {
1217         }
1218 
1219         @Override
1220         public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1221         }
1222     }
1223 }
1224