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