1 /* 2 * Copyright (C) 2007 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 android.location; 18 19 import static android.Manifest.permission.ACCESS_COARSE_LOCATION; 20 import static android.Manifest.permission.ACCESS_FINE_LOCATION; 21 import static android.Manifest.permission.LOCATION_BYPASS; 22 import static android.Manifest.permission.LOCATION_HARDWARE; 23 import static android.Manifest.permission.WRITE_SECURE_SETTINGS; 24 import static android.location.LocationRequest.createFromDeprecatedCriteria; 25 import static android.location.LocationRequest.createFromDeprecatedProvider; 26 27 import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR; 28 29 import android.Manifest; 30 import android.annotation.CallbackExecutor; 31 import android.annotation.FlaggedApi; 32 import android.annotation.NonNull; 33 import android.annotation.Nullable; 34 import android.annotation.RequiresFeature; 35 import android.annotation.RequiresPermission; 36 import android.annotation.SdkConstant; 37 import android.annotation.SdkConstant.SdkConstantType; 38 import android.annotation.SuppressLint; 39 import android.annotation.SystemApi; 40 import android.annotation.SystemService; 41 import android.annotation.TestApi; 42 import android.app.AppOpsManager; 43 import android.app.PendingIntent; 44 import android.app.PropertyInvalidatedCache; 45 import android.compat.Compatibility; 46 import android.compat.annotation.ChangeId; 47 import android.compat.annotation.EnabledAfter; 48 import android.content.Context; 49 import android.content.Intent; 50 import android.content.pm.PackageManager; 51 import android.location.flags.Flags; 52 import android.location.provider.IProviderRequestListener; 53 import android.location.provider.ProviderProperties; 54 import android.location.provider.ProviderRequest; 55 import android.location.provider.ProviderRequest.ChangedListener; 56 import android.os.Build; 57 import android.os.Bundle; 58 import android.os.CancellationSignal; 59 import android.os.Handler; 60 import android.os.HandlerExecutor; 61 import android.os.ICancellationSignal; 62 import android.os.IRemoteCallback; 63 import android.os.Looper; 64 import android.os.PackageTagsList; 65 import android.os.Process; 66 import android.os.RemoteException; 67 import android.os.ServiceManager; 68 import android.os.UserHandle; 69 70 import com.android.internal.annotations.GuardedBy; 71 import com.android.internal.listeners.ListenerExecutor; 72 import com.android.internal.listeners.ListenerTransport; 73 import com.android.internal.listeners.ListenerTransportManager; 74 import com.android.internal.util.Preconditions; 75 76 import java.lang.ref.WeakReference; 77 import java.util.ArrayList; 78 import java.util.Collections; 79 import java.util.List; 80 import java.util.Objects; 81 import java.util.Set; 82 import java.util.WeakHashMap; 83 import java.util.concurrent.Executor; 84 import java.util.function.Consumer; 85 86 /** 87 * This class provides access to the system location services. These services allow applications to 88 * obtain periodic updates of the device's geographical location, or to be notified when the device 89 * enters the proximity of a given geographical location. 90 * 91 * <p class="note">Unless otherwise noted, all Location API methods require the 92 * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION} or 93 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permissions. If your application only 94 * has the coarse permission then providers will still return location results, but the exact 95 * location will be obfuscated to a coarse level of accuracy. 96 */ 97 @SuppressWarnings({"deprecation"}) 98 @SystemService(Context.LOCATION_SERVICE) 99 @RequiresFeature(PackageManager.FEATURE_LOCATION) 100 public class LocationManager { 101 102 /** 103 * For apps targeting Android S and above, immutable PendingIntents passed into location APIs 104 * will generate an IllegalArgumentException. 105 * 106 * @hide 107 */ 108 @ChangeId 109 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) 110 public static final long BLOCK_IMMUTABLE_PENDING_INTENTS = 171317480L; 111 112 /** 113 * For apps targeting Android S and above, LocationRequest system APIs may not be used with 114 * PendingIntent location requests. 115 * 116 * @hide 117 */ 118 @ChangeId 119 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) 120 public static final long BLOCK_PENDING_INTENT_SYSTEM_API_USAGE = 169887240L; 121 122 /** 123 * For apps targeting Android S and above, location clients may receive historical locations 124 * (from before the present time) under some circumstances. 125 * 126 * @hide 127 */ 128 @ChangeId 129 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) 130 public static final long DELIVER_HISTORICAL_LOCATIONS = 73144566L; 131 132 /** 133 * For apps targeting Android R and above, {@link #getProvider(String)} will no longer throw any 134 * security exceptions. 135 * 136 * @hide 137 */ 138 @ChangeId 139 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.Q) 140 public static final long GET_PROVIDER_SECURITY_EXCEPTIONS = 150935354L; 141 142 /** 143 * For apps targeting Android K and above, supplied {@link PendingIntent}s must be targeted to a 144 * specific package. 145 * 146 * @hide 147 */ 148 @ChangeId 149 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.JELLY_BEAN) 150 public static final long BLOCK_UNTARGETED_PENDING_INTENTS = 148963590L; 151 152 /** 153 * For apps targeting Android K and above, incomplete locations may not be passed to 154 * {@link #setTestProviderLocation}. 155 * 156 * @hide 157 */ 158 @ChangeId 159 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.JELLY_BEAN) 160 public static final long BLOCK_INCOMPLETE_LOCATIONS = 148964793L; 161 162 /** 163 * For apps targeting Android S and above, all {@link GpsStatus} API usage must be replaced with 164 * {@link GnssStatus} APIs. 165 * 166 * @hide 167 */ 168 @ChangeId 169 @EnabledAfter(targetSdkVersion = Build.VERSION_CODES.R) 170 public static final long BLOCK_GPS_STATUS_USAGE = 144027538L; 171 172 /** 173 * Standard name of the network location provider. 174 * 175 * <p>If present, this provider determines location based on nearby of cell tower and WiFi 176 * access points. Operation of this provider may require a data connection. 177 */ 178 public static final String NETWORK_PROVIDER = "network"; 179 180 /** 181 * Standard name of the GNSS location provider. 182 * 183 * <p>If present, this provider determines location using GNSS satellites. The responsiveness 184 * and accuracy of location fixes may depend on GNSS signal conditions. 185 * 186 * <p>Locations returned from this provider are with respect to the primary GNSS antenna 187 * position within the device. {@link #getGnssAntennaInfos()} may be used to determine the GNSS 188 * antenna position with respect to the Android Coordinate System, and convert between them if 189 * necessary. This is generally only necessary for high accuracy applications. 190 * 191 * <p>The extras Bundle for locations derived by this location provider may contain the 192 * following key/value pairs: 193 * <ul> 194 * <li> satellites - the number of satellites used to derive the fix 195 * </ul> 196 */ 197 public static final String GPS_PROVIDER = "gps"; 198 199 /** 200 * Standard name of the GNSS hardware location provider. 201 * 202 * <p>This provider is similar to {@link LocationManager#GPS_PROVIDER}, but it directly uses the 203 * HAL GNSS implementation and doesn't go through any provider overrides that may exist. This 204 * provider will only be available when the GPS_PROVIDER is overridden with a proxy using {@link 205 * android.location.provider.LocationProviderBase#ACTION_GNSS_PROVIDER}, and is intended only 206 * for use internally by the location provider system. 207 * 208 * @hide 209 */ 210 @SystemApi 211 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) 212 public static final String GPS_HARDWARE_PROVIDER = "gps_hardware"; 213 214 /** 215 * A special location provider for receiving locations without actively initiating a location 216 * fix. This location provider is always present. 217 * 218 * <p>This provider can be used to passively receive location updates when other applications or 219 * services request them without actually requesting the locations yourself. This provider will 220 * only return locations generated by other providers. 221 */ 222 public static final String PASSIVE_PROVIDER = "passive"; 223 224 /** 225 * Standard name of the fused location provider. 226 * 227 * <p>If present, this provider may combine inputs from several other location providers to 228 * provide the best possible location fix. It is implicitly used for all requestLocationUpdates 229 * APIs that involve a {@link Criteria}. 230 */ 231 public static final String FUSED_PROVIDER = "fused"; 232 233 /** 234 * Key used for the Bundle extra holding a boolean indicating whether 235 * a proximity alert is entering (true) or exiting (false).. 236 */ 237 public static final String KEY_PROXIMITY_ENTERING = "entering"; 238 239 /** 240 * This key is no longer in use. 241 * 242 * <p>Key used for a Bundle extra holding an Integer status value when a status change is 243 * broadcast using a PendingIntent. 244 * 245 * @deprecated Status changes are deprecated and no longer broadcast from Android Q onwards. 246 */ 247 @Deprecated 248 public static final String KEY_STATUS_CHANGED = "status"; 249 250 /** 251 * Key used for an extra holding a boolean enabled/disabled status value when a provider 252 * enabled/disabled event is broadcast using a PendingIntent. 253 * 254 * @see #requestLocationUpdates(String, LocationRequest, PendingIntent) 255 */ 256 public static final String KEY_PROVIDER_ENABLED = "providerEnabled"; 257 258 /** 259 * Key used for an extra holding a {@link Location} value when a location change is sent using 260 * a PendingIntent. If the location change includes a list of batched locations via 261 * {@link #KEY_LOCATIONS} then this key will still be present, and will hold the last location 262 * in the batch. Use {@link Intent#getParcelableExtra(String)} to retrieve the location. 263 * 264 * @see #requestLocationUpdates(String, LocationRequest, PendingIntent) 265 */ 266 public static final String KEY_LOCATION_CHANGED = "location"; 267 268 /** 269 * Key used for an extra holding a array of {@link Location}s when a location change is sent 270 * using a PendingIntent. This key will only be present if the location change includes 271 * multiple (ie, batched) locations, otherwise only {@link #KEY_LOCATION_CHANGED} will be 272 * present. Use {@link Intent#getParcelableArrayExtra(String)} to retrieve the locations. 273 * 274 * <p>The array of locations will never be empty, and will ordered from earliest location to 275 * latest location, the same as with {@link LocationListener#onLocationChanged(List)}. 276 * 277 * @see #requestLocationUpdates(String, LocationRequest, PendingIntent) 278 */ 279 public static final String KEY_LOCATIONS = "locations"; 280 281 /** 282 * Key used for an extra holding an integer request code when location flush completion is sent 283 * using a PendingIntent. 284 * 285 * @see #requestFlush(String, PendingIntent, int) 286 */ 287 public static final String KEY_FLUSH_COMPLETE = "flushComplete"; 288 289 /** 290 * Broadcast intent action when the set of enabled location providers changes. To check the 291 * status of a provider, use {@link #isProviderEnabled(String)}. From Android Q and above, will 292 * include a string intent extra, {@link #EXTRA_PROVIDER_NAME}, with the name of the provider 293 * whose state has changed. From Android R and above, will include a boolean intent extra, 294 * {@link #EXTRA_PROVIDER_ENABLED}, with the enabled state of the provider. 295 * 296 * @see #EXTRA_PROVIDER_NAME 297 * @see #EXTRA_PROVIDER_ENABLED 298 * @see #isProviderEnabled(String) 299 */ 300 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 301 public static final String PROVIDERS_CHANGED_ACTION = "android.location.PROVIDERS_CHANGED"; 302 303 /** 304 * Intent extra included with {@link #PROVIDERS_CHANGED_ACTION} broadcasts, containing the name 305 * of the location provider that has changed. 306 * 307 * @see #PROVIDERS_CHANGED_ACTION 308 * @see #EXTRA_PROVIDER_ENABLED 309 */ 310 public static final String EXTRA_PROVIDER_NAME = "android.location.extra.PROVIDER_NAME"; 311 312 /** 313 * Intent extra included with {@link #PROVIDERS_CHANGED_ACTION} broadcasts, containing the 314 * boolean enabled state of the location provider that has changed. 315 * 316 * @see #PROVIDERS_CHANGED_ACTION 317 * @see #EXTRA_PROVIDER_NAME 318 */ 319 public static final String EXTRA_PROVIDER_ENABLED = "android.location.extra.PROVIDER_ENABLED"; 320 321 /** 322 * Broadcast intent action when the device location enabled state changes. From Android R and 323 * above, will include a boolean intent extra, {@link #EXTRA_LOCATION_ENABLED}, with the enabled 324 * state of location. 325 * 326 * @see #EXTRA_LOCATION_ENABLED 327 * @see #isLocationEnabled() 328 */ 329 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 330 public static final String MODE_CHANGED_ACTION = "android.location.MODE_CHANGED"; 331 332 /** 333 * Intent extra included with {@link #MODE_CHANGED_ACTION} broadcasts, containing the boolean 334 * enabled state of location. 335 * 336 * @see #MODE_CHANGED_ACTION 337 */ 338 public static final String EXTRA_LOCATION_ENABLED = "android.location.extra.LOCATION_ENABLED"; 339 340 /** 341 * Broadcast intent action when the ADAS (Advanced Driving Assistance Systems) GNSS location 342 * enabled state changes. Includes a boolean intent extra, {@link #EXTRA_ADAS_GNSS_ENABLED}, 343 * with the enabled state of ADAS GNSS location. This broadcast only has meaning on automotive 344 * devices. 345 * 346 * @see #EXTRA_ADAS_GNSS_ENABLED 347 * @see #isAdasGnssLocationEnabled() 348 * 349 * @hide 350 */ 351 @SystemApi 352 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 353 public static final String ACTION_ADAS_GNSS_ENABLED_CHANGED = 354 "android.location.action.ADAS_GNSS_ENABLED_CHANGED"; 355 356 /** 357 * Intent extra included with {@link #ACTION_ADAS_GNSS_ENABLED_CHANGED} broadcasts, containing 358 * the boolean enabled state of ADAS GNSS location. 359 * 360 * @see #ACTION_ADAS_GNSS_ENABLED_CHANGED 361 * 362 * @hide 363 */ 364 @SystemApi 365 public static final String EXTRA_ADAS_GNSS_ENABLED = "android.location.extra.ADAS_GNSS_ENABLED"; 366 367 /** 368 * Broadcast intent action indicating that a high power location requests 369 * has either started or stopped being active. The current state of 370 * active location requests should be read from AppOpsManager using 371 * {@code OP_MONITOR_HIGH_POWER_LOCATION}. 372 * 373 * @hide 374 * @deprecated This action is unnecessary from Android S forward. 375 */ 376 @Deprecated 377 public static final String HIGH_POWER_REQUEST_CHANGE_ACTION = 378 "android.location.HIGH_POWER_REQUEST_CHANGE"; 379 380 /** 381 * Broadcast intent action when GNSS capabilities change. This is most common at boot time as 382 * GNSS capabilities are queried from the chipset. Includes an intent extra, 383 * {@link #EXTRA_GNSS_CAPABILITIES}, with the new {@link GnssCapabilities}. 384 * 385 * @see #EXTRA_GNSS_CAPABILITIES 386 * @see #getGnssCapabilities() 387 */ 388 @SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION) 389 public static final String ACTION_GNSS_CAPABILITIES_CHANGED = 390 "android.location.action.GNSS_CAPABILITIES_CHANGED"; 391 392 /** 393 * Intent extra included with {@link #ACTION_GNSS_CAPABILITIES_CHANGED} broadcasts, containing 394 * the new {@link GnssCapabilities}. 395 * 396 * @see #ACTION_GNSS_CAPABILITIES_CHANGED 397 */ 398 public static final String EXTRA_GNSS_CAPABILITIES = "android.location.extra.GNSS_CAPABILITIES"; 399 400 /** 401 * Broadcast intent action for Settings app to inject a footer at the bottom of location 402 * settings. This is for use only by apps that are included in the system image. 403 * 404 * <p>To inject a footer to location settings, you must declare a broadcast receiver for 405 * this action in the manifest: 406 * <pre> 407 * <receiver android:name="com.example.android.footer.MyFooterInjector"> 408 * <intent-filter> 409 * <action android:name="com.android.settings.location.INJECT_FOOTER" /> 410 * </intent-filter> 411 * <meta-data 412 * android:name="com.android.settings.location.FOOTER_STRING" 413 * android:resource="@string/my_injected_footer_string" /> 414 * </receiver> 415 * </pre> 416 * 417 * <p>This broadcast receiver will never actually be invoked. See also 418 * {#METADATA_SETTINGS_FOOTER_STRING}. 419 * 420 * @hide 421 */ 422 public static final String SETTINGS_FOOTER_DISPLAYED_ACTION = 423 "com.android.settings.location.DISPLAYED_FOOTER"; 424 425 /** 426 * Metadata name for {@link LocationManager#SETTINGS_FOOTER_DISPLAYED_ACTION} broadcast 427 * receivers to specify a string resource id as location settings footer text. This is for use 428 * only by apps that are included in the system image. 429 * 430 * <p>See {@link #SETTINGS_FOOTER_DISPLAYED_ACTION} for more detail on how to use. 431 * 432 * @hide 433 */ 434 public static final String METADATA_SETTINGS_FOOTER_STRING = 435 "com.android.settings.location.FOOTER_STRING"; 436 437 /** 438 * Metadata name for {@link LocationManager#SETTINGS_FOOTER_DISPLAYED_ACTION} broadcast 439 * receivers to specify a string resource id as location settings footer HTML snippet. This is 440 * for use only by apps that are included in the system image. If HTML snippet is provided, 441 * plain text footer text specified with {@link #METADATA_SETTINGS_FOOTER_STRING} will be 442 * ignored. 443 * 444 * <p>See {@link #SETTINGS_FOOTER_DISPLAYED_ACTION} for more detail on how to use. 445 * 446 * @hide 447 */ 448 public static final String METADATA_SETTINGS_FOOTER_HTML = 449 "com.android.settings.location.FOOTER_HTML"; 450 451 private static final long MAX_SINGLE_LOCATION_TIMEOUT_MS = 30 * 1000; 452 453 private static final String CACHE_KEY_LOCATION_ENABLED_PROPERTY = 454 PropertyInvalidatedCache.createSystemCacheKey("location_enabled"); 455 getService()456 static ILocationManager getService() throws RemoteException { 457 try { 458 return ILocationManager.Stub.asInterface( 459 ServiceManager.getServiceOrThrow(Context.LOCATION_SERVICE)); 460 } catch (ServiceManager.ServiceNotFoundException e) { 461 throw new RemoteException(e); 462 } 463 } 464 465 private static volatile LocationEnabledCache sLocationEnabledCache = 466 new LocationEnabledCache(4); 467 468 @GuardedBy("sLocationListeners") 469 private static final WeakHashMap<LocationListener, WeakReference<LocationListenerTransport>> 470 sLocationListeners = new WeakHashMap<>(); 471 472 // allows lazy instantiation since most processes do not use GNSS APIs 473 private static class GnssLazyLoader { 474 static final GnssStatusTransportManager sGnssStatusListeners = 475 new GnssStatusTransportManager(); 476 static final GnssNmeaTransportManager sGnssNmeaListeners = 477 new GnssNmeaTransportManager(); 478 static final GnssMeasurementsTransportManager sGnssMeasurementsListeners = 479 new GnssMeasurementsTransportManager(); 480 static final GnssAntennaTransportManager sGnssAntennaInfoListeners = 481 new GnssAntennaTransportManager(); 482 static final GnssNavigationTransportManager sGnssNavigationListeners = 483 new GnssNavigationTransportManager(); 484 } 485 486 private static class ProviderRequestLazyLoader { 487 static final ProviderRequestTransportManager sProviderRequestListeners = 488 new ProviderRequestTransportManager(); 489 } 490 491 final Context mContext; 492 final ILocationManager mService; 493 494 /** 495 * @hide 496 */ LocationManager(@onNull Context context, @NonNull ILocationManager service)497 public LocationManager(@NonNull Context context, @NonNull ILocationManager service) { 498 mContext = Objects.requireNonNull(context); 499 mService = Objects.requireNonNull(service); 500 } 501 502 /** 503 * @hide 504 */ 505 @TestApi getBackgroundThrottlingWhitelist()506 public @NonNull String[] getBackgroundThrottlingWhitelist() { 507 try { 508 return mService.getBackgroundThrottlingWhitelist(); 509 } catch (RemoteException e) { 510 throw e.rethrowFromSystemServer(); 511 } 512 } 513 514 /** 515 * @deprecated Do not use. 516 * @hide 517 */ 518 @Deprecated 519 @TestApi getIgnoreSettingsWhitelist()520 public @NonNull String[] getIgnoreSettingsWhitelist() { 521 return new String[0]; 522 } 523 524 /** 525 * For testing purposes only. 526 * @hide 527 */ 528 @TestApi getIgnoreSettingsAllowlist()529 public @NonNull PackageTagsList getIgnoreSettingsAllowlist() { 530 try { 531 return mService.getIgnoreSettingsAllowlist(); 532 } catch (RemoteException e) { 533 throw e.rethrowFromSystemServer(); 534 } 535 } 536 537 /** 538 * Returns ADAS packages and their associated attribution tags. 539 * 540 * @hide 541 */ getAdasAllowlist()542 public @NonNull PackageTagsList getAdasAllowlist() { 543 try { 544 return mService.getAdasAllowlist(); 545 } catch (RemoteException e) { 546 throw e.rethrowFromSystemServer(); 547 } 548 } 549 550 /** 551 * Returns the extra location controller package on the device. 552 * 553 * @hide 554 */ 555 @SystemApi getExtraLocationControllerPackage()556 public @Nullable String getExtraLocationControllerPackage() { 557 try { 558 return mService.getExtraLocationControllerPackage(); 559 } catch (RemoteException e) { 560 throw e.rethrowFromSystemServer(); 561 } 562 } 563 564 /** 565 * Set the extra location controller package for location services on the device. 566 * 567 * @hide 568 */ 569 @SystemApi 570 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) setExtraLocationControllerPackage(@ullable String packageName)571 public void setExtraLocationControllerPackage(@Nullable String packageName) { 572 try { 573 mService.setExtraLocationControllerPackage(packageName); 574 } catch (RemoteException e) { 575 throw e.rethrowFromSystemServer(); 576 } 577 } 578 579 /** 580 * Set whether the extra location controller package is currently enabled on the device. 581 * 582 * @hide 583 */ 584 @SystemApi 585 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) setExtraLocationControllerPackageEnabled(boolean enabled)586 public void setExtraLocationControllerPackageEnabled(boolean enabled) { 587 try { 588 mService.setExtraLocationControllerPackageEnabled(enabled); 589 } catch (RemoteException e) { 590 throw e.rethrowFromSystemServer(); 591 } 592 } 593 594 /** 595 * Returns whether extra location controller package is currently enabled on the device. 596 * 597 * @hide 598 */ 599 @SystemApi isExtraLocationControllerPackageEnabled()600 public boolean isExtraLocationControllerPackageEnabled() { 601 try { 602 return mService.isExtraLocationControllerPackageEnabled(); 603 } catch (RemoteException e) { 604 throw e.rethrowFromSystemServer(); 605 } 606 } 607 608 /** 609 * Set the extra location controller package for location services on the device. 610 * 611 * @removed 612 * @deprecated Use {@link #setExtraLocationControllerPackage} instead. 613 * @hide 614 */ 615 @Deprecated 616 @SystemApi 617 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) setLocationControllerExtraPackage(String packageName)618 public void setLocationControllerExtraPackage(String packageName) { 619 try { 620 mService.setExtraLocationControllerPackage(packageName); 621 } catch (RemoteException e) { 622 throw e.rethrowFromSystemServer(); 623 } 624 } 625 626 /** 627 * Set whether the extra location controller package is currently enabled on the device. 628 * 629 * @removed 630 * @deprecated Use {@link #setExtraLocationControllerPackageEnabled} instead. 631 * @hide 632 */ 633 @SystemApi 634 @Deprecated 635 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) setLocationControllerExtraPackageEnabled(boolean enabled)636 public void setLocationControllerExtraPackageEnabled(boolean enabled) { 637 try { 638 mService.setExtraLocationControllerPackageEnabled(enabled); 639 } catch (RemoteException e) { 640 throw e.rethrowFromSystemServer(); 641 } 642 } 643 644 /** 645 * Returns the current enabled/disabled state of location. To listen for changes, see 646 * {@link #MODE_CHANGED_ACTION}. 647 * 648 * @return true if location is enabled and false if location is disabled. 649 */ isLocationEnabled()650 public boolean isLocationEnabled() { 651 return isLocationEnabledForUser(mContext.getUser()); 652 } 653 654 /** 655 * Returns the current enabled/disabled state of location for the given user. 656 * 657 * @param userHandle the user to query 658 * @return true if location is enabled and false if location is disabled. 659 * 660 * @hide 661 */ 662 @SystemApi isLocationEnabledForUser(@onNull UserHandle userHandle)663 public boolean isLocationEnabledForUser(@NonNull UserHandle userHandle) { 664 // skip the cache for any "special" user ids - special ids like CURRENT_USER may change 665 // their meaning over time and should never be in the cache. we could resolve the special 666 // user ids here, but that would require an x-process call anyways, and the whole point of 667 // the cache is to avoid x-process calls. 668 if (userHandle.getIdentifier() >= 0) { 669 PropertyInvalidatedCache<Integer, Boolean> cache = sLocationEnabledCache; 670 if (cache != null) { 671 return cache.query(userHandle.getIdentifier()); 672 } 673 } 674 675 try { 676 return mService.isLocationEnabledForUser(userHandle.getIdentifier()); 677 } catch (RemoteException e) { 678 throw e.rethrowFromSystemServer(); 679 } 680 } 681 682 /** 683 * Enables or disables location for the given user. 684 * 685 * @param enabled true to enable location and false to disable location. 686 * @param userHandle the user to set 687 * 688 * @hide 689 */ 690 @SystemApi 691 @RequiresPermission(WRITE_SECURE_SETTINGS) setLocationEnabledForUser(boolean enabled, @NonNull UserHandle userHandle)692 public void setLocationEnabledForUser(boolean enabled, @NonNull UserHandle userHandle) { 693 try { 694 mService.setLocationEnabledForUser(enabled, userHandle.getIdentifier()); 695 } catch (RemoteException e) { 696 throw e.rethrowFromSystemServer(); 697 } 698 } 699 700 /** 701 * Returns the current enabled/disabled state of ADAS (Advanced Driving Assistance Systems) 702 * GNSS location access for the given user. This controls safety critical automotive access to 703 * GNSS location. This only has meaning on automotive devices. 704 * 705 * @return true if ADAS location is enabled and false if ADAS location is disabled. 706 * 707 * @hide 708 */ 709 @SystemApi isAdasGnssLocationEnabled()710 public boolean isAdasGnssLocationEnabled() { 711 try { 712 return mService.isAdasGnssLocationEnabledForUser(mContext.getUser().getIdentifier()); 713 } catch (RemoteException e) { 714 throw e.rethrowFromSystemServer(); 715 } 716 } 717 718 /** 719 * Enables or disables ADAS (Advanced Driving Assistance Systems) GNSS location access for the 720 * given user. This only has meaning on automotive devices. 721 * 722 * @param enabled true to enable ADAS location and false to disable ADAS location. 723 * 724 * @hide 725 */ 726 @SystemApi 727 @RequiresPermission(LOCATION_BYPASS) 728 @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) setAdasGnssLocationEnabled(boolean enabled)729 public void setAdasGnssLocationEnabled(boolean enabled) { 730 try { 731 mService.setAdasGnssLocationEnabledForUser(enabled, mContext.getUser().getIdentifier()); 732 } catch (RemoteException e) { 733 throw e.rethrowFromSystemServer(); 734 } 735 } 736 737 /** 738 * Returns the current enabled/disabled status of the given provider. To listen for changes, see 739 * {@link #PROVIDERS_CHANGED_ACTION}. 740 * 741 * Before API version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method would throw 742 * {@link SecurityException} if the location permissions were not sufficient to use the 743 * specified provider. 744 * 745 * @param provider a provider listed by {@link #getAllProviders()} 746 * @return true if the provider exists and is enabled 747 * 748 * @throws IllegalArgumentException if provider is null 749 */ isProviderEnabled(@onNull String provider)750 public boolean isProviderEnabled(@NonNull String provider) { 751 return isProviderEnabledForUser(provider, Process.myUserHandle()); 752 } 753 754 /** 755 * Returns the current enabled/disabled status of the given provider and user. Callers should 756 * prefer {@link #isLocationEnabledForUser(UserHandle)} unless they depend on provider-specific 757 * APIs. 758 * 759 * Before API version {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method would throw 760 * {@link SecurityException} if the location permissions were not sufficient to use the 761 * specified provider. 762 * 763 * @param provider a provider listed by {@link #getAllProviders()} 764 * @param userHandle the user to query 765 * @return true if the provider exists and is enabled 766 * 767 * @throws IllegalArgumentException if provider is null 768 * @hide 769 */ 770 @SystemApi isProviderEnabledForUser( @onNull String provider, @NonNull UserHandle userHandle)771 public boolean isProviderEnabledForUser( 772 @NonNull String provider, @NonNull UserHandle userHandle) { 773 Preconditions.checkArgument(provider != null, "invalid null provider"); 774 775 try { 776 return mService.isProviderEnabledForUser(provider, userHandle.getIdentifier()); 777 } catch (RemoteException e) { 778 throw e.rethrowFromSystemServer(); 779 } 780 } 781 782 /** 783 * Method for enabling or disabling a single location provider. This method is deprecated and 784 * functions as a best effort. It should not be relied on in any meaningful sense as providers 785 * may no longer be enabled or disabled by clients. 786 * 787 * @param provider a provider listed by {@link #getAllProviders()} 788 * @param enabled whether to enable or disable the provider 789 * @param userHandle the user to set 790 * @return true if the value was set, false otherwise 791 * 792 * @throws IllegalArgumentException if provider is null 793 * @deprecated Do not manipulate providers individually, use 794 * {@link #setLocationEnabledForUser(boolean, UserHandle)} instead. 795 * @hide 796 */ 797 @Deprecated 798 @SystemApi 799 @RequiresPermission(WRITE_SECURE_SETTINGS) setProviderEnabledForUser( @onNull String provider, boolean enabled, @NonNull UserHandle userHandle)800 public boolean setProviderEnabledForUser( 801 @NonNull String provider, boolean enabled, @NonNull UserHandle userHandle) { 802 Preconditions.checkArgument(provider != null, "invalid null provider"); 803 return false; 804 } 805 806 /** 807 * Set whether GNSS requests are suspended on the automotive device. 808 * 809 * For devices where GNSS prevents the system from going into a low power state, GNSS should 810 * be suspended right before going into the lower power state and resumed right after the device 811 * wakes up. 812 * 813 * This method disables GNSS and should only be used for power management use cases such as 814 * suspend-to-RAM or suspend-to-disk. 815 * 816 * @hide 817 */ 818 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 819 @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) 820 @RequiresPermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS) setAutomotiveGnssSuspended(boolean suspended)821 public void setAutomotiveGnssSuspended(boolean suspended) { 822 try { 823 mService.setAutomotiveGnssSuspended(suspended); 824 } catch (RemoteException e) { 825 throw e.rethrowFromSystemServer(); 826 } 827 } 828 829 /** 830 * Return whether GNSS requests are suspended on the automotive device. 831 * 832 * @return true if GNSS requests are suspended and false if they aren't. 833 * 834 * @hide 835 */ 836 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 837 @RequiresFeature(PackageManager.FEATURE_AUTOMOTIVE) 838 @RequiresPermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS) isAutomotiveGnssSuspended()839 public boolean isAutomotiveGnssSuspended() { 840 try { 841 return mService.isAutomotiveGnssSuspended(); 842 } catch (RemoteException e) { 843 throw e.rethrowFromSystemServer(); 844 } 845 } 846 847 /** 848 * Gets the last known location from the fused provider, or null if there is no last known 849 * location. The returned location may be quite old in some circumstances, so the age of the 850 * location should always be checked. 851 * 852 * @return the last known location, or null if not available 853 * 854 * @throws SecurityException if no suitable location permission is present 855 * 856 * @hide 857 */ 858 @Nullable 859 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) getLastLocation()860 public Location getLastLocation() { 861 return getLastKnownLocation(FUSED_PROVIDER); 862 } 863 864 /** 865 * Gets the last known location from the given provider, or null if there is no last known 866 * location. The returned location may be quite old in some circumstances, so the age of the 867 * location should always be checked. 868 * 869 * <p>This will never activate sensors to compute a new location, and will only ever return a 870 * cached location. 871 * 872 * <p>See also {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)} which 873 * will always attempt to return a current location, but will potentially use additional power 874 * in the course of the attempt as compared to this method. 875 * 876 * @param provider a provider listed by {@link #getAllProviders()} 877 * 878 * @return the last known location for the given provider, or null if not available 879 * 880 * @throws SecurityException if no suitable permission is present 881 * @throws IllegalArgumentException if provider is null or doesn't exist 882 */ 883 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) 884 @Nullable getLastKnownLocation(@onNull String provider)885 public Location getLastKnownLocation(@NonNull String provider) { 886 return getLastKnownLocation(provider, new LastLocationRequest.Builder().build()); 887 } 888 889 /** 890 * Gets the last known location from the given provider, or null if there is no last known 891 * location. 892 * 893 * <p>See {@link LastLocationRequest} documentation for an explanation of various request 894 * parameters and how they can affect the returned location. 895 * 896 * <p>See {@link #getLastKnownLocation(String)} for more detail on how this method works. 897 * 898 * @param provider a provider listed by {@link #getAllProviders()} 899 * @param lastLocationRequest the last location request containing location parameters 900 * 901 * @return the last known location for the given provider, or null if not available 902 * 903 * @throws SecurityException if no suitable permission is present 904 * @throws IllegalArgumentException if provider is null or doesn't exist 905 * @throws IllegalArgumentException if lastLocationRequest is null 906 * 907 * @hide 908 */ 909 @SystemApi 910 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) 911 @Nullable getLastKnownLocation(@onNull String provider, @NonNull LastLocationRequest lastLocationRequest)912 public Location getLastKnownLocation(@NonNull String provider, 913 @NonNull LastLocationRequest lastLocationRequest) { 914 Preconditions.checkArgument(provider != null, "invalid null provider"); 915 Preconditions.checkArgument(lastLocationRequest != null, 916 "invalid null last location request"); 917 918 try { 919 return mService.getLastLocation(provider, lastLocationRequest, 920 mContext.getPackageName(), mContext.getAttributionTag()); 921 } catch (RemoteException e) { 922 throw e.rethrowFromSystemServer(); 923 } 924 } 925 926 /** 927 * Asynchronously returns a single current location fix from the given provider. 928 * 929 * <p>See 930 * {@link #getCurrentLocation(String, LocationRequest, CancellationSignal, Executor, Consumer)} 931 * for more information. 932 * 933 * @param provider a provider listed by {@link #getAllProviders()} 934 * @param cancellationSignal an optional signal that allows for cancelling this call 935 * @param executor the callback will take place on this {@link Executor} 936 * @param consumer the callback invoked with either a {@link Location} or null 937 * 938 * @throws IllegalArgumentException if provider is null or doesn't exist 939 * @throws IllegalArgumentException if executor is null 940 * @throws IllegalArgumentException if consumer is null 941 * @throws SecurityException if no suitable permission is present 942 */ 943 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) getCurrentLocation(@onNull String provider, @Nullable CancellationSignal cancellationSignal, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer)944 public void getCurrentLocation(@NonNull String provider, 945 @Nullable CancellationSignal cancellationSignal, 946 @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer) { 947 getCurrentLocation( 948 provider, 949 new LocationRequest.Builder(0).build(), 950 cancellationSignal, executor, consumer); 951 } 952 953 /** 954 * Asynchronously returns a single current location fix from the given provider based on the 955 * given {@link LocationRequest}. 956 * 957 * <p>See 958 * {@link #getCurrentLocation(String, LocationRequest, CancellationSignal, Executor, Consumer)} 959 * for more information. 960 * 961 * @param locationRequest the location request containing location parameters 962 * @param cancellationSignal an optional signal that allows for cancelling this call 963 * @param executor the callback will take place on this {@link Executor} 964 * @param consumer the callback invoked with either a {@link Location} or null 965 * 966 * @throws IllegalArgumentException if provider is null or doesn't exist 967 * @throws IllegalArgumentException if executor is null 968 * @throws IllegalArgumentException if consumer is null 969 * @throws SecurityException if no suitable permission is present 970 * @hide 971 * @deprecated Use 972 * {@link #getCurrentLocation(String, LocationRequest, CancellationSignal, Executor, Consumer)} 973 * instead. 974 */ 975 @Deprecated 976 @SystemApi 977 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) getCurrentLocation(@onNull LocationRequest locationRequest, @Nullable CancellationSignal cancellationSignal, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer)978 public void getCurrentLocation(@NonNull LocationRequest locationRequest, 979 @Nullable CancellationSignal cancellationSignal, 980 @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer) { 981 Preconditions.checkArgument(locationRequest.getProvider() != null); 982 getCurrentLocation(locationRequest.getProvider(), locationRequest, cancellationSignal, 983 executor, consumer); 984 } 985 986 /** 987 * Asynchronously returns a single current location fix from the given provider based on the 988 * given {@link LocationRequest}. This may activate sensors in order to compute a new location, 989 * unlike {@link #getLastKnownLocation(String)}, which will only return a cached fix if 990 * available. The given callback will be invoked once and only once, either with a valid 991 * location or with a null location if the provider was unable to generate a valid location. 992 * 993 * <p>A client may supply an optional {@link CancellationSignal}. If this is used to cancel the 994 * operation, no callback should be expected after the cancellation. 995 * 996 * <p>This method may return locations from the very recent past (on the order of several 997 * seconds), but will never return older locations (for example, several minutes old or older). 998 * Clients may rely upon the guarantee that if this method returns a location, it will represent 999 * the best estimation of the location of the device in the present moment. 1000 * 1001 * <p>Clients calling this method from the background may notice that the method fails to 1002 * determine a valid location fix more often than while in the foreground. Background 1003 * applications may be throttled in their location accesses to some degree. 1004 * 1005 * The given location request may be used to provide hints on how a fresh location is computed 1006 * if necessary. In particular {@link LocationRequest#getDurationMillis()} can be used to 1007 * provide maximum duration allowed before failing. The system will always cap the maximum 1008 * amount of time a request for current location may run to some reasonable value (less than a 1009 * minute for example) before the request is failed. 1010 * 1011 * @param provider a provider listed by {@link #getAllProviders()} 1012 * @param locationRequest the location request containing location parameters 1013 * @param cancellationSignal an optional signal that allows for cancelling this call 1014 * @param executor the callback will take place on this {@link Executor} 1015 * @param consumer the callback invoked with either a {@link Location} or null 1016 * 1017 * @throws IllegalArgumentException if provider is null or doesn't exist 1018 * @throws IllegalArgumentException if executor is null 1019 * @throws IllegalArgumentException if consumer is null 1020 * @throws SecurityException if no suitable permission is present 1021 */ 1022 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) getCurrentLocation(@onNull String provider, @NonNull LocationRequest locationRequest, @Nullable CancellationSignal cancellationSignal, @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer)1023 public void getCurrentLocation(@NonNull String provider, 1024 @NonNull LocationRequest locationRequest, 1025 @Nullable CancellationSignal cancellationSignal, 1026 @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<Location> consumer) { 1027 Preconditions.checkArgument(provider != null, "invalid null provider"); 1028 Preconditions.checkArgument(locationRequest != null, "invalid null location request"); 1029 1030 if (cancellationSignal != null) { 1031 cancellationSignal.throwIfCanceled(); 1032 } 1033 1034 GetCurrentLocationTransport transport = new GetCurrentLocationTransport(executor, consumer, 1035 cancellationSignal); 1036 1037 ICancellationSignal cancelRemote; 1038 try { 1039 cancelRemote = mService.getCurrentLocation(provider, 1040 locationRequest, transport, mContext.getPackageName(), 1041 mContext.getAttributionTag(), AppOpsManager.toReceiverId(consumer)); 1042 } catch (RemoteException e) { 1043 throw e.rethrowFromSystemServer(); 1044 } 1045 1046 if (cancellationSignal != null) { 1047 cancellationSignal.setRemote(cancelRemote); 1048 } 1049 } 1050 1051 /** 1052 * Register for a single location update using the named provider and a callback. 1053 * 1054 * <p>See {@link #requestLocationUpdates(String, long, float, LocationListener, Looper)} for 1055 * more detail on how to use this method. 1056 * 1057 * @param provider a provider listed by {@link #getAllProviders()} 1058 * @param listener the listener to receive location updates 1059 * @param looper the looper handling listener callbacks, or null to use the looper of the 1060 * calling thread 1061 * 1062 * @throws IllegalArgumentException if provider is null or doesn't exist 1063 * @throws IllegalArgumentException if listener is null 1064 * @throws SecurityException if no suitable permission is present 1065 * @deprecated Use {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)} 1066 * instead as it does not carry a risk of extreme battery drain. 1067 */ 1068 @Deprecated 1069 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestSingleUpdate( @onNull String provider, @NonNull LocationListener listener, @Nullable Looper looper)1070 public void requestSingleUpdate( 1071 @NonNull String provider, @NonNull LocationListener listener, @Nullable Looper looper) { 1072 Preconditions.checkArgument(provider != null, "invalid null provider"); 1073 1074 Handler handler = looper == null ? new Handler() : new Handler(looper); 1075 requestLocationUpdates( 1076 provider, 1077 new LocationRequest.Builder(0) 1078 .setMaxUpdates(1) 1079 .setDurationMillis(MAX_SINGLE_LOCATION_TIMEOUT_MS) 1080 .build(), 1081 new HandlerExecutor(handler), 1082 listener); 1083 } 1084 1085 /** 1086 * Register for a single location update using a Criteria and a callback. 1087 * 1088 * <p>Note: Since Android KitKat, Criteria requests will always result in using the 1089 * {@link #FUSED_PROVIDER}. 1090 * 1091 * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} for more detail 1092 * on how to use this method. 1093 * 1094 * @param criteria contains parameters to choose the appropriate provider for location updates 1095 * @param listener the listener to receive location updates 1096 * @param looper the looper handling listener callbacks, or null to use the looper of the 1097 * calling thread 1098 * 1099 * @throws IllegalArgumentException if criteria is null 1100 * @throws IllegalArgumentException if listener is null 1101 * @throws SecurityException if no suitable permission is present 1102 * @deprecated Use {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)} 1103 * instead as it does not carry a risk of extreme battery drain. 1104 */ 1105 @Deprecated 1106 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestSingleUpdate( @onNull Criteria criteria, @NonNull LocationListener listener, @Nullable Looper looper)1107 public void requestSingleUpdate( 1108 @NonNull Criteria criteria, 1109 @NonNull LocationListener listener, 1110 @Nullable Looper looper) { 1111 Preconditions.checkArgument(criteria != null, "invalid null criteria"); 1112 1113 Handler handler = looper == null ? new Handler() : new Handler(looper); 1114 requestLocationUpdates( 1115 FUSED_PROVIDER, 1116 new LocationRequest.Builder(0) 1117 .setQuality(criteria) 1118 .setMaxUpdates(1) 1119 .setDurationMillis(MAX_SINGLE_LOCATION_TIMEOUT_MS) 1120 .build(), 1121 new HandlerExecutor(handler), 1122 listener); 1123 } 1124 1125 /** 1126 * Register for a single location update using a named provider and pending intent. 1127 * 1128 * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} for more detail 1129 * on how to use this method. 1130 * 1131 * @param provider a provider listed by {@link #getAllProviders()} 1132 * @param pendingIntent the pending intent to send location updates 1133 * 1134 * @throws IllegalArgumentException if provider is null or doesn't exist 1135 * @throws IllegalArgumentException if intent is null 1136 * @throws SecurityException if no suitable permission is present 1137 * @deprecated Use {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)} 1138 * instead as it does not carry a risk of extreme battery drain. 1139 */ 1140 @Deprecated 1141 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestSingleUpdate(@onNull String provider, @NonNull PendingIntent pendingIntent)1142 public void requestSingleUpdate(@NonNull String provider, 1143 @NonNull PendingIntent pendingIntent) { 1144 Preconditions.checkArgument(provider != null, "invalid null provider"); 1145 1146 requestLocationUpdates( 1147 provider, 1148 new LocationRequest.Builder(0) 1149 .setMaxUpdates(1) 1150 .setDurationMillis(MAX_SINGLE_LOCATION_TIMEOUT_MS) 1151 .build(), 1152 pendingIntent); 1153 } 1154 1155 /** 1156 * Register for a single location update using a Criteria and pending intent. 1157 * 1158 * <p>Note: Since Android KitKat, Criteria requests will always result in using the 1159 * {@link #FUSED_PROVIDER}. 1160 * 1161 * <p>See {@link #requestLocationUpdates(long, float, Criteria, PendingIntent)} for more detail 1162 * on how to use this method. 1163 * 1164 * @param criteria contains parameters to choose the appropriate provider for location 1165 * updates 1166 * @param pendingIntent the pending intent to send location updates 1167 * 1168 * @throws IllegalArgumentException if provider is null or doesn't exist 1169 * @throws IllegalArgumentException if intent is null 1170 * @throws SecurityException if no suitable permission is present 1171 * @deprecated Use {@link #getCurrentLocation(String, CancellationSignal, Executor, Consumer)} 1172 * instead as it does not carry a risk of extreme battery drain. 1173 */ 1174 @Deprecated 1175 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestSingleUpdate(@onNull Criteria criteria, @NonNull PendingIntent pendingIntent)1176 public void requestSingleUpdate(@NonNull Criteria criteria, 1177 @NonNull PendingIntent pendingIntent) { 1178 Preconditions.checkArgument(criteria != null, "invalid null criteria"); 1179 1180 requestLocationUpdates( 1181 FUSED_PROVIDER, 1182 new LocationRequest.Builder(0) 1183 .setQuality(criteria) 1184 .setMaxUpdates(1) 1185 .setDurationMillis(MAX_SINGLE_LOCATION_TIMEOUT_MS) 1186 .build(), 1187 pendingIntent); 1188 } 1189 1190 /** 1191 * Register for location updates from the given provider with the given arguments, and a 1192 * callback on the {@link Looper} of the calling thread. 1193 * 1194 * <p>See {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} 1195 * for more detail on how this method works. 1196 * 1197 * <p class="note"> Prior to Jellybean, the minTime parameter was only a hint, and some location 1198 * provider implementations ignored it. For Jellybean and onwards however, it is mandatory for 1199 * Android compatible devices to observe both the minTime and minDistance parameters. 1200 * 1201 * @param provider a provider listed by {@link #getAllProviders()} 1202 * @param minTimeMs minimum time interval between location updates in milliseconds 1203 * @param minDistanceM minimum distance between location updates in meters 1204 * @param listener the listener to receive location updates 1205 * 1206 * @throws IllegalArgumentException if provider is null or doesn't exist 1207 * @throws IllegalArgumentException if listener is null 1208 * @throws RuntimeException if the calling thread has no Looper 1209 * @throws SecurityException if no suitable permission is present 1210 */ 1211 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates(@onNull String provider, long minTimeMs, float minDistanceM, @NonNull LocationListener listener)1212 public void requestLocationUpdates(@NonNull String provider, long minTimeMs, float minDistanceM, 1213 @NonNull LocationListener listener) { 1214 requestLocationUpdates(provider, minTimeMs, minDistanceM, listener, null); 1215 } 1216 1217 /** 1218 * Register for location updates from the given provider with the given arguments, and a 1219 * callback on the specified {@link Looper}. 1220 * 1221 * <p>See {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} 1222 * for more detail on how this method works. 1223 * 1224 * <p class="note">Prior to Jellybean, the minTime parameter was only a hint, and some location 1225 * provider implementations ignored it. For Jellybean and onwards however, it is mandatory for 1226 * Android compatible devices to observe both the minTime and minDistance parameters. 1227 * 1228 * @param provider a provider listed by {@link #getAllProviders()} 1229 * @param minTimeMs minimum time interval between location updates in milliseconds 1230 * @param minDistanceM minimum distance between location updates in meters 1231 * @param listener the listener to receive location updates 1232 * @param looper the looper handling listener callbacks, or null to use the looper of the 1233 * calling thread 1234 * 1235 * @throws IllegalArgumentException if provider is null or doesn't exist 1236 * @throws IllegalArgumentException if listener is null 1237 * @throws SecurityException if no suitable permission is present 1238 */ 1239 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates(@onNull String provider, long minTimeMs, float minDistanceM, @NonNull LocationListener listener, @Nullable Looper looper)1240 public void requestLocationUpdates(@NonNull String provider, long minTimeMs, float minDistanceM, 1241 @NonNull LocationListener listener, @Nullable Looper looper) { 1242 Handler handler = looper == null ? new Handler() : new Handler(looper); 1243 requestLocationUpdates(provider, minTimeMs, minDistanceM, new HandlerExecutor(handler), 1244 listener); 1245 } 1246 1247 /** 1248 * Register for location updates using the named provider, and a callback on 1249 * the specified {@link Executor}. 1250 * 1251 * <p>See {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} 1252 * for more detail on how this method works. 1253 * 1254 * <p class="note">Prior to Jellybean, the minTime parameter was only a hint, and some location 1255 * provider implementations ignored it. For Jellybean and onwards however, it is mandatory for 1256 * Android compatible devices to observe both the minTime and minDistance parameters. 1257 * 1258 * @param provider a provider listed by {@link #getAllProviders()} 1259 * @param minTimeMs minimum time interval between location updates in milliseconds 1260 * @param minDistanceM minimum distance between location updates in meters 1261 * @param executor the executor handling listener callbacks 1262 * @param listener the listener to receive location updates 1263 * 1264 * @throws IllegalArgumentException if provider is null or doesn't exist 1265 * @throws IllegalArgumentException if executor is null 1266 * @throws IllegalArgumentException if listener is null 1267 * @throws SecurityException if no suitable permission is present 1268 */ 1269 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates( @onNull String provider, long minTimeMs, float minDistanceM, @NonNull @CallbackExecutor Executor executor, @NonNull LocationListener listener)1270 public void requestLocationUpdates( 1271 @NonNull String provider, 1272 long minTimeMs, 1273 float minDistanceM, 1274 @NonNull @CallbackExecutor Executor executor, 1275 @NonNull LocationListener listener) { 1276 Preconditions.checkArgument(provider != null, "invalid null provider"); 1277 1278 requestLocationUpdates( 1279 provider, 1280 createFromDeprecatedProvider(provider, minTimeMs, minDistanceM, false), 1281 executor, 1282 listener); 1283 } 1284 1285 /** 1286 * Register for location updates using a provider selected through the given Criteria, and a 1287 * callback on the specified {@link Looper}. 1288 * 1289 * <p>Note: Since Android KitKat, Criteria requests will always result in using the 1290 * {@link #FUSED_PROVIDER}. 1291 * 1292 * <p>See {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} 1293 * for more detail on how this method works. 1294 * 1295 * @param minTimeMs minimum time interval between location updates in milliseconds 1296 * @param minDistanceM minimum distance between location updates in meters 1297 * @param criteria contains parameters to choose the appropriate provider for location updates 1298 * @param listener the listener to receive location updates 1299 * 1300 * @throws IllegalArgumentException if criteria is null 1301 * @throws IllegalArgumentException if listener is null 1302 * @throws SecurityException if no suitable permission is present 1303 * 1304 * @deprecated Use 1305 * {@link #requestLocationUpdates(String, long, float, LocationListener, Looper)} instead to 1306 * explicitly select a provider. 1307 */ 1308 @Deprecated 1309 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates(long minTimeMs, float minDistanceM, @NonNull Criteria criteria, @NonNull LocationListener listener, @Nullable Looper looper)1310 public void requestLocationUpdates(long minTimeMs, float minDistanceM, 1311 @NonNull Criteria criteria, @NonNull LocationListener listener, 1312 @Nullable Looper looper) { 1313 Handler handler = looper == null ? new Handler() : new Handler(looper); 1314 requestLocationUpdates(minTimeMs, minDistanceM, criteria, new HandlerExecutor(handler), 1315 listener); 1316 } 1317 1318 /** 1319 * Register for location updates using a provider selected through the given Criteria, and a 1320 * callback on the specified {@link Executor}. 1321 * 1322 * <p>Note: Since Android KitKat, Criteria requests will always result in using the 1323 * {@link #FUSED_PROVIDER}. 1324 * 1325 * <p>See {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} 1326 * for more detail on how this method works. 1327 * 1328 * @param minTimeMs minimum time interval between location updates in milliseconds 1329 * @param minDistanceM minimum distance between location updates in meters 1330 * @param criteria contains parameters to choose the appropriate provider for location updates 1331 * @param executor the executor handling listener callbacks 1332 * @param listener the listener to receive location updates 1333 * 1334 * @throws IllegalArgumentException if criteria is null 1335 * @throws IllegalArgumentException if executor is null 1336 * @throws IllegalArgumentException if listener is null 1337 * @throws SecurityException if no suitable permission is present 1338 * 1339 * @deprecated Use 1340 * {@link #requestLocationUpdates(String, long, float, Executor, LocationListener)} instead to 1341 * explicitly select a provider. 1342 */ 1343 @Deprecated 1344 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates( long minTimeMs, float minDistanceM, @NonNull Criteria criteria, @NonNull @CallbackExecutor Executor executor, @NonNull LocationListener listener)1345 public void requestLocationUpdates( 1346 long minTimeMs, 1347 float minDistanceM, 1348 @NonNull Criteria criteria, 1349 @NonNull @CallbackExecutor Executor executor, 1350 @NonNull LocationListener listener) { 1351 Preconditions.checkArgument(criteria != null, "invalid null criteria"); 1352 1353 requestLocationUpdates( 1354 FUSED_PROVIDER, 1355 createFromDeprecatedCriteria(criteria, minTimeMs, minDistanceM, false), 1356 executor, 1357 listener); 1358 } 1359 1360 /** 1361 * Register for location updates using the named provider, and callbacks delivered via the 1362 * provided {@link PendingIntent}. 1363 * 1364 * <p>See {@link #requestLocationUpdates(String, LocationRequest, PendingIntent)} for more 1365 * detail on how this method works. 1366 * 1367 * @param provider a provider listed by {@link #getAllProviders()} 1368 * @param minTimeMs minimum time interval between location updates in milliseconds 1369 * @param minDistanceM minimum distance between location updates in meters 1370 * @param pendingIntent the pending intent to send location updates 1371 * 1372 * @throws IllegalArgumentException if provider is null or doesn't exist 1373 * @throws IllegalArgumentException if pendingIntent is null 1374 * @throws SecurityException if no suitable permission is present 1375 */ 1376 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates(@onNull String provider, long minTimeMs, float minDistanceM, @NonNull PendingIntent pendingIntent)1377 public void requestLocationUpdates(@NonNull String provider, long minTimeMs, float minDistanceM, 1378 @NonNull PendingIntent pendingIntent) { 1379 Preconditions.checkArgument(provider != null, "invalid null provider"); 1380 1381 requestLocationUpdates( 1382 provider, 1383 createFromDeprecatedProvider(provider, minTimeMs, minDistanceM, false), 1384 pendingIntent); 1385 } 1386 1387 /** 1388 * Register for location updates using a provider selected through the given Criteria, and 1389 * callbacks delivered via the provided {@link PendingIntent}. 1390 * 1391 * <p>Note: Since Android KitKat, Criteria requests will always result in using the 1392 * {@link #FUSED_PROVIDER}. 1393 * 1394 * <p>See {@link #requestLocationUpdates(String, long, float, PendingIntent)} for more detail on 1395 * how this method works. 1396 * 1397 * @param minTimeMs minimum time interval between location updates in milliseconds 1398 * @param minDistanceM minimum distance between location updates in meters 1399 * @param criteria contains parameters to choose the appropriate provider for location updates 1400 * @param pendingIntent the pending intent to send location updates 1401 * 1402 * @throws IllegalArgumentException if provider is null or doesn't exist 1403 * @throws IllegalArgumentException if pendingIntent is null 1404 * @throws SecurityException if no suitable permission is present 1405 * 1406 * @deprecated Use {@link #requestLocationUpdates(String, long, float, PendingIntent)} instead 1407 * to explicitly select a provider. 1408 */ 1409 @Deprecated 1410 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates(long minTimeMs, float minDistanceM, @NonNull Criteria criteria, @NonNull PendingIntent pendingIntent)1411 public void requestLocationUpdates(long minTimeMs, float minDistanceM, 1412 @NonNull Criteria criteria, @NonNull PendingIntent pendingIntent) { 1413 Preconditions.checkArgument(criteria != null, "invalid null criteria"); 1414 requestLocationUpdates( 1415 FUSED_PROVIDER, 1416 createFromDeprecatedCriteria(criteria, minTimeMs, minDistanceM, false), 1417 pendingIntent); 1418 } 1419 1420 /** 1421 * Register for location updates using a {@link LocationRequest}, and a callback on the 1422 * specified {@link Looper}. 1423 * 1424 * <p>The system will automatically select and enable the best provider based on the given 1425 * {@link LocationRequest}. The LocationRequest can be null, in which case the system will 1426 * choose default low power parameters for location updates, but this is heavily discouraged, 1427 * and an explicit LocationRequest should always be provided. 1428 * 1429 * <p>See {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} 1430 * for more detail on how this method works. 1431 * 1432 * @param locationRequest the location request containing location parameters 1433 * @param listener the listener to receive location updates 1434 * @param looper the looper handling listener callbacks, or null to use the looper of the 1435 * calling thread 1436 * 1437 * @throws IllegalArgumentException if listener is null 1438 * @throws SecurityException if no suitable permission is present 1439 * 1440 * @hide 1441 * @deprecated Use 1442 * {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} instead. 1443 */ 1444 @Deprecated 1445 @SystemApi 1446 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates( @ullable LocationRequest locationRequest, @NonNull LocationListener listener, @Nullable Looper looper)1447 public void requestLocationUpdates( 1448 @Nullable LocationRequest locationRequest, 1449 @NonNull LocationListener listener, 1450 @Nullable Looper looper) { 1451 Handler handler = looper == null ? new Handler() : new Handler(looper); 1452 requestLocationUpdates(locationRequest, new HandlerExecutor(handler), listener); 1453 } 1454 1455 /** 1456 * Register for location updates using a {@link LocationRequest}, and a callback on the 1457 * specified {@link Executor}. 1458 * 1459 * <p>See {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} 1460 * for more detail on how this method works. 1461 * 1462 * @param locationRequest the location request containing location parameters 1463 * @param executor the executor handling listener callbacks 1464 * @param listener the listener to receive location updates 1465 * 1466 * @throws IllegalArgumentException if executor is null 1467 * @throws IllegalArgumentException if listener is null 1468 * @throws SecurityException if no suitable permission is present 1469 * 1470 * @hide 1471 * @deprecated Use 1472 * {@link #requestLocationUpdates(String, LocationRequest, Executor, LocationListener)} instead. 1473 */ 1474 @Deprecated 1475 @SystemApi 1476 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates( @ullable LocationRequest locationRequest, @NonNull @CallbackExecutor Executor executor, @NonNull LocationListener listener)1477 public void requestLocationUpdates( 1478 @Nullable LocationRequest locationRequest, 1479 @NonNull @CallbackExecutor Executor executor, 1480 @NonNull LocationListener listener) { 1481 if (locationRequest == null) { 1482 locationRequest = LocationRequest.create(); 1483 } 1484 Preconditions.checkArgument(locationRequest.getProvider() != null); 1485 requestLocationUpdates(locationRequest.getProvider(), locationRequest, executor, listener); 1486 } 1487 1488 /** 1489 * Register for location updates using a {@link LocationRequest}, and callbacks delivered via 1490 * the provided {@link PendingIntent}. 1491 * 1492 * <p>See {@link #requestLocationUpdates(String, LocationRequest, PendingIntent)} for more 1493 * detail on how this method works. 1494 * 1495 * @param locationRequest the location request containing location parameters 1496 * @param pendingIntent the pending intent to send location updates 1497 * 1498 * @throws IllegalArgumentException if pendingIntent is null 1499 * @throws SecurityException if no suitable permission is present 1500 * 1501 * @hide 1502 * @deprecated Use {@link #requestLocationUpdates(String, LocationRequest, PendingIntent)} 1503 * instead. 1504 */ 1505 @Deprecated 1506 @SystemApi 1507 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates( @ullable LocationRequest locationRequest, @NonNull PendingIntent pendingIntent)1508 public void requestLocationUpdates( 1509 @Nullable LocationRequest locationRequest, 1510 @NonNull PendingIntent pendingIntent) { 1511 if (locationRequest == null) { 1512 locationRequest = LocationRequest.create(); 1513 } 1514 Preconditions.checkArgument(locationRequest.getProvider() != null); 1515 requestLocationUpdates(locationRequest.getProvider(), locationRequest, pendingIntent); 1516 } 1517 1518 /** 1519 * Register for location updates from the specified provider, using a {@link LocationRequest}, 1520 * and a callback on the specified {@link Executor}. 1521 * 1522 * <p>Only one request can be registered for each unique listener/provider pair, so any 1523 * subsequent requests with the same provider and listener will overwrite all associated 1524 * arguments. The same listener may be used across multiple providers with different requests 1525 * for each provider. 1526 * 1527 * <p>It may take some time to receive the first location update depending on the conditions the 1528 * device finds itself in. In order to take advantage of cached locations, application may 1529 * consider using {@link #getLastKnownLocation(String)} or {@link #getCurrentLocation(String, 1530 * LocationRequest, CancellationSignal, Executor, Consumer)} instead. 1531 * 1532 * <p>See {@link LocationRequest} documentation for an explanation of various request parameters 1533 * and how they can affect the received locations. 1534 * 1535 * <p>If your application wants to passively observe location updates from all providers, then 1536 * use the {@link #PASSIVE_PROVIDER}. This provider does not turn on or modify active location 1537 * providers, so you do not need to be as careful about minimum time and minimum distance 1538 * parameters. However, if your application performs heavy work on a location update (such as 1539 * network activity) then you should set an explicit fastest interval on your location request 1540 * in case another application enables a location provider with extremely fast updates. 1541 * 1542 * <p>In case the provider you have selected is disabled, location updates will cease, and a 1543 * provider availability update will be sent. As soon as the provider is enabled again, another 1544 * provider availability update will be sent and location updates will resume. 1545 * 1546 * <p>Locations returned from {@link #GPS_PROVIDER} are with respect to the primary GNSS antenna 1547 * position within the device. {@link #getGnssAntennaInfos()} may be used to determine the GNSS 1548 * antenna position with respect to the Android Coordinate System, and convert between them if 1549 * necessary. This is generally only necessary for high accuracy applications. 1550 * 1551 * <p>When location callbacks are invoked, the system will hold a wakelock on your 1552 * application's behalf for some period of time, but not indefinitely. If your application 1553 * requires a long running wakelock within the location callback, you should acquire it 1554 * yourself. 1555 * 1556 * <p>Spamming location requests is a drain on system resources, and the system has preventative 1557 * measures in place to ensure that this behavior will never result in more locations than could 1558 * be achieved with a single location request with an equivalent interval that is left in place 1559 * the whole time. As part of this amelioration, applications that target Android S and above 1560 * may receive cached or historical locations through their listener. These locations will never 1561 * be older than the interval of the location request. 1562 * 1563 * <p>To unregister for location updates, use {@link #removeUpdates(LocationListener)}. 1564 * 1565 * @param provider a provider listed by {@link #getAllProviders()} 1566 * @param locationRequest the location request containing location parameters 1567 * @param executor the executor handling listener callbacks 1568 * @param listener the listener to receive location updates 1569 * 1570 * @throws IllegalArgumentException if provider is null or doesn't exist 1571 * @throws IllegalArgumentException if locationRequest is null 1572 * @throws IllegalArgumentException if listener is null 1573 * @throws SecurityException if no suitable permission is present 1574 */ 1575 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates(@onNull String provider, @NonNull LocationRequest locationRequest, @NonNull @CallbackExecutor Executor executor, @NonNull LocationListener listener)1576 public void requestLocationUpdates(@NonNull String provider, 1577 @NonNull LocationRequest locationRequest, 1578 @NonNull @CallbackExecutor Executor executor, 1579 @NonNull LocationListener listener) { 1580 Preconditions.checkArgument(provider != null, "invalid null provider"); 1581 Preconditions.checkArgument(locationRequest != null, "invalid null location request"); 1582 1583 try { 1584 synchronized (sLocationListeners) { 1585 WeakReference<LocationListenerTransport> reference = sLocationListeners.get( 1586 listener); 1587 LocationListenerTransport transport = reference != null ? reference.get() : null; 1588 if (transport == null) { 1589 transport = new LocationListenerTransport(listener, executor); 1590 } else { 1591 Preconditions.checkState(transport.isRegistered()); 1592 transport.setExecutor(executor); 1593 } 1594 1595 mService.registerLocationListener(provider, locationRequest, transport, 1596 mContext.getPackageName(), mContext.getAttributionTag(), 1597 AppOpsManager.toReceiverId(listener)); 1598 1599 sLocationListeners.put(listener, new WeakReference<>(transport)); 1600 } 1601 } catch (RemoteException e) { 1602 throw e.rethrowFromSystemServer(); 1603 } 1604 } 1605 1606 /** 1607 * Register for location updates from the specified provider, using a {@link LocationRequest}, 1608 * and callbacks delivered via the provided {@link PendingIntent}. 1609 * 1610 * <p>The delivered pending intents will contain extras with the callback information. The keys 1611 * used for the extras are {@link #KEY_LOCATION_CHANGED} and {@link #KEY_PROVIDER_ENABLED}. See 1612 * the documentation for each respective extra key for information on the values. 1613 * 1614 * <p>To unregister for location updates, use {@link #removeUpdates(PendingIntent)}. 1615 * 1616 * @param provider a provider listed by {@link #getAllProviders()} 1617 * @param locationRequest the location request containing location parameters 1618 * @param pendingIntent the pending intent to send location updates 1619 * 1620 * @throws IllegalArgumentException if provider is null or doesn't exist 1621 * @throws IllegalArgumentException if locationRequest is null 1622 * @throws IllegalArgumentException if pendingIntent is null 1623 * @throws SecurityException if no suitable permission is present 1624 */ 1625 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) requestLocationUpdates(@onNull String provider, @NonNull LocationRequest locationRequest, @NonNull PendingIntent pendingIntent)1626 public void requestLocationUpdates(@NonNull String provider, 1627 @NonNull LocationRequest locationRequest, 1628 @NonNull PendingIntent pendingIntent) { 1629 Preconditions.checkArgument(provider != null, "invalid null provider"); 1630 Preconditions.checkArgument(locationRequest != null, "invalid null location request"); 1631 Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent"); 1632 1633 if (Compatibility.isChangeEnabled(BLOCK_UNTARGETED_PENDING_INTENTS)) { 1634 Preconditions.checkArgument(pendingIntent.isTargetedToPackage(), 1635 "pending intent must be targeted to a package"); 1636 } 1637 1638 if (Compatibility.isChangeEnabled(BLOCK_IMMUTABLE_PENDING_INTENTS)) { 1639 Preconditions.checkArgument(!pendingIntent.isImmutable(), 1640 "pending intent must be mutable"); 1641 } 1642 1643 try { 1644 mService.registerLocationPendingIntent(provider, locationRequest, pendingIntent, 1645 mContext.getPackageName(), mContext.getAttributionTag()); 1646 } catch (RemoteException e) { 1647 throw e.rethrowFromSystemServer(); 1648 } 1649 } 1650 1651 /** 1652 * Set the last known location with a new location. 1653 * 1654 * <p>A privileged client can inject a {@link Location} if it has a better estimate of what 1655 * the recent location is. This is especially useful when the device boots up and the GPS 1656 * chipset is in the process of getting the first fix. If the client has cached the location, 1657 * it can inject the {@link Location}, so if an app requests for a {@link Location} from {@link 1658 * #getLastKnownLocation(String)}, the location information is still useful before getting 1659 * the first fix. 1660 * 1661 * @param location newly available {@link Location} object 1662 * @return true if the location was injected, false otherwise 1663 * 1664 * @throws IllegalArgumentException if location is null 1665 * @throws SecurityException if permissions are not present 1666 * 1667 * @hide 1668 */ 1669 @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) 1670 @RequiresPermission(allOf = {LOCATION_HARDWARE, ACCESS_FINE_LOCATION}) injectLocation(@onNull Location location)1671 public boolean injectLocation(@NonNull Location location) { 1672 Preconditions.checkArgument(location != null, "invalid null location"); 1673 Preconditions.checkArgument(location.isComplete(), 1674 "incomplete location object, missing timestamp or accuracy?"); 1675 1676 try { 1677 mService.injectLocation(location); 1678 return true; 1679 } catch (RemoteException e) { 1680 throw e.rethrowFromSystemServer(); 1681 } 1682 } 1683 1684 /** 1685 * Requests that the given provider flush any batched locations to listeners. The given listener 1686 * (registered with the provider) will have {@link LocationListener#onFlushComplete(int)} 1687 * invoked with the given result code after any locations that were flushed have been delivered. 1688 * If {@link #removeUpdates(LocationListener)} is invoked before the flush callback is executed, 1689 * then the flush callback will never be executed. 1690 * 1691 * @param provider a provider listed by {@link #getAllProviders()} 1692 * @param listener a listener registered under the provider 1693 * @param requestCode an arbitrary integer passed through to 1694 * {@link LocationListener#onFlushComplete(int)} 1695 * 1696 * @throws IllegalArgumentException if provider is null or doesn't exist 1697 * @throws IllegalArgumentException if listener is null or is not registered under the provider 1698 */ 1699 @SuppressLint("SamShouldBeLast") requestFlush(@onNull String provider, @NonNull LocationListener listener, @SuppressLint("ListenerLast") int requestCode)1700 public void requestFlush(@NonNull String provider, @NonNull LocationListener listener, 1701 @SuppressLint("ListenerLast") int requestCode) { 1702 Preconditions.checkArgument(provider != null, "invalid null provider"); 1703 Preconditions.checkArgument(listener != null, "invalid null listener"); 1704 1705 synchronized (sLocationListeners) { 1706 WeakReference<LocationListenerTransport> ref = sLocationListeners.get(listener); 1707 LocationListenerTransport transport = ref != null ? ref.get() : null; 1708 1709 Preconditions.checkArgument(transport != null, 1710 "unregistered listener cannot be flushed"); 1711 1712 try { 1713 mService.requestListenerFlush(provider, transport, requestCode); 1714 } catch (RemoteException e) { 1715 throw e.rethrowFromSystemServer(); 1716 } 1717 } 1718 } 1719 1720 /** 1721 * Requests that the given provider flush any batched locations to listeners. The given 1722 * PendingIntent (registered with the provider) will be sent with {@link #KEY_FLUSH_COMPLETE} 1723 * present in the extra keys, and {@code requestCode} as the corresponding value. 1724 * 1725 * @param provider a provider listed by {@link #getAllProviders()} 1726 * @param pendingIntent a pendingIntent registered under the provider 1727 * @param requestCode an arbitrary integer that will be passed back as the extra value for 1728 * {@link #KEY_FLUSH_COMPLETE} 1729 * 1730 * @throws IllegalArgumentException if provider is null or doesn't exist 1731 * @throws IllegalArgumentException if pending intent is null or is not registered under the 1732 * provider 1733 */ requestFlush(@onNull String provider, @NonNull PendingIntent pendingIntent, int requestCode)1734 public void requestFlush(@NonNull String provider, @NonNull PendingIntent pendingIntent, 1735 int requestCode) { 1736 Preconditions.checkArgument(provider != null, "invalid null provider"); 1737 Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent"); 1738 1739 try { 1740 mService.requestPendingIntentFlush(provider, pendingIntent, requestCode); 1741 } catch (RemoteException e) { 1742 throw e.rethrowFromSystemServer(); 1743 } 1744 } 1745 1746 /** 1747 * Removes all location updates for the specified {@link LocationListener}. The given listener 1748 * is guaranteed not to receive any invocations that <b>happens-after</b> this method is 1749 * invoked. 1750 * 1751 * <p>If the given listener has any batched requests, this method will not flush any incomplete 1752 * location batches before stopping location updates. If you wish to flush any pending locations 1753 * before stopping, you must first call {@link #requestFlush(String, LocationListener, int)} and 1754 * then call this method once the flush is complete. If this method is invoked before the flush 1755 * is complete, you may not receive the flushed locations. 1756 * 1757 * @param listener listener that no longer needs location updates 1758 * 1759 * @throws IllegalArgumentException if listener is null 1760 */ removeUpdates(@onNull LocationListener listener)1761 public void removeUpdates(@NonNull LocationListener listener) { 1762 Preconditions.checkArgument(listener != null, "invalid null listener"); 1763 1764 try { 1765 synchronized (sLocationListeners) { 1766 WeakReference<LocationListenerTransport> ref = sLocationListeners.remove(listener); 1767 LocationListenerTransport transport = ref != null ? ref.get() : null; 1768 if (transport != null) { 1769 transport.unregister(); 1770 mService.unregisterLocationListener(transport); 1771 } 1772 } 1773 } catch (RemoteException e) { 1774 throw e.rethrowFromSystemServer(); 1775 } 1776 } 1777 1778 /** 1779 * Removes location updates for the specified {@link PendingIntent}. Following this call, the 1780 * PendingIntent will no longer receive location updates. 1781 * 1782 * <p>See {@link #removeUpdates(LocationListener)} for more detail on how this method works. 1783 * 1784 * @param pendingIntent pending intent that no longer needs location updates 1785 * 1786 * @throws IllegalArgumentException if pendingIntent is null 1787 */ removeUpdates(@onNull PendingIntent pendingIntent)1788 public void removeUpdates(@NonNull PendingIntent pendingIntent) { 1789 Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent"); 1790 1791 try { 1792 mService.unregisterLocationPendingIntent(pendingIntent); 1793 } catch (RemoteException e) { 1794 throw e.rethrowFromSystemServer(); 1795 } 1796 } 1797 1798 /** 1799 * Returns true if the given location provider exists on this device, irrespective of whether 1800 * it is currently enabled or not. 1801 * 1802 * @param provider a potential location provider 1803 * @return true if the location provider exists, false otherwise 1804 * 1805 * @throws IllegalArgumentException if provider is null 1806 */ hasProvider(@onNull String provider)1807 public boolean hasProvider(@NonNull String provider) { 1808 Preconditions.checkArgument(provider != null, "invalid null provider"); 1809 1810 try { 1811 return mService.hasProvider(provider); 1812 } catch (RemoteException e) { 1813 throw e.rethrowFromSystemServer(); 1814 } 1815 } 1816 1817 /** 1818 * Returns a list of the names of all available location providers. All providers are returned, 1819 * including those that are currently disabled. 1820 * 1821 * @return list of provider names 1822 */ getAllProviders()1823 public @NonNull List<String> getAllProviders() { 1824 try { 1825 return mService.getAllProviders(); 1826 } catch (RemoteException e) { 1827 throw e.rethrowFromSystemServer(); 1828 } 1829 } 1830 1831 /** 1832 * Returns a list of the names of available location providers. If {@code enabledOnly} is false, 1833 * this is functionally the same as {@link #getAllProviders()}. 1834 * 1835 * @param enabledOnly if true then only enabled providers are included 1836 * @return list of provider names 1837 */ getProviders(boolean enabledOnly)1838 public @NonNull List<String> getProviders(boolean enabledOnly) { 1839 try { 1840 return mService.getProviders(null, enabledOnly); 1841 } catch (RemoteException e) { 1842 throw e.rethrowFromSystemServer(); 1843 } 1844 } 1845 1846 /** 1847 * Returns a list of the names of available location providers that satisfy the given criteria. 1848 * 1849 * @param criteria the criteria that providers must match 1850 * @param enabledOnly if true then only enabled providers are included 1851 * @return list of provider names 1852 * 1853 * @throws IllegalArgumentException if criteria is null 1854 * 1855 * @deprecated Criteria based APIs are deprecated, prefer to select a provider explicitly. 1856 */ 1857 @Deprecated getProviders(@onNull Criteria criteria, boolean enabledOnly)1858 public @NonNull List<String> getProviders(@NonNull Criteria criteria, boolean enabledOnly) { 1859 Preconditions.checkArgument(criteria != null, "invalid null criteria"); 1860 1861 try { 1862 return mService.getProviders(criteria, enabledOnly); 1863 } catch (RemoteException e) { 1864 throw e.rethrowFromSystemServer(); 1865 } 1866 } 1867 1868 /** 1869 * Returns the name of the provider that best meets the given criteria. Only providers that are 1870 * permitted to be accessed by the caller will be returned. If several providers meet the 1871 * criteria, the one with the best accuracy is returned. If no provider meets the criteria, the 1872 * criteria are loosened in the following order: 1873 * 1874 * <ul> 1875 * <li> power requirement 1876 * <li> accuracy 1877 * <li> bearing 1878 * <li> speed 1879 * <li> altitude 1880 * </ul> 1881 * 1882 * <p> Note that the requirement on monetary cost is not removed in this process. 1883 * 1884 * @param criteria the criteria that need to be matched 1885 * @param enabledOnly if true then only enabled providers are included 1886 * @return name of the provider that best matches the criteria, or null if none match 1887 * 1888 * @throws IllegalArgumentException if criteria is null 1889 * 1890 * @deprecated Criteria based APIs are deprecated, prefer to select a provider explicitly. 1891 */ 1892 @Deprecated getBestProvider(@onNull Criteria criteria, boolean enabledOnly)1893 public @Nullable String getBestProvider(@NonNull Criteria criteria, boolean enabledOnly) { 1894 Preconditions.checkArgument(criteria != null, "invalid null criteria"); 1895 1896 try { 1897 return mService.getBestProvider(criteria, enabledOnly); 1898 } catch (RemoteException e) { 1899 throw e.rethrowFromSystemServer(); 1900 } 1901 } 1902 1903 /** 1904 * Returns the information about the location provider with the given name, or null if no 1905 * provider exists by that name. 1906 * 1907 * @param provider a provider listed by {@link #getAllProviders()} 1908 * @return location provider information, or null if provider does not exist 1909 * 1910 * @throws IllegalArgumentException if provider is null 1911 * 1912 * @deprecated This method has no way to indicate that a provider's properties are unknown, and 1913 * so may return incorrect results on rare occasions. Use {@link #getProviderProperties(String)} 1914 * instead. 1915 */ 1916 @Deprecated getProvider(@onNull String provider)1917 public @Nullable LocationProvider getProvider(@NonNull String provider) { 1918 Preconditions.checkArgument(provider != null, "invalid null provider"); 1919 1920 if (!Compatibility.isChangeEnabled(GET_PROVIDER_SECURITY_EXCEPTIONS)) { 1921 if (NETWORK_PROVIDER.equals(provider) || FUSED_PROVIDER.equals(provider)) { 1922 try { 1923 mContext.enforcePermission(ACCESS_FINE_LOCATION, Process.myPid(), 1924 Process.myUid(), null); 1925 } catch (SecurityException e) { 1926 mContext.enforcePermission(ACCESS_COARSE_LOCATION, Process.myPid(), 1927 Process.myUid(), null); 1928 } 1929 } else { 1930 mContext.enforcePermission(ACCESS_FINE_LOCATION, Process.myPid(), Process.myUid(), 1931 null); 1932 } 1933 } 1934 1935 try { 1936 ProviderProperties properties = mService.getProviderProperties(provider); 1937 return new LocationProvider(provider, properties); 1938 } catch (IllegalArgumentException e) { 1939 // provider does not exist 1940 return null; 1941 } catch (RemoteException e) { 1942 throw e.rethrowFromSystemServer(); 1943 } 1944 } 1945 1946 /** 1947 * Returns the properties of the given provider, or null if the properties are currently 1948 * unknown. Provider properties may change over time, although this is discouraged, and should 1949 * be rare. The most common transition is when provider properties go from being unknown to 1950 * known, which is most common near boot time. 1951 * 1952 * @param provider a provider listed by {@link #getAllProviders()} 1953 * @return location provider properties, or null if properties are currently unknown 1954 * 1955 * @throws IllegalArgumentException if provider is null or does not exist 1956 */ getProviderProperties(@onNull String provider)1957 public @Nullable ProviderProperties getProviderProperties(@NonNull String provider) { 1958 Preconditions.checkArgument(provider != null, "invalid null provider"); 1959 1960 try { 1961 return mService.getProviderProperties(provider); 1962 } catch (RemoteException e) { 1963 throw e.rethrowFromSystemServer(); 1964 } 1965 } 1966 1967 /** 1968 * Returns true if the given package name matches a location provider package, and false 1969 * otherwise. 1970 * 1971 * @hide 1972 * @deprecated Prefer {@link #isProviderPackage(String, String, String)} instead. 1973 */ 1974 @Deprecated 1975 @SystemApi 1976 @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) isProviderPackage(@onNull String packageName)1977 public boolean isProviderPackage(@NonNull String packageName) { 1978 return isProviderPackage(null, packageName, null); 1979 } 1980 1981 /** 1982 * Returns true if the given provider corresponds to the given package name. If the given 1983 * provider is null, this will return true if any provider corresponds to the given package 1984 * name. 1985 * 1986 * @param provider a provider listed by {@link #getAllProviders()} or null 1987 * @param packageName the package name to test if it is a provider 1988 * @return true if the given arguments correspond to a provider 1989 * 1990 * @deprecated Use {@link #isProviderPackage(String, String, String)} instead. 1991 * 1992 * @hide 1993 * @removed 1994 */ 1995 @Deprecated 1996 @SystemApi 1997 @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) isProviderPackage(@ullable String provider, @NonNull String packageName)1998 public boolean isProviderPackage(@Nullable String provider, @NonNull String packageName) { 1999 return isProviderPackage(provider, packageName, null); 2000 } 2001 2002 /** 2003 * Returns true if the given provider corresponds to the given package name. If the given 2004 * provider is null, this will return true if any provider corresponds to the given package 2005 * name and/or attribution tag. If attribution tag is non-null, the provider identity must match 2006 * both the given package name and attribution tag. 2007 * 2008 * @param provider a provider listed by {@link #getAllProviders()} or null 2009 * @param packageName the package name to test if it is a provider 2010 * @param attributionTag an optional attribution tag within the given package 2011 * @return true if the given arguments correspond to a provider 2012 * @hide 2013 */ 2014 @SystemApi 2015 @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) isProviderPackage(@ullable String provider, @NonNull String packageName, @Nullable String attributionTag)2016 public boolean isProviderPackage(@Nullable String provider, @NonNull String packageName, 2017 @Nullable String attributionTag) { 2018 try { 2019 return mService.isProviderPackage(provider, Objects.requireNonNull(packageName), 2020 attributionTag); 2021 } catch (RemoteException e) { 2022 throw e.rethrowFromSystemServer(); 2023 } 2024 } 2025 2026 /** 2027 * Returns a list of packages associated with the given provider, 2028 * and an empty list if no package is associated with the provider. 2029 * 2030 * @hide 2031 * @deprecated Prefer {@link #isProviderPackage(String, String, String)} instead. 2032 */ 2033 @TestApi 2034 @Deprecated 2035 @RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG) 2036 @Nullable 2037 @SuppressWarnings("NullableCollection") getProviderPackages(@onNull String provider)2038 public List<String> getProviderPackages(@NonNull String provider) { 2039 try { 2040 return mService.getProviderPackages(provider); 2041 } catch (RemoteException e) { 2042 throw e.rethrowFromSystemServer(); 2043 } 2044 } 2045 2046 /** 2047 * Sends additional commands to a location provider. Can be used to support provider specific 2048 * extensions to the Location Manager API. 2049 * 2050 * @param provider a provider listed by {@link #getAllProviders()} 2051 * @param command name of the command to send to the provider 2052 * @param extras optional arguments for the command, or null 2053 * @return true always, the return value may be ignored 2054 */ sendExtraCommand( @onNull String provider, @NonNull String command, @Nullable Bundle extras)2055 public boolean sendExtraCommand( 2056 @NonNull String provider, @NonNull String command, @Nullable Bundle extras) { 2057 Preconditions.checkArgument(provider != null, "invalid null provider"); 2058 Preconditions.checkArgument(command != null, "invalid null command"); 2059 2060 try { 2061 mService.sendExtraCommand(provider, command, extras); 2062 return true; 2063 } catch (RemoteException e) { 2064 throw e.rethrowFromSystemServer(); 2065 } 2066 } 2067 2068 /** 2069 * Creates a test location provider and adds it to the set of active providers. This provider 2070 * will replace any provider with the same name that exists prior to this call. 2071 * 2072 * @param provider the provider name 2073 * 2074 * @throws IllegalArgumentException if provider is null 2075 * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION 2076 * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED 2077 * allowed} for your app. 2078 */ addTestProvider( @onNull String provider, boolean requiresNetwork, boolean requiresSatellite, boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude, boolean supportsSpeed, boolean supportsBearing, @ProviderProperties.PowerUsage int powerUsage, @ProviderProperties.Accuracy int accuracy)2079 public void addTestProvider( 2080 @NonNull String provider, boolean requiresNetwork, boolean requiresSatellite, 2081 boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude, 2082 boolean supportsSpeed, boolean supportsBearing, 2083 @ProviderProperties.PowerUsage int powerUsage, 2084 @ProviderProperties.Accuracy int accuracy) { 2085 addTestProvider(provider, new ProviderProperties.Builder() 2086 .setHasNetworkRequirement(requiresNetwork) 2087 .setHasSatelliteRequirement(requiresSatellite) 2088 .setHasCellRequirement(requiresCell) 2089 .setHasMonetaryCost(hasMonetaryCost) 2090 .setHasAltitudeSupport(supportsAltitude) 2091 .setHasSpeedSupport(supportsSpeed) 2092 .setHasBearingSupport(supportsBearing) 2093 .setPowerUsage(powerUsage) 2094 .setAccuracy(accuracy) 2095 .build()); 2096 } 2097 2098 /** 2099 * Creates a test location provider and adds it to the set of active providers. This provider 2100 * will replace any provider with the same name that exists prior to this call. 2101 * 2102 * @param provider the provider name 2103 * 2104 * @throws IllegalArgumentException if provider is null 2105 * @throws IllegalArgumentException if properties is null 2106 * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION 2107 * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED 2108 * allowed} for your app. 2109 */ addTestProvider(@onNull String provider, @NonNull ProviderProperties properties)2110 public void addTestProvider(@NonNull String provider, @NonNull ProviderProperties properties) { 2111 addTestProvider(provider, properties, Collections.emptySet()); 2112 } 2113 2114 /** 2115 * Creates a test location provider and adds it to the set of active providers. This provider 2116 * will replace any provider with the same name that exists prior to this call. 2117 * 2118 * @param provider the provider name 2119 * @param properties the provider properties 2120 * @param extraAttributionTags additional attribution tags associated with this provider 2121 * 2122 * @throws IllegalArgumentException if provider is null 2123 * @throws IllegalArgumentException if properties is null 2124 * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION 2125 * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED 2126 * allowed} for your app. 2127 */ addTestProvider(@onNull String provider, @NonNull ProviderProperties properties, @NonNull Set<String> extraAttributionTags)2128 public void addTestProvider(@NonNull String provider, @NonNull ProviderProperties properties, 2129 @NonNull Set<String> extraAttributionTags) { 2130 Preconditions.checkArgument(provider != null, "invalid null provider"); 2131 Preconditions.checkArgument(properties != null, "invalid null properties"); 2132 Preconditions.checkArgument(extraAttributionTags != null, 2133 "invalid null extra attribution tags"); 2134 2135 try { 2136 mService.addTestProvider(provider, properties, new ArrayList<>(extraAttributionTags), 2137 mContext.getOpPackageName(), mContext.getAttributionTag()); 2138 } catch (RemoteException e) { 2139 throw e.rethrowFromSystemServer(); 2140 } 2141 } 2142 2143 /** 2144 * Removes the test location provider with the given name or does nothing if no such test 2145 * location provider exists. 2146 * 2147 * @param provider the provider name 2148 * 2149 * @throws IllegalArgumentException if provider is null 2150 * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION 2151 * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED 2152 * allowed} for your app. 2153 */ removeTestProvider(@onNull String provider)2154 public void removeTestProvider(@NonNull String provider) { 2155 Preconditions.checkArgument(provider != null, "invalid null provider"); 2156 2157 try { 2158 mService.removeTestProvider(provider, mContext.getOpPackageName(), 2159 mContext.getAttributionTag()); 2160 } catch (RemoteException e) { 2161 throw e.rethrowFromSystemServer(); 2162 } 2163 } 2164 2165 /** 2166 * Sets a new location for the given test provider. This location will be identiable as a mock 2167 * location to all clients via {@link Location#isMock()}. 2168 * 2169 * <p>The location object must have a minimum number of fields set to be considered valid, as 2170 * per documentation on {@link Location} class. 2171 * 2172 * @param provider the provider name 2173 * @param location the mock location 2174 * 2175 * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION 2176 * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED 2177 * allowed} for your app. 2178 * @throws IllegalArgumentException if the provider is null or not a test provider 2179 * @throws IllegalArgumentException if the location is null or incomplete 2180 */ setTestProviderLocation(@onNull String provider, @NonNull Location location)2181 public void setTestProviderLocation(@NonNull String provider, @NonNull Location location) { 2182 Preconditions.checkArgument(provider != null, "invalid null provider"); 2183 Preconditions.checkArgument(location != null, "invalid null location"); 2184 2185 if (Compatibility.isChangeEnabled(BLOCK_INCOMPLETE_LOCATIONS)) { 2186 Preconditions.checkArgument(location.isComplete(), 2187 "incomplete location object, missing timestamp or accuracy?"); 2188 } else { 2189 location.makeComplete(); 2190 } 2191 2192 try { 2193 mService.setTestProviderLocation(provider, location, mContext.getOpPackageName(), 2194 mContext.getAttributionTag()); 2195 } catch (RemoteException e) { 2196 throw e.rethrowFromSystemServer(); 2197 } 2198 } 2199 2200 /** 2201 * Does nothing. 2202 * 2203 * @deprecated This method has always been a no-op, and may be removed in the future. 2204 */ 2205 @Deprecated clearTestProviderLocation(@onNull String provider)2206 public void clearTestProviderLocation(@NonNull String provider) {} 2207 2208 /** 2209 * Sets the given test provider to be enabled or disabled. 2210 * 2211 * @param provider the provider name 2212 * @param enabled the mock enabled value 2213 * 2214 * @throws SecurityException if {@link android.app.AppOpsManager#OPSTR_MOCK_LOCATION 2215 * mock location app op} is not set to {@link android.app.AppOpsManager#MODE_ALLOWED 2216 * allowed} for your app. 2217 * @throws IllegalArgumentException if provider is null or not a test provider 2218 */ setTestProviderEnabled(@onNull String provider, boolean enabled)2219 public void setTestProviderEnabled(@NonNull String provider, boolean enabled) { 2220 Preconditions.checkArgument(provider != null, "invalid null provider"); 2221 2222 try { 2223 mService.setTestProviderEnabled(provider, enabled, mContext.getOpPackageName(), 2224 mContext.getAttributionTag()); 2225 } catch (RemoteException e) { 2226 throw e.rethrowFromSystemServer(); 2227 } 2228 } 2229 2230 /** 2231 * Equivalent to calling {@link #setTestProviderEnabled(String, boolean)} to disable a test 2232 * provider. 2233 * 2234 * @deprecated Use {@link #setTestProviderEnabled(String, boolean)} instead. 2235 */ 2236 @Deprecated clearTestProviderEnabled(@onNull String provider)2237 public void clearTestProviderEnabled(@NonNull String provider) { 2238 setTestProviderEnabled(provider, false); 2239 } 2240 2241 /** 2242 * This method has no effect as provider status has been deprecated and is no longer supported. 2243 * 2244 * @deprecated This method has no effect. 2245 */ 2246 @Deprecated setTestProviderStatus( @onNull String provider, int status, @Nullable Bundle extras, long updateTime)2247 public void setTestProviderStatus( 2248 @NonNull String provider, int status, @Nullable Bundle extras, long updateTime) {} 2249 2250 /** 2251 * This method has no effect as provider status has been deprecated and is no longer supported. 2252 * 2253 * @deprecated This method has no effect. 2254 */ 2255 @Deprecated clearTestProviderStatus(@onNull String provider)2256 public void clearTestProviderStatus(@NonNull String provider) {} 2257 2258 /** 2259 * Sets a proximity alert for the location given by the position (latitude, longitude) and the 2260 * given radius. 2261 * 2262 * <p>When the device detects that it has entered or exited the area surrounding the location, 2263 * the given PendingIntent will be fired. 2264 * 2265 * <p>The fired intent will have a boolean extra added with key {@link #KEY_PROXIMITY_ENTERING}. 2266 * If the value is true, the device is entering the proximity region; if false, it is exiting. 2267 * 2268 * <p>Due to the approximate nature of position estimation, if the device passes through the 2269 * given area briefly, it is possible that no Intent will be fired. Similarly, an intent could 2270 * be fired if the device passes very close to the given area but does not actually enter it. 2271 * 2272 * <p>Before API version 17, this method could be used with 2273 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or 2274 * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. From API version 17 and onwards, 2275 * this method requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission. 2276 * 2277 * @param latitude the latitude of the central point of the alert region 2278 * @param longitude the longitude of the central point of the alert region 2279 * @param radius the radius of the central point of the alert region in meters 2280 * @param expiration expiration realtime for this proximity alert in milliseconds, or -1 to 2281 * indicate no expiration 2282 * @param pendingIntent a {@link PendingIntent} that will sent when entry to or exit from the 2283 * alert region is detected 2284 * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION} 2285 * permission is not present 2286 */ 2287 @RequiresPermission(anyOf = {ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION}) addProximityAlert(double latitude, double longitude, float radius, long expiration, @NonNull PendingIntent pendingIntent)2288 public void addProximityAlert(double latitude, double longitude, float radius, long expiration, 2289 @NonNull PendingIntent pendingIntent) { 2290 Preconditions.checkArgument(pendingIntent != null, "invalid null pending intent"); 2291 2292 if (Compatibility.isChangeEnabled(BLOCK_UNTARGETED_PENDING_INTENTS)) { 2293 Preconditions.checkArgument(pendingIntent.isTargetedToPackage(), 2294 "pending intent must be targeted to a package"); 2295 } 2296 2297 if (Compatibility.isChangeEnabled(BLOCK_IMMUTABLE_PENDING_INTENTS)) { 2298 Preconditions.checkArgument(!pendingIntent.isImmutable(), 2299 "pending intent must be mutable"); 2300 } 2301 2302 if (expiration < 0) { 2303 expiration = Long.MAX_VALUE; 2304 } 2305 2306 try { 2307 Geofence fence = Geofence.createCircle(latitude, longitude, radius, expiration); 2308 mService.requestGeofence(fence, pendingIntent, mContext.getPackageName(), 2309 mContext.getAttributionTag()); 2310 } catch (RemoteException e) { 2311 throw e.rethrowFromSystemServer(); 2312 } 2313 } 2314 2315 /** 2316 * Removes the proximity alert with the given PendingIntent. 2317 * 2318 * <p>Before API version 17, this method could be used with 2319 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} or 2320 * {@link android.Manifest.permission#ACCESS_COARSE_LOCATION}. 2321 * From API version 17 and onwards, this method requires 2322 * {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission. 2323 * 2324 * @param intent the PendingIntent that no longer needs to be notified of 2325 * proximity alerts 2326 * 2327 * @throws IllegalArgumentException if intent is null 2328 * @throws SecurityException if {@link android.Manifest.permission#ACCESS_FINE_LOCATION} 2329 * permission is not present 2330 */ removeProximityAlert(@onNull PendingIntent intent)2331 public void removeProximityAlert(@NonNull PendingIntent intent) { 2332 Preconditions.checkArgument(intent != null, "invalid null pending intent"); 2333 2334 try { 2335 mService.removeGeofence(intent); 2336 } catch (RemoteException e) { 2337 throw e.rethrowFromSystemServer(); 2338 } 2339 } 2340 2341 // ================= GNSS APIs ================= 2342 2343 /** 2344 * Returns the supported capabilities of the GNSS chipset. 2345 */ getGnssCapabilities()2346 public @NonNull GnssCapabilities getGnssCapabilities() { 2347 try { 2348 return mService.getGnssCapabilities(); 2349 } catch (RemoteException e) { 2350 throw e.rethrowFromSystemServer(); 2351 } 2352 } 2353 2354 /** 2355 * Returns the model year of the GNSS hardware and software build, or 0 if the model year 2356 * is before 2016. 2357 */ getGnssYearOfHardware()2358 public int getGnssYearOfHardware() { 2359 try { 2360 return mService.getGnssYearOfHardware(); 2361 } catch (RemoteException e) { 2362 throw e.rethrowFromSystemServer(); 2363 } 2364 } 2365 2366 /** 2367 * Returns the model name (including vendor and hardware/software version) of the GNSS hardware 2368 * driver, or null if this information is not available. 2369 * 2370 * <p>No device-specific serial number or ID is returned from this API. 2371 */ 2372 @Nullable getGnssHardwareModelName()2373 public String getGnssHardwareModelName() { 2374 try { 2375 return mService.getGnssHardwareModelName(); 2376 } catch (RemoteException e) { 2377 throw e.rethrowFromSystemServer(); 2378 } 2379 } 2380 2381 /** 2382 * Returns the current list of GNSS antenna infos, or null if unknown or unsupported. 2383 * 2384 * @see #getGnssCapabilities() 2385 */ 2386 @Nullable 2387 @SuppressLint("NullableCollection") getGnssAntennaInfos()2388 public List<GnssAntennaInfo> getGnssAntennaInfos() { 2389 try { 2390 return mService.getGnssAntennaInfos(); 2391 } catch (RemoteException e) { 2392 throw e.rethrowFromSystemServer(); 2393 } 2394 } 2395 2396 /** 2397 * Retrieves information about the current status of the GPS engine. This should only be called 2398 * from within the {@link GpsStatus.Listener#onGpsStatusChanged} callback to ensure that the 2399 * data is copied atomically. 2400 * 2401 * The caller may either pass in an existing {@link GpsStatus} object to be overwritten, or pass 2402 * null to create a new {@link GpsStatus} object. 2403 * 2404 * @param status object containing GPS status details, or null. 2405 * @return status object containing updated GPS status. 2406 * 2407 * @deprecated GpsStatus APIs are deprecated, use {@link GnssStatus} APIs instead. No longer 2408 * supported in apps targeting S and above. 2409 */ 2410 @Deprecated 2411 @RequiresPermission(ACCESS_FINE_LOCATION) getGpsStatus(@ullable GpsStatus status)2412 public @Nullable GpsStatus getGpsStatus(@Nullable GpsStatus status) { 2413 if (Compatibility.isChangeEnabled(BLOCK_GPS_STATUS_USAGE)) { 2414 throw new UnsupportedOperationException( 2415 "GpsStatus APIs not supported, please use GnssStatus APIs instead"); 2416 } 2417 2418 GnssStatus gnssStatus = GpsStatusTransport.sGnssStatus; 2419 int ttff = GpsStatusTransport.sTtff; 2420 if (gnssStatus != null) { 2421 if (status == null) { 2422 status = GpsStatus.create(gnssStatus, ttff); 2423 } else { 2424 status.setStatus(gnssStatus, ttff); 2425 } 2426 } else if (status == null) { 2427 // even though this method is marked as nullable, legacy behavior was to never return 2428 // a null result, and there are applications that rely on this behavior. 2429 status = GpsStatus.createEmpty(); 2430 } 2431 return status; 2432 } 2433 2434 /** 2435 * Adds a GPS status listener. 2436 * 2437 * @param listener GPS status listener object to register 2438 * @return true if the listener was successfully added 2439 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2440 * 2441 * @deprecated Use {@link #registerGnssStatusCallback(GnssStatus.Callback, Handler)} or {@link 2442 * #registerGnssStatusCallback(Executor, GnssStatus.Callback)} instead. 2443 */ 2444 @Deprecated 2445 @RequiresPermission(ACCESS_FINE_LOCATION) addGpsStatusListener(GpsStatus.Listener listener)2446 public boolean addGpsStatusListener(GpsStatus.Listener listener) { 2447 if (Compatibility.isChangeEnabled(BLOCK_GPS_STATUS_USAGE)) { 2448 throw new UnsupportedOperationException( 2449 "GpsStatus APIs not supported, please use GnssStatus APIs instead"); 2450 } 2451 2452 GnssLazyLoader.sGnssStatusListeners.addListener(listener, 2453 new GpsStatusTransport(new HandlerExecutor(new Handler()), mContext, listener)); 2454 return true; 2455 } 2456 2457 /** 2458 * Removes a GPS status listener. 2459 * 2460 * @param listener GPS status listener object to remove 2461 * 2462 * @deprecated use {@link #unregisterGnssStatusCallback(GnssStatus.Callback)} instead. No longer 2463 * supported in apps targeting S and above. 2464 */ 2465 @Deprecated removeGpsStatusListener(GpsStatus.Listener listener)2466 public void removeGpsStatusListener(GpsStatus.Listener listener) { 2467 if (Compatibility.isChangeEnabled(BLOCK_GPS_STATUS_USAGE)) { 2468 throw new UnsupportedOperationException( 2469 "GpsStatus APIs not supported, please use GnssStatus APIs instead"); 2470 } 2471 2472 GnssLazyLoader.sGnssStatusListeners.removeListener(listener); 2473 } 2474 2475 /** 2476 * Registers a GNSS status callback. This method must be called from a {@link Looper} thread, 2477 * and callbacks will occur on that looper. 2478 * 2479 * <p>See {@link #registerGnssStatusCallback(Executor, GnssStatus.Callback)} for more detail on 2480 * how this method works. 2481 * 2482 * @param callback the callback to register 2483 * @return {@code true} always 2484 * 2485 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2486 * 2487 * @deprecated Use {@link #registerGnssStatusCallback(GnssStatus.Callback, Handler)} or {@link 2488 * #registerGnssStatusCallback(Executor, GnssStatus.Callback)} instead. 2489 */ 2490 @Deprecated 2491 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssStatusCallback(@onNull GnssStatus.Callback callback)2492 public boolean registerGnssStatusCallback(@NonNull GnssStatus.Callback callback) { 2493 return registerGnssStatusCallback(callback, null); 2494 } 2495 2496 /** 2497 * Registers a GNSS status callback. 2498 * 2499 * <p>See {@link #registerGnssStatusCallback(Executor, GnssStatus.Callback)} for more detail on 2500 * how this method works. 2501 * 2502 * @param callback the callback to register 2503 * @param handler the handler the callback runs on 2504 * @return {@code true} always 2505 * 2506 * @throws IllegalArgumentException if callback is null 2507 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2508 */ 2509 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssStatusCallback( @onNull GnssStatus.Callback callback, @Nullable Handler handler)2510 public boolean registerGnssStatusCallback( 2511 @NonNull GnssStatus.Callback callback, @Nullable Handler handler) { 2512 if (handler == null) { 2513 handler = new Handler(); 2514 } 2515 2516 return registerGnssStatusCallback(new HandlerExecutor(handler), callback); 2517 } 2518 2519 /** 2520 * Registers a GNSS status callback. GNSS status information will only be received while the 2521 * {@link #GPS_PROVIDER} is enabled, and while the client app is in the foreground. 2522 * 2523 * @param executor the executor that the callback runs on 2524 * @param callback the callback to register 2525 * @return {@code true} always 2526 * 2527 * @throws IllegalArgumentException if executor is null 2528 * @throws IllegalArgumentException if callback is null 2529 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2530 */ 2531 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssStatusCallback( @onNull @allbackExecutor Executor executor, @NonNull GnssStatus.Callback callback)2532 public boolean registerGnssStatusCallback( 2533 @NonNull @CallbackExecutor Executor executor, 2534 @NonNull GnssStatus.Callback callback) { 2535 GnssLazyLoader.sGnssStatusListeners.addListener(callback, 2536 new GnssStatusTransport(executor, mContext, callback)); 2537 return true; 2538 } 2539 2540 /** 2541 * Removes a GNSS status callback. 2542 * 2543 * @param callback GNSS status callback object to remove 2544 */ unregisterGnssStatusCallback(@onNull GnssStatus.Callback callback)2545 public void unregisterGnssStatusCallback(@NonNull GnssStatus.Callback callback) { 2546 GnssLazyLoader.sGnssStatusListeners.removeListener(callback); 2547 } 2548 2549 /** 2550 * No-op method to keep backward-compatibility. 2551 * 2552 * @deprecated Use {@link #addNmeaListener(OnNmeaMessageListener, Handler)} or {@link 2553 * #addNmeaListener(Executor, OnNmeaMessageListener)} instead. 2554 */ 2555 @Deprecated 2556 @RequiresPermission(ACCESS_FINE_LOCATION) addNmeaListener(@onNull GpsStatus.NmeaListener listener)2557 public boolean addNmeaListener(@NonNull GpsStatus.NmeaListener listener) { 2558 return false; 2559 } 2560 2561 /** 2562 * No-op method to keep backward-compatibility. 2563 * 2564 * @deprecated Use {@link #removeNmeaListener(OnNmeaMessageListener)} instead. 2565 */ 2566 @Deprecated removeNmeaListener(@onNull GpsStatus.NmeaListener listener)2567 public void removeNmeaListener(@NonNull GpsStatus.NmeaListener listener) {} 2568 2569 /** 2570 * Adds an NMEA listener. 2571 * 2572 * <p>See {@link #addNmeaListener(Executor, OnNmeaMessageListener)} for more detail on how this 2573 * method works. 2574 * 2575 * @param listener the listener to register 2576 * @return {@code true} always 2577 * 2578 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2579 * @deprecated Use {@link #addNmeaListener(OnNmeaMessageListener, Handler)} or {@link 2580 * #addNmeaListener(Executor, OnNmeaMessageListener)} instead. 2581 */ 2582 @Deprecated 2583 @RequiresPermission(ACCESS_FINE_LOCATION) addNmeaListener(@onNull OnNmeaMessageListener listener)2584 public boolean addNmeaListener(@NonNull OnNmeaMessageListener listener) { 2585 return addNmeaListener(listener, null); 2586 } 2587 2588 /** 2589 * Adds an NMEA listener. 2590 * 2591 * <p>See {@link #addNmeaListener(Executor, OnNmeaMessageListener)} for more detail on how this 2592 * method works. 2593 * 2594 * @param listener the listener to register 2595 * @param handler the handler that the listener runs on 2596 * @return {@code true} always 2597 * 2598 * @throws IllegalArgumentException if listener is null 2599 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2600 */ 2601 @RequiresPermission(ACCESS_FINE_LOCATION) addNmeaListener( @onNull OnNmeaMessageListener listener, @Nullable Handler handler)2602 public boolean addNmeaListener( 2603 @NonNull OnNmeaMessageListener listener, @Nullable Handler handler) { 2604 if (handler == null) { 2605 handler = new Handler(); 2606 } 2607 2608 return addNmeaListener(new HandlerExecutor(handler), listener); 2609 } 2610 2611 /** 2612 * Adds an NMEA listener. GNSS NMEA information will only be received while the 2613 * {@link #GPS_PROVIDER} is enabled, and while the client app is in the foreground. 2614 * 2615 * @param listener the listener to register 2616 * @param executor the executor that the listener runs on 2617 * @return {@code true} always 2618 * 2619 * @throws IllegalArgumentException if executor is null 2620 * @throws IllegalArgumentException if listener is null 2621 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2622 */ 2623 @RequiresPermission(ACCESS_FINE_LOCATION) addNmeaListener( @onNull @allbackExecutor Executor executor, @NonNull OnNmeaMessageListener listener)2624 public boolean addNmeaListener( 2625 @NonNull @CallbackExecutor Executor executor, 2626 @NonNull OnNmeaMessageListener listener) { 2627 GnssLazyLoader.sGnssNmeaListeners.addListener(listener, 2628 new GnssNmeaTransport(executor, mContext, listener)); 2629 return true; 2630 } 2631 2632 /** 2633 * Removes an NMEA listener. 2634 * 2635 * @param listener a {@link OnNmeaMessageListener} object to remove 2636 */ removeNmeaListener(@onNull OnNmeaMessageListener listener)2637 public void removeNmeaListener(@NonNull OnNmeaMessageListener listener) { 2638 GnssLazyLoader.sGnssNmeaListeners.removeListener(listener); 2639 } 2640 2641 /** 2642 * No-op method to keep backward-compatibility. 2643 * 2644 * @hide 2645 * @deprecated Use {@link #registerGnssMeasurementsCallback} instead. 2646 * @removed 2647 */ 2648 @Deprecated 2649 @SystemApi addGpsMeasurementListener(GpsMeasurementsEvent.Listener listener)2650 public boolean addGpsMeasurementListener(GpsMeasurementsEvent.Listener listener) { 2651 return false; 2652 } 2653 2654 /** 2655 * No-op method to keep backward-compatibility. 2656 * 2657 * @hide 2658 * @deprecated Use {@link #unregisterGnssMeasurementsCallback} instead. 2659 * @removed 2660 */ 2661 @Deprecated 2662 @SystemApi removeGpsMeasurementListener(GpsMeasurementsEvent.Listener listener)2663 public void removeGpsMeasurementListener(GpsMeasurementsEvent.Listener listener) {} 2664 2665 /** 2666 * Registers a GNSS measurements callback which will run on a binder thread. 2667 * 2668 * <p>See {@link #registerGnssMeasurementsCallback(Executor, GnssMeasurementsEvent.Callback) 2669 * for more detail on how this method works. 2670 * 2671 * @param callback a {@link GnssMeasurementsEvent.Callback} object to register 2672 * @return {@code true} always 2673 * 2674 * @deprecated Use {@link 2675 * #registerGnssMeasurementsCallback(GnssMeasurementsEvent.Callback, Handler)} or {@link 2676 * #registerGnssMeasurementsCallback(Executor, GnssMeasurementsEvent.Callback)} instead. 2677 */ 2678 @Deprecated 2679 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssMeasurementsCallback( @onNull GnssMeasurementsEvent.Callback callback)2680 public boolean registerGnssMeasurementsCallback( 2681 @NonNull GnssMeasurementsEvent.Callback callback) { 2682 return registerGnssMeasurementsCallback(DIRECT_EXECUTOR, callback); 2683 } 2684 2685 /** 2686 * Registers a GNSS measurements callback. 2687 * 2688 * <p>See {@link #registerGnssMeasurementsCallback(Executor, GnssMeasurementsEvent.Callback) 2689 * for more detail on how this method works. 2690 * 2691 * @param callback a {@link GnssMeasurementsEvent.Callback} object to register 2692 * @param handler the handler that the callback runs on 2693 * @return {@code true} always 2694 * 2695 * @throws IllegalArgumentException if callback is null 2696 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2697 */ 2698 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssMeasurementsCallback( @onNull GnssMeasurementsEvent.Callback callback, @Nullable Handler handler)2699 public boolean registerGnssMeasurementsCallback( 2700 @NonNull GnssMeasurementsEvent.Callback callback, @Nullable Handler handler) { 2701 if (handler == null) { 2702 handler = new Handler(); 2703 } 2704 2705 return registerGnssMeasurementsCallback(new GnssMeasurementRequest.Builder().build(), 2706 new HandlerExecutor(handler), callback); 2707 } 2708 2709 /** 2710 * Registers a GNSS measurements callback. GNSS measurements information will only be received 2711 * while the {@link #GPS_PROVIDER} is enabled, and while the client app is in the foreground. 2712 * 2713 * <p>Not all GNSS chipsets support measurements updates, see {@link #getGnssCapabilities()}. 2714 * 2715 * <p class="caution">On Android R devices that have not yet upgraded to Android R QPR1, using 2716 * this API will cause unavoidable crashes in the client application when GNSS measurements 2717 * are received. If a client needs to receive GNSS measurements on Android R devices that have 2718 * not been upgraded to QPR1, clients are instead encouraged to use 2719 * <a href="https://developer.android.com/reference/androidx/core/location/LocationManagerCompat#registerGnssMeasurementsCallback(android.location.LocationManager,java.util.concurrent.Executor,android.location.GnssMeasurementsEvent.Callback)">LocationManagerCompat.registerGnssMeasurementsCallback()</a> 2720 * from the compat libraries instead to avoid this crash. 2721 * 2722 * @param executor the executor that the callback runs on 2723 * @param callback the callback to register 2724 * @return {@code true} always 2725 * 2726 * @throws IllegalArgumentException if executor is null 2727 * @throws IllegalArgumentException if callback is null 2728 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2729 */ 2730 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssMeasurementsCallback( @onNull @allbackExecutor Executor executor, @NonNull GnssMeasurementsEvent.Callback callback)2731 public boolean registerGnssMeasurementsCallback( 2732 @NonNull @CallbackExecutor Executor executor, 2733 @NonNull GnssMeasurementsEvent.Callback callback) { 2734 return registerGnssMeasurementsCallback(new GnssMeasurementRequest.Builder().build(), 2735 executor, callback); 2736 } 2737 2738 /** 2739 * Registers a GNSS Measurement callback. 2740 * 2741 * @param request the gnss measurement request containgin measurement parameters 2742 * @param executor the executor that the callback runs on 2743 * @param callback the callack to register 2744 * @return {@code true} always 2745 * 2746 * @throws IllegalArgumentException if request is null 2747 * @throws IllegalArgumentException if executor is null 2748 * @throws IllegalArgumentException if callback is null 2749 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2750 * @hide 2751 * @deprecated Use {@link #registerGnssMeasurementsCallback(GnssMeasurementRequest, Executor, 2752 * GnssMeasurementsEvent.Callback)} instead. 2753 */ 2754 @Deprecated 2755 @SystemApi 2756 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssMeasurementsCallback( @onNull GnssRequest request, @NonNull @CallbackExecutor Executor executor, @NonNull GnssMeasurementsEvent.Callback callback)2757 public boolean registerGnssMeasurementsCallback( 2758 @NonNull GnssRequest request, 2759 @NonNull @CallbackExecutor Executor executor, 2760 @NonNull GnssMeasurementsEvent.Callback callback) { 2761 return registerGnssMeasurementsCallback(request.toGnssMeasurementRequest(), executor, 2762 callback); 2763 } 2764 2765 /** 2766 * Registers a GNSS measurement callback. 2767 * 2768 * @param request extra parameters to pass to GNSS measurement provider. For example, if {@link 2769 * GnssMeasurementRequest#isFullTracking()} is true, GNSS chipset switches off 2770 * duty cycling. 2771 * @param executor the executor that the callback runs on 2772 * @param callback a {@link GnssMeasurementsEvent.Callback} object to register. 2773 * @return {@code true} always if the callback was added successfully, {@code false} otherwise. 2774 * @throws IllegalArgumentException if request is null 2775 * @throws IllegalArgumentException if executor is null 2776 * @throws IllegalArgumentException if callback is null 2777 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2778 */ 2779 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssMeasurementsCallback( @onNull GnssMeasurementRequest request, @NonNull @CallbackExecutor Executor executor, @NonNull GnssMeasurementsEvent.Callback callback)2780 public boolean registerGnssMeasurementsCallback( 2781 @NonNull GnssMeasurementRequest request, 2782 @NonNull @CallbackExecutor Executor executor, 2783 @NonNull GnssMeasurementsEvent.Callback callback) { 2784 GnssLazyLoader.sGnssMeasurementsListeners.addListener(callback, 2785 new GnssMeasurementsTransport(executor, mContext, request, callback)); 2786 return true; 2787 } 2788 2789 /** 2790 * Injects GNSS measurement corrections into the GNSS chipset. 2791 * 2792 * @param measurementCorrections measurement corrections to be injected into the chipset 2793 * 2794 * @throws IllegalArgumentException if measurementCorrections is null 2795 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2796 * @hide 2797 */ 2798 @SystemApi 2799 @RequiresPermission(ACCESS_FINE_LOCATION) injectGnssMeasurementCorrections( @onNull GnssMeasurementCorrections measurementCorrections)2800 public void injectGnssMeasurementCorrections( 2801 @NonNull GnssMeasurementCorrections measurementCorrections) { 2802 Preconditions.checkArgument(measurementCorrections != null); 2803 try { 2804 mService.injectGnssMeasurementCorrections(measurementCorrections); 2805 } catch (RemoteException e) { 2806 throw e.rethrowFromSystemServer(); 2807 } 2808 } 2809 2810 /** 2811 * Unregisters a GPS Measurement callback. 2812 * 2813 * @param callback a {@link GnssMeasurementsEvent.Callback} object to remove. 2814 */ unregisterGnssMeasurementsCallback( @onNull GnssMeasurementsEvent.Callback callback)2815 public void unregisterGnssMeasurementsCallback( 2816 @NonNull GnssMeasurementsEvent.Callback callback) { 2817 GnssLazyLoader.sGnssMeasurementsListeners.removeListener(callback); 2818 } 2819 2820 /** 2821 * Registers a GNSS antenna info listener that will receive all changes to antenna info. Use 2822 * {@link #getGnssAntennaInfos()} to get current antenna info. 2823 * 2824 * <p>Not all GNSS chipsets support antenna info updates, see {@link #getGnssCapabilities()}. If 2825 * unsupported, the listener will never be invoked. 2826 * 2827 * <p>Prior to Android S, this requires the {@link Manifest.permission#ACCESS_FINE_LOCATION} 2828 * permission. 2829 * 2830 * @param executor the executor that the listener runs on 2831 * @param listener the listener to register 2832 * @return {@code true} always 2833 * 2834 * @throws IllegalArgumentException if executor is null 2835 * @throws IllegalArgumentException if listener is null 2836 */ registerAntennaInfoListener( @onNull @allbackExecutor Executor executor, @NonNull GnssAntennaInfo.Listener listener)2837 public boolean registerAntennaInfoListener( 2838 @NonNull @CallbackExecutor Executor executor, 2839 @NonNull GnssAntennaInfo.Listener listener) { 2840 GnssLazyLoader.sGnssAntennaInfoListeners.addListener(listener, 2841 new GnssAntennaInfoTransport(executor, mContext, listener)); 2842 return true; 2843 } 2844 2845 /** 2846 * Unregisters a GNSS antenna info listener. 2847 * 2848 * @param listener a {@link GnssAntennaInfo.Listener} object to remove 2849 */ unregisterAntennaInfoListener(@onNull GnssAntennaInfo.Listener listener)2850 public void unregisterAntennaInfoListener(@NonNull GnssAntennaInfo.Listener listener) { 2851 GnssLazyLoader.sGnssAntennaInfoListeners.removeListener(listener); 2852 } 2853 2854 /** 2855 * No-op method to keep backward-compatibility. 2856 * 2857 * @hide 2858 * @deprecated Use {@link #registerGnssNavigationMessageCallback} instead. 2859 * @removed 2860 */ 2861 @Deprecated 2862 @SystemApi addGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener)2863 public boolean addGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) { 2864 return false; 2865 } 2866 2867 /** 2868 * No-op method to keep backward-compatibility. 2869 * 2870 * @hide 2871 * @deprecated Use {@link #unregisterGnssNavigationMessageCallback} instead. 2872 * @removed 2873 */ 2874 @Deprecated 2875 @SystemApi removeGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener)2876 public void removeGpsNavigationMessageListener(GpsNavigationMessageEvent.Listener listener) {} 2877 2878 /** 2879 * Registers a GNSS navigation message callback which will run on a binder thread. 2880 * 2881 * <p>See 2882 * {@link #registerGnssNavigationMessageCallback(Executor, GnssNavigationMessage.Callback)} for 2883 * more detail on how this method works. 2884 * 2885 * @param callback the callback to register 2886 * @return {@code true} always 2887 * 2888 * @deprecated Use {@link 2889 * #registerGnssNavigationMessageCallback(GnssNavigationMessage.Callback, Handler)} or {@link 2890 * #registerGnssNavigationMessageCallback(Executor, GnssNavigationMessage.Callback)} instead. 2891 */ 2892 @Deprecated registerGnssNavigationMessageCallback( @onNull GnssNavigationMessage.Callback callback)2893 public boolean registerGnssNavigationMessageCallback( 2894 @NonNull GnssNavigationMessage.Callback callback) { 2895 return registerGnssNavigationMessageCallback(DIRECT_EXECUTOR, callback); 2896 } 2897 2898 /** 2899 * Registers a GNSS navigation message callback. 2900 * 2901 * <p>See 2902 * {@link #registerGnssNavigationMessageCallback(Executor, GnssNavigationMessage.Callback)} for 2903 * more detail on how this method works. 2904 * 2905 * @param callback the callback to register 2906 * @param handler the handler that the callback runs on 2907 * @return {@code true} always 2908 * 2909 * @throws IllegalArgumentException if callback is null 2910 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2911 */ 2912 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssNavigationMessageCallback( @onNull GnssNavigationMessage.Callback callback, @Nullable Handler handler)2913 public boolean registerGnssNavigationMessageCallback( 2914 @NonNull GnssNavigationMessage.Callback callback, @Nullable Handler handler) { 2915 if (handler == null) { 2916 handler = new Handler(); 2917 } 2918 2919 return registerGnssNavigationMessageCallback(new HandlerExecutor(handler), callback); 2920 } 2921 2922 /** 2923 * Registers a GNSS navigation message callback. GNSS navigation messages will only be received 2924 * while the {@link #GPS_PROVIDER} is enabled, and while the client app is in the foreground. 2925 * 2926 * <p>Not all GNSS chipsets support navigation message updates, see 2927 * {@link #getGnssCapabilities()}. 2928 * 2929 * @param executor the executor that the callback runs on 2930 * @param callback the callback to register 2931 * @return {@code true} always 2932 * 2933 * @throws IllegalArgumentException if executor is null 2934 * @throws IllegalArgumentException if callback is null 2935 * @throws SecurityException if the ACCESS_FINE_LOCATION permission is not present 2936 */ 2937 @RequiresPermission(ACCESS_FINE_LOCATION) registerGnssNavigationMessageCallback( @onNull @allbackExecutor Executor executor, @NonNull GnssNavigationMessage.Callback callback)2938 public boolean registerGnssNavigationMessageCallback( 2939 @NonNull @CallbackExecutor Executor executor, 2940 @NonNull GnssNavigationMessage.Callback callback) { 2941 GnssLazyLoader.sGnssNavigationListeners.addListener(callback, 2942 new GnssNavigationTransport(executor, mContext, callback)); 2943 return true; 2944 } 2945 2946 /** 2947 * Unregisters a GNSS Navigation Message callback. 2948 * 2949 * @param callback a {@link GnssNavigationMessage.Callback} object to remove. 2950 */ unregisterGnssNavigationMessageCallback( @onNull GnssNavigationMessage.Callback callback)2951 public void unregisterGnssNavigationMessageCallback( 2952 @NonNull GnssNavigationMessage.Callback callback) { 2953 GnssLazyLoader.sGnssNavigationListeners.removeListener(callback); 2954 } 2955 2956 /** 2957 * Adds a {@link ProviderRequest.ChangedListener} for listening to all providers' 2958 * {@link ProviderRequest} changed events. 2959 * 2960 * @param executor the executor that the callback runs on 2961 * @param listener the listener to register 2962 * 2963 * @deprecated Do not use - this API was intended for testing only, and may not return any 2964 * results in the future. 2965 * @hide 2966 */ 2967 @FlaggedApi(Flags.FLAG_DEPRECATE_PROVIDER_REQUEST_APIS) 2968 @Deprecated 2969 @SystemApi 2970 @RequiresPermission(allOf = {Manifest.permission.LOCATION_HARDWARE, 2971 Manifest.permission.INTERACT_ACROSS_USERS}) addProviderRequestChangedListener( @onNull @allbackExecutor Executor executor, @NonNull ChangedListener listener)2972 public void addProviderRequestChangedListener( 2973 @NonNull @CallbackExecutor Executor executor, 2974 @NonNull ChangedListener listener) { 2975 ProviderRequestLazyLoader.sProviderRequestListeners.addListener(listener, 2976 new ProviderRequestTransport(executor, listener)); 2977 } 2978 2979 /** 2980 * Removes a {@link ProviderRequest.ChangedListener} that has been added. 2981 * 2982 * @param listener the listener to remove. 2983 * 2984 * @deprecated Do not use - this API was intended for testing only, and may not return any 2985 * results in the future. 2986 * @hide 2987 */ 2988 @FlaggedApi(Flags.FLAG_DEPRECATE_PROVIDER_REQUEST_APIS) 2989 @Deprecated 2990 @SystemApi 2991 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) removeProviderRequestChangedListener( @onNull ProviderRequest.ChangedListener listener)2992 public void removeProviderRequestChangedListener( 2993 @NonNull ProviderRequest.ChangedListener listener) { 2994 ProviderRequestLazyLoader.sProviderRequestListeners.removeListener(listener); 2995 } 2996 2997 /** 2998 * Returns the batch size (in number of Location objects) that are supported by the batching 2999 * interface. 3000 * 3001 * Prior to Android S this call requires the {@link Manifest.permission#LOCATION_HARDWARE} 3002 * permission. 3003 * 3004 * @return Maximum number of location objects that can be returned 3005 * @deprecated Do not use 3006 * @hide 3007 */ 3008 @Deprecated 3009 @SystemApi getGnssBatchSize()3010 public int getGnssBatchSize() { 3011 try { 3012 return mService.getGnssBatchSize(); 3013 } catch (RemoteException e) { 3014 throw e.rethrowFromSystemServer(); 3015 } 3016 } 3017 3018 /** 3019 * Start hardware-batching of GNSS locations. This API is primarily used when the AP is 3020 * asleep and the device can batch GNSS locations in the hardware. 3021 * 3022 * Note this is designed (as was the fused location interface before it) for a single user 3023 * SystemApi - requests are not consolidated. Care should be taken when the System switches 3024 * users that may have different batching requests, to stop hardware batching for one user, and 3025 * restart it for the next. 3026 * 3027 * @param periodNanos Time interval, in nanoseconds, that the GNSS locations are requested 3028 * within the batch 3029 * @param wakeOnFifoFull ignored 3030 * @param callback The listener on which to return the batched locations 3031 * @param handler The handler on which to process the callback 3032 * 3033 * @return True always 3034 * @deprecated Use {@link LocationRequest.Builder#setMaxUpdateDelayMillis(long)} instead. 3035 * @hide 3036 */ 3037 @Deprecated 3038 @SystemApi 3039 @RequiresPermission(allOf = {Manifest.permission.LOCATION_HARDWARE, 3040 Manifest.permission.UPDATE_APP_OPS_STATS}) registerGnssBatchedLocationCallback(long periodNanos, boolean wakeOnFifoFull, @NonNull BatchedLocationCallback callback, @Nullable Handler handler)3041 public boolean registerGnssBatchedLocationCallback(long periodNanos, boolean wakeOnFifoFull, 3042 @NonNull BatchedLocationCallback callback, @Nullable Handler handler) { 3043 if (handler == null) { 3044 handler = new Handler(); 3045 } 3046 3047 try { 3048 mService.startGnssBatch( 3049 periodNanos, 3050 new BatchedLocationCallbackTransport(callback, handler), 3051 mContext.getPackageName(), 3052 mContext.getAttributionTag(), 3053 AppOpsManager.toReceiverId(callback)); 3054 return true; 3055 } catch (RemoteException e) { 3056 throw e.rethrowFromSystemServer(); 3057 } 3058 } 3059 3060 /** 3061 * Flush the batched GNSS locations. All GNSS locations currently ready in the batch are 3062 * returned via the callback sent in startGnssBatch(), and the buffer containing the batched 3063 * locations is cleared. 3064 * 3065 * @hide 3066 * @deprecated Use {@link #requestFlush(String, LocationListener, int)} or 3067 * {@link #requestFlush(String, PendingIntent, int)} instead. 3068 */ 3069 @Deprecated 3070 @SystemApi 3071 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) flushGnssBatch()3072 public void flushGnssBatch() { 3073 try { 3074 mService.flushGnssBatch(); 3075 } catch (RemoteException e) { 3076 throw e.rethrowFromSystemServer(); 3077 } 3078 } 3079 3080 /** 3081 * Stop batching locations. This API is primarily used when the AP is asleep and the device can 3082 * batch locations in the hardware. 3083 * 3084 * @param callback ignored 3085 * 3086 * @return True always 3087 * @deprecated Use {@link LocationRequest.Builder#setMaxUpdateDelayMillis(long)} instead. 3088 * @hide 3089 */ 3090 @Deprecated 3091 @SystemApi 3092 @RequiresPermission(Manifest.permission.LOCATION_HARDWARE) unregisterGnssBatchedLocationCallback( @onNull BatchedLocationCallback callback)3093 public boolean unregisterGnssBatchedLocationCallback( 3094 @NonNull BatchedLocationCallback callback) { 3095 try { 3096 mService.stopGnssBatch(); 3097 return true; 3098 } catch (RemoteException e) { 3099 throw e.rethrowFromSystemServer(); 3100 } 3101 } 3102 3103 private static class GnssStatusTransportManager extends 3104 ListenerTransportManager<GnssStatusTransport> { 3105 GnssStatusTransportManager()3106 GnssStatusTransportManager() { 3107 super(false); 3108 } 3109 3110 @Override registerTransport(GnssStatusTransport transport)3111 protected void registerTransport(GnssStatusTransport transport) 3112 throws RemoteException { 3113 getService().registerGnssStatusCallback(transport, transport.getPackage(), 3114 transport.getAttributionTag(), 3115 AppOpsManager.toReceiverId(transport.getListener())); 3116 } 3117 3118 @Override unregisterTransport(GnssStatusTransport transport)3119 protected void unregisterTransport(GnssStatusTransport transport) 3120 throws RemoteException { 3121 getService().unregisterGnssStatusCallback(transport); 3122 } 3123 } 3124 3125 private static class GnssNmeaTransportManager extends 3126 ListenerTransportManager<GnssNmeaTransport> { 3127 GnssNmeaTransportManager()3128 GnssNmeaTransportManager() { 3129 super(false); 3130 } 3131 3132 @Override registerTransport(GnssNmeaTransport transport)3133 protected void registerTransport(GnssNmeaTransport transport) 3134 throws RemoteException { 3135 getService().registerGnssNmeaCallback(transport, transport.getPackage(), 3136 transport.getAttributionTag(), 3137 AppOpsManager.toReceiverId(transport.getListener())); 3138 } 3139 3140 @Override unregisterTransport(GnssNmeaTransport transport)3141 protected void unregisterTransport(GnssNmeaTransport transport) 3142 throws RemoteException { 3143 getService().unregisterGnssNmeaCallback(transport); 3144 } 3145 } 3146 3147 private static class GnssMeasurementsTransportManager extends 3148 ListenerTransportManager<GnssMeasurementsTransport> { 3149 GnssMeasurementsTransportManager()3150 GnssMeasurementsTransportManager() { 3151 super(false); 3152 } 3153 3154 @Override registerTransport(GnssMeasurementsTransport transport)3155 protected void registerTransport(GnssMeasurementsTransport transport) 3156 throws RemoteException { 3157 getService().addGnssMeasurementsListener(transport.getRequest(), transport, 3158 transport.getPackage(), transport.getAttributionTag(), 3159 AppOpsManager.toReceiverId(transport.getListener())); 3160 } 3161 3162 @Override unregisterTransport(GnssMeasurementsTransport transport)3163 protected void unregisterTransport(GnssMeasurementsTransport transport) 3164 throws RemoteException { 3165 getService().removeGnssMeasurementsListener(transport); 3166 } 3167 } 3168 3169 private static class GnssAntennaTransportManager extends 3170 ListenerTransportManager<GnssAntennaInfoTransport> { 3171 GnssAntennaTransportManager()3172 GnssAntennaTransportManager() { 3173 super(false); 3174 } 3175 3176 @Override registerTransport(GnssAntennaInfoTransport transport)3177 protected void registerTransport(GnssAntennaInfoTransport transport) 3178 throws RemoteException { 3179 getService().addGnssAntennaInfoListener(transport, transport.getPackage(), 3180 transport.getAttributionTag(), 3181 AppOpsManager.toReceiverId(transport.getListener())); 3182 } 3183 3184 @Override unregisterTransport(GnssAntennaInfoTransport transport)3185 protected void unregisterTransport(GnssAntennaInfoTransport transport) 3186 throws RemoteException { 3187 getService().removeGnssAntennaInfoListener(transport); 3188 } 3189 } 3190 3191 private static class GnssNavigationTransportManager extends 3192 ListenerTransportManager<GnssNavigationTransport> { 3193 GnssNavigationTransportManager()3194 GnssNavigationTransportManager() { 3195 super(false); 3196 } 3197 3198 @Override registerTransport(GnssNavigationTransport transport)3199 protected void registerTransport(GnssNavigationTransport transport) 3200 throws RemoteException { 3201 getService().addGnssNavigationMessageListener(transport, 3202 transport.getPackage(), transport.getAttributionTag(), 3203 AppOpsManager.toReceiverId(transport.getListener())); 3204 } 3205 3206 @Override unregisterTransport(GnssNavigationTransport transport)3207 protected void unregisterTransport(GnssNavigationTransport transport) 3208 throws RemoteException { 3209 getService().removeGnssNavigationMessageListener(transport); 3210 } 3211 } 3212 3213 private static class ProviderRequestTransportManager extends 3214 ListenerTransportManager<ProviderRequestTransport> { 3215 ProviderRequestTransportManager()3216 ProviderRequestTransportManager() { 3217 super(false); 3218 } 3219 3220 @Override registerTransport(ProviderRequestTransport transport)3221 protected void registerTransport(ProviderRequestTransport transport) 3222 throws RemoteException { 3223 getService().addProviderRequestListener(transport); 3224 } 3225 3226 @Override unregisterTransport(ProviderRequestTransport transport)3227 protected void unregisterTransport(ProviderRequestTransport transport) 3228 throws RemoteException { 3229 getService().removeProviderRequestListener(transport); 3230 } 3231 } 3232 3233 private static class GetCurrentLocationTransport extends ILocationCallback.Stub implements 3234 ListenerExecutor, CancellationSignal.OnCancelListener { 3235 3236 private final Executor mExecutor; 3237 volatile @Nullable Consumer<Location> mConsumer; 3238 GetCurrentLocationTransport(Executor executor, Consumer<Location> consumer, @Nullable CancellationSignal cancellationSignal)3239 GetCurrentLocationTransport(Executor executor, Consumer<Location> consumer, 3240 @Nullable CancellationSignal cancellationSignal) { 3241 Preconditions.checkArgument(executor != null, "illegal null executor"); 3242 Preconditions.checkArgument(consumer != null, "illegal null consumer"); 3243 mExecutor = executor; 3244 mConsumer = consumer; 3245 3246 if (cancellationSignal != null) { 3247 cancellationSignal.setOnCancelListener(this); 3248 } 3249 } 3250 3251 @Override onCancel()3252 public void onCancel() { 3253 mConsumer = null; 3254 } 3255 3256 @Override onLocation(@ullable Location location)3257 public void onLocation(@Nullable Location location) { 3258 executeSafely(mExecutor, () -> mConsumer, new ListenerOperation<Consumer<Location>>() { 3259 @Override 3260 public void operate(Consumer<Location> consumer) { 3261 consumer.accept(location); 3262 } 3263 3264 @Override 3265 public void onPostExecute(boolean success) { 3266 mConsumer = null; 3267 } 3268 }); 3269 } 3270 } 3271 3272 private static class LocationListenerTransport extends ILocationListener.Stub implements 3273 ListenerExecutor { 3274 3275 private Executor mExecutor; 3276 private volatile @Nullable LocationListener mListener; 3277 LocationListenerTransport(LocationListener listener, Executor executor)3278 LocationListenerTransport(LocationListener listener, Executor executor) { 3279 Preconditions.checkArgument(listener != null, "invalid null listener"); 3280 mListener = listener; 3281 setExecutor(executor); 3282 } 3283 setExecutor(Executor executor)3284 void setExecutor(Executor executor) { 3285 Preconditions.checkArgument(executor != null, "invalid null executor"); 3286 mExecutor = executor; 3287 } 3288 isRegistered()3289 boolean isRegistered() { 3290 return mListener != null; 3291 } 3292 unregister()3293 void unregister() { 3294 mListener = null; 3295 } 3296 3297 @Override onLocationChanged(List<Location> locations, @Nullable IRemoteCallback onCompleteCallback)3298 public void onLocationChanged(List<Location> locations, 3299 @Nullable IRemoteCallback onCompleteCallback) { 3300 executeSafely(mExecutor, () -> mListener, new ListenerOperation<LocationListener>() { 3301 @Override 3302 public void operate(LocationListener listener) { 3303 listener.onLocationChanged(locations); 3304 } 3305 3306 @Override 3307 public void onComplete(boolean success) { 3308 if (onCompleteCallback != null) { 3309 try { 3310 onCompleteCallback.sendResult(null); 3311 } catch (RemoteException e) { 3312 throw e.rethrowFromSystemServer(); 3313 } 3314 } 3315 } 3316 }); 3317 } 3318 3319 @Override onFlushComplete(int requestCode)3320 public void onFlushComplete(int requestCode) { 3321 executeSafely(mExecutor, () -> mListener, 3322 listener -> listener.onFlushComplete(requestCode)); 3323 } 3324 3325 @Override onProviderEnabledChanged(String provider, boolean enabled)3326 public void onProviderEnabledChanged(String provider, boolean enabled) { 3327 executeSafely(mExecutor, () -> mListener, listener -> { 3328 if (enabled) { 3329 listener.onProviderEnabled(provider); 3330 } else { 3331 listener.onProviderDisabled(provider); 3332 } 3333 }); 3334 } 3335 } 3336 3337 /** @deprecated */ 3338 @Deprecated 3339 private static class GpsAdapter extends GnssStatus.Callback { 3340 3341 private final GpsStatus.Listener mGpsListener; 3342 GpsAdapter(GpsStatus.Listener gpsListener)3343 GpsAdapter(GpsStatus.Listener gpsListener) { 3344 mGpsListener = gpsListener; 3345 } 3346 3347 @Override onStarted()3348 public void onStarted() { 3349 mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STARTED); 3350 } 3351 3352 @Override onStopped()3353 public void onStopped() { 3354 mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_STOPPED); 3355 } 3356 3357 @Override onFirstFix(int ttffMillis)3358 public void onFirstFix(int ttffMillis) { 3359 mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_FIRST_FIX); 3360 } 3361 3362 @Override onSatelliteStatusChanged(GnssStatus status)3363 public void onSatelliteStatusChanged(GnssStatus status) { 3364 mGpsListener.onGpsStatusChanged(GpsStatus.GPS_EVENT_SATELLITE_STATUS); 3365 } 3366 } 3367 3368 private static class GnssStatusTransport extends IGnssStatusListener.Stub implements 3369 ListenerTransport<GnssStatus.Callback> { 3370 3371 private final Executor mExecutor; 3372 private final String mPackageName; 3373 private final String mAttributionTag; 3374 3375 private volatile @Nullable GnssStatus.Callback mListener; 3376 GnssStatusTransport(Executor executor, Context context, GnssStatus.Callback listener)3377 GnssStatusTransport(Executor executor, Context context, GnssStatus.Callback listener) { 3378 Preconditions.checkArgument(executor != null, "invalid null executor"); 3379 Preconditions.checkArgument(listener != null, "invalid null callback"); 3380 mExecutor = executor; 3381 mPackageName = context.getPackageName(); 3382 mAttributionTag = context.getAttributionTag(); 3383 mListener = listener; 3384 } 3385 getPackage()3386 public String getPackage() { 3387 return mPackageName; 3388 } 3389 getAttributionTag()3390 public String getAttributionTag() { 3391 return mAttributionTag; 3392 } 3393 3394 @Override unregister()3395 public void unregister() { 3396 mListener = null; 3397 } 3398 3399 @Override getListener()3400 public @Nullable GnssStatus.Callback getListener() { 3401 return mListener; 3402 } 3403 3404 @Override onGnssStarted()3405 public void onGnssStarted() { 3406 execute(mExecutor, GnssStatus.Callback::onStarted); 3407 } 3408 3409 @Override onGnssStopped()3410 public void onGnssStopped() { 3411 execute(mExecutor, GnssStatus.Callback::onStopped); 3412 } 3413 3414 @Override onFirstFix(int ttff)3415 public void onFirstFix(int ttff) { 3416 execute(mExecutor, listener -> listener.onFirstFix(ttff)); 3417 3418 } 3419 3420 @Override onSvStatusChanged(GnssStatus gnssStatus)3421 public void onSvStatusChanged(GnssStatus gnssStatus) { 3422 execute(mExecutor, listener -> listener.onSatelliteStatusChanged(gnssStatus)); 3423 } 3424 } 3425 3426 /** @deprecated */ 3427 @Deprecated 3428 private static class GpsStatusTransport extends GnssStatusTransport { 3429 3430 static volatile int sTtff; 3431 static volatile GnssStatus sGnssStatus; 3432 GpsStatusTransport(Executor executor, Context context, GpsStatus.Listener listener)3433 GpsStatusTransport(Executor executor, Context context, GpsStatus.Listener listener) { 3434 super(executor, context, new GpsAdapter(listener)); 3435 } 3436 3437 @Override onFirstFix(int ttff)3438 public void onFirstFix(int ttff) { 3439 sTtff = ttff; 3440 super.onFirstFix(ttff); 3441 } 3442 3443 @Override onSvStatusChanged(GnssStatus gnssStatus)3444 public void onSvStatusChanged(GnssStatus gnssStatus) { 3445 sGnssStatus = gnssStatus; 3446 super.onSvStatusChanged(gnssStatus); 3447 } 3448 } 3449 3450 private static class GnssNmeaTransport extends IGnssNmeaListener.Stub implements 3451 ListenerTransport<OnNmeaMessageListener> { 3452 3453 private final Executor mExecutor; 3454 private final String mPackageName; 3455 private final String mAttributionTag; 3456 3457 private volatile @Nullable OnNmeaMessageListener mListener; 3458 GnssNmeaTransport(Executor executor, Context context, OnNmeaMessageListener listener)3459 GnssNmeaTransport(Executor executor, Context context, OnNmeaMessageListener listener) { 3460 Preconditions.checkArgument(executor != null, "invalid null executor"); 3461 Preconditions.checkArgument(listener != null, "invalid null listener"); 3462 mExecutor = executor; 3463 mPackageName = context.getPackageName(); 3464 mAttributionTag = context.getAttributionTag(); 3465 mListener = listener; 3466 } 3467 getPackage()3468 public String getPackage() { 3469 return mPackageName; 3470 } 3471 getAttributionTag()3472 public String getAttributionTag() { 3473 return mAttributionTag; 3474 } 3475 3476 @Override unregister()3477 public void unregister() { 3478 mListener = null; 3479 } 3480 3481 @Override getListener()3482 public @Nullable OnNmeaMessageListener getListener() { 3483 return mListener; 3484 } 3485 3486 @Override onNmeaReceived(long timestamp, String nmea)3487 public void onNmeaReceived(long timestamp, String nmea) { 3488 execute(mExecutor, callback -> callback.onNmeaMessage(nmea, timestamp)); 3489 } 3490 } 3491 3492 private static class GnssMeasurementsTransport extends IGnssMeasurementsListener.Stub implements 3493 ListenerTransport<GnssMeasurementsEvent.Callback> { 3494 3495 private final Executor mExecutor; 3496 private final String mPackageName; 3497 private final String mAttributionTag; 3498 private final GnssMeasurementRequest mRequest; 3499 3500 private volatile @Nullable GnssMeasurementsEvent.Callback mListener; 3501 GnssMeasurementsTransport(Executor executor, Context context, GnssMeasurementRequest request, GnssMeasurementsEvent.Callback listener)3502 GnssMeasurementsTransport(Executor executor, Context context, 3503 GnssMeasurementRequest request, GnssMeasurementsEvent.Callback listener) { 3504 Preconditions.checkArgument(executor != null, "invalid null executor"); 3505 Preconditions.checkArgument(listener != null, "invalid null callback"); 3506 Preconditions.checkArgument(request != null, "invalid null request"); 3507 mExecutor = executor; 3508 mPackageName = context.getPackageName(); 3509 mAttributionTag = context.getAttributionTag(); 3510 mRequest = request; 3511 mListener = listener; 3512 } 3513 getPackage()3514 public String getPackage() { 3515 return mPackageName; 3516 } 3517 getAttributionTag()3518 public String getAttributionTag() { 3519 return mAttributionTag; 3520 } 3521 getRequest()3522 public GnssMeasurementRequest getRequest() { 3523 return mRequest; 3524 } 3525 3526 @Override unregister()3527 public void unregister() { 3528 mListener = null; 3529 } 3530 3531 @Override getListener()3532 public @Nullable GnssMeasurementsEvent.Callback getListener() { 3533 return mListener; 3534 } 3535 3536 @Override onGnssMeasurementsReceived(GnssMeasurementsEvent event)3537 public void onGnssMeasurementsReceived(GnssMeasurementsEvent event) { 3538 execute(mExecutor, callback -> callback.onGnssMeasurementsReceived(event)); 3539 } 3540 3541 @Override onStatusChanged(int status)3542 public void onStatusChanged(int status) { 3543 execute(mExecutor, callback -> callback.onStatusChanged(status)); 3544 } 3545 } 3546 3547 private static class GnssAntennaInfoTransport extends IGnssAntennaInfoListener.Stub implements 3548 ListenerTransport<GnssAntennaInfo.Listener> { 3549 3550 private final Executor mExecutor; 3551 private final String mPackageName; 3552 private final String mAttributionTag; 3553 3554 private volatile @Nullable GnssAntennaInfo.Listener mListener; 3555 GnssAntennaInfoTransport(Executor executor, Context context, GnssAntennaInfo.Listener listener)3556 GnssAntennaInfoTransport(Executor executor, Context context, 3557 GnssAntennaInfo.Listener listener) { 3558 Preconditions.checkArgument(executor != null, "invalid null executor"); 3559 Preconditions.checkArgument(listener != null, "invalid null listener"); 3560 mExecutor = executor; 3561 mPackageName = context.getPackageName(); 3562 mAttributionTag = context.getAttributionTag(); 3563 mListener = listener; 3564 } 3565 getPackage()3566 public String getPackage() { 3567 return mPackageName; 3568 } 3569 getAttributionTag()3570 public String getAttributionTag() { 3571 return mAttributionTag; 3572 } 3573 3574 @Override unregister()3575 public void unregister() { 3576 mListener = null; 3577 } 3578 3579 @Override getListener()3580 public @Nullable GnssAntennaInfo.Listener getListener() { 3581 return mListener; 3582 } 3583 3584 @Override onGnssAntennaInfoChanged(List<GnssAntennaInfo> antennaInfos)3585 public void onGnssAntennaInfoChanged(List<GnssAntennaInfo> antennaInfos) { 3586 execute(mExecutor, callback -> callback.onGnssAntennaInfoReceived(antennaInfos)); 3587 } 3588 } 3589 3590 private static class GnssNavigationTransport extends IGnssNavigationMessageListener.Stub 3591 implements ListenerTransport<GnssNavigationMessage.Callback> { 3592 3593 private final Executor mExecutor; 3594 private final String mPackageName; 3595 private final String mAttributionTag; 3596 3597 private volatile @Nullable GnssNavigationMessage.Callback mListener; 3598 GnssNavigationTransport(Executor executor, Context context, GnssNavigationMessage.Callback listener)3599 GnssNavigationTransport(Executor executor, Context context, 3600 GnssNavigationMessage.Callback listener) { 3601 Preconditions.checkArgument(executor != null, "invalid null executor"); 3602 Preconditions.checkArgument(listener != null, "invalid null callback"); 3603 mExecutor = executor; 3604 mPackageName = context.getPackageName(); 3605 mAttributionTag = context.getAttributionTag(); 3606 mListener = listener; 3607 } 3608 getPackage()3609 public String getPackage() { 3610 return mPackageName; 3611 } 3612 getAttributionTag()3613 public String getAttributionTag() { 3614 return mAttributionTag; 3615 } 3616 3617 @Override unregister()3618 public void unregister() { 3619 mListener = null; 3620 } 3621 3622 @Override getListener()3623 public @Nullable GnssNavigationMessage.Callback getListener() { 3624 return mListener; 3625 } 3626 3627 @Override onGnssNavigationMessageReceived(GnssNavigationMessage event)3628 public void onGnssNavigationMessageReceived(GnssNavigationMessage event) { 3629 execute(mExecutor, listener -> listener.onGnssNavigationMessageReceived(event)); 3630 } 3631 3632 @Override onStatusChanged(int status)3633 public void onStatusChanged(int status) { 3634 execute(mExecutor, listener -> listener.onStatusChanged(status)); 3635 } 3636 } 3637 3638 private static class ProviderRequestTransport extends IProviderRequestListener.Stub 3639 implements ListenerTransport<ChangedListener> { 3640 3641 private final Executor mExecutor; 3642 3643 private volatile @Nullable ProviderRequest.ChangedListener mListener; 3644 ProviderRequestTransport(Executor executor, ChangedListener listener)3645 ProviderRequestTransport(Executor executor, ChangedListener listener) { 3646 Preconditions.checkArgument(executor != null, "invalid null executor"); 3647 Preconditions.checkArgument(listener != null, "invalid null callback"); 3648 mExecutor = executor; 3649 mListener = listener; 3650 } 3651 3652 @Override unregister()3653 public void unregister() { 3654 mListener = null; 3655 } 3656 3657 @Override getListener()3658 public @Nullable ProviderRequest.ChangedListener getListener() { 3659 return mListener; 3660 } 3661 3662 @Override onProviderRequestChanged(String provider, ProviderRequest request)3663 public void onProviderRequestChanged(String provider, ProviderRequest request) { 3664 execute(mExecutor, listener -> listener.onProviderRequestChanged(provider, request)); 3665 } 3666 } 3667 3668 /** @deprecated */ 3669 @Deprecated 3670 private static class BatchedLocationCallbackWrapper implements LocationListener { 3671 3672 private final BatchedLocationCallback mCallback; 3673 BatchedLocationCallbackWrapper(BatchedLocationCallback callback)3674 BatchedLocationCallbackWrapper(BatchedLocationCallback callback) { 3675 mCallback = callback; 3676 } 3677 3678 @Override onLocationChanged(@onNull Location location)3679 public void onLocationChanged(@NonNull Location location) { 3680 mCallback.onLocationBatch(Collections.singletonList(location)); 3681 } 3682 3683 @Override onLocationChanged(@onNull List<Location> locations)3684 public void onLocationChanged(@NonNull List<Location> locations) { 3685 mCallback.onLocationBatch(locations); 3686 } 3687 } 3688 3689 /** @deprecated */ 3690 @Deprecated 3691 private static class BatchedLocationCallbackTransport extends LocationListenerTransport { 3692 BatchedLocationCallbackTransport(BatchedLocationCallback callback, Handler handler)3693 BatchedLocationCallbackTransport(BatchedLocationCallback callback, Handler handler) { 3694 super(new BatchedLocationCallbackWrapper(callback), new HandlerExecutor(handler)); 3695 } 3696 } 3697 3698 private static class LocationEnabledCache extends PropertyInvalidatedCache<Integer, Boolean> { 3699 3700 // this is not loaded immediately because this class is created as soon as LocationManager 3701 // is referenced for the first time, and within the system server, the ILocationManager 3702 // service may not have been loaded yet at that time. 3703 private @Nullable ILocationManager mManager; 3704 LocationEnabledCache(int numEntries)3705 LocationEnabledCache(int numEntries) { 3706 super(numEntries, CACHE_KEY_LOCATION_ENABLED_PROPERTY); 3707 } 3708 3709 @Override recompute(Integer userId)3710 public Boolean recompute(Integer userId) { 3711 Preconditions.checkArgument(userId >= 0); 3712 3713 if (mManager == null) { 3714 try { 3715 mManager = getService(); 3716 } catch (RemoteException e) { 3717 e.rethrowFromSystemServer(); 3718 } 3719 } 3720 3721 try { 3722 return mManager.isLocationEnabledForUser(userId); 3723 } catch (RemoteException e) { 3724 throw e.rethrowFromSystemServer(); 3725 } 3726 } 3727 } 3728 3729 /** 3730 * @hide 3731 */ invalidateLocalLocationEnabledCaches()3732 public static void invalidateLocalLocationEnabledCaches() { 3733 PropertyInvalidatedCache.invalidateCache(CACHE_KEY_LOCATION_ENABLED_PROPERTY); 3734 } 3735 3736 /** 3737 * @hide 3738 */ disableLocalLocationEnabledCaches()3739 public static void disableLocalLocationEnabledCaches() { 3740 sLocationEnabledCache = null; 3741 } 3742 } 3743