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