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