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