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