1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.server.location; 18 19 import static android.Manifest.permission.INTERACT_ACROSS_USERS; 20 import static android.Manifest.permission.LOCATION_BYPASS; 21 import static android.Manifest.permission.WRITE_SECURE_SETTINGS; 22 import static android.app.compat.CompatChanges.isChangeEnabled; 23 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE; 24 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY; 25 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 26 import static android.location.LocationManager.BLOCK_PENDING_INTENT_SYSTEM_API_USAGE; 27 import static android.location.LocationManager.FUSED_PROVIDER; 28 import static android.location.LocationManager.GPS_HARDWARE_PROVIDER; 29 import static android.location.LocationManager.GPS_PROVIDER; 30 import static android.location.LocationManager.NETWORK_PROVIDER; 31 import static android.location.LocationRequest.LOW_POWER_EXCEPTIONS; 32 import static android.location.provider.LocationProviderBase.ACTION_FUSED_PROVIDER; 33 import static android.location.provider.LocationProviderBase.ACTION_GNSS_PROVIDER; 34 import static android.location.provider.LocationProviderBase.ACTION_NETWORK_PROVIDER; 35 36 import static com.android.server.location.LocationPermissions.PERMISSION_COARSE; 37 import static com.android.server.location.LocationPermissions.PERMISSION_FINE; 38 import static com.android.server.location.LocationPermissions.PERMISSION_NONE; 39 import static com.android.server.location.eventlog.LocationEventLog.EVENT_LOG; 40 41 import static java.util.concurrent.TimeUnit.NANOSECONDS; 42 43 import android.Manifest; 44 import android.Manifest.permission; 45 import android.annotation.NonNull; 46 import android.annotation.Nullable; 47 import android.annotation.RequiresPermission; 48 import android.app.ActivityManager; 49 import android.app.ActivityManagerInternal; 50 import android.app.AppOpsManager; 51 import android.app.PendingIntent; 52 import android.app.compat.CompatChanges; 53 import android.content.Context; 54 import android.content.Intent; 55 import android.content.pm.PackageManager; 56 import android.location.Criteria; 57 import android.location.Geofence; 58 import android.location.GnssAntennaInfo; 59 import android.location.GnssCapabilities; 60 import android.location.GnssMeasurementCorrections; 61 import android.location.GnssMeasurementRequest; 62 import android.location.IGnssAntennaInfoListener; 63 import android.location.IGnssMeasurementsListener; 64 import android.location.IGnssNavigationMessageListener; 65 import android.location.IGnssNmeaListener; 66 import android.location.IGnssStatusListener; 67 import android.location.ILocationCallback; 68 import android.location.ILocationListener; 69 import android.location.ILocationManager; 70 import android.location.LastLocationRequest; 71 import android.location.Location; 72 import android.location.LocationManager; 73 import android.location.LocationManagerInternal; 74 import android.location.LocationManagerInternal.LocationPackageTagsListener; 75 import android.location.LocationProvider; 76 import android.location.LocationRequest; 77 import android.location.LocationTime; 78 import android.location.flags.Flags; 79 import android.location.provider.ForwardGeocodeRequest; 80 import android.location.provider.IGeocodeCallback; 81 import android.location.provider.IProviderRequestListener; 82 import android.location.provider.ProviderProperties; 83 import android.location.provider.ReverseGeocodeRequest; 84 import android.location.util.identity.CallerIdentity; 85 import android.os.Binder; 86 import android.os.Build; 87 import android.os.Bundle; 88 import android.os.ICancellationSignal; 89 import android.os.PackageTagsList; 90 import android.os.ParcelFileDescriptor; 91 import android.os.Process; 92 import android.os.RemoteException; 93 import android.os.UserHandle; 94 import android.os.WorkSource; 95 import android.os.WorkSource.WorkChain; 96 import android.provider.Settings; 97 import android.stats.location.LocationStatsEnums; 98 import android.util.ArrayMap; 99 import android.util.ArraySet; 100 import android.util.IndentingPrintWriter; 101 import android.util.Log; 102 103 import com.android.internal.annotations.GuardedBy; 104 import com.android.internal.annotations.VisibleForTesting; 105 import com.android.internal.util.DumpUtils; 106 import com.android.internal.util.FrameworkStatsLog; 107 import com.android.internal.util.Preconditions; 108 import com.android.server.FgThread; 109 import com.android.server.LocalServices; 110 import com.android.server.SystemService; 111 import com.android.server.location.eventlog.LocationEventLog; 112 import com.android.server.location.fudger.LocationFudgerCache; 113 import com.android.server.location.geofence.GeofenceManager; 114 import com.android.server.location.geofence.GeofenceProxy; 115 import com.android.server.location.gnss.GnssConfiguration; 116 import com.android.server.location.gnss.GnssManagerService; 117 import com.android.server.location.gnss.hal.GnssNative; 118 import com.android.server.location.injector.AlarmHelper; 119 import com.android.server.location.injector.AppForegroundHelper; 120 import com.android.server.location.injector.AppOpsHelper; 121 import com.android.server.location.injector.DeviceIdleHelper; 122 import com.android.server.location.injector.DeviceStationaryHelper; 123 import com.android.server.location.injector.EmergencyHelper; 124 import com.android.server.location.injector.Injector; 125 import com.android.server.location.injector.LocationPermissionsHelper; 126 import com.android.server.location.injector.LocationPowerSaveModeHelper; 127 import com.android.server.location.injector.LocationUsageLogger; 128 import com.android.server.location.injector.PackageResetHelper; 129 import com.android.server.location.injector.ScreenInteractiveHelper; 130 import com.android.server.location.injector.SettingsHelper; 131 import com.android.server.location.injector.SystemAlarmHelper; 132 import com.android.server.location.injector.SystemAppForegroundHelper; 133 import com.android.server.location.injector.SystemAppOpsHelper; 134 import com.android.server.location.injector.SystemDeviceIdleHelper; 135 import com.android.server.location.injector.SystemDeviceStationaryHelper; 136 import com.android.server.location.injector.SystemEmergencyHelper; 137 import com.android.server.location.injector.SystemLocationPermissionsHelper; 138 import com.android.server.location.injector.SystemLocationPowerSaveModeHelper; 139 import com.android.server.location.injector.SystemPackageResetHelper; 140 import com.android.server.location.injector.SystemScreenInteractiveHelper; 141 import com.android.server.location.injector.SystemSettingsHelper; 142 import com.android.server.location.injector.SystemUserInfoHelper; 143 import com.android.server.location.injector.UserInfoHelper; 144 import com.android.server.location.provider.AbstractLocationProvider; 145 import com.android.server.location.provider.LocationProviderManager; 146 import com.android.server.location.provider.MockLocationProvider; 147 import com.android.server.location.provider.PassiveLocationProvider; 148 import com.android.server.location.provider.PassiveLocationProviderManager; 149 import com.android.server.location.provider.StationaryThrottlingLocationProvider; 150 import com.android.server.location.provider.proxy.ProxyGeocodeProvider; 151 import com.android.server.location.provider.proxy.ProxyLocationProvider; 152 import com.android.server.location.provider.proxy.ProxyPopulationDensityProvider; 153 import com.android.server.location.settings.LocationSettings; 154 import com.android.server.location.settings.LocationUserSettings; 155 import com.android.server.pm.permission.LegacyPermissionManagerInternal; 156 157 import java.io.FileDescriptor; 158 import java.io.PrintWriter; 159 import java.util.ArrayList; 160 import java.util.Collections; 161 import java.util.List; 162 import java.util.Objects; 163 import java.util.concurrent.CopyOnWriteArrayList; 164 165 /** 166 * The service class that manages LocationProviders and issues location 167 * updates and alerts. 168 */ 169 public class LocationManagerService extends ILocationManager.Stub implements 170 LocationProviderManager.StateChangedListener { 171 172 /** 173 * Controls lifecycle of LocationManagerService. 174 */ 175 public static class Lifecycle extends SystemService { 176 177 private final LifecycleUserInfoHelper mUserInfoHelper; 178 private final SystemInjector mSystemInjector; 179 private final LocationManagerService mService; 180 Lifecycle(Context context)181 public Lifecycle(Context context) { 182 super(context); 183 mUserInfoHelper = new LifecycleUserInfoHelper(context); 184 mSystemInjector = new SystemInjector(context, mUserInfoHelper); 185 mService = new LocationManagerService(context, mSystemInjector); 186 } 187 188 @Override onStart()189 public void onStart() { 190 publishBinderService(Context.LOCATION_SERVICE, mService); 191 192 // client caching behavior is only enabled after seeing the first invalidate 193 LocationManager.invalidateLocalLocationEnabledCaches(); 194 // disable caching for our own process 195 LocationManager.disableLocalLocationEnabledCaches(); 196 } 197 198 @Override onBootPhase(int phase)199 public void onBootPhase(int phase) { 200 if (phase == PHASE_SYSTEM_SERVICES_READY) { 201 // the location service must be functioning after this boot phase 202 mSystemInjector.onSystemReady(); 203 mService.onSystemReady(); 204 } else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) { 205 // some providers rely on third party code, so we wait to initialize 206 // providers until third party code is allowed to run 207 mService.onSystemThirdPartyAppsCanStart(); 208 } 209 } 210 211 @Override onUserStarting(TargetUser user)212 public void onUserStarting(TargetUser user) { 213 mUserInfoHelper.onUserStarted(user.getUserIdentifier()); 214 215 // log location enabled state and emergency state on start to minimize coverage loss 216 mService.logLocationEnabledState(); 217 mService.logEmergencyState(); 218 } 219 220 @Override onUserSwitching(TargetUser from, TargetUser to)221 public void onUserSwitching(TargetUser from, TargetUser to) { 222 mUserInfoHelper.onCurrentUserChanged(from.getUserIdentifier(), 223 to.getUserIdentifier()); 224 } 225 226 @Override onUserStopped(TargetUser user)227 public void onUserStopped(TargetUser user) { 228 mUserInfoHelper.onUserStopped(user.getUserIdentifier()); 229 } 230 231 private static class LifecycleUserInfoHelper extends SystemUserInfoHelper { 232 LifecycleUserInfoHelper(Context context)233 LifecycleUserInfoHelper(Context context) { 234 super(context); 235 } 236 onUserStarted(int userId)237 void onUserStarted(int userId) { 238 dispatchOnUserStarted(userId); 239 } 240 onUserStopped(int userId)241 void onUserStopped(int userId) { 242 dispatchOnUserStopped(userId); 243 } 244 onCurrentUserChanged(int fromUserId, int toUserId)245 void onCurrentUserChanged(int fromUserId, int toUserId) { 246 dispatchOnCurrentUserChanged(fromUserId, toUserId); 247 } 248 } 249 } 250 251 public static final String TAG = "LocationManagerService"; 252 public static final boolean D = Log.isLoggable(TAG, Log.DEBUG); 253 254 private static final String ATTRIBUTION_TAG = "LocationService"; 255 256 final Object mLock = new Object(); 257 258 private final Context mContext; 259 private final Injector mInjector; 260 private final LocalService mLocalService; 261 262 private final GeofenceManager mGeofenceManager; 263 private volatile @Nullable GnssManagerService mGnssManagerService = null; 264 private ProxyGeocodeProvider mGeocodeProvider; 265 266 private @Nullable ProxyPopulationDensityProvider mPopulationDensityProvider = null; 267 268 // A cache for population density lookups. Used if density-based coarse locations are enabled. 269 private @Nullable LocationFudgerCache mLocationFudgerCache = null; 270 271 private final Object mDeprecatedGnssBatchingLock = new Object(); 272 @GuardedBy("mDeprecatedGnssBatchingLock") 273 private @Nullable ILocationListener mDeprecatedGnssBatchingListener; 274 275 @GuardedBy("mLock") 276 private String mExtraLocationControllerPackage; 277 @GuardedBy("mLock") 278 private boolean mExtraLocationControllerPackageEnabled; 279 280 // location provider managers 281 282 private final PassiveLocationProviderManager mPassiveManager; 283 284 // @GuardedBy("mProviderManagers") 285 // hold lock for writes, no lock necessary for simple reads 286 final CopyOnWriteArrayList<LocationProviderManager> mProviderManagers = 287 new CopyOnWriteArrayList<>(); 288 289 @GuardedBy("mLock") 290 @Nullable LocationPackageTagsListener mLocationTagsChangedListener; 291 LocationManagerService(Context context, Injector injector)292 LocationManagerService(Context context, Injector injector) { 293 mContext = context.createAttributionContext(ATTRIBUTION_TAG); 294 mInjector = injector; 295 mLocalService = new LocalService(); 296 LocalServices.addService(LocationManagerInternal.class, mLocalService); 297 298 mGeofenceManager = new GeofenceManager(mContext, injector); 299 300 mInjector.getLocationSettings().registerLocationUserSettingsListener( 301 this::onLocationUserSettingsChanged); 302 mInjector.getSettingsHelper().addOnLocationEnabledChangedListener( 303 this::onLocationModeChanged); 304 mInjector.getSettingsHelper().addAdasAllowlistChangedListener( 305 () -> refreshAppOpsRestrictions(UserHandle.USER_ALL) 306 ); 307 mInjector.getSettingsHelper().addIgnoreSettingsAllowlistChangedListener( 308 () -> refreshAppOpsRestrictions(UserHandle.USER_ALL)); 309 mInjector.getUserInfoHelper().addListener((userId, change) -> { 310 if (change == UserInfoHelper.UserListener.USER_STARTED) { 311 refreshAppOpsRestrictions(userId); 312 } 313 }); 314 mInjector.getEmergencyHelper().addOnEmergencyStateChangedListener( 315 this::onEmergencyStateChanged); 316 317 // set up passive provider first since it will be required for all other location providers, 318 // which are loaded later once the system is ready. 319 mPassiveManager = new PassiveLocationProviderManager(mContext, injector); 320 addLocationProviderManager(mPassiveManager, new PassiveLocationProvider(mContext)); 321 322 // TODO: load the gps provider here as well, which will require refactoring 323 324 // Let the package manager query which are the default location 325 // providers as they get certain permissions granted by default. 326 LegacyPermissionManagerInternal permissionManagerInternal = LocalServices.getService( 327 LegacyPermissionManagerInternal.class); 328 permissionManagerInternal.setLocationPackagesProvider( 329 userId -> mContext.getResources().getStringArray( 330 com.android.internal.R.array.config_locationProviderPackageNames)); 331 permissionManagerInternal.setLocationExtraPackagesProvider( 332 userId -> mContext.getResources().getStringArray( 333 com.android.internal.R.array.config_locationExtraPackageNames)); 334 } 335 336 @Nullable getLocationProviderManager(String providerName)337 LocationProviderManager getLocationProviderManager(String providerName) { 338 if (providerName == null) { 339 return null; 340 } 341 342 for (LocationProviderManager manager : mProviderManagers) { 343 if (providerName.equals(manager.getName())) { 344 if (!manager.isVisibleToCaller()) { 345 return null; 346 } 347 return manager; 348 } 349 } 350 351 return null; 352 } 353 getOrAddLocationProviderManager(String providerName)354 private LocationProviderManager getOrAddLocationProviderManager(String providerName) { 355 synchronized (mProviderManagers) { 356 for (LocationProviderManager manager : mProviderManagers) { 357 if (providerName.equals(manager.getName())) { 358 return manager; 359 } 360 } 361 362 LocationProviderManager manager = new LocationProviderManager(mContext, mInjector, 363 providerName, mPassiveManager); 364 addLocationProviderManager(manager, null); 365 return manager; 366 } 367 } 368 369 @VisibleForTesting addLocationProviderManager( LocationProviderManager manager, @Nullable AbstractLocationProvider realProvider)370 void addLocationProviderManager( 371 LocationProviderManager manager, @Nullable AbstractLocationProvider realProvider) { 372 synchronized (mProviderManagers) { 373 Preconditions.checkState(getLocationProviderManager(manager.getName()) == null); 374 375 manager.startManager(this); 376 377 if (realProvider != null) { 378 // custom logic wrapping all non-passive providers 379 if (manager != mPassiveManager) { 380 int defaultStationaryThrottlingSetting = 381 mContext.getPackageManager().hasSystemFeature( 382 PackageManager.FEATURE_WATCH) ? 0 : 1; 383 boolean enableStationaryThrottling = Settings.Global.getInt( 384 mContext.getContentResolver(), 385 Settings.Global.LOCATION_ENABLE_STATIONARY_THROTTLE, 386 defaultStationaryThrottlingSetting) != 0; 387 if (Flags.disableStationaryThrottling() && !( 388 Flags.keepGnssStationaryThrottling() && enableStationaryThrottling 389 && GPS_PROVIDER.equals(manager.getName()))) { 390 enableStationaryThrottling = false; 391 } 392 if (enableStationaryThrottling) { 393 realProvider = new StationaryThrottlingLocationProvider(manager.getName(), 394 mInjector, realProvider); 395 } 396 } 397 manager.setRealProvider(realProvider); 398 } 399 mProviderManagers.add(manager); 400 } 401 } 402 403 @VisibleForTesting setProxyPopulationDensityProvider(ProxyPopulationDensityProvider provider)404 protected void setProxyPopulationDensityProvider(ProxyPopulationDensityProvider provider) { 405 if (Flags.populationDensityProvider()) { 406 mPopulationDensityProvider = provider; 407 } 408 } 409 410 @VisibleForTesting setLocationFudgerCache(LocationFudgerCache cache)411 protected void setLocationFudgerCache(LocationFudgerCache cache) { 412 if (!Flags.densityBasedCoarseLocations()) { 413 return; 414 } 415 416 mLocationFudgerCache = cache; 417 for (LocationProviderManager manager : mProviderManagers) { 418 manager.setLocationFudgerCache(cache); 419 } 420 } 421 removeLocationProviderManager(LocationProviderManager manager)422 private void removeLocationProviderManager(LocationProviderManager manager) { 423 synchronized (mProviderManagers) { 424 boolean removed = mProviderManagers.remove(manager); 425 Preconditions.checkArgument(removed); 426 manager.setMockProvider(null); 427 manager.setRealProvider(null); 428 manager.stopManager(); 429 } 430 } 431 onSystemReady()432 void onSystemReady() { 433 if (Build.IS_DEBUGGABLE) { 434 // on debug builds, watch for location noteOps while location is off. there are some 435 // scenarios (emergency location) where this is expected, but generally this should 436 // rarely occur, and may indicate bugs. dump occurrences to logs for further evaluation 437 AppOpsManager appOps = Objects.requireNonNull( 438 mContext.getSystemService(AppOpsManager.class)); 439 appOps.startWatchingNoted( 440 new int[]{AppOpsManager.OP_FINE_LOCATION, AppOpsManager.OP_COARSE_LOCATION}, 441 (code, uid, packageName, attributionTag, flags, result) -> { 442 if (!isLocationEnabledForUser(UserHandle.getUserId(uid))) { 443 Log.w(TAG, "location noteOp with location off - " 444 + CallerIdentity.forTest(uid, 0, packageName, attributionTag)); 445 } 446 }); 447 } 448 } 449 onSystemThirdPartyAppsCanStart()450 void onSystemThirdPartyAppsCanStart() { 451 // network provider should always be initialized before the gps provider since the gps 452 // provider has unfortunate hard dependencies on the network provider 453 ProxyLocationProvider networkProvider = ProxyLocationProvider.create( 454 mContext, 455 NETWORK_PROVIDER, 456 ACTION_NETWORK_PROVIDER, 457 com.android.internal.R.bool.config_enableNetworkLocationOverlay, 458 com.android.internal.R.string.config_networkLocationProviderPackageName); 459 if (networkProvider != null) { 460 LocationProviderManager networkManager = new LocationProviderManager(mContext, 461 mInjector, NETWORK_PROVIDER, mPassiveManager); 462 addLocationProviderManager(networkManager, networkProvider); 463 } else { 464 Log.w(TAG, "no network location provider found"); 465 } 466 467 // ensure that a fused provider exists which will work in direct boot 468 Preconditions.checkState(!mContext.getPackageManager().queryIntentServicesAsUser( 469 new Intent(ACTION_FUSED_PROVIDER), 470 MATCH_DIRECT_BOOT_AWARE | MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM).isEmpty(), 471 "Unable to find a direct boot aware fused location provider"); 472 473 ProxyLocationProvider fusedProvider = ProxyLocationProvider.create( 474 mContext, 475 FUSED_PROVIDER, 476 ACTION_FUSED_PROVIDER, 477 com.android.internal.R.bool.config_enableFusedLocationOverlay, 478 com.android.internal.R.string.config_fusedLocationProviderPackageName, 479 com.android.internal.R.bool.config_fusedLocationOverlayUnstableFallback); 480 if (fusedProvider != null) { 481 LocationProviderManager fusedManager = new LocationProviderManager(mContext, mInjector, 482 FUSED_PROVIDER, mPassiveManager); 483 addLocationProviderManager(fusedManager, fusedProvider); 484 } else { 485 Log.wtf(TAG, "no fused location provider found"); 486 } 487 488 // initialize gnss last because it has no awareness of boot phases and blindly assumes that 489 // all other location providers are loaded at initialization 490 boolean hasLocationFeature = mContext.getPackageManager().hasSystemFeature( 491 PackageManager.FEATURE_LOCATION); 492 if (hasLocationFeature && GnssNative.isSupported()) { 493 GnssConfiguration gnssConfiguration = new GnssConfiguration(mContext); 494 GnssNative gnssNative = GnssNative.create(mInjector, gnssConfiguration); 495 mGnssManagerService = new GnssManagerService(mContext, mInjector, gnssNative); 496 mGnssManagerService.onSystemReady(); 497 498 boolean useGnssHardwareProvider = mContext.getResources().getBoolean( 499 com.android.internal.R.bool.config_useGnssHardwareProvider); 500 AbstractLocationProvider gnssProvider = null; 501 if (!useGnssHardwareProvider) { 502 gnssProvider = ProxyLocationProvider.create( 503 mContext, 504 GPS_PROVIDER, 505 ACTION_GNSS_PROVIDER, 506 com.android.internal.R.bool.config_enableGnssLocationOverlay, 507 com.android.internal.R.string.config_gnssLocationProviderPackageName, 508 com.android.internal.R.bool.config_gnssLocationOverlayUnstableFallback); 509 } 510 if (gnssProvider == null) { 511 gnssProvider = mGnssManagerService.getGnssLocationProvider(); 512 } else { 513 // If we have a GNSS provider override, add the hardware provider as a standalone 514 // option for use by apps with the correct permission. Note the GNSS HAL can only 515 // support a single client, so mGnssManagerService.getGnssLocationProvider() can 516 // only be installed with a single provider. Locations from this provider won't 517 // be reported through the passive provider. 518 LocationProviderManager gnssHardwareManager = 519 new LocationProviderManager( 520 mContext, 521 mInjector, 522 GPS_HARDWARE_PROVIDER, 523 /*passiveManager=*/ null, 524 Collections.singletonList(Manifest.permission.LOCATION_HARDWARE)); 525 addLocationProviderManager( 526 gnssHardwareManager, mGnssManagerService.getGnssLocationProvider()); 527 } 528 529 LocationProviderManager gnssManager = new LocationProviderManager(mContext, mInjector, 530 GPS_PROVIDER, mPassiveManager); 531 addLocationProviderManager(gnssManager, gnssProvider); 532 } 533 534 // bind to geocoder provider 535 mGeocodeProvider = ProxyGeocodeProvider.createAndRegister(mContext); 536 if (mGeocodeProvider == null) { 537 Log.e(TAG, "no geocoder provider found"); 538 } 539 540 if (Flags.populationDensityProvider()) { 541 long startTime = System.currentTimeMillis(); 542 setProxyPopulationDensityProvider( 543 ProxyPopulationDensityProvider.createAndRegister(mContext)); 544 int duration = (int) (System.currentTimeMillis() - startTime); 545 if (mPopulationDensityProvider == null) { 546 Log.e(TAG, "no population density provider found"); 547 } 548 FrameworkStatsLog.write(FrameworkStatsLog.POPULATION_DENSITY_PROVIDER_LOADING_REPORTED, 549 /* provider_null= */ (mPopulationDensityProvider == null), 550 /* provider_start_time_millis= */ duration); 551 } 552 if (mPopulationDensityProvider != null && Flags.densityBasedCoarseLocations()) { 553 setLocationFudgerCache(new LocationFudgerCache(mPopulationDensityProvider)); 554 } 555 556 // bind to hardware activity recognition 557 HardwareActivityRecognitionProxy hardwareActivityRecognitionProxy = 558 HardwareActivityRecognitionProxy.createAndRegister(mContext); 559 if (hardwareActivityRecognitionProxy == null) { 560 Log.e(TAG, "unable to bind ActivityRecognitionProxy"); 561 } 562 563 // bind to gnss geofence proxy 564 if (mGnssManagerService != null) { 565 GeofenceProxy provider = GeofenceProxy.createAndBind(mContext, 566 mGnssManagerService.getGnssGeofenceProxy()); 567 if (provider == null) { 568 Log.e(TAG, "unable to bind to GeofenceProxy"); 569 } 570 } 571 572 // create any predefined test providers 573 String[] testProviderStrings = mContext.getResources().getStringArray( 574 com.android.internal.R.array.config_testLocationProviders); 575 for (String testProviderString : testProviderStrings) { 576 String[] fragments = testProviderString.split(","); 577 String name = fragments[0].trim(); 578 ProviderProperties properties = new ProviderProperties.Builder() 579 .setHasNetworkRequirement(Boolean.parseBoolean(fragments[1])) 580 .setHasSatelliteRequirement(Boolean.parseBoolean(fragments[2])) 581 .setHasCellRequirement(Boolean.parseBoolean(fragments[3])) 582 .setHasMonetaryCost(Boolean.parseBoolean(fragments[4])) 583 .setHasAltitudeSupport(Boolean.parseBoolean(fragments[5])) 584 .setHasSpeedSupport(Boolean.parseBoolean(fragments[6])) 585 .setHasBearingSupport(Boolean.parseBoolean(fragments[7])) 586 .setPowerUsage(Integer.parseInt(fragments[8])) 587 .setAccuracy(Integer.parseInt(fragments[9])) 588 .build(); 589 final LocationProviderManager manager = getOrAddLocationProviderManager(name); 590 manager.setMockProvider(new MockLocationProvider(properties, 591 CallerIdentity.fromContext(mContext), Collections.emptySet())); 592 } 593 } 594 onLocationUserSettingsChanged(int userId, LocationUserSettings oldSettings, LocationUserSettings newSettings)595 private void onLocationUserSettingsChanged(int userId, LocationUserSettings oldSettings, 596 LocationUserSettings newSettings) { 597 if (oldSettings.isAdasGnssLocationEnabled() != newSettings.isAdasGnssLocationEnabled()) { 598 boolean enabled = newSettings.isAdasGnssLocationEnabled(); 599 600 if (D) { 601 Log.d(TAG, "[u" + userId + "] adas gnss location enabled = " + enabled); 602 } 603 604 EVENT_LOG.logAdasLocationEnabled(userId, enabled); 605 606 Intent intent = new Intent(LocationManager.ACTION_ADAS_GNSS_ENABLED_CHANGED) 607 .putExtra(LocationManager.EXTRA_ADAS_GNSS_ENABLED, enabled) 608 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY) 609 .addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 610 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); 611 } 612 } 613 onLocationModeChanged(int userId)614 private void onLocationModeChanged(int userId) { 615 boolean enabled = mInjector.getSettingsHelper().isLocationEnabled(userId); 616 LocationManager.invalidateLocalLocationEnabledCaches(); 617 618 if (D) { 619 Log.d(TAG, "[u" + userId + "] location enabled = " + enabled); 620 } 621 622 EVENT_LOG.logLocationEnabled(userId, enabled); 623 logLocationEnabledState(); 624 625 Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION) 626 .putExtra(LocationManager.EXTRA_LOCATION_ENABLED, enabled) 627 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY) 628 .addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 629 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); 630 631 refreshAppOpsRestrictions(userId); 632 } 633 onEmergencyStateChanged()634 private void onEmergencyStateChanged() { 635 this.logEmergencyState(); 636 } 637 logEmergencyState()638 private void logEmergencyState() { 639 boolean isInEmergency = mInjector.getEmergencyHelper().isInEmergency(Long.MIN_VALUE); 640 mInjector.getLocationUsageLogger().logEmergencyStateChanged(isInEmergency); 641 } 642 logLocationEnabledState()643 private void logLocationEnabledState() { 644 boolean locationEnabled = false; 645 // Location setting is considered on if it is enabled for any one user 646 int[] runningUserIds = mInjector.getUserInfoHelper().getRunningUserIds(); 647 for (int userId : runningUserIds) { 648 locationEnabled = mInjector.getSettingsHelper().isLocationEnabled(userId); 649 if (locationEnabled) { 650 break; 651 } 652 } 653 mInjector.getLocationUsageLogger() 654 .logLocationEnabledStateChanged(locationEnabled); 655 } 656 657 @Override getGnssYearOfHardware()658 public int getGnssYearOfHardware() { 659 return mGnssManagerService == null ? 0 : mGnssManagerService.getGnssYearOfHardware(); 660 } 661 662 @Override 663 @Nullable getGnssHardwareModelName()664 public String getGnssHardwareModelName() { 665 return mGnssManagerService == null ? "" : mGnssManagerService.getGnssHardwareModelName(); 666 } 667 668 @Override getGnssBatchSize()669 public int getGnssBatchSize() { 670 return mGnssManagerService == null ? 0 : mGnssManagerService.getGnssBatchSize(); 671 } 672 673 @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE) 674 @Override startGnssBatch(long periodNanos, ILocationListener listener, String packageName, @Nullable String attributionTag, String listenerId)675 public void startGnssBatch(long periodNanos, ILocationListener listener, String packageName, 676 @Nullable String attributionTag, String listenerId) { 677 startGnssBatch_enforcePermission(); 678 679 if (mGnssManagerService == null) { 680 return; 681 } 682 683 long intervalMs = NANOSECONDS.toMillis(periodNanos); 684 685 synchronized (mDeprecatedGnssBatchingLock) { 686 stopGnssBatch(); 687 688 registerLocationListener( 689 GPS_PROVIDER, 690 new LocationRequest.Builder(intervalMs) 691 .setMaxUpdateDelayMillis( 692 intervalMs * mGnssManagerService.getGnssBatchSize()) 693 .setHiddenFromAppOps(true) 694 .build(), 695 listener, 696 packageName, 697 attributionTag, 698 listenerId); 699 mDeprecatedGnssBatchingListener = listener; 700 } 701 } 702 703 @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE) 704 @Override flushGnssBatch()705 public void flushGnssBatch() { 706 flushGnssBatch_enforcePermission(); 707 708 if (mGnssManagerService == null) { 709 return; 710 } 711 712 synchronized (mDeprecatedGnssBatchingLock) { 713 if (mDeprecatedGnssBatchingListener != null) { 714 requestListenerFlush(GPS_PROVIDER, mDeprecatedGnssBatchingListener, 0); 715 } 716 } 717 } 718 719 @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE) 720 @Override stopGnssBatch()721 public void stopGnssBatch() { 722 stopGnssBatch_enforcePermission(); 723 724 if (mGnssManagerService == null) { 725 return; 726 } 727 728 synchronized (mDeprecatedGnssBatchingLock) { 729 if (mDeprecatedGnssBatchingListener != null) { 730 ILocationListener listener = mDeprecatedGnssBatchingListener; 731 mDeprecatedGnssBatchingListener = null; 732 unregisterLocationListener(listener); 733 } 734 } 735 } 736 737 @Override hasProvider(String provider)738 public boolean hasProvider(String provider) { 739 return getLocationProviderManager(provider) != null; 740 } 741 742 @Override getAllProviders()743 public List<String> getAllProviders() { 744 ArrayList<String> providers = new ArrayList<>(mProviderManagers.size()); 745 for (LocationProviderManager manager : mProviderManagers) { 746 if (manager.isVisibleToCaller()) { 747 providers.add(manager.getName()); 748 } 749 } 750 return providers; 751 } 752 753 @Override getProviders(Criteria criteria, boolean enabledOnly)754 public List<String> getProviders(Criteria criteria, boolean enabledOnly) { 755 if (!LocationPermissions.checkCallingOrSelfLocationPermission(mContext, 756 PERMISSION_COARSE)) { 757 return Collections.emptyList(); 758 } 759 760 synchronized (mLock) { 761 ArrayList<String> providers = new ArrayList<>(mProviderManagers.size()); 762 for (LocationProviderManager manager : mProviderManagers) { 763 if (manager.isVisibleToCaller()) { 764 String name = manager.getName(); 765 if (enabledOnly && !manager.isEnabled(UserHandle.getCallingUserId())) { 766 continue; 767 } 768 if (criteria != null 769 && !LocationProvider.propertiesMeetCriteria( 770 name, manager.getProperties(), criteria)) { 771 continue; 772 } 773 providers.add(name); 774 } 775 } 776 return providers; 777 } 778 } 779 780 @Override getBestProvider(Criteria criteria, boolean enabledOnly)781 public String getBestProvider(Criteria criteria, boolean enabledOnly) { 782 List<String> providers; 783 synchronized (mLock) { 784 providers = getProviders(criteria, enabledOnly); 785 if (providers.isEmpty()) { 786 providers = getProviders(null, enabledOnly); 787 } 788 } 789 790 if (!providers.isEmpty()) { 791 if (providers.contains(FUSED_PROVIDER)) { 792 return FUSED_PROVIDER; 793 } else if (providers.contains(GPS_PROVIDER)) { 794 return GPS_PROVIDER; 795 } else if (providers.contains(NETWORK_PROVIDER)) { 796 return NETWORK_PROVIDER; 797 } else { 798 return providers.get(0); 799 } 800 } 801 802 return null; 803 } 804 805 @Override getBackgroundThrottlingWhitelist()806 public String[] getBackgroundThrottlingWhitelist() { 807 return mInjector.getSettingsHelper().getBackgroundThrottlePackageWhitelist().toArray( 808 new String[0]); 809 } 810 811 @Override getIgnoreSettingsAllowlist()812 public PackageTagsList getIgnoreSettingsAllowlist() { 813 return mInjector.getSettingsHelper().getIgnoreSettingsAllowlist(); 814 } 815 816 @Override getAdasAllowlist()817 public PackageTagsList getAdasAllowlist() { 818 return mInjector.getSettingsHelper().getAdasAllowlist(); 819 } 820 821 @Nullable 822 @Override getCurrentLocation(String provider, LocationRequest request, ILocationCallback consumer, String packageName, @Nullable String attributionTag, String listenerId)823 public ICancellationSignal getCurrentLocation(String provider, LocationRequest request, 824 ILocationCallback consumer, String packageName, @Nullable String attributionTag, 825 String listenerId) { 826 CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag, 827 listenerId); 828 int permissionLevel = LocationPermissions.getPermissionLevel(mContext, identity.getUid(), 829 identity.getPid()); 830 if (Flags.enableLocationBypass()) { 831 if (permissionLevel == PERMISSION_NONE) { 832 if (mContext.checkCallingPermission(LOCATION_BYPASS) != PERMISSION_GRANTED) { 833 LocationPermissions.enforceLocationPermission( 834 identity.getUid(), permissionLevel, PERMISSION_COARSE); 835 } else { 836 permissionLevel = PERMISSION_FINE; 837 } 838 } 839 } else { 840 LocationPermissions.enforceLocationPermission(identity.getUid(), permissionLevel, 841 PERMISSION_COARSE); 842 } 843 844 // clients in the system process must have an attribution tag set 845 Preconditions.checkState(identity.getPid() != Process.myPid() || attributionTag != null); 846 847 request = validateLocationRequest(provider, request, identity); 848 849 LocationProviderManager manager = getLocationProviderManager(provider); 850 Preconditions.checkArgument(manager != null, 851 "provider \"" + provider + "\" does not exist"); 852 853 return manager.getCurrentLocation(request, identity, permissionLevel, consumer); 854 } 855 856 @Override registerLocationListener(String provider, LocationRequest request, ILocationListener listener, String packageName, @Nullable String attributionTag, String listenerId)857 public void registerLocationListener(String provider, LocationRequest request, 858 ILocationListener listener, String packageName, @Nullable String attributionTag, 859 String listenerId) { 860 ActivityManagerInternal managerInternal = 861 LocalServices.getService(ActivityManagerInternal.class); 862 if (managerInternal != null) { 863 managerInternal.logFgsApiBegin(ActivityManager.FOREGROUND_SERVICE_API_TYPE_LOCATION, 864 Binder.getCallingUid(), Binder.getCallingPid()); 865 } 866 CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag, 867 listenerId); 868 int permissionLevel = LocationPermissions.getPermissionLevel(mContext, identity.getUid(), 869 identity.getPid()); 870 if (Flags.enableLocationBypass()) { 871 if (permissionLevel == PERMISSION_NONE) { 872 if (mContext.checkCallingPermission(LOCATION_BYPASS) != PERMISSION_GRANTED) { 873 LocationPermissions.enforceLocationPermission( 874 identity.getUid(), permissionLevel, PERMISSION_COARSE); 875 } else { 876 permissionLevel = PERMISSION_FINE; 877 } 878 } 879 } else { 880 LocationPermissions.enforceLocationPermission(identity.getUid(), permissionLevel, 881 PERMISSION_COARSE); 882 } 883 884 // clients in the system process should have an attribution tag set 885 if (identity.getPid() == Process.myPid() && attributionTag == null) { 886 Log.w(TAG, "system location request with no attribution tag", 887 new IllegalArgumentException()); 888 } 889 890 request = validateLocationRequest(provider, request, identity); 891 892 LocationProviderManager manager = getLocationProviderManager(provider); 893 Preconditions.checkArgument(manager != null, 894 "provider \"" + provider + "\" does not exist"); 895 896 manager.registerLocationRequest(request, identity, permissionLevel, listener); 897 } 898 899 @Override registerLocationPendingIntent(String provider, LocationRequest request, PendingIntent pendingIntent, String packageName, @Nullable String attributionTag)900 public void registerLocationPendingIntent(String provider, LocationRequest request, 901 PendingIntent pendingIntent, String packageName, @Nullable String attributionTag) { 902 CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag, 903 AppOpsManager.toReceiverId(pendingIntent)); 904 int permissionLevel = LocationPermissions.getPermissionLevel(mContext, identity.getUid(), 905 identity.getPid()); 906 if (Flags.enableLocationBypass()) { 907 if (permissionLevel == PERMISSION_NONE) { 908 if (mContext.checkCallingPermission(LOCATION_BYPASS) != PERMISSION_GRANTED) { 909 LocationPermissions.enforceLocationPermission( 910 identity.getUid(), permissionLevel, PERMISSION_COARSE); 911 } else { 912 permissionLevel = PERMISSION_FINE; 913 } 914 } 915 } else { 916 LocationPermissions.enforceLocationPermission(identity.getUid(), permissionLevel, 917 PERMISSION_COARSE); 918 } 919 920 // clients in the system process must have an attribution tag set 921 Preconditions.checkArgument(identity.getPid() != Process.myPid() || attributionTag != null); 922 923 // pending intents requests may not use system apis because we do not keep track if clients 924 // lose the relevant permissions, and thus should not get the benefit of those apis. its 925 // simplest to ensure these apis are simply never set for pending intent requests. the same 926 // does not apply for listener requests since those will have the process (including the 927 // listener) killed on permission removal 928 if (isChangeEnabled(BLOCK_PENDING_INTENT_SYSTEM_API_USAGE, identity.getUid())) { 929 boolean usesSystemApi = request.isLowPower() 930 || request.isHiddenFromAppOps() 931 || request.isLocationSettingsIgnored() 932 || !request.getWorkSource().isEmpty(); 933 if (usesSystemApi) { 934 throw new SecurityException( 935 "PendingIntent location requests may not use system APIs: " + request); 936 } 937 } 938 939 request = validateLocationRequest(provider, request, identity); 940 941 LocationProviderManager manager = getLocationProviderManager(provider); 942 Preconditions.checkArgument(manager != null, 943 "provider \"" + provider + "\" does not exist"); 944 945 manager.registerLocationRequest(request, identity, permissionLevel, pendingIntent); 946 } 947 validateLocationRequest(String provider, LocationRequest request, CallerIdentity identity)948 private LocationRequest validateLocationRequest(String provider, LocationRequest request, 949 CallerIdentity identity) { 950 // validate unsanitized request 951 if (!request.getWorkSource().isEmpty()) { 952 mContext.enforceCallingOrSelfPermission( 953 permission.UPDATE_DEVICE_STATS, 954 "setting a work source requires " + permission.UPDATE_DEVICE_STATS); 955 } 956 957 // sanitize request 958 LocationRequest.Builder sanitized = new LocationRequest.Builder(request); 959 960 if (!CompatChanges.isChangeEnabled(LOW_POWER_EXCEPTIONS, Binder.getCallingUid())) { 961 if (mContext.checkCallingPermission(permission.LOCATION_HARDWARE) 962 != PERMISSION_GRANTED) { 963 sanitized.setLowPower(false); 964 } 965 } 966 967 WorkSource workSource = new WorkSource(request.getWorkSource()); 968 if (workSource.size() > 0 && workSource.getPackageName(0) == null) { 969 Log.w(TAG, "received (and ignoring) illegal worksource with no package name"); 970 workSource.clear(); 971 } else { 972 List<WorkChain> workChains = workSource.getWorkChains(); 973 if (workChains != null && !workChains.isEmpty() 974 && workChains.get(0).getAttributionTag() == null) { 975 Log.w(TAG, 976 "received (and ignoring) illegal worksource with no attribution tag"); 977 workSource.clear(); 978 } 979 } 980 981 if (workSource.isEmpty()) { 982 identity.addToWorkSource(workSource); 983 } 984 sanitized.setWorkSource(workSource); 985 986 request = sanitized.build(); 987 988 // validate sanitized request 989 boolean isLocationProvider = mLocalService.isProvider(null, identity); 990 991 if (request.isLowPower() && CompatChanges.isChangeEnabled(LOW_POWER_EXCEPTIONS, 992 identity.getUid())) { 993 mContext.enforceCallingOrSelfPermission( 994 permission.LOCATION_HARDWARE, 995 "low power request requires " + permission.LOCATION_HARDWARE); 996 } 997 if (request.isHiddenFromAppOps()) { 998 mContext.enforceCallingOrSelfPermission( 999 permission.UPDATE_APP_OPS_STATS, 1000 "hiding from app ops requires " + permission.UPDATE_APP_OPS_STATS); 1001 } 1002 if (request.isAdasGnssBypass()) { 1003 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { 1004 throw new IllegalArgumentException( 1005 "adas gnss bypass requests are only allowed on automotive devices"); 1006 } 1007 if (!GPS_PROVIDER.equals(provider)) { 1008 throw new IllegalArgumentException( 1009 "adas gnss bypass requests are only allowed on the \"gps\" provider"); 1010 } 1011 if (!isLocationProvider) { 1012 LocationPermissions.enforceCallingOrSelfBypassPermission(mContext); 1013 } 1014 } 1015 if (request.isLocationSettingsIgnored()) { 1016 if (!isLocationProvider) { 1017 LocationPermissions.enforceCallingOrSelfBypassPermission(mContext); 1018 } 1019 } 1020 1021 return request; 1022 } 1023 1024 @Override requestListenerFlush(String provider, ILocationListener listener, int requestCode)1025 public void requestListenerFlush(String provider, ILocationListener listener, int requestCode) { 1026 LocationProviderManager manager = getLocationProviderManager(provider); 1027 Preconditions.checkArgument(manager != null, 1028 "provider \"" + provider + "\" does not exist"); 1029 1030 manager.flush(Objects.requireNonNull(listener), requestCode); 1031 } 1032 1033 @Override requestPendingIntentFlush(String provider, PendingIntent pendingIntent, int requestCode)1034 public void requestPendingIntentFlush(String provider, PendingIntent pendingIntent, 1035 int requestCode) { 1036 LocationProviderManager manager = getLocationProviderManager(provider); 1037 Preconditions.checkArgument(manager != null, 1038 "provider \"" + provider + "\" does not exist"); 1039 1040 manager.flush(Objects.requireNonNull(pendingIntent), requestCode); 1041 } 1042 1043 @Override unregisterLocationListener(ILocationListener listener)1044 public void unregisterLocationListener(ILocationListener listener) { 1045 ActivityManagerInternal managerInternal = 1046 LocalServices.getService(ActivityManagerInternal.class); 1047 if (managerInternal != null) { 1048 managerInternal.logFgsApiEnd(ActivityManager.FOREGROUND_SERVICE_API_TYPE_LOCATION, 1049 Binder.getCallingUid(), Binder.getCallingPid()); 1050 } 1051 for (LocationProviderManager manager : mProviderManagers) { 1052 manager.unregisterLocationRequest(listener); 1053 } 1054 } 1055 1056 @Override unregisterLocationPendingIntent(PendingIntent pendingIntent)1057 public void unregisterLocationPendingIntent(PendingIntent pendingIntent) { 1058 for (LocationProviderManager manager : mProviderManagers) { 1059 manager.unregisterLocationRequest(pendingIntent); 1060 } 1061 } 1062 1063 @Override getLastLocation(String provider, LastLocationRequest request, String packageName, @Nullable String attributionTag)1064 public Location getLastLocation(String provider, LastLocationRequest request, 1065 String packageName, @Nullable String attributionTag) { 1066 CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag); 1067 int permissionLevel = LocationPermissions.getPermissionLevel(mContext, identity.getUid(), 1068 identity.getPid()); 1069 if (Flags.enableLocationBypass()) { 1070 if (permissionLevel == PERMISSION_NONE) { 1071 if (mContext.checkCallingPermission(LOCATION_BYPASS) != PERMISSION_GRANTED) { 1072 LocationPermissions.enforceLocationPermission( 1073 identity.getUid(), permissionLevel, PERMISSION_COARSE); 1074 } else { 1075 permissionLevel = PERMISSION_FINE; 1076 } 1077 } 1078 } else { 1079 LocationPermissions.enforceLocationPermission(identity.getUid(), permissionLevel, 1080 PERMISSION_COARSE); 1081 } 1082 1083 // clients in the system process must have an attribution tag set 1084 Preconditions.checkArgument(identity.getPid() != Process.myPid() || attributionTag != null); 1085 1086 request = validateLastLocationRequest(provider, request, identity); 1087 1088 LocationProviderManager manager = getLocationProviderManager(provider); 1089 if (manager == null) { 1090 return null; 1091 } 1092 1093 return manager.getLastLocation(request, identity, permissionLevel); 1094 } 1095 validateLastLocationRequest(String provider, LastLocationRequest request, CallerIdentity identity)1096 private LastLocationRequest validateLastLocationRequest(String provider, 1097 LastLocationRequest request, 1098 CallerIdentity identity) { 1099 // sanitize request 1100 LastLocationRequest.Builder sanitized = new LastLocationRequest.Builder(request); 1101 1102 request = sanitized.build(); 1103 1104 // validate request 1105 boolean isLocationProvider = mLocalService.isProvider(null, identity); 1106 1107 if (request.isHiddenFromAppOps()) { 1108 mContext.enforceCallingOrSelfPermission( 1109 permission.UPDATE_APP_OPS_STATS, 1110 "hiding from app ops requires " + permission.UPDATE_APP_OPS_STATS); 1111 } 1112 1113 if (request.isAdasGnssBypass()) { 1114 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { 1115 throw new IllegalArgumentException( 1116 "adas gnss bypass requests are only allowed on automotive devices"); 1117 } 1118 if (!GPS_PROVIDER.equals(provider)) { 1119 throw new IllegalArgumentException( 1120 "adas gnss bypass requests are only allowed on the \"gps\" provider"); 1121 } 1122 if (!isLocationProvider) { 1123 LocationPermissions.enforceCallingOrSelfBypassPermission(mContext); 1124 } 1125 } 1126 if (request.isLocationSettingsIgnored()) { 1127 if (!isLocationProvider) { 1128 LocationPermissions.enforceCallingOrSelfBypassPermission(mContext); 1129 } 1130 } 1131 1132 return request; 1133 } 1134 1135 @Override getGnssTimeMillis()1136 public LocationTime getGnssTimeMillis() { 1137 return mLocalService.getGnssTimeMillis(); 1138 } 1139 1140 @android.annotation.EnforcePermission(allOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_FINE_LOCATION}) 1141 @Override injectLocation(Location location)1142 public void injectLocation(Location location) { 1143 1144 super.injectLocation_enforcePermission(); 1145 1146 Preconditions.checkArgument(location.isComplete()); 1147 1148 int userId = UserHandle.getCallingUserId(); 1149 LocationProviderManager manager = getLocationProviderManager(location.getProvider()); 1150 if (manager != null && manager.isEnabled(userId)) { 1151 manager.injectLastLocation(Objects.requireNonNull(location), userId); 1152 } 1153 } 1154 1155 @Override requestGeofence(Geofence geofence, PendingIntent intent, String packageName, String attributionTag)1156 public void requestGeofence(Geofence geofence, PendingIntent intent, String packageName, 1157 String attributionTag) { 1158 mGeofenceManager.addGeofence(geofence, intent, packageName, attributionTag); 1159 } 1160 1161 @Override removeGeofence(PendingIntent pendingIntent)1162 public void removeGeofence(PendingIntent pendingIntent) { 1163 mGeofenceManager.removeGeofence(pendingIntent); 1164 } 1165 1166 @Override registerGnssStatusCallback(IGnssStatusListener listener, String packageName, @Nullable String attributionTag, String listenerId)1167 public void registerGnssStatusCallback(IGnssStatusListener listener, String packageName, 1168 @Nullable String attributionTag, String listenerId) { 1169 if (mGnssManagerService != null) { 1170 mGnssManagerService.registerGnssStatusCallback(listener, packageName, attributionTag, 1171 listenerId); 1172 } 1173 } 1174 1175 @Override unregisterGnssStatusCallback(IGnssStatusListener listener)1176 public void unregisterGnssStatusCallback(IGnssStatusListener listener) { 1177 if (mGnssManagerService != null) { 1178 mGnssManagerService.unregisterGnssStatusCallback(listener); 1179 } 1180 } 1181 1182 @Override registerGnssNmeaCallback(IGnssNmeaListener listener, String packageName, @Nullable String attributionTag, String listenerId)1183 public void registerGnssNmeaCallback(IGnssNmeaListener listener, String packageName, 1184 @Nullable String attributionTag, String listenerId) { 1185 if (mGnssManagerService != null) { 1186 mGnssManagerService.registerGnssNmeaCallback(listener, packageName, attributionTag, 1187 listenerId); 1188 } 1189 } 1190 1191 @Override unregisterGnssNmeaCallback(IGnssNmeaListener listener)1192 public void unregisterGnssNmeaCallback(IGnssNmeaListener listener) { 1193 if (mGnssManagerService != null) { 1194 mGnssManagerService.unregisterGnssNmeaCallback(listener); 1195 } 1196 } 1197 1198 @Override addGnssMeasurementsListener(GnssMeasurementRequest request, IGnssMeasurementsListener listener, String packageName, @Nullable String attributionTag, String listenerId)1199 public void addGnssMeasurementsListener(GnssMeasurementRequest request, 1200 IGnssMeasurementsListener listener, String packageName, @Nullable String attributionTag, 1201 String listenerId) { 1202 if (mGnssManagerService != null) { 1203 mGnssManagerService.addGnssMeasurementsListener(request, listener, packageName, 1204 attributionTag, listenerId); 1205 } 1206 } 1207 1208 @Override removeGnssMeasurementsListener(IGnssMeasurementsListener listener)1209 public void removeGnssMeasurementsListener(IGnssMeasurementsListener listener) { 1210 if (mGnssManagerService != null) { 1211 mGnssManagerService.removeGnssMeasurementsListener( 1212 listener); 1213 } 1214 } 1215 1216 @Override addGnssAntennaInfoListener(IGnssAntennaInfoListener listener, String packageName, @Nullable String attributionTag, String listenerId)1217 public void addGnssAntennaInfoListener(IGnssAntennaInfoListener listener, String packageName, 1218 @Nullable String attributionTag, String listenerId) { 1219 if (mGnssManagerService != null) { 1220 mGnssManagerService.addGnssAntennaInfoListener(listener, packageName, attributionTag, 1221 listenerId); 1222 } 1223 } 1224 1225 @Override removeGnssAntennaInfoListener(IGnssAntennaInfoListener listener)1226 public void removeGnssAntennaInfoListener(IGnssAntennaInfoListener listener) { 1227 if (mGnssManagerService != null) { 1228 mGnssManagerService.removeGnssAntennaInfoListener(listener); 1229 } 1230 } 1231 1232 @android.annotation.EnforcePermission(android.Manifest.permission.INTERACT_ACROSS_USERS) 1233 @Override 1234 @RequiresPermission(INTERACT_ACROSS_USERS) addProviderRequestListener(IProviderRequestListener listener)1235 public void addProviderRequestListener(IProviderRequestListener listener) { 1236 addProviderRequestListener_enforcePermission(); 1237 for (LocationProviderManager manager : mProviderManagers) { 1238 if (manager.isVisibleToCaller()) { 1239 manager.addProviderRequestListener(listener); 1240 } 1241 } 1242 } 1243 1244 @Override removeProviderRequestListener(IProviderRequestListener listener)1245 public void removeProviderRequestListener(IProviderRequestListener listener) { 1246 for (LocationProviderManager manager : mProviderManagers) { 1247 manager.removeProviderRequestListener(listener); 1248 } 1249 } 1250 1251 @Override injectGnssMeasurementCorrections(GnssMeasurementCorrections corrections)1252 public void injectGnssMeasurementCorrections(GnssMeasurementCorrections corrections) { 1253 if (mGnssManagerService != null) { 1254 mGnssManagerService.injectGnssMeasurementCorrections(corrections); 1255 } 1256 } 1257 1258 @Override getGnssCapabilities()1259 public GnssCapabilities getGnssCapabilities() { 1260 return mGnssManagerService == null ? new GnssCapabilities.Builder().build() 1261 : mGnssManagerService.getGnssCapabilities(); 1262 } 1263 1264 @Override getGnssAntennaInfos()1265 public List<GnssAntennaInfo> getGnssAntennaInfos() { 1266 return mGnssManagerService == null ? null : mGnssManagerService.getGnssAntennaInfos(); 1267 } 1268 1269 @Override addGnssNavigationMessageListener(IGnssNavigationMessageListener listener, String packageName, @Nullable String attributionTag, String listenerId)1270 public void addGnssNavigationMessageListener(IGnssNavigationMessageListener listener, 1271 String packageName, @Nullable String attributionTag, String listenerId) { 1272 if (mGnssManagerService != null) { 1273 mGnssManagerService.addGnssNavigationMessageListener(listener, packageName, 1274 attributionTag, listenerId); 1275 } 1276 } 1277 1278 @Override removeGnssNavigationMessageListener(IGnssNavigationMessageListener listener)1279 public void removeGnssNavigationMessageListener(IGnssNavigationMessageListener listener) { 1280 if (mGnssManagerService != null) { 1281 mGnssManagerService.removeGnssNavigationMessageListener( 1282 listener); 1283 } 1284 } 1285 1286 @Override sendExtraCommand(String provider, String command, Bundle extras)1287 public void sendExtraCommand(String provider, String command, Bundle extras) { 1288 LocationPermissions.enforceCallingOrSelfLocationPermission(mContext, PERMISSION_COARSE); 1289 mContext.enforceCallingOrSelfPermission( 1290 permission.ACCESS_LOCATION_EXTRA_COMMANDS, null); 1291 1292 LocationProviderManager manager = getLocationProviderManager( 1293 Objects.requireNonNull(provider)); 1294 if (manager != null) { 1295 manager.sendExtraCommand(Binder.getCallingUid(), Binder.getCallingPid(), 1296 Objects.requireNonNull(command), extras); 1297 } 1298 1299 mInjector.getLocationUsageLogger().logLocationApiUsage( 1300 LocationStatsEnums.USAGE_STARTED, 1301 LocationStatsEnums.API_SEND_EXTRA_COMMAND, 1302 provider); 1303 mInjector.getLocationUsageLogger().logLocationApiUsage( 1304 LocationStatsEnums.USAGE_ENDED, 1305 LocationStatsEnums.API_SEND_EXTRA_COMMAND, 1306 provider); 1307 } 1308 1309 @Override getProviderProperties(String provider)1310 public ProviderProperties getProviderProperties(String provider) { 1311 LocationProviderManager manager = getLocationProviderManager(provider); 1312 Preconditions.checkArgument(manager != null, 1313 "provider \"" + provider + "\" does not exist"); 1314 return manager.getProperties(); 1315 } 1316 1317 @android.annotation.EnforcePermission(android.Manifest.permission.READ_DEVICE_CONFIG) 1318 @Override isProviderPackage(@ullable String provider, String packageName, @Nullable String attributionTag)1319 public boolean isProviderPackage(@Nullable String provider, String packageName, 1320 @Nullable String attributionTag) { 1321 isProviderPackage_enforcePermission(); 1322 1323 for (LocationProviderManager manager : mProviderManagers) { 1324 if (provider != null && !provider.equals(manager.getName())) { 1325 continue; 1326 } 1327 CallerIdentity identity = manager.getProviderIdentity(); 1328 if (identity == null) { 1329 continue; 1330 } 1331 if (identity.getPackageName().equals(packageName) && (attributionTag == null 1332 || Objects.equals(identity.getAttributionTag(), attributionTag))) { 1333 return true; 1334 } 1335 } 1336 1337 return false; 1338 } 1339 1340 @android.annotation.EnforcePermission(android.Manifest.permission.READ_DEVICE_CONFIG) 1341 @Override getProviderPackages(String provider)1342 public List<String> getProviderPackages(String provider) { 1343 getProviderPackages_enforcePermission(); 1344 1345 LocationProviderManager manager = getLocationProviderManager(provider); 1346 if (manager == null) { 1347 return Collections.emptyList(); 1348 } 1349 1350 CallerIdentity identity = manager.getProviderIdentity(); 1351 if (identity == null) { 1352 return Collections.emptyList(); 1353 } 1354 1355 return Collections.singletonList(identity.getPackageName()); 1356 } 1357 1358 @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE) 1359 @Override setExtraLocationControllerPackage(String packageName)1360 public void setExtraLocationControllerPackage(String packageName) { 1361 super.setExtraLocationControllerPackage_enforcePermission(); 1362 1363 synchronized (mLock) { 1364 mExtraLocationControllerPackage = packageName; 1365 } 1366 } 1367 1368 @Override getExtraLocationControllerPackage()1369 public String getExtraLocationControllerPackage() { 1370 synchronized (mLock) { 1371 return mExtraLocationControllerPackage; 1372 } 1373 } 1374 1375 @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE) 1376 @Override setExtraLocationControllerPackageEnabled(boolean enabled)1377 public void setExtraLocationControllerPackageEnabled(boolean enabled) { 1378 super.setExtraLocationControllerPackageEnabled_enforcePermission(); 1379 1380 synchronized (mLock) { 1381 mExtraLocationControllerPackageEnabled = enabled; 1382 } 1383 } 1384 1385 @Override isExtraLocationControllerPackageEnabled()1386 public boolean isExtraLocationControllerPackageEnabled() { 1387 synchronized (mLock) { 1388 return mExtraLocationControllerPackageEnabled 1389 && (mExtraLocationControllerPackage != null); 1390 } 1391 } 1392 1393 @Override setLocationEnabledForUser(boolean enabled, int userId)1394 public void setLocationEnabledForUser(boolean enabled, int userId) { 1395 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 1396 userId, false, false, "setLocationEnabledForUser", null); 1397 1398 mContext.enforceCallingOrSelfPermission(WRITE_SECURE_SETTINGS, null); 1399 1400 LocationManager.invalidateLocalLocationEnabledCaches(); 1401 mInjector.getSettingsHelper().setLocationEnabled(enabled, userId); 1402 } 1403 1404 @Override isLocationEnabledForUser(int userId)1405 public boolean isLocationEnabledForUser(int userId) { 1406 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 1407 userId, false, false, "isLocationEnabledForUser", null); 1408 return mInjector.getSettingsHelper().isLocationEnabled(userId); 1409 } 1410 1411 @Override setAdasGnssLocationEnabledForUser(boolean enabled, int userId)1412 public void setAdasGnssLocationEnabledForUser(boolean enabled, int userId) { 1413 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 1414 userId, false, false, "setAdasGnssLocationEnabledForUser", null); 1415 1416 LocationPermissions.enforceCallingOrSelfBypassPermission(mContext); 1417 1418 mInjector.getLocationSettings().updateUserSettings(userId, 1419 settings -> settings.withAdasGnssLocationEnabled(enabled)); 1420 } 1421 1422 @Override isAdasGnssLocationEnabledForUser(int userId)1423 public boolean isAdasGnssLocationEnabledForUser(int userId) { 1424 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 1425 userId, false, false, "isAdasGnssLocationEnabledForUser", null); 1426 return mInjector.getLocationSettings().getUserSettings(userId).isAdasGnssLocationEnabled(); 1427 } 1428 1429 @Override isProviderEnabledForUser(String provider, int userId)1430 public boolean isProviderEnabledForUser(String provider, int userId) { 1431 return mLocalService.isProviderEnabledForUser(provider, userId); 1432 } 1433 1434 @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS) 1435 @Override 1436 @RequiresPermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS) setAutomotiveGnssSuspended(boolean suspended)1437 public void setAutomotiveGnssSuspended(boolean suspended) { 1438 1439 super.setAutomotiveGnssSuspended_enforcePermission(); 1440 1441 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { 1442 throw new IllegalStateException( 1443 "setAutomotiveGnssSuspended only allowed on automotive devices"); 1444 } 1445 1446 if (mGnssManagerService != null) { 1447 mGnssManagerService.setAutomotiveGnssSuspended(suspended); 1448 } 1449 } 1450 1451 @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS) 1452 @Override 1453 @RequiresPermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS) isAutomotiveGnssSuspended()1454 public boolean isAutomotiveGnssSuspended() { 1455 1456 super.isAutomotiveGnssSuspended_enforcePermission(); 1457 1458 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { 1459 throw new IllegalStateException( 1460 "isAutomotiveGnssSuspended only allowed on automotive devices"); 1461 } 1462 1463 if (mGnssManagerService != null) { 1464 return mGnssManagerService.isAutomotiveGnssSuspended(); 1465 } 1466 return false; 1467 } 1468 1469 @Override isGeocodeAvailable()1470 public boolean isGeocodeAvailable() { 1471 return mGeocodeProvider != null; 1472 } 1473 1474 @Override reverseGeocode(ReverseGeocodeRequest request, IGeocodeCallback callback)1475 public void reverseGeocode(ReverseGeocodeRequest request, IGeocodeCallback callback) { 1476 CallerIdentity identity = 1477 CallerIdentity.fromBinder( 1478 mContext, request.getCallingPackage(), request.getCallingAttributionTag()); 1479 Preconditions.checkArgument(identity.getUid() == request.getCallingUid()); 1480 1481 if (mGeocodeProvider != null) { 1482 mGeocodeProvider.reverseGeocode(request, callback); 1483 } else { 1484 try { 1485 callback.onError(null); 1486 } catch (RemoteException e) { 1487 // ignore 1488 } 1489 } 1490 } 1491 1492 @Override forwardGeocode(ForwardGeocodeRequest request, IGeocodeCallback callback)1493 public void forwardGeocode(ForwardGeocodeRequest request, IGeocodeCallback callback) { 1494 CallerIdentity identity = 1495 CallerIdentity.fromBinder( 1496 mContext, request.getCallingPackage(), request.getCallingAttributionTag()); 1497 Preconditions.checkArgument(identity.getUid() == request.getCallingUid()); 1498 1499 if (mGeocodeProvider != null) { 1500 mGeocodeProvider.forwardGeocode(request, callback); 1501 } else { 1502 try { 1503 callback.onError(null); 1504 } catch (RemoteException e) { 1505 // ignore 1506 } 1507 } 1508 } 1509 1510 @Override addTestProvider(String provider, ProviderProperties properties, List<String> extraAttributionTags, String packageName, String attributionTag)1511 public void addTestProvider(String provider, ProviderProperties properties, 1512 List<String> extraAttributionTags, String packageName, String attributionTag) { 1513 // unsafe is ok because app ops will verify the package name 1514 CallerIdentity identity = CallerIdentity.fromBinderUnsafe(packageName, attributionTag); 1515 if (!mInjector.getAppOpsHelper().noteOp(AppOpsManager.OP_MOCK_LOCATION, identity)) { 1516 return; 1517 } 1518 1519 final LocationProviderManager manager = getOrAddLocationProviderManager(provider); 1520 manager.setMockProvider(new MockLocationProvider(properties, identity, 1521 new ArraySet<>(extraAttributionTags))); 1522 } 1523 1524 @Override removeTestProvider(String provider, String packageName, String attributionTag)1525 public void removeTestProvider(String provider, String packageName, String attributionTag) { 1526 // unsafe is ok because app ops will verify the package name 1527 CallerIdentity identity = CallerIdentity.fromBinderUnsafe(packageName, attributionTag); 1528 if (!mInjector.getAppOpsHelper().noteOp(AppOpsManager.OP_MOCK_LOCATION, identity)) { 1529 return; 1530 } 1531 1532 synchronized (mLock) { 1533 LocationProviderManager manager = getLocationProviderManager(provider); 1534 if (manager == null) { 1535 return; 1536 } 1537 1538 manager.setMockProvider(null); 1539 if (!manager.hasProvider()) { 1540 removeLocationProviderManager(manager); 1541 } 1542 } 1543 } 1544 1545 @Override setTestProviderLocation(String provider, Location location, String packageName, String attributionTag)1546 public void setTestProviderLocation(String provider, Location location, String packageName, 1547 String attributionTag) { 1548 // unsafe is ok because app ops will verify the package name 1549 CallerIdentity identity = CallerIdentity.fromBinderUnsafe(packageName, 1550 attributionTag); 1551 if (!mInjector.getAppOpsHelper().noteOp(AppOpsManager.OP_MOCK_LOCATION, identity)) { 1552 return; 1553 } 1554 1555 Preconditions.checkArgument(location.isComplete(), 1556 "incomplete location object, missing timestamp or accuracy?"); 1557 1558 LocationProviderManager manager = getLocationProviderManager(provider); 1559 if (manager == null) { 1560 throw new IllegalArgumentException("provider doesn't exist: " + provider); 1561 } 1562 1563 manager.setMockProviderLocation(location); 1564 } 1565 1566 @Override setTestProviderEnabled(String provider, boolean enabled, String packageName, String attributionTag)1567 public void setTestProviderEnabled(String provider, boolean enabled, String packageName, 1568 String attributionTag) { 1569 // unsafe is ok because app ops will verify the package name 1570 CallerIdentity identity = CallerIdentity.fromBinderUnsafe(packageName, 1571 attributionTag); 1572 if (!mInjector.getAppOpsHelper().noteOp(AppOpsManager.OP_MOCK_LOCATION, identity)) { 1573 return; 1574 } 1575 1576 LocationProviderManager manager = getLocationProviderManager(provider); 1577 if (manager == null) { 1578 throw new IllegalArgumentException("provider doesn't exist: " + provider); 1579 } 1580 1581 manager.setMockProviderAllowed(enabled); 1582 } 1583 1584 @Override handleShellCommand(ParcelFileDescriptor in, ParcelFileDescriptor out, ParcelFileDescriptor err, String[] args)1585 public int handleShellCommand(ParcelFileDescriptor in, ParcelFileDescriptor out, 1586 ParcelFileDescriptor err, String[] args) { 1587 return new LocationShellCommand(mContext, this).exec( 1588 this, in.getFileDescriptor(), out.getFileDescriptor(), err.getFileDescriptor(), 1589 args); 1590 } 1591 1592 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1593 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1594 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) { 1595 return; 1596 } 1597 1598 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 1599 1600 if (args.length > 0) { 1601 LocationProviderManager manager = getLocationProviderManager(args[0]); 1602 if (manager != null) { 1603 ipw.println("Provider:"); 1604 ipw.increaseIndent(); 1605 manager.dump(fd, ipw, args); 1606 ipw.decreaseIndent(); 1607 1608 ipw.println("Event Log:"); 1609 ipw.increaseIndent(); 1610 EVENT_LOG.iterate(ipw::println, manager.getName()); 1611 ipw.decreaseIndent(); 1612 return; 1613 } 1614 1615 if ("--gnssmetrics".equals(args[0])) { 1616 if (mGnssManagerService != null) { 1617 mGnssManagerService.dump(fd, ipw, args); 1618 } 1619 return; 1620 } 1621 } 1622 1623 ipw.println("Location Manager State:"); 1624 ipw.increaseIndent(); 1625 1626 ipw.println("User Info:"); 1627 ipw.increaseIndent(); 1628 mInjector.getUserInfoHelper().dump(fd, ipw, args); 1629 ipw.decreaseIndent(); 1630 1631 ipw.println("Location Settings:"); 1632 ipw.increaseIndent(); 1633 mInjector.getSettingsHelper().dump(fd, ipw, args); 1634 mInjector.getLocationSettings().dump(fd, ipw, args); 1635 ipw.decreaseIndent(); 1636 1637 synchronized (mLock) { 1638 if (mExtraLocationControllerPackage != null) { 1639 ipw.println( 1640 "Location Controller Extra Package: " + mExtraLocationControllerPackage 1641 + (mExtraLocationControllerPackageEnabled ? " [enabled]" 1642 : " [disabled]")); 1643 } 1644 } 1645 1646 ipw.println("Location Providers:"); 1647 ipw.increaseIndent(); 1648 for (LocationProviderManager manager : mProviderManagers) { 1649 manager.dump(fd, ipw, args); 1650 } 1651 ipw.decreaseIndent(); 1652 1653 ipw.println("Historical Aggregate Location Provider Data:"); 1654 ipw.increaseIndent(); 1655 ArrayMap<String, ArrayMap<CallerIdentity, LocationEventLog.AggregateStats>> aggregateStats = 1656 EVENT_LOG.copyAggregateStats(); 1657 for (int i = 0; i < aggregateStats.size(); i++) { 1658 ipw.print(aggregateStats.keyAt(i)); 1659 ipw.println(":"); 1660 ipw.increaseIndent(); 1661 ArrayMap<CallerIdentity, LocationEventLog.AggregateStats> providerStats = 1662 aggregateStats.valueAt(i); 1663 for (int j = 0; j < providerStats.size(); j++) { 1664 ipw.print(providerStats.keyAt(j)); 1665 ipw.print(": "); 1666 providerStats.valueAt(j).updateTotals(); 1667 ipw.println(providerStats.valueAt(j)); 1668 } 1669 ipw.decreaseIndent(); 1670 } 1671 ipw.decreaseIndent(); 1672 1673 ipw.println("Historical Aggregate Gnss Measurement Provider Data:"); 1674 ipw.increaseIndent(); 1675 ArrayMap<CallerIdentity, LocationEventLog.GnssMeasurementAggregateStats> 1676 gnssAggregateStats = EVENT_LOG.copyGnssMeasurementAggregateStats(); 1677 for (int i = 0; i < gnssAggregateStats.size(); i++) { 1678 ipw.print(gnssAggregateStats.keyAt(i)); 1679 ipw.print(": "); 1680 gnssAggregateStats.valueAt(i).updateTotals(); 1681 ipw.println(gnssAggregateStats.valueAt(i)); 1682 } 1683 ipw.decreaseIndent(); 1684 1685 if (mGnssManagerService != null) { 1686 ipw.println("GNSS Manager:"); 1687 ipw.increaseIndent(); 1688 mGnssManagerService.dump(fd, ipw, args); 1689 ipw.decreaseIndent(); 1690 } 1691 1692 ipw.println("Geofence Manager:"); 1693 ipw.increaseIndent(); 1694 mGeofenceManager.dump(fd, ipw, args); 1695 ipw.decreaseIndent(); 1696 1697 ipw.println("Event Log:"); 1698 ipw.increaseIndent(); 1699 EVENT_LOG.iterate(ipw::println); 1700 ipw.decreaseIndent(); 1701 } 1702 1703 @Override onStateChanged(String provider, AbstractLocationProvider.State oldState, AbstractLocationProvider.State newState)1704 public void onStateChanged(String provider, AbstractLocationProvider.State oldState, 1705 AbstractLocationProvider.State newState) { 1706 if (!Objects.equals(oldState.identity, newState.identity)) { 1707 refreshAppOpsRestrictions(UserHandle.USER_ALL); 1708 } 1709 1710 if (!oldState.extraAttributionTags.equals(newState.extraAttributionTags) 1711 || !Objects.equals(oldState.identity, newState.identity)) { 1712 // since we're potentially affecting the tag lists for two different uids, acquire the 1713 // lock to ensure providers cannot change while we're looping over the providers 1714 // multiple times, which could lead to inconsistent results. 1715 synchronized (mLock) { 1716 LocationPackageTagsListener listener = mLocationTagsChangedListener; 1717 if (listener != null) { 1718 int oldUid = oldState.identity != null ? oldState.identity.getUid() : -1; 1719 int newUid = newState.identity != null ? newState.identity.getUid() : -1; 1720 if (oldUid != -1) { 1721 PackageTagsList tags = calculateAppOpsLocationSourceTags(oldUid); 1722 FgThread.getHandler().post( 1723 () -> listener.onLocationPackageTagsChanged(oldUid, tags)); 1724 } 1725 // if the new app id is the same as the old app id, no need to invoke the 1726 // listener twice, it's already been taken care of 1727 if (newUid != -1 && newUid != oldUid) { 1728 PackageTagsList tags = calculateAppOpsLocationSourceTags(newUid); 1729 FgThread.getHandler().post( 1730 () -> listener.onLocationPackageTagsChanged(newUid, tags)); 1731 } 1732 } 1733 } 1734 } 1735 } 1736 refreshAppOpsRestrictions(int userId)1737 private void refreshAppOpsRestrictions(int userId) { 1738 if (userId == UserHandle.USER_ALL) { 1739 final int[] runningUserIds = mInjector.getUserInfoHelper().getRunningUserIds(); 1740 for (int i = 0; i < runningUserIds.length; i++) { 1741 refreshAppOpsRestrictions(runningUserIds[i]); 1742 } 1743 return; 1744 } 1745 1746 Preconditions.checkArgument(userId >= 0); 1747 1748 boolean enabled = mInjector.getSettingsHelper().isLocationEnabled(userId); 1749 1750 PackageTagsList allowedPackages = null; 1751 if (!enabled) { 1752 PackageTagsList.Builder builder = new PackageTagsList.Builder(); 1753 for (LocationProviderManager manager : mProviderManagers) { 1754 CallerIdentity identity = manager.getProviderIdentity(); 1755 if (identity != null) { 1756 builder.add(identity.getPackageName(), identity.getAttributionTag()); 1757 } 1758 } 1759 builder.add(mInjector.getSettingsHelper().getIgnoreSettingsAllowlist()); 1760 builder.add(mInjector.getSettingsHelper().getAdasAllowlist()); 1761 allowedPackages = builder.build(); 1762 } 1763 1764 AppOpsManager appOpsManager = Objects.requireNonNull( 1765 mContext.getSystemService(AppOpsManager.class)); 1766 appOpsManager.setUserRestrictionForUser( 1767 AppOpsManager.OP_COARSE_LOCATION, 1768 !enabled, 1769 LocationManagerService.this, 1770 allowedPackages, 1771 userId); 1772 appOpsManager.setUserRestrictionForUser( 1773 AppOpsManager.OP_FINE_LOCATION, 1774 !enabled, 1775 LocationManagerService.this, 1776 allowedPackages, 1777 userId); 1778 } 1779 calculateAppOpsLocationSourceTags(int uid)1780 PackageTagsList calculateAppOpsLocationSourceTags(int uid) { 1781 PackageTagsList.Builder builder = new PackageTagsList.Builder(); 1782 for (LocationProviderManager manager : mProviderManagers) { 1783 AbstractLocationProvider.State managerState = manager.getState(); 1784 if (managerState.identity == null) { 1785 continue; 1786 } 1787 if (managerState.identity.getUid() != uid) { 1788 continue; 1789 } 1790 1791 builder.add(managerState.identity.getPackageName(), managerState.extraAttributionTags); 1792 if (managerState.extraAttributionTags.isEmpty() 1793 || managerState.identity.getAttributionTag() != null) { 1794 builder.add(managerState.identity.getPackageName(), 1795 managerState.identity.getAttributionTag()); 1796 } else { 1797 Log.e(TAG, manager.getName() + " provider has specified a null attribution tag and " 1798 + "a non-empty set of extra attribution tags - dropping the null " 1799 + "attribution tag"); 1800 } 1801 } 1802 return builder.build(); 1803 } 1804 1805 private class LocalService extends LocationManagerInternal { 1806 LocalService()1807 LocalService() {} 1808 1809 @Override isProviderEnabledForUser(@onNull String provider, int userId)1810 public boolean isProviderEnabledForUser(@NonNull String provider, int userId) { 1811 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 1812 Binder.getCallingUid(), userId, false, false, "isProviderEnabledForUser", null); 1813 1814 LocationProviderManager manager = getLocationProviderManager(provider); 1815 if (manager == null) { 1816 return false; 1817 } 1818 1819 return manager.isEnabled(userId); 1820 } 1821 1822 @Override addProviderEnabledListener(String provider, ProviderEnabledListener listener)1823 public void addProviderEnabledListener(String provider, ProviderEnabledListener listener) { 1824 LocationProviderManager manager = Objects.requireNonNull( 1825 getLocationProviderManager(provider)); 1826 manager.addEnabledListener(listener); 1827 } 1828 1829 @Override removeProviderEnabledListener(String provider, ProviderEnabledListener listener)1830 public void removeProviderEnabledListener(String provider, 1831 ProviderEnabledListener listener) { 1832 LocationProviderManager manager = Objects.requireNonNull( 1833 getLocationProviderManager(provider)); 1834 manager.removeEnabledListener(listener); 1835 } 1836 1837 @Override isProvider(@ullable String provider, CallerIdentity identity)1838 public boolean isProvider(@Nullable String provider, CallerIdentity identity) { 1839 for (LocationProviderManager manager : mProviderManagers) { 1840 if (provider != null && !provider.equals(manager.getName())) { 1841 continue; 1842 } 1843 if (identity.equals(manager.getProviderIdentity()) && manager.isVisibleToCaller()) { 1844 return true; 1845 } 1846 } 1847 1848 return false; 1849 } 1850 1851 @Override getGnssTimeMillis()1852 public @Nullable LocationTime getGnssTimeMillis() { 1853 LocationProviderManager gpsManager = getLocationProviderManager(GPS_PROVIDER); 1854 if (gpsManager == null) { 1855 return null; 1856 } 1857 1858 Location location = gpsManager.getLastLocationUnsafe(UserHandle.USER_ALL, 1859 PERMISSION_FINE, false, Long.MAX_VALUE); 1860 if (location == null) { 1861 return null; 1862 } 1863 1864 return new LocationTime(location.getTime(), location.getElapsedRealtimeNanos()); 1865 } 1866 1867 @Override setLocationPackageTagsListener( @ullable LocationPackageTagsListener listener)1868 public void setLocationPackageTagsListener( 1869 @Nullable LocationPackageTagsListener listener) { 1870 synchronized (mLock) { 1871 mLocationTagsChangedListener = listener; 1872 1873 // calculate initial tag list and send to listener 1874 if (listener != null) { 1875 ArraySet<Integer> uids = new ArraySet<>(mProviderManagers.size()); 1876 for (LocationProviderManager manager : mProviderManagers) { 1877 CallerIdentity identity = manager.getProviderIdentity(); 1878 if (identity != null) { 1879 uids.add(identity.getUid()); 1880 } 1881 } 1882 1883 for (int uid : uids) { 1884 PackageTagsList tags = calculateAppOpsLocationSourceTags(uid); 1885 if (!tags.isEmpty()) { 1886 FgThread.getHandler().post( 1887 () -> listener.onLocationPackageTagsChanged(uid, tags)); 1888 } 1889 } 1890 } 1891 } 1892 } 1893 } 1894 1895 private static final class SystemInjector implements Injector { 1896 1897 private final Context mContext; 1898 1899 private final SystemUserInfoHelper mUserInfoHelper; 1900 private final LocationSettings mLocationSettings; 1901 private final AlarmHelper mAlarmHelper; 1902 private final SystemAppOpsHelper mAppOpsHelper; 1903 private final SystemLocationPermissionsHelper mLocationPermissionsHelper; 1904 private final SystemSettingsHelper mSettingsHelper; 1905 private final SystemAppForegroundHelper mAppForegroundHelper; 1906 private final SystemLocationPowerSaveModeHelper mLocationPowerSaveModeHelper; 1907 private final SystemScreenInteractiveHelper mScreenInteractiveHelper; 1908 private final SystemDeviceStationaryHelper mDeviceStationaryHelper; 1909 private final SystemDeviceIdleHelper mDeviceIdleHelper; 1910 private final LocationUsageLogger mLocationUsageLogger; 1911 private final PackageResetHelper mPackageResetHelper; 1912 1913 // lazily instantiated since they may not always be used 1914 1915 @GuardedBy("this") 1916 @Nullable 1917 private SystemEmergencyHelper mEmergencyCallHelper; 1918 1919 @GuardedBy("this") 1920 private boolean mSystemReady; 1921 SystemInjector(Context context, SystemUserInfoHelper userInfoHelper)1922 SystemInjector(Context context, SystemUserInfoHelper userInfoHelper) { 1923 mContext = context; 1924 1925 mUserInfoHelper = userInfoHelper; 1926 mLocationSettings = new LocationSettings(context); 1927 mAlarmHelper = new SystemAlarmHelper(context); 1928 mAppOpsHelper = new SystemAppOpsHelper(context); 1929 mLocationPermissionsHelper = new SystemLocationPermissionsHelper(context, 1930 mAppOpsHelper); 1931 mSettingsHelper = new SystemSettingsHelper(context); 1932 mAppForegroundHelper = new SystemAppForegroundHelper(context); 1933 mLocationPowerSaveModeHelper = new SystemLocationPowerSaveModeHelper(context); 1934 mScreenInteractiveHelper = new SystemScreenInteractiveHelper(context); 1935 mDeviceStationaryHelper = new SystemDeviceStationaryHelper(); 1936 mDeviceIdleHelper = new SystemDeviceIdleHelper(context); 1937 mLocationUsageLogger = new LocationUsageLogger(); 1938 mPackageResetHelper = new SystemPackageResetHelper(context); 1939 } 1940 onSystemReady()1941 synchronized void onSystemReady() { 1942 mUserInfoHelper.onSystemReady(); 1943 mAppOpsHelper.onSystemReady(); 1944 mLocationPermissionsHelper.onSystemReady(); 1945 mSettingsHelper.onSystemReady(); 1946 mAppForegroundHelper.onSystemReady(); 1947 mLocationPowerSaveModeHelper.onSystemReady(); 1948 mScreenInteractiveHelper.onSystemReady(); 1949 mDeviceStationaryHelper.onSystemReady(); 1950 mDeviceIdleHelper.onSystemReady(); 1951 1952 if (mEmergencyCallHelper != null) { 1953 mEmergencyCallHelper.onSystemReady(); 1954 } 1955 1956 mSystemReady = true; 1957 } 1958 1959 @Override getUserInfoHelper()1960 public UserInfoHelper getUserInfoHelper() { 1961 return mUserInfoHelper; 1962 } 1963 1964 @Override getLocationSettings()1965 public LocationSettings getLocationSettings() { 1966 return mLocationSettings; 1967 } 1968 1969 @Override getAlarmHelper()1970 public AlarmHelper getAlarmHelper() { 1971 return mAlarmHelper; 1972 } 1973 1974 @Override getAppOpsHelper()1975 public AppOpsHelper getAppOpsHelper() { 1976 return mAppOpsHelper; 1977 } 1978 1979 @Override getLocationPermissionsHelper()1980 public LocationPermissionsHelper getLocationPermissionsHelper() { 1981 return mLocationPermissionsHelper; 1982 } 1983 1984 @Override getSettingsHelper()1985 public SettingsHelper getSettingsHelper() { 1986 return mSettingsHelper; 1987 } 1988 1989 @Override getAppForegroundHelper()1990 public AppForegroundHelper getAppForegroundHelper() { 1991 return mAppForegroundHelper; 1992 } 1993 1994 @Override getLocationPowerSaveModeHelper()1995 public LocationPowerSaveModeHelper getLocationPowerSaveModeHelper() { 1996 return mLocationPowerSaveModeHelper; 1997 } 1998 1999 @Override getScreenInteractiveHelper()2000 public ScreenInteractiveHelper getScreenInteractiveHelper() { 2001 return mScreenInteractiveHelper; 2002 } 2003 2004 @Override getDeviceStationaryHelper()2005 public DeviceStationaryHelper getDeviceStationaryHelper() { 2006 return mDeviceStationaryHelper; 2007 } 2008 2009 @Override getDeviceIdleHelper()2010 public DeviceIdleHelper getDeviceIdleHelper() { 2011 return mDeviceIdleHelper; 2012 } 2013 2014 @Override getEmergencyHelper()2015 public synchronized EmergencyHelper getEmergencyHelper() { 2016 if (mEmergencyCallHelper == null) { 2017 mEmergencyCallHelper = new SystemEmergencyHelper(mContext); 2018 if (mSystemReady) { 2019 mEmergencyCallHelper.onSystemReady(); 2020 } 2021 } 2022 2023 return mEmergencyCallHelper; 2024 } 2025 2026 @Override getLocationUsageLogger()2027 public LocationUsageLogger getLocationUsageLogger() { 2028 return mLocationUsageLogger; 2029 } 2030 2031 @Override getPackageResetHelper()2032 public PackageResetHelper getPackageResetHelper() { 2033 return mPackageResetHelper; 2034 } 2035 } 2036 } 2037