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. Locations from this provider won't 471 // be reported through the passive provider. 472 LocationProviderManager gnssHardwareManager = 473 new LocationProviderManager( 474 mContext, 475 mInjector, 476 GPS_HARDWARE_PROVIDER, 477 /*passiveManager=*/ null, 478 Collections.singletonList(Manifest.permission.LOCATION_HARDWARE)); 479 addLocationProviderManager( 480 gnssHardwareManager, mGnssManagerService.getGnssLocationProvider()); 481 } 482 483 LocationProviderManager gnssManager = new LocationProviderManager(mContext, mInjector, 484 GPS_PROVIDER, mPassiveManager); 485 addLocationProviderManager(gnssManager, gnssProvider); 486 } 487 488 // bind to geocoder provider 489 mGeocodeProvider = GeocoderProxy.createAndRegister(mContext); 490 if (mGeocodeProvider == null) { 491 Log.e(TAG, "no geocoder provider found"); 492 } 493 494 // bind to hardware activity recognition 495 HardwareActivityRecognitionProxy hardwareActivityRecognitionProxy = 496 HardwareActivityRecognitionProxy.createAndRegister(mContext); 497 if (hardwareActivityRecognitionProxy == null) { 498 Log.e(TAG, "unable to bind ActivityRecognitionProxy"); 499 } 500 501 // bind to gnss geofence proxy 502 if (mGnssManagerService != null) { 503 GeofenceProxy provider = GeofenceProxy.createAndBind(mContext, 504 mGnssManagerService.getGnssGeofenceProxy()); 505 if (provider == null) { 506 Log.e(TAG, "unable to bind to GeofenceProxy"); 507 } 508 } 509 510 // create any predefined test providers 511 String[] testProviderStrings = mContext.getResources().getStringArray( 512 com.android.internal.R.array.config_testLocationProviders); 513 for (String testProviderString : testProviderStrings) { 514 String[] fragments = testProviderString.split(","); 515 String name = fragments[0].trim(); 516 ProviderProperties properties = new ProviderProperties.Builder() 517 .setHasNetworkRequirement(Boolean.parseBoolean(fragments[1])) 518 .setHasSatelliteRequirement(Boolean.parseBoolean(fragments[2])) 519 .setHasCellRequirement(Boolean.parseBoolean(fragments[3])) 520 .setHasMonetaryCost(Boolean.parseBoolean(fragments[4])) 521 .setHasAltitudeSupport(Boolean.parseBoolean(fragments[5])) 522 .setHasSpeedSupport(Boolean.parseBoolean(fragments[6])) 523 .setHasBearingSupport(Boolean.parseBoolean(fragments[7])) 524 .setPowerUsage(Integer.parseInt(fragments[8])) 525 .setAccuracy(Integer.parseInt(fragments[9])) 526 .build(); 527 final LocationProviderManager manager = getOrAddLocationProviderManager(name); 528 manager.setMockProvider(new MockLocationProvider(properties, 529 CallerIdentity.fromContext(mContext), Collections.emptySet())); 530 } 531 } 532 onLocationUserSettingsChanged(int userId, LocationUserSettings oldSettings, LocationUserSettings newSettings)533 private void onLocationUserSettingsChanged(int userId, LocationUserSettings oldSettings, 534 LocationUserSettings newSettings) { 535 if (oldSettings.isAdasGnssLocationEnabled() != newSettings.isAdasGnssLocationEnabled()) { 536 boolean enabled = newSettings.isAdasGnssLocationEnabled(); 537 538 if (D) { 539 Log.d(TAG, "[u" + userId + "] adas gnss location enabled = " + enabled); 540 } 541 542 EVENT_LOG.logAdasLocationEnabled(userId, enabled); 543 544 Intent intent = new Intent(LocationManager.ACTION_ADAS_GNSS_ENABLED_CHANGED) 545 .putExtra(LocationManager.EXTRA_ADAS_GNSS_ENABLED, enabled) 546 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY) 547 .addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 548 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); 549 } 550 } 551 onLocationModeChanged(int userId)552 private void onLocationModeChanged(int userId) { 553 boolean enabled = mInjector.getSettingsHelper().isLocationEnabled(userId); 554 LocationManager.invalidateLocalLocationEnabledCaches(); 555 556 if (D) { 557 Log.d(TAG, "[u" + userId + "] location enabled = " + enabled); 558 } 559 560 EVENT_LOG.logLocationEnabled(userId, enabled); 561 logLocationEnabledState(); 562 563 Intent intent = new Intent(LocationManager.MODE_CHANGED_ACTION) 564 .putExtra(LocationManager.EXTRA_LOCATION_ENABLED, enabled) 565 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY) 566 .addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 567 mContext.sendBroadcastAsUser(intent, UserHandle.of(userId)); 568 569 refreshAppOpsRestrictions(userId); 570 } 571 logLocationEnabledState()572 private void logLocationEnabledState() { 573 boolean locationEnabled = false; 574 // Location setting is considered on if it is enabled for any one user 575 int[] runningUserIds = mInjector.getUserInfoHelper().getRunningUserIds(); 576 for (int userId : runningUserIds) { 577 locationEnabled = mInjector.getSettingsHelper().isLocationEnabled(userId); 578 if (locationEnabled) { 579 break; 580 } 581 } 582 mInjector.getLocationUsageLogger() 583 .logLocationEnabledStateChanged(locationEnabled); 584 } 585 586 @Override getGnssYearOfHardware()587 public int getGnssYearOfHardware() { 588 return mGnssManagerService == null ? 0 : mGnssManagerService.getGnssYearOfHardware(); 589 } 590 591 @Override 592 @Nullable getGnssHardwareModelName()593 public String getGnssHardwareModelName() { 594 return mGnssManagerService == null ? "" : mGnssManagerService.getGnssHardwareModelName(); 595 } 596 597 @Override getGnssBatchSize()598 public int getGnssBatchSize() { 599 return mGnssManagerService == null ? 0 : mGnssManagerService.getGnssBatchSize(); 600 } 601 602 @Override startGnssBatch(long periodNanos, ILocationListener listener, String packageName, @Nullable String attributionTag, String listenerId)603 public void startGnssBatch(long periodNanos, ILocationListener listener, String packageName, 604 @Nullable String attributionTag, String listenerId) { 605 mContext.enforceCallingOrSelfPermission(Manifest.permission.LOCATION_HARDWARE, null); 606 607 if (mGnssManagerService == null) { 608 return; 609 } 610 611 long intervalMs = NANOSECONDS.toMillis(periodNanos); 612 613 synchronized (mDeprecatedGnssBatchingLock) { 614 stopGnssBatch(); 615 616 registerLocationListener( 617 GPS_PROVIDER, 618 new LocationRequest.Builder(intervalMs) 619 .setMaxUpdateDelayMillis( 620 intervalMs * mGnssManagerService.getGnssBatchSize()) 621 .setHiddenFromAppOps(true) 622 .build(), 623 listener, 624 packageName, 625 attributionTag, 626 listenerId); 627 mDeprecatedGnssBatchingListener = listener; 628 } 629 } 630 631 @Override flushGnssBatch()632 public void flushGnssBatch() { 633 mContext.enforceCallingOrSelfPermission(Manifest.permission.LOCATION_HARDWARE, null); 634 635 if (mGnssManagerService == null) { 636 return; 637 } 638 639 synchronized (mDeprecatedGnssBatchingLock) { 640 if (mDeprecatedGnssBatchingListener != null) { 641 requestListenerFlush(GPS_PROVIDER, mDeprecatedGnssBatchingListener, 0); 642 } 643 } 644 } 645 646 @Override stopGnssBatch()647 public void stopGnssBatch() { 648 mContext.enforceCallingOrSelfPermission(Manifest.permission.LOCATION_HARDWARE, null); 649 650 if (mGnssManagerService == null) { 651 return; 652 } 653 654 synchronized (mDeprecatedGnssBatchingLock) { 655 if (mDeprecatedGnssBatchingListener != null) { 656 ILocationListener listener = mDeprecatedGnssBatchingListener; 657 mDeprecatedGnssBatchingListener = null; 658 unregisterLocationListener(listener); 659 } 660 } 661 } 662 663 @Override hasProvider(String provider)664 public boolean hasProvider(String provider) { 665 return getLocationProviderManager(provider) != null; 666 } 667 668 @Override getAllProviders()669 public List<String> getAllProviders() { 670 ArrayList<String> providers = new ArrayList<>(mProviderManagers.size()); 671 for (LocationProviderManager manager : mProviderManagers) { 672 if (manager.isVisibleToCaller()) { 673 providers.add(manager.getName()); 674 } 675 } 676 return providers; 677 } 678 679 @Override getProviders(Criteria criteria, boolean enabledOnly)680 public List<String> getProviders(Criteria criteria, boolean enabledOnly) { 681 if (!LocationPermissions.checkCallingOrSelfLocationPermission(mContext, 682 PERMISSION_COARSE)) { 683 return Collections.emptyList(); 684 } 685 686 synchronized (mLock) { 687 ArrayList<String> providers = new ArrayList<>(mProviderManagers.size()); 688 for (LocationProviderManager manager : mProviderManagers) { 689 if (manager.isVisibleToCaller()) { 690 String name = manager.getName(); 691 if (enabledOnly && !manager.isEnabled(UserHandle.getCallingUserId())) { 692 continue; 693 } 694 if (criteria != null 695 && !LocationProvider.propertiesMeetCriteria( 696 name, manager.getProperties(), criteria)) { 697 continue; 698 } 699 providers.add(name); 700 } 701 } 702 return providers; 703 } 704 } 705 706 @Override getBestProvider(Criteria criteria, boolean enabledOnly)707 public String getBestProvider(Criteria criteria, boolean enabledOnly) { 708 List<String> providers; 709 synchronized (mLock) { 710 providers = getProviders(criteria, enabledOnly); 711 if (providers.isEmpty()) { 712 providers = getProviders(null, enabledOnly); 713 } 714 } 715 716 if (!providers.isEmpty()) { 717 if (providers.contains(FUSED_PROVIDER)) { 718 return FUSED_PROVIDER; 719 } else if (providers.contains(GPS_PROVIDER)) { 720 return GPS_PROVIDER; 721 } else if (providers.contains(NETWORK_PROVIDER)) { 722 return NETWORK_PROVIDER; 723 } else { 724 return providers.get(0); 725 } 726 } 727 728 return null; 729 } 730 731 @Override getBackgroundThrottlingWhitelist()732 public String[] getBackgroundThrottlingWhitelist() { 733 return mInjector.getSettingsHelper().getBackgroundThrottlePackageWhitelist().toArray( 734 new String[0]); 735 } 736 737 @Override getIgnoreSettingsAllowlist()738 public PackageTagsList getIgnoreSettingsAllowlist() { 739 return mInjector.getSettingsHelper().getIgnoreSettingsAllowlist(); 740 } 741 742 @Override getAdasAllowlist()743 public PackageTagsList getAdasAllowlist() { 744 return mInjector.getSettingsHelper().getAdasAllowlist(); 745 } 746 747 @Nullable 748 @Override getCurrentLocation(String provider, LocationRequest request, ILocationCallback consumer, String packageName, @Nullable String attributionTag, String listenerId)749 public ICancellationSignal getCurrentLocation(String provider, LocationRequest request, 750 ILocationCallback consumer, String packageName, @Nullable String attributionTag, 751 String listenerId) { 752 CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag, 753 listenerId); 754 int permissionLevel = LocationPermissions.getPermissionLevel(mContext, identity.getUid(), 755 identity.getPid()); 756 LocationPermissions.enforceLocationPermission(identity.getUid(), permissionLevel, 757 PERMISSION_COARSE); 758 759 // clients in the system process must have an attribution tag set 760 Preconditions.checkState(identity.getPid() != Process.myPid() || attributionTag != null); 761 762 request = validateLocationRequest(provider, request, identity); 763 764 LocationProviderManager manager = getLocationProviderManager(provider); 765 Preconditions.checkArgument(manager != null, 766 "provider \"" + provider + "\" does not exist"); 767 768 return manager.getCurrentLocation(request, identity, permissionLevel, consumer); 769 } 770 771 @Override registerLocationListener(String provider, LocationRequest request, ILocationListener listener, String packageName, @Nullable String attributionTag, String listenerId)772 public void registerLocationListener(String provider, LocationRequest request, 773 ILocationListener listener, String packageName, @Nullable String attributionTag, 774 String listenerId) { 775 ActivityManagerInternal managerInternal = 776 LocalServices.getService(ActivityManagerInternal.class); 777 if (managerInternal != null) { 778 managerInternal.logFgsApiBegin(ActivityManager.FOREGROUND_SERVICE_API_TYPE_LOCATION, 779 Binder.getCallingUid(), Binder.getCallingPid()); 780 } 781 CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag, 782 listenerId); 783 int permissionLevel = LocationPermissions.getPermissionLevel(mContext, identity.getUid(), 784 identity.getPid()); 785 LocationPermissions.enforceLocationPermission(identity.getUid(), permissionLevel, 786 PERMISSION_COARSE); 787 788 // clients in the system process should have an attribution tag set 789 if (identity.getPid() == Process.myPid() && attributionTag == null) { 790 Log.w(TAG, "system location request with no attribution tag", 791 new IllegalArgumentException()); 792 } 793 794 request = validateLocationRequest(provider, request, identity); 795 796 LocationProviderManager manager = getLocationProviderManager(provider); 797 Preconditions.checkArgument(manager != null, 798 "provider \"" + provider + "\" does not exist"); 799 800 manager.registerLocationRequest(request, identity, permissionLevel, listener); 801 } 802 803 @Override registerLocationPendingIntent(String provider, LocationRequest request, PendingIntent pendingIntent, String packageName, @Nullable String attributionTag)804 public void registerLocationPendingIntent(String provider, LocationRequest request, 805 PendingIntent pendingIntent, String packageName, @Nullable String attributionTag) { 806 CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag, 807 AppOpsManager.toReceiverId(pendingIntent)); 808 int permissionLevel = LocationPermissions.getPermissionLevel(mContext, identity.getUid(), 809 identity.getPid()); 810 LocationPermissions.enforceLocationPermission(identity.getUid(), permissionLevel, 811 PERMISSION_COARSE); 812 813 // clients in the system process must have an attribution tag set 814 Preconditions.checkArgument(identity.getPid() != Process.myPid() || attributionTag != null); 815 816 // pending intents requests may not use system apis because we do not keep track if clients 817 // lose the relevant permissions, and thus should not get the benefit of those apis. its 818 // simplest to ensure these apis are simply never set for pending intent requests. the same 819 // does not apply for listener requests since those will have the process (including the 820 // listener) killed on permission removal 821 if (isChangeEnabled(BLOCK_PENDING_INTENT_SYSTEM_API_USAGE, identity.getUid())) { 822 boolean usesSystemApi = request.isLowPower() 823 || request.isHiddenFromAppOps() 824 || request.isLocationSettingsIgnored() 825 || !request.getWorkSource().isEmpty(); 826 if (usesSystemApi) { 827 throw new SecurityException( 828 "PendingIntent location requests may not use system APIs: " + request); 829 } 830 } 831 832 request = validateLocationRequest(provider, request, identity); 833 834 LocationProviderManager manager = getLocationProviderManager(provider); 835 Preconditions.checkArgument(manager != null, 836 "provider \"" + provider + "\" does not exist"); 837 838 manager.registerLocationRequest(request, identity, permissionLevel, pendingIntent); 839 } 840 validateLocationRequest(String provider, LocationRequest request, CallerIdentity identity)841 private LocationRequest validateLocationRequest(String provider, LocationRequest request, 842 CallerIdentity identity) { 843 // validate unsanitized request 844 if (!request.getWorkSource().isEmpty()) { 845 mContext.enforceCallingOrSelfPermission( 846 permission.UPDATE_DEVICE_STATS, 847 "setting a work source requires " + permission.UPDATE_DEVICE_STATS); 848 } 849 850 // sanitize request 851 LocationRequest.Builder sanitized = new LocationRequest.Builder(request); 852 853 if (!CompatChanges.isChangeEnabled(LOW_POWER_EXCEPTIONS, Binder.getCallingUid())) { 854 if (mContext.checkCallingPermission(permission.LOCATION_HARDWARE) 855 != PERMISSION_GRANTED) { 856 sanitized.setLowPower(false); 857 } 858 } 859 860 WorkSource workSource = new WorkSource(request.getWorkSource()); 861 if (workSource.size() > 0 && workSource.getPackageName(0) == null) { 862 Log.w(TAG, "received (and ignoring) illegal worksource with no package name"); 863 workSource.clear(); 864 } else { 865 List<WorkChain> workChains = workSource.getWorkChains(); 866 if (workChains != null && !workChains.isEmpty() 867 && workChains.get(0).getAttributionTag() == null) { 868 Log.w(TAG, 869 "received (and ignoring) illegal worksource with no attribution tag"); 870 workSource.clear(); 871 } 872 } 873 874 if (workSource.isEmpty()) { 875 identity.addToWorkSource(workSource); 876 } 877 sanitized.setWorkSource(workSource); 878 879 request = sanitized.build(); 880 881 // validate sanitized request 882 boolean isLocationProvider = mLocalService.isProvider(null, identity); 883 884 if (request.isLowPower() && CompatChanges.isChangeEnabled(LOW_POWER_EXCEPTIONS, 885 identity.getUid())) { 886 mContext.enforceCallingOrSelfPermission( 887 permission.LOCATION_HARDWARE, 888 "low power request requires " + permission.LOCATION_HARDWARE); 889 } 890 if (request.isHiddenFromAppOps()) { 891 mContext.enforceCallingOrSelfPermission( 892 permission.UPDATE_APP_OPS_STATS, 893 "hiding from app ops requires " + permission.UPDATE_APP_OPS_STATS); 894 } 895 if (request.isAdasGnssBypass()) { 896 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { 897 throw new IllegalArgumentException( 898 "adas gnss bypass requests are only allowed on automotive devices"); 899 } 900 if (!GPS_PROVIDER.equals(provider)) { 901 throw new IllegalArgumentException( 902 "adas gnss bypass requests are only allowed on the \"gps\" provider"); 903 } 904 if (!isLocationProvider) { 905 LocationPermissions.enforceCallingOrSelfBypassPermission(mContext); 906 } 907 } 908 if (request.isLocationSettingsIgnored()) { 909 if (!isLocationProvider) { 910 LocationPermissions.enforceCallingOrSelfBypassPermission(mContext); 911 } 912 } 913 914 return request; 915 } 916 917 @Override requestListenerFlush(String provider, ILocationListener listener, int requestCode)918 public void requestListenerFlush(String provider, ILocationListener listener, int requestCode) { 919 LocationProviderManager manager = getLocationProviderManager(provider); 920 Preconditions.checkArgument(manager != null, 921 "provider \"" + provider + "\" does not exist"); 922 923 manager.flush(Objects.requireNonNull(listener), requestCode); 924 } 925 926 @Override requestPendingIntentFlush(String provider, PendingIntent pendingIntent, int requestCode)927 public void requestPendingIntentFlush(String provider, PendingIntent pendingIntent, 928 int requestCode) { 929 LocationProviderManager manager = getLocationProviderManager(provider); 930 Preconditions.checkArgument(manager != null, 931 "provider \"" + provider + "\" does not exist"); 932 933 manager.flush(Objects.requireNonNull(pendingIntent), requestCode); 934 } 935 936 @Override unregisterLocationListener(ILocationListener listener)937 public void unregisterLocationListener(ILocationListener listener) { 938 ActivityManagerInternal managerInternal = 939 LocalServices.getService(ActivityManagerInternal.class); 940 if (managerInternal != null) { 941 managerInternal.logFgsApiEnd(ActivityManager.FOREGROUND_SERVICE_API_TYPE_LOCATION, 942 Binder.getCallingUid(), Binder.getCallingPid()); 943 } 944 for (LocationProviderManager manager : mProviderManagers) { 945 manager.unregisterLocationRequest(listener); 946 } 947 } 948 949 @Override unregisterLocationPendingIntent(PendingIntent pendingIntent)950 public void unregisterLocationPendingIntent(PendingIntent pendingIntent) { 951 for (LocationProviderManager manager : mProviderManagers) { 952 manager.unregisterLocationRequest(pendingIntent); 953 } 954 } 955 956 @Override getLastLocation(String provider, LastLocationRequest request, String packageName, @Nullable String attributionTag)957 public Location getLastLocation(String provider, LastLocationRequest request, 958 String packageName, @Nullable String attributionTag) { 959 CallerIdentity identity = CallerIdentity.fromBinder(mContext, packageName, attributionTag); 960 int permissionLevel = LocationPermissions.getPermissionLevel(mContext, identity.getUid(), 961 identity.getPid()); 962 LocationPermissions.enforceLocationPermission(identity.getUid(), permissionLevel, 963 PERMISSION_COARSE); 964 965 // clients in the system process must have an attribution tag set 966 Preconditions.checkArgument(identity.getPid() != Process.myPid() || attributionTag != null); 967 968 request = validateLastLocationRequest(provider, request, identity); 969 970 LocationProviderManager manager = getLocationProviderManager(provider); 971 if (manager == null) { 972 return null; 973 } 974 975 return manager.getLastLocation(request, identity, permissionLevel); 976 } 977 validateLastLocationRequest(String provider, LastLocationRequest request, CallerIdentity identity)978 private LastLocationRequest validateLastLocationRequest(String provider, 979 LastLocationRequest request, 980 CallerIdentity identity) { 981 // sanitize request 982 LastLocationRequest.Builder sanitized = new LastLocationRequest.Builder(request); 983 984 request = sanitized.build(); 985 986 // validate request 987 boolean isLocationProvider = mLocalService.isProvider(null, identity); 988 989 if (request.isHiddenFromAppOps()) { 990 mContext.enforceCallingOrSelfPermission( 991 permission.UPDATE_APP_OPS_STATS, 992 "hiding from app ops requires " + permission.UPDATE_APP_OPS_STATS); 993 } 994 995 if (request.isAdasGnssBypass()) { 996 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { 997 throw new IllegalArgumentException( 998 "adas gnss bypass requests are only allowed on automotive devices"); 999 } 1000 if (!GPS_PROVIDER.equals(provider)) { 1001 throw new IllegalArgumentException( 1002 "adas gnss bypass requests are only allowed on the \"gps\" provider"); 1003 } 1004 if (!isLocationProvider) { 1005 LocationPermissions.enforceCallingOrSelfBypassPermission(mContext); 1006 } 1007 } 1008 if (request.isLocationSettingsIgnored()) { 1009 if (!isLocationProvider) { 1010 LocationPermissions.enforceCallingOrSelfBypassPermission(mContext); 1011 } 1012 } 1013 1014 return request; 1015 } 1016 1017 @Override getGnssTimeMillis()1018 public LocationTime getGnssTimeMillis() { 1019 return mLocalService.getGnssTimeMillis(); 1020 } 1021 1022 @android.annotation.EnforcePermission(allOf={android.Manifest.permission.LOCATION_HARDWARE, android.Manifest.permission.ACCESS_FINE_LOCATION}) 1023 @Override injectLocation(Location location)1024 public void injectLocation(Location location) { 1025 1026 super.injectLocation_enforcePermission(); 1027 1028 Preconditions.checkArgument(location.isComplete()); 1029 1030 int userId = UserHandle.getCallingUserId(); 1031 LocationProviderManager manager = getLocationProviderManager(location.getProvider()); 1032 if (manager != null && manager.isEnabled(userId)) { 1033 manager.injectLastLocation(Objects.requireNonNull(location), userId); 1034 } 1035 } 1036 1037 @Override requestGeofence(Geofence geofence, PendingIntent intent, String packageName, String attributionTag)1038 public void requestGeofence(Geofence geofence, PendingIntent intent, String packageName, 1039 String attributionTag) { 1040 mGeofenceManager.addGeofence(geofence, intent, packageName, attributionTag); 1041 } 1042 1043 @Override removeGeofence(PendingIntent pendingIntent)1044 public void removeGeofence(PendingIntent pendingIntent) { 1045 mGeofenceManager.removeGeofence(pendingIntent); 1046 } 1047 1048 @Override registerGnssStatusCallback(IGnssStatusListener listener, String packageName, @Nullable String attributionTag, String listenerId)1049 public void registerGnssStatusCallback(IGnssStatusListener listener, String packageName, 1050 @Nullable String attributionTag, String listenerId) { 1051 if (mGnssManagerService != null) { 1052 mGnssManagerService.registerGnssStatusCallback(listener, packageName, attributionTag, 1053 listenerId); 1054 } 1055 } 1056 1057 @Override unregisterGnssStatusCallback(IGnssStatusListener listener)1058 public void unregisterGnssStatusCallback(IGnssStatusListener listener) { 1059 if (mGnssManagerService != null) { 1060 mGnssManagerService.unregisterGnssStatusCallback(listener); 1061 } 1062 } 1063 1064 @Override registerGnssNmeaCallback(IGnssNmeaListener listener, String packageName, @Nullable String attributionTag, String listenerId)1065 public void registerGnssNmeaCallback(IGnssNmeaListener listener, String packageName, 1066 @Nullable String attributionTag, String listenerId) { 1067 if (mGnssManagerService != null) { 1068 mGnssManagerService.registerGnssNmeaCallback(listener, packageName, attributionTag, 1069 listenerId); 1070 } 1071 } 1072 1073 @Override unregisterGnssNmeaCallback(IGnssNmeaListener listener)1074 public void unregisterGnssNmeaCallback(IGnssNmeaListener listener) { 1075 if (mGnssManagerService != null) { 1076 mGnssManagerService.unregisterGnssNmeaCallback(listener); 1077 } 1078 } 1079 1080 @Override addGnssMeasurementsListener(GnssMeasurementRequest request, IGnssMeasurementsListener listener, String packageName, @Nullable String attributionTag, String listenerId)1081 public void addGnssMeasurementsListener(GnssMeasurementRequest request, 1082 IGnssMeasurementsListener listener, String packageName, @Nullable String attributionTag, 1083 String listenerId) { 1084 if (mGnssManagerService != null) { 1085 mGnssManagerService.addGnssMeasurementsListener(request, listener, packageName, 1086 attributionTag, listenerId); 1087 } 1088 } 1089 1090 @Override removeGnssMeasurementsListener(IGnssMeasurementsListener listener)1091 public void removeGnssMeasurementsListener(IGnssMeasurementsListener listener) { 1092 if (mGnssManagerService != null) { 1093 mGnssManagerService.removeGnssMeasurementsListener( 1094 listener); 1095 } 1096 } 1097 1098 @Override addGnssAntennaInfoListener(IGnssAntennaInfoListener listener, String packageName, @Nullable String attributionTag, String listenerId)1099 public void addGnssAntennaInfoListener(IGnssAntennaInfoListener listener, String packageName, 1100 @Nullable String attributionTag, String listenerId) { 1101 if (mGnssManagerService != null) { 1102 mGnssManagerService.addGnssAntennaInfoListener(listener, packageName, attributionTag, 1103 listenerId); 1104 } 1105 } 1106 1107 @Override removeGnssAntennaInfoListener(IGnssAntennaInfoListener listener)1108 public void removeGnssAntennaInfoListener(IGnssAntennaInfoListener listener) { 1109 if (mGnssManagerService != null) { 1110 mGnssManagerService.removeGnssAntennaInfoListener(listener); 1111 } 1112 } 1113 1114 @Override 1115 @RequiresPermission(INTERACT_ACROSS_USERS) addProviderRequestListener(IProviderRequestListener listener)1116 public void addProviderRequestListener(IProviderRequestListener listener) { 1117 mContext.enforceCallingOrSelfPermission(INTERACT_ACROSS_USERS, null); 1118 for (LocationProviderManager manager : mProviderManagers) { 1119 if (manager.isVisibleToCaller()) { 1120 manager.addProviderRequestListener(listener); 1121 } 1122 } 1123 } 1124 1125 @Override removeProviderRequestListener(IProviderRequestListener listener)1126 public void removeProviderRequestListener(IProviderRequestListener listener) { 1127 for (LocationProviderManager manager : mProviderManagers) { 1128 manager.removeProviderRequestListener(listener); 1129 } 1130 } 1131 1132 @Override injectGnssMeasurementCorrections(GnssMeasurementCorrections corrections)1133 public void injectGnssMeasurementCorrections(GnssMeasurementCorrections corrections) { 1134 if (mGnssManagerService != null) { 1135 mGnssManagerService.injectGnssMeasurementCorrections(corrections); 1136 } 1137 } 1138 1139 @Override getGnssCapabilities()1140 public GnssCapabilities getGnssCapabilities() { 1141 return mGnssManagerService == null ? new GnssCapabilities.Builder().build() 1142 : mGnssManagerService.getGnssCapabilities(); 1143 } 1144 1145 @Override getGnssAntennaInfos()1146 public List<GnssAntennaInfo> getGnssAntennaInfos() { 1147 return mGnssManagerService == null ? null : mGnssManagerService.getGnssAntennaInfos(); 1148 } 1149 1150 @Override addGnssNavigationMessageListener(IGnssNavigationMessageListener listener, String packageName, @Nullable String attributionTag, String listenerId)1151 public void addGnssNavigationMessageListener(IGnssNavigationMessageListener listener, 1152 String packageName, @Nullable String attributionTag, String listenerId) { 1153 if (mGnssManagerService != null) { 1154 mGnssManagerService.addGnssNavigationMessageListener(listener, packageName, 1155 attributionTag, listenerId); 1156 } 1157 } 1158 1159 @Override removeGnssNavigationMessageListener(IGnssNavigationMessageListener listener)1160 public void removeGnssNavigationMessageListener(IGnssNavigationMessageListener listener) { 1161 if (mGnssManagerService != null) { 1162 mGnssManagerService.removeGnssNavigationMessageListener( 1163 listener); 1164 } 1165 } 1166 1167 @Override sendExtraCommand(String provider, String command, Bundle extras)1168 public void sendExtraCommand(String provider, String command, Bundle extras) { 1169 LocationPermissions.enforceCallingOrSelfLocationPermission(mContext, PERMISSION_COARSE); 1170 mContext.enforceCallingOrSelfPermission( 1171 permission.ACCESS_LOCATION_EXTRA_COMMANDS, null); 1172 1173 LocationProviderManager manager = getLocationProviderManager( 1174 Objects.requireNonNull(provider)); 1175 if (manager != null) { 1176 manager.sendExtraCommand(Binder.getCallingUid(), Binder.getCallingPid(), 1177 Objects.requireNonNull(command), extras); 1178 } 1179 1180 mInjector.getLocationUsageLogger().logLocationApiUsage( 1181 LocationStatsEnums.USAGE_STARTED, 1182 LocationStatsEnums.API_SEND_EXTRA_COMMAND, 1183 provider); 1184 mInjector.getLocationUsageLogger().logLocationApiUsage( 1185 LocationStatsEnums.USAGE_ENDED, 1186 LocationStatsEnums.API_SEND_EXTRA_COMMAND, 1187 provider); 1188 } 1189 1190 @Override getProviderProperties(String provider)1191 public ProviderProperties getProviderProperties(String provider) { 1192 LocationProviderManager manager = getLocationProviderManager(provider); 1193 Preconditions.checkArgument(manager != null, 1194 "provider \"" + provider + "\" does not exist"); 1195 return manager.getProperties(); 1196 } 1197 1198 @Override isProviderPackage(@ullable String provider, String packageName, @Nullable String attributionTag)1199 public boolean isProviderPackage(@Nullable String provider, String packageName, 1200 @Nullable String attributionTag) { 1201 mContext.enforceCallingOrSelfPermission(permission.READ_DEVICE_CONFIG, null); 1202 1203 for (LocationProviderManager manager : mProviderManagers) { 1204 if (provider != null && !provider.equals(manager.getName())) { 1205 continue; 1206 } 1207 CallerIdentity identity = manager.getProviderIdentity(); 1208 if (identity == null) { 1209 continue; 1210 } 1211 if (identity.getPackageName().equals(packageName) && (attributionTag == null 1212 || Objects.equals(identity.getAttributionTag(), attributionTag))) { 1213 return true; 1214 } 1215 } 1216 1217 return false; 1218 } 1219 1220 @Override getProviderPackages(String provider)1221 public List<String> getProviderPackages(String provider) { 1222 mContext.enforceCallingOrSelfPermission(permission.READ_DEVICE_CONFIG, null); 1223 1224 LocationProviderManager manager = getLocationProviderManager(provider); 1225 if (manager == null) { 1226 return Collections.emptyList(); 1227 } 1228 1229 CallerIdentity identity = manager.getProviderIdentity(); 1230 if (identity == null) { 1231 return Collections.emptyList(); 1232 } 1233 1234 return Collections.singletonList(identity.getPackageName()); 1235 } 1236 1237 @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE) 1238 @Override setExtraLocationControllerPackage(String packageName)1239 public void setExtraLocationControllerPackage(String packageName) { 1240 super.setExtraLocationControllerPackage_enforcePermission(); 1241 1242 synchronized (mLock) { 1243 mExtraLocationControllerPackage = packageName; 1244 } 1245 } 1246 1247 @Override getExtraLocationControllerPackage()1248 public String getExtraLocationControllerPackage() { 1249 synchronized (mLock) { 1250 return mExtraLocationControllerPackage; 1251 } 1252 } 1253 1254 @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE) 1255 @Override setExtraLocationControllerPackageEnabled(boolean enabled)1256 public void setExtraLocationControllerPackageEnabled(boolean enabled) { 1257 super.setExtraLocationControllerPackageEnabled_enforcePermission(); 1258 1259 synchronized (mLock) { 1260 mExtraLocationControllerPackageEnabled = enabled; 1261 } 1262 } 1263 1264 @Override isExtraLocationControllerPackageEnabled()1265 public boolean isExtraLocationControllerPackageEnabled() { 1266 synchronized (mLock) { 1267 return mExtraLocationControllerPackageEnabled 1268 && (mExtraLocationControllerPackage != null); 1269 } 1270 } 1271 1272 @Override setLocationEnabledForUser(boolean enabled, int userId)1273 public void setLocationEnabledForUser(boolean enabled, int userId) { 1274 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 1275 userId, false, false, "setLocationEnabledForUser", null); 1276 1277 mContext.enforceCallingOrSelfPermission(WRITE_SECURE_SETTINGS, null); 1278 1279 LocationManager.invalidateLocalLocationEnabledCaches(); 1280 mInjector.getSettingsHelper().setLocationEnabled(enabled, userId); 1281 } 1282 1283 @Override isLocationEnabledForUser(int userId)1284 public boolean isLocationEnabledForUser(int userId) { 1285 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 1286 userId, false, false, "isLocationEnabledForUser", null); 1287 return mInjector.getSettingsHelper().isLocationEnabled(userId); 1288 } 1289 1290 @Override setAdasGnssLocationEnabledForUser(boolean enabled, int userId)1291 public void setAdasGnssLocationEnabledForUser(boolean enabled, int userId) { 1292 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 1293 userId, false, false, "setAdasGnssLocationEnabledForUser", null); 1294 1295 LocationPermissions.enforceCallingOrSelfBypassPermission(mContext); 1296 1297 mInjector.getLocationSettings().updateUserSettings(userId, 1298 settings -> settings.withAdasGnssLocationEnabled(enabled)); 1299 } 1300 1301 @Override isAdasGnssLocationEnabledForUser(int userId)1302 public boolean isAdasGnssLocationEnabledForUser(int userId) { 1303 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), 1304 userId, false, false, "isAdasGnssLocationEnabledForUser", null); 1305 return mInjector.getLocationSettings().getUserSettings(userId).isAdasGnssLocationEnabled(); 1306 } 1307 1308 @Override isProviderEnabledForUser(String provider, int userId)1309 public boolean isProviderEnabledForUser(String provider, int userId) { 1310 return mLocalService.isProviderEnabledForUser(provider, userId); 1311 } 1312 1313 @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS) 1314 @Override 1315 @RequiresPermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS) setAutomotiveGnssSuspended(boolean suspended)1316 public void setAutomotiveGnssSuspended(boolean suspended) { 1317 1318 super.setAutomotiveGnssSuspended_enforcePermission(); 1319 1320 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { 1321 throw new IllegalStateException( 1322 "setAutomotiveGnssSuspended only allowed on automotive devices"); 1323 } 1324 1325 mGnssManagerService.setAutomotiveGnssSuspended(suspended); 1326 } 1327 1328 @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS) 1329 @Override 1330 @RequiresPermission(android.Manifest.permission.CONTROL_AUTOMOTIVE_GNSS) isAutomotiveGnssSuspended()1331 public boolean isAutomotiveGnssSuspended() { 1332 1333 super.isAutomotiveGnssSuspended_enforcePermission(); 1334 1335 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_AUTOMOTIVE)) { 1336 throw new IllegalStateException( 1337 "isAutomotiveGnssSuspended only allowed on automotive devices"); 1338 } 1339 1340 return mGnssManagerService.isAutomotiveGnssSuspended(); 1341 } 1342 1343 @Override geocoderIsPresent()1344 public boolean geocoderIsPresent() { 1345 return mGeocodeProvider != null; 1346 } 1347 1348 @Override getFromLocation(double latitude, double longitude, int maxResults, GeocoderParams params, IGeocodeListener listener)1349 public void getFromLocation(double latitude, double longitude, int maxResults, 1350 GeocoderParams params, IGeocodeListener listener) { 1351 // validate identity 1352 CallerIdentity identity = CallerIdentity.fromBinder(mContext, params.getClientPackage(), 1353 params.getClientAttributionTag()); 1354 Preconditions.checkArgument(identity.getUid() == params.getClientUid()); 1355 1356 if (mGeocodeProvider != null) { 1357 mGeocodeProvider.getFromLocation(latitude, longitude, maxResults, params, listener); 1358 } else { 1359 try { 1360 listener.onResults(null, Collections.emptyList()); 1361 } catch (RemoteException e) { 1362 // ignore 1363 } 1364 } 1365 } 1366 1367 @Override getFromLocationName(String locationName, double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude, double upperRightLongitude, int maxResults, GeocoderParams params, IGeocodeListener listener)1368 public void getFromLocationName(String locationName, 1369 double lowerLeftLatitude, double lowerLeftLongitude, 1370 double upperRightLatitude, double upperRightLongitude, int maxResults, 1371 GeocoderParams params, IGeocodeListener listener) { 1372 // validate identity 1373 CallerIdentity identity = CallerIdentity.fromBinder(mContext, params.getClientPackage(), 1374 params.getClientAttributionTag()); 1375 Preconditions.checkArgument(identity.getUid() == params.getClientUid()); 1376 1377 if (mGeocodeProvider != null) { 1378 mGeocodeProvider.getFromLocationName(locationName, lowerLeftLatitude, 1379 lowerLeftLongitude, upperRightLatitude, upperRightLongitude, 1380 maxResults, params, listener); 1381 } else { 1382 try { 1383 listener.onResults(null, Collections.emptyList()); 1384 } catch (RemoteException e) { 1385 // ignore 1386 } 1387 } 1388 } 1389 1390 @Override addTestProvider(String provider, ProviderProperties properties, List<String> extraAttributionTags, String packageName, String attributionTag)1391 public void addTestProvider(String provider, ProviderProperties properties, 1392 List<String> extraAttributionTags, String packageName, String attributionTag) { 1393 // unsafe is ok because app ops will verify the package name 1394 CallerIdentity identity = CallerIdentity.fromBinderUnsafe(packageName, attributionTag); 1395 if (!mInjector.getAppOpsHelper().noteOp(AppOpsManager.OP_MOCK_LOCATION, identity)) { 1396 return; 1397 } 1398 1399 final LocationProviderManager manager = getOrAddLocationProviderManager(provider); 1400 manager.setMockProvider(new MockLocationProvider(properties, identity, 1401 new ArraySet<>(extraAttributionTags))); 1402 } 1403 1404 @Override removeTestProvider(String provider, String packageName, String attributionTag)1405 public void removeTestProvider(String provider, String packageName, String attributionTag) { 1406 // unsafe is ok because app ops will verify the package name 1407 CallerIdentity identity = CallerIdentity.fromBinderUnsafe(packageName, attributionTag); 1408 if (!mInjector.getAppOpsHelper().noteOp(AppOpsManager.OP_MOCK_LOCATION, identity)) { 1409 return; 1410 } 1411 1412 synchronized (mLock) { 1413 LocationProviderManager manager = getLocationProviderManager(provider); 1414 if (manager == null) { 1415 return; 1416 } 1417 1418 manager.setMockProvider(null); 1419 if (!manager.hasProvider()) { 1420 removeLocationProviderManager(manager); 1421 } 1422 } 1423 } 1424 1425 @Override setTestProviderLocation(String provider, Location location, String packageName, String attributionTag)1426 public void setTestProviderLocation(String provider, Location location, String packageName, 1427 String attributionTag) { 1428 // unsafe is ok because app ops will verify the package name 1429 CallerIdentity identity = CallerIdentity.fromBinderUnsafe(packageName, 1430 attributionTag); 1431 if (!mInjector.getAppOpsHelper().noteOp(AppOpsManager.OP_MOCK_LOCATION, identity)) { 1432 return; 1433 } 1434 1435 Preconditions.checkArgument(location.isComplete(), 1436 "incomplete location object, missing timestamp or accuracy?"); 1437 1438 LocationProviderManager manager = getLocationProviderManager(provider); 1439 if (manager == null) { 1440 throw new IllegalArgumentException("provider doesn't exist: " + provider); 1441 } 1442 1443 manager.setMockProviderLocation(location); 1444 } 1445 1446 @Override setTestProviderEnabled(String provider, boolean enabled, String packageName, String attributionTag)1447 public void setTestProviderEnabled(String provider, boolean enabled, String packageName, 1448 String attributionTag) { 1449 // unsafe is ok because app ops will verify the package name 1450 CallerIdentity identity = CallerIdentity.fromBinderUnsafe(packageName, 1451 attributionTag); 1452 if (!mInjector.getAppOpsHelper().noteOp(AppOpsManager.OP_MOCK_LOCATION, identity)) { 1453 return; 1454 } 1455 1456 LocationProviderManager manager = getLocationProviderManager(provider); 1457 if (manager == null) { 1458 throw new IllegalArgumentException("provider doesn't exist: " + provider); 1459 } 1460 1461 manager.setMockProviderAllowed(enabled); 1462 } 1463 1464 @Override handleShellCommand(ParcelFileDescriptor in, ParcelFileDescriptor out, ParcelFileDescriptor err, String[] args)1465 public int handleShellCommand(ParcelFileDescriptor in, ParcelFileDescriptor out, 1466 ParcelFileDescriptor err, String[] args) { 1467 return new LocationShellCommand(mContext, this).exec( 1468 this, in.getFileDescriptor(), out.getFileDescriptor(), err.getFileDescriptor(), 1469 args); 1470 } 1471 1472 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1473 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1474 if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) { 1475 return; 1476 } 1477 1478 IndentingPrintWriter ipw = new IndentingPrintWriter(pw, " "); 1479 1480 if (args.length > 0) { 1481 LocationProviderManager manager = getLocationProviderManager(args[0]); 1482 if (manager != null) { 1483 ipw.println("Provider:"); 1484 ipw.increaseIndent(); 1485 manager.dump(fd, ipw, args); 1486 ipw.decreaseIndent(); 1487 1488 ipw.println("Event Log:"); 1489 ipw.increaseIndent(); 1490 EVENT_LOG.iterate(ipw::println, manager.getName()); 1491 ipw.decreaseIndent(); 1492 return; 1493 } 1494 1495 if ("--gnssmetrics".equals(args[0])) { 1496 if (mGnssManagerService != null) { 1497 mGnssManagerService.dump(fd, ipw, args); 1498 } 1499 return; 1500 } 1501 } 1502 1503 ipw.println("Location Manager State:"); 1504 ipw.increaseIndent(); 1505 1506 ipw.println("User Info:"); 1507 ipw.increaseIndent(); 1508 mInjector.getUserInfoHelper().dump(fd, ipw, args); 1509 ipw.decreaseIndent(); 1510 1511 ipw.println("Location Settings:"); 1512 ipw.increaseIndent(); 1513 mInjector.getSettingsHelper().dump(fd, ipw, args); 1514 mInjector.getLocationSettings().dump(fd, ipw, args); 1515 ipw.decreaseIndent(); 1516 1517 synchronized (mLock) { 1518 if (mExtraLocationControllerPackage != null) { 1519 ipw.println( 1520 "Location Controller Extra Package: " + mExtraLocationControllerPackage 1521 + (mExtraLocationControllerPackageEnabled ? " [enabled]" 1522 : " [disabled]")); 1523 } 1524 } 1525 1526 ipw.println("Location Providers:"); 1527 ipw.increaseIndent(); 1528 for (LocationProviderManager manager : mProviderManagers) { 1529 manager.dump(fd, ipw, args); 1530 } 1531 ipw.decreaseIndent(); 1532 1533 ipw.println("Historical Aggregate Location Provider Data:"); 1534 ipw.increaseIndent(); 1535 ArrayMap<String, ArrayMap<CallerIdentity, LocationEventLog.AggregateStats>> aggregateStats = 1536 EVENT_LOG.copyAggregateStats(); 1537 for (int i = 0; i < aggregateStats.size(); i++) { 1538 ipw.print(aggregateStats.keyAt(i)); 1539 ipw.println(":"); 1540 ipw.increaseIndent(); 1541 ArrayMap<CallerIdentity, LocationEventLog.AggregateStats> providerStats = 1542 aggregateStats.valueAt(i); 1543 for (int j = 0; j < providerStats.size(); j++) { 1544 ipw.print(providerStats.keyAt(j)); 1545 ipw.print(": "); 1546 providerStats.valueAt(j).updateTotals(); 1547 ipw.println(providerStats.valueAt(j)); 1548 } 1549 ipw.decreaseIndent(); 1550 } 1551 ipw.decreaseIndent(); 1552 1553 if (mGnssManagerService != null) { 1554 ipw.println("GNSS Manager:"); 1555 ipw.increaseIndent(); 1556 mGnssManagerService.dump(fd, ipw, args); 1557 ipw.decreaseIndent(); 1558 } 1559 1560 ipw.println("Geofence Manager:"); 1561 ipw.increaseIndent(); 1562 mGeofenceManager.dump(fd, ipw, args); 1563 ipw.decreaseIndent(); 1564 1565 ipw.println("Event Log:"); 1566 ipw.increaseIndent(); 1567 EVENT_LOG.iterate(ipw::println); 1568 ipw.decreaseIndent(); 1569 } 1570 1571 @Override onStateChanged(String provider, AbstractLocationProvider.State oldState, AbstractLocationProvider.State newState)1572 public void onStateChanged(String provider, AbstractLocationProvider.State oldState, 1573 AbstractLocationProvider.State newState) { 1574 if (!Objects.equals(oldState.identity, newState.identity)) { 1575 refreshAppOpsRestrictions(UserHandle.USER_ALL); 1576 } 1577 1578 if (!oldState.extraAttributionTags.equals(newState.extraAttributionTags) 1579 || !Objects.equals(oldState.identity, newState.identity)) { 1580 // since we're potentially affecting the tag lists for two different uids, acquire the 1581 // lock to ensure providers cannot change while we're looping over the providers 1582 // multiple times, which could lead to inconsistent results. 1583 synchronized (mLock) { 1584 LocationPackageTagsListener listener = mLocationTagsChangedListener; 1585 if (listener != null) { 1586 int oldUid = oldState.identity != null ? oldState.identity.getUid() : -1; 1587 int newUid = newState.identity != null ? newState.identity.getUid() : -1; 1588 if (oldUid != -1) { 1589 PackageTagsList tags = calculateAppOpsLocationSourceTags(oldUid); 1590 FgThread.getHandler().post( 1591 () -> listener.onLocationPackageTagsChanged(oldUid, tags)); 1592 } 1593 // if the new app id is the same as the old app id, no need to invoke the 1594 // listener twice, it's already been taken care of 1595 if (newUid != -1 && newUid != oldUid) { 1596 PackageTagsList tags = calculateAppOpsLocationSourceTags(newUid); 1597 FgThread.getHandler().post( 1598 () -> listener.onLocationPackageTagsChanged(newUid, tags)); 1599 } 1600 } 1601 } 1602 } 1603 } 1604 refreshAppOpsRestrictions(int userId)1605 private void refreshAppOpsRestrictions(int userId) { 1606 if (userId == UserHandle.USER_ALL) { 1607 final int[] runningUserIds = mInjector.getUserInfoHelper().getRunningUserIds(); 1608 for (int i = 0; i < runningUserIds.length; i++) { 1609 refreshAppOpsRestrictions(runningUserIds[i]); 1610 } 1611 return; 1612 } 1613 1614 Preconditions.checkArgument(userId >= 0); 1615 1616 boolean enabled = mInjector.getSettingsHelper().isLocationEnabled(userId); 1617 1618 PackageTagsList allowedPackages = null; 1619 if (!enabled) { 1620 PackageTagsList.Builder builder = new PackageTagsList.Builder(); 1621 for (LocationProviderManager manager : mProviderManagers) { 1622 CallerIdentity identity = manager.getProviderIdentity(); 1623 if (identity != null) { 1624 builder.add(identity.getPackageName(), identity.getAttributionTag()); 1625 } 1626 } 1627 builder.add(mInjector.getSettingsHelper().getIgnoreSettingsAllowlist()); 1628 builder.add(mInjector.getSettingsHelper().getAdasAllowlist()); 1629 allowedPackages = builder.build(); 1630 } 1631 1632 AppOpsManager appOpsManager = Objects.requireNonNull( 1633 mContext.getSystemService(AppOpsManager.class)); 1634 appOpsManager.setUserRestrictionForUser( 1635 AppOpsManager.OP_COARSE_LOCATION, 1636 !enabled, 1637 LocationManagerService.this, 1638 allowedPackages, 1639 userId); 1640 appOpsManager.setUserRestrictionForUser( 1641 AppOpsManager.OP_FINE_LOCATION, 1642 !enabled, 1643 LocationManagerService.this, 1644 allowedPackages, 1645 userId); 1646 } 1647 calculateAppOpsLocationSourceTags(int uid)1648 PackageTagsList calculateAppOpsLocationSourceTags(int uid) { 1649 PackageTagsList.Builder builder = new PackageTagsList.Builder(); 1650 for (LocationProviderManager manager : mProviderManagers) { 1651 AbstractLocationProvider.State managerState = manager.getState(); 1652 if (managerState.identity == null) { 1653 continue; 1654 } 1655 if (managerState.identity.getUid() != uid) { 1656 continue; 1657 } 1658 1659 builder.add(managerState.identity.getPackageName(), managerState.extraAttributionTags); 1660 if (managerState.extraAttributionTags.isEmpty() 1661 || managerState.identity.getAttributionTag() != null) { 1662 builder.add(managerState.identity.getPackageName(), 1663 managerState.identity.getAttributionTag()); 1664 } else { 1665 Log.e(TAG, manager.getName() + " provider has specified a null attribution tag and " 1666 + "a non-empty set of extra attribution tags - dropping the null " 1667 + "attribution tag"); 1668 } 1669 } 1670 return builder.build(); 1671 } 1672 1673 private class LocalService extends LocationManagerInternal { 1674 LocalService()1675 LocalService() {} 1676 1677 @Override isProviderEnabledForUser(@onNull String provider, int userId)1678 public boolean isProviderEnabledForUser(@NonNull String provider, int userId) { 1679 userId = ActivityManager.handleIncomingUser(Binder.getCallingPid(), 1680 Binder.getCallingUid(), userId, false, false, "isProviderEnabledForUser", null); 1681 1682 LocationProviderManager manager = getLocationProviderManager(provider); 1683 if (manager == null) { 1684 return false; 1685 } 1686 1687 return manager.isEnabled(userId); 1688 } 1689 1690 @Override addProviderEnabledListener(String provider, ProviderEnabledListener listener)1691 public void addProviderEnabledListener(String provider, ProviderEnabledListener listener) { 1692 LocationProviderManager manager = Objects.requireNonNull( 1693 getLocationProviderManager(provider)); 1694 manager.addEnabledListener(listener); 1695 } 1696 1697 @Override removeProviderEnabledListener(String provider, ProviderEnabledListener listener)1698 public void removeProviderEnabledListener(String provider, 1699 ProviderEnabledListener listener) { 1700 LocationProviderManager manager = Objects.requireNonNull( 1701 getLocationProviderManager(provider)); 1702 manager.removeEnabledListener(listener); 1703 } 1704 1705 @Override isProvider(@ullable String provider, CallerIdentity identity)1706 public boolean isProvider(@Nullable String provider, CallerIdentity identity) { 1707 for (LocationProviderManager manager : mProviderManagers) { 1708 if (provider != null && !provider.equals(manager.getName())) { 1709 continue; 1710 } 1711 if (identity.equals(manager.getProviderIdentity()) && manager.isVisibleToCaller()) { 1712 return true; 1713 } 1714 } 1715 1716 return false; 1717 } 1718 1719 @Override sendNiResponse(int notifId, int userResponse)1720 public void sendNiResponse(int notifId, int userResponse) { 1721 if (mGnssManagerService != null) { 1722 mGnssManagerService.sendNiResponse(notifId, userResponse); 1723 } 1724 } 1725 1726 @Override getGnssTimeMillis()1727 public @Nullable LocationTime getGnssTimeMillis() { 1728 LocationProviderManager gpsManager = getLocationProviderManager(GPS_PROVIDER); 1729 if (gpsManager == null) { 1730 return null; 1731 } 1732 1733 Location location = gpsManager.getLastLocationUnsafe(UserHandle.USER_ALL, 1734 PERMISSION_FINE, false, Long.MAX_VALUE); 1735 if (location == null) { 1736 return null; 1737 } 1738 1739 return new LocationTime(location.getTime(), location.getElapsedRealtimeNanos()); 1740 } 1741 1742 @Override setLocationPackageTagsListener( @ullable LocationPackageTagsListener listener)1743 public void setLocationPackageTagsListener( 1744 @Nullable LocationPackageTagsListener listener) { 1745 synchronized (mLock) { 1746 mLocationTagsChangedListener = listener; 1747 1748 // calculate initial tag list and send to listener 1749 if (listener != null) { 1750 ArraySet<Integer> uids = new ArraySet<>(mProviderManagers.size()); 1751 for (LocationProviderManager manager : mProviderManagers) { 1752 CallerIdentity identity = manager.getProviderIdentity(); 1753 if (identity != null) { 1754 uids.add(identity.getUid()); 1755 } 1756 } 1757 1758 for (int uid : uids) { 1759 PackageTagsList tags = calculateAppOpsLocationSourceTags(uid); 1760 if (!tags.isEmpty()) { 1761 FgThread.getHandler().post( 1762 () -> listener.onLocationPackageTagsChanged(uid, tags)); 1763 } 1764 } 1765 } 1766 } 1767 } 1768 } 1769 1770 private static final class SystemInjector implements Injector { 1771 1772 private final Context mContext; 1773 1774 private final SystemUserInfoHelper mUserInfoHelper; 1775 private final LocationSettings mLocationSettings; 1776 private final AlarmHelper mAlarmHelper; 1777 private final SystemAppOpsHelper mAppOpsHelper; 1778 private final SystemLocationPermissionsHelper mLocationPermissionsHelper; 1779 private final SystemSettingsHelper mSettingsHelper; 1780 private final SystemAppForegroundHelper mAppForegroundHelper; 1781 private final SystemLocationPowerSaveModeHelper mLocationPowerSaveModeHelper; 1782 private final SystemScreenInteractiveHelper mScreenInteractiveHelper; 1783 private final SystemDeviceStationaryHelper mDeviceStationaryHelper; 1784 private final SystemDeviceIdleHelper mDeviceIdleHelper; 1785 private final LocationUsageLogger mLocationUsageLogger; 1786 private final PackageResetHelper mPackageResetHelper; 1787 1788 // lazily instantiated since they may not always be used 1789 1790 @GuardedBy("this") 1791 @Nullable 1792 private SystemEmergencyHelper mEmergencyCallHelper; 1793 1794 @GuardedBy("this") 1795 private boolean mSystemReady; 1796 SystemInjector(Context context, SystemUserInfoHelper userInfoHelper)1797 SystemInjector(Context context, SystemUserInfoHelper userInfoHelper) { 1798 mContext = context; 1799 1800 mUserInfoHelper = userInfoHelper; 1801 mLocationSettings = new LocationSettings(context); 1802 mAlarmHelper = new SystemAlarmHelper(context); 1803 mAppOpsHelper = new SystemAppOpsHelper(context); 1804 mLocationPermissionsHelper = new SystemLocationPermissionsHelper(context, 1805 mAppOpsHelper); 1806 mSettingsHelper = new SystemSettingsHelper(context); 1807 mAppForegroundHelper = new SystemAppForegroundHelper(context); 1808 mLocationPowerSaveModeHelper = new SystemLocationPowerSaveModeHelper(context); 1809 mScreenInteractiveHelper = new SystemScreenInteractiveHelper(context); 1810 mDeviceStationaryHelper = new SystemDeviceStationaryHelper(); 1811 mDeviceIdleHelper = new SystemDeviceIdleHelper(context); 1812 mLocationUsageLogger = new LocationUsageLogger(); 1813 mPackageResetHelper = new SystemPackageResetHelper(context); 1814 } 1815 onSystemReady()1816 synchronized void onSystemReady() { 1817 mUserInfoHelper.onSystemReady(); 1818 mAppOpsHelper.onSystemReady(); 1819 mLocationPermissionsHelper.onSystemReady(); 1820 mSettingsHelper.onSystemReady(); 1821 mAppForegroundHelper.onSystemReady(); 1822 mLocationPowerSaveModeHelper.onSystemReady(); 1823 mScreenInteractiveHelper.onSystemReady(); 1824 mDeviceStationaryHelper.onSystemReady(); 1825 mDeviceIdleHelper.onSystemReady(); 1826 1827 if (mEmergencyCallHelper != null) { 1828 mEmergencyCallHelper.onSystemReady(); 1829 } 1830 1831 mSystemReady = true; 1832 } 1833 1834 @Override getUserInfoHelper()1835 public UserInfoHelper getUserInfoHelper() { 1836 return mUserInfoHelper; 1837 } 1838 1839 @Override getLocationSettings()1840 public LocationSettings getLocationSettings() { 1841 return mLocationSettings; 1842 } 1843 1844 @Override getAlarmHelper()1845 public AlarmHelper getAlarmHelper() { 1846 return mAlarmHelper; 1847 } 1848 1849 @Override getAppOpsHelper()1850 public AppOpsHelper getAppOpsHelper() { 1851 return mAppOpsHelper; 1852 } 1853 1854 @Override getLocationPermissionsHelper()1855 public LocationPermissionsHelper getLocationPermissionsHelper() { 1856 return mLocationPermissionsHelper; 1857 } 1858 1859 @Override getSettingsHelper()1860 public SettingsHelper getSettingsHelper() { 1861 return mSettingsHelper; 1862 } 1863 1864 @Override getAppForegroundHelper()1865 public AppForegroundHelper getAppForegroundHelper() { 1866 return mAppForegroundHelper; 1867 } 1868 1869 @Override getLocationPowerSaveModeHelper()1870 public LocationPowerSaveModeHelper getLocationPowerSaveModeHelper() { 1871 return mLocationPowerSaveModeHelper; 1872 } 1873 1874 @Override getScreenInteractiveHelper()1875 public ScreenInteractiveHelper getScreenInteractiveHelper() { 1876 return mScreenInteractiveHelper; 1877 } 1878 1879 @Override getDeviceStationaryHelper()1880 public DeviceStationaryHelper getDeviceStationaryHelper() { 1881 return mDeviceStationaryHelper; 1882 } 1883 1884 @Override getDeviceIdleHelper()1885 public DeviceIdleHelper getDeviceIdleHelper() { 1886 return mDeviceIdleHelper; 1887 } 1888 1889 @Override getEmergencyHelper()1890 public synchronized EmergencyHelper getEmergencyHelper() { 1891 if (mEmergencyCallHelper == null) { 1892 mEmergencyCallHelper = new SystemEmergencyHelper(mContext); 1893 if (mSystemReady) { 1894 mEmergencyCallHelper.onSystemReady(); 1895 } 1896 } 1897 1898 return mEmergencyCallHelper; 1899 } 1900 1901 @Override getLocationUsageLogger()1902 public LocationUsageLogger getLocationUsageLogger() { 1903 return mLocationUsageLogger; 1904 } 1905 1906 @Override getPackageResetHelper()1907 public PackageResetHelper getPackageResetHelper() { 1908 return mPackageResetHelper; 1909 } 1910 } 1911 } 1912