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