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