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