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