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