19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.server; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackbornimport android.app.AppOpsManager; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.PendingIntent; 2138389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Leaseimport android.content.BroadcastReceiver; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 2538389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Leaseimport android.content.IntentFilter; 266fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.content.pm.ApplicationInfo; 27fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamiltonimport android.content.pm.PackageInfo; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.content.pm.PackageManager.NameNotFoundException; 30fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamiltonimport android.content.pm.ResolveInfo; 31fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamiltonimport android.content.pm.Signature; 32628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwoodimport android.content.res.Resources; 33bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsuimport android.database.ContentObserver; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Address; 3503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwoodimport android.location.Criteria; 3634901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwoodimport android.location.GeocoderParams; 376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.location.Geofence; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.IGpsStatusListener; 3915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwoodimport android.location.IGpsStatusProvider; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.ILocationListener; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.ILocationManager; 4222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.location.INetInitiatedListener; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Location; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationManager; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationProvider; 466fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.location.LocationRequest; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 513d12b51ee38537f6760a833618948f936e75561dMike Lockwoodimport android.os.Looper; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.PowerManager; 54e932f7f2a47b770c636443d411436bd29cc4bb43Mike Lockwoodimport android.os.Process; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.os.SystemClock; 575ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackbornimport android.os.UserHandle; 587e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackbornimport android.os.WorkSource; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 618a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 62e97ae40dffe7d7f8917c51c4f3f6c1b18c238565Mike Lockwoodimport com.android.internal.content.PackageMonitor; 636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport com.android.internal.location.ProviderProperties; 646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport com.android.internal.location.ProviderRequest; 658d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackbornimport com.android.internal.os.BackgroundThread; 661af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport com.android.server.location.FlpHardwareProvider; 671af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport com.android.server.location.FusedProxy; 6843e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.GeocoderProxy; 698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport com.android.server.location.GeofenceProxy; 70e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pellyimport com.android.server.location.GeofenceManager; 7143e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.GpsLocationProvider; 724035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pellyimport com.android.server.location.LocationBlacklist; 7374fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pellyimport com.android.server.location.LocationFudger; 7443e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.LocationProviderInterface; 7543e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.LocationProviderProxy; 7643e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.MockProvider; 7743e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.PassiveProvider; 7843e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwood 7943e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.io.FileDescriptor; 8043e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.io.PrintWriter; 8143e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.ArrayList; 826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport java.util.Arrays; 8343e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.HashMap; 8443e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.HashSet; 8543e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.List; 8643e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.Map; 8743e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.Set; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The service class that manages LocationProviders and issues location 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * updates and alerts. 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 935cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Leasepublic class LocationManagerService extends ILocationManager.Stub { 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "LocationManagerService"; 95f79811e7b9611066b3ca2df3ceea07bdd99597e9JP Abgrall public static final boolean D = Log.isLoggable(TAG, Log.DEBUG); 966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final String WAKELOCK_KEY = TAG; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease // Location resolution level: no location data whatsoever 10037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private static final int RESOLUTION_LEVEL_NONE = 0; 10137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease // Location resolution level: coarse location data only 10237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private static final int RESOLUTION_LEVEL_COARSE = 1; 10337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease // Location resolution level: fine location data 10437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private static final int RESOLUTION_LEVEL_FINE = 2; 10537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_MOCK_LOCATION = 1076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly android.Manifest.permission.ACCESS_MOCK_LOCATION; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_LOCATION_EXTRA_COMMANDS = 1096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly android.Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS; 110275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood private static final String INSTALL_LOCATION_PROVIDER = 1116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly android.Manifest.permission.INSTALL_LOCATION_PROVIDER; 1126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1136fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final String NETWORK_LOCATION_SERVICE_ACTION = 11439062ddff24ce2a3e3a61ba1a087363842f9d1aeStan Chesnutt "com.android.location.service.v3.NetworkLocationProvider"; 1156fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final String FUSED_LOCATION_SERVICE_ACTION = 1166fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly "com.android.location.service.FusedLocationProvider"; 1176fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final int MSG_LOCATION_CHANGED = 1; 1196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1201b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie private static final long NANOS_PER_MILLI = 1000000L; 1211b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie 1220b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie // The maximum interval a location request can have and still be considered "high power". 1230b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie private static final long HIGH_POWER_INTERVAL_MS = 5 * 60 * 1000; 1240b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie 125f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly // Location Providers may sometimes deliver location updates 126f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly // slightly faster that requested - provide grace period so 127f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly // we don't unnecessarily filter events that are otherwise on 128f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly // time 1296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final int MAX_PROVIDER_SCHEDULING_JITTER_MS = 100; 130f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly 1316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final LocationRequest DEFAULT_LOCATION_REQUEST = new LocationRequest(); 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final Context mContext; 134a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn private final AppOpsManager mAppOps; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // used internally for synchronization 1376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final Object mLock = new Object(); 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1395cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease // --- fields below are final after systemReady() --- 14074fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pelly private LocationFudger mLocationFudger; 1416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private GeofenceManager mGeofenceManager; 1426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private PackageManager mPackageManager; 1430aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease private PowerManager mPowerManager; 144628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood private GeocoderProxy mGeocodeProvider; 14515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private IGpsStatusProvider mGpsStatusProvider; 14622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private INetInitiatedListener mNetInitiatedListener; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private LocationWorkerHandler mLocationHandler; 1484035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly private PassiveProvider mPassiveProvider; // track passive provider for special cases 1494035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly private LocationBlacklist mBlacklist; 1506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // --- fields below are protected by mLock --- 1526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Set of providers that are explicitly enabled 1536fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final Set<String> mEnabledProviders = new HashSet<String>(); 1547566c1debebe072af76411e11d96810fd1409482Mike Lockwood 1556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Set of providers that are explicitly disabled 1566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final Set<String> mDisabledProviders = new HashSet<String>(); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Mock (test) providers 1596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final HashMap<String, MockProvider> mMockProviders = 1606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new HashMap<String, MockProvider>(); 161e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 1626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // all receivers 1632f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final HashMap<Object, Receiver> mReceivers = new HashMap<Object, Receiver>(); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // currently installed providers (with mocks replacing real providers) 166d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood private final ArrayList<LocationProviderInterface> mProviders = 1676fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new ArrayList<LocationProviderInterface>(); 16815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 1696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // real providers, saved here when mocked out 1706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final HashMap<String, LocationProviderInterface> mRealProviders = 1716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new HashMap<String, LocationProviderInterface>(); 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // mapping from provider name to provider 1746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final HashMap<String, LocationProviderInterface> mProvidersByName = 1756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new HashMap<String, LocationProviderInterface>(); 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1776fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // mapping from provider name to all its UpdateRecords 1786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final HashMap<String, ArrayList<UpdateRecord>> mRecordsByProvider = 1796fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new HashMap<String, ArrayList<UpdateRecord>>(); 1806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // mapping from provider name to last known location 1826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final HashMap<String, Location> mLastLocation = new HashMap<String, Location>(); 1837e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn 1841b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie // same as mLastLocation, but is not updated faster than LocationFudger.FASTEST_INTERVAL_MS. 1851b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie // locations stored here are not fudged for coarse permissions. 1861b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie private final HashMap<String, Location> mLastLocationCoarseInterval = 1871b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie new HashMap<String, Location>(); 1881b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie 1896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // all providers that operate over proxy, for authorizing incoming location 1906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final ArrayList<LocationProviderProxy> mProxyProviders = 1916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new ArrayList<LocationProviderProxy>(); 1926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 19338389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease // current active user on the device - other users are denied location data 19438389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease private int mCurrentUserId = UserHandle.USER_OWNER; 19538389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease 1966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public LocationManagerService(Context context) { 1976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly super(); 1986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mContext = context; 199a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn mAppOps = (AppOpsManager)context.getSystemService(Context.APP_OPS_SERVICE); 2006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 2016fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "Constructed"); 2026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 2036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // most startup is deferred until systemReady() 2046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 2056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 206a00271533f639c8ed36429c663889ac9f654bc72Svetoslav Ganov public void systemRunning() { 2075cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease synchronized (mLock) { 2085cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease if (D) Log.d(TAG, "systemReady()"); 2096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 2105cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease // fetch package manager 2115cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease mPackageManager = mContext.getPackageManager(); 2126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 2130aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease // fetch power manager 2140aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 2156fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 2165cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease // prepare worker thread 2178d044e8bc287c1a567d82aedbe30085b011544c3Dianne Hackborn mLocationHandler = new LocationWorkerHandler(BackgroundThread.get().getLooper()); 2186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 2195cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease // prepare mLocationHandler's dependents 2205cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease mLocationFudger = new LocationFudger(mContext, mLocationHandler); 2215cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease mBlacklist = new LocationBlacklist(mContext, mLocationHandler); 2225cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease mBlacklist.init(); 2235cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease mGeofenceManager = new GeofenceManager(mContext, mBlacklist); 224bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu 225c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn // Monitor for app ops mode changes. 2269bb0ee9131b0fa8cf2720f200575ba2ede48a65cDianne Hackborn AppOpsManager.OnOpChangedListener callback 2279bb0ee9131b0fa8cf2720f200575ba2ede48a65cDianne Hackborn = new AppOpsManager.OnOpChangedInternalListener() { 2289bb0ee9131b0fa8cf2720f200575ba2ede48a65cDianne Hackborn public void onOpChanged(int op, String packageName) { 229c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn synchronized (mLock) { 2301304f4ae32cf7121fe11e95f2a7151ea208b6ccaDianne Hackborn for (Receiver receiver : mReceivers.values()) { 2311304f4ae32cf7121fe11e95f2a7151ea208b6ccaDianne Hackborn receiver.updateMonitoring(true); 2321304f4ae32cf7121fe11e95f2a7151ea208b6ccaDianne Hackborn } 233c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn applyAllProviderRequirementsLocked(); 234c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 235c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 236c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn }; 237c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn mAppOps.startWatchingMode(AppOpsManager.OP_COARSE_LOCATION, null, callback); 238c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 2395cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease // prepare providers 2406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly loadProvidersLocked(); 2415cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease updateProvidersLocked(); 2426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 243bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu 2446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // listen for settings changes 245bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu mContext.getContentResolver().registerContentObserver( 24675defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu Settings.Secure.getUriFor(Settings.Secure.LOCATION_PROVIDERS_ALLOWED), true, 247bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu new ContentObserver(mLocationHandler) { 2485cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease @Override 2495cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease public void onChange(boolean selfChange) { 2505cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease synchronized (mLock) { 2515cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease updateProvidersLocked(); 2525cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease } 2535cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease } 2545cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease }, UserHandle.USER_ALL); 2555cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease mPackageMonitor.register(mContext, mLocationHandler.getLooper(), true); 256bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu 25738389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease // listen for user change 25838389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease IntentFilter intentFilter = new IntentFilter(); 25938389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease intentFilter.addAction(Intent.ACTION_USER_SWITCHED); 26038389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease 26138389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease mContext.registerReceiverAsUser(new BroadcastReceiver() { 26238389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease @Override 26338389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease public void onReceive(Context context, Intent intent) { 26438389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease String action = intent.getAction(); 26538389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease if (Intent.ACTION_USER_SWITCHED.equals(action)) { 26638389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); 26738389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease } 26838389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease } 2695cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease }, UserHandle.ALL, intentFilter, null, mLocationHandler); 2706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 2716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 272fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton private void ensureFallbackFusedProviderPresentLocked(ArrayList<String> pkgs) { 273fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton PackageManager pm = mContext.getPackageManager(); 274fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton String systemPackageName = mContext.getPackageName(); 275fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton ArrayList<HashSet<Signature>> sigSets = ServiceWatcher.getSignatureSets(mContext, pkgs); 276fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 277fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton List<ResolveInfo> rInfos = pm.queryIntentServicesAsUser( 278fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton new Intent(FUSED_LOCATION_SERVICE_ACTION), 279fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton PackageManager.GET_META_DATA, mCurrentUserId); 280fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton for (ResolveInfo rInfo : rInfos) { 281fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton String packageName = rInfo.serviceInfo.packageName; 282fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 283fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // Check that the signature is in the list of supported sigs. If it's not in 284fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // this list the standard provider binding logic won't bind to it. 285fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton try { 286fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton PackageInfo pInfo; 287fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton pInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); 288fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (!ServiceWatcher.isSignatureMatch(pInfo.signatures, sigSets)) { 289fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton Log.w(TAG, packageName + " resolves service " + FUSED_LOCATION_SERVICE_ACTION + 290fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton ", but has wrong signature, ignoring"); 291fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton continue; 292fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 293fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } catch (NameNotFoundException e) { 294fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton Log.e(TAG, "missing package: " + packageName); 295fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton continue; 296fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 297fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 298fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // Get the version info 299fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (rInfo.serviceInfo.metaData == null) { 300fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton Log.w(TAG, "Found fused provider without metadata: " + packageName); 301fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton continue; 302fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 303fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 304fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton int version = rInfo.serviceInfo.metaData.getInt( 305fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton ServiceWatcher.EXTRA_SERVICE_VERSION, -1); 306fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (version == 0) { 307fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // This should be the fallback fused location provider. 308fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 309fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // Make sure it's in the system partition. 310fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if ((rInfo.serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 311fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (D) Log.d(TAG, "Fallback candidate not in /system: " + packageName); 312fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton continue; 313fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 314fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 315fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // Check that the fallback is signed the same as the OS 316fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // as a proxy for coreApp="true" 317fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (pm.checkSignatures(systemPackageName, packageName) 318fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton != PackageManager.SIGNATURE_MATCH) { 319fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (D) Log.d(TAG, "Fallback candidate not signed the same as system: " 320fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton + packageName); 321fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton continue; 322fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 323fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 324fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // Found a valid fallback. 325fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (D) Log.d(TAG, "Found fallback provider: " + packageName); 326fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton return; 327fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } else { 328fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (D) Log.d(TAG, "Fallback candidate not version 0: " + packageName); 329fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 330fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 331fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 332fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton throw new IllegalStateException("Unable to find a fused location provider that is in the " 333fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton + "system partition with version 0 and signed with the platform certificate. " 334fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton + "Such a package is needed to provide a default fused location provider in the " 335fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton + "event that no other fused location provider has been installed or is currently " 336fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton + "available. For example, coreOnly boot mode when decrypting the data " 337fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton + "partition. The fallback must also be marked coreApp=\"true\" in the manifest"); 338fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 339fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 3406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void loadProvidersLocked() { 3415c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease // create a passive location provider, which is always enabled 3425c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease PassiveProvider passiveProvider = new PassiveProvider(this); 3435c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease addProviderLocked(passiveProvider); 3445c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease mEnabledProviders.add(passiveProvider.getName()); 3455c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease mPassiveProvider = passiveProvider; 3468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // Create a gps location provider 3478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this, 3488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mLocationHandler.getLooper()); 3495c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease 3506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (GpsLocationProvider.isSupported()) { 3516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mGpsStatusProvider = gpsProvider.getGpsStatusProvider(); 3526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mNetInitiatedListener = gpsProvider.getNetInitiatedListener(); 3536fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly addProviderLocked(gpsProvider); 3546fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mRealProviders.put(LocationManager.GPS_PROVIDER, gpsProvider); 3556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3576fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly /* 3586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Load package name(s) containing location provider support. 3596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly These packages can contain services implementing location providers: 3606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Geocoder Provider, Network Location Provider, and 3616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Fused Location Provider. They will each be searched for 3626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly service components implementing these providers. 3636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly The location framework also has support for installation 3646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly of new location providers at run-time. The new package does not 3656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly have to be explicitly listed here, however it must have a signature 3666fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly that matches the signature of at least one package on this list. 3676fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly */ 3686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Resources resources = mContext.getResources(); 3696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<String> providerPackageNames = new ArrayList<String>(); 370fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton String[] pkgs = resources.getStringArray( 3716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly com.android.internal.R.array.config_locationProviderPackageNames); 372fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (D) Log.d(TAG, "certificates for location providers pulled from: " + 373fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton Arrays.toString(pkgs)); 374fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (pkgs != null) providerPackageNames.addAll(Arrays.asList(pkgs)); 375fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 376fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton ensureFallbackFusedProviderPresentLocked(providerPackageNames); 3776fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 3786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // bind to network provider 3796fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderProxy networkProvider = LocationProviderProxy.createAndBind( 3806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mContext, 3816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationManager.NETWORK_PROVIDER, 3826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly NETWORK_LOCATION_SERVICE_ACTION, 383c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun com.android.internal.R.bool.config_enableNetworkLocationOverlay, 384c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun com.android.internal.R.string.config_networkLocationProviderPackageName, 385c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun com.android.internal.R.array.config_locationProviderPackageNames, 386c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun mLocationHandler); 3876fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (networkProvider != null) { 3886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mRealProviders.put(LocationManager.NETWORK_PROVIDER, networkProvider); 3896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mProxyProviders.add(networkProvider); 3906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly addProviderLocked(networkProvider); 3916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 3926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Slog.w(TAG, "no network location provider found"); 3936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 3946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 3956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // bind to fused provider 3966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderProxy fusedLocationProvider = LocationProviderProxy.createAndBind( 3976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mContext, 3986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationManager.FUSED_PROVIDER, 3996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly FUSED_LOCATION_SERVICE_ACTION, 400c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun com.android.internal.R.bool.config_enableFusedLocationOverlay, 401c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun com.android.internal.R.string.config_fusedLocationProviderPackageName, 402c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun com.android.internal.R.array.config_locationProviderPackageNames, 403c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun mLocationHandler); 4046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (fusedLocationProvider != null) { 4056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly addProviderLocked(fusedLocationProvider); 4066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mProxyProviders.add(fusedLocationProvider); 4076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mEnabledProviders.add(fusedLocationProvider.getName()); 408c3575188c2f2ad27b1f03b9b9c0705a686a5e42fKenny Root mRealProviders.put(LocationManager.FUSED_PROVIDER, fusedLocationProvider); 4096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 4106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Slog.e(TAG, "no fused location provider found", 4116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new IllegalStateException("Location service needs a fused location provider")); 4126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // bind to geocoder provider 415c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun mGeocodeProvider = GeocoderProxy.createAndBind(mContext, 416c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun com.android.internal.R.bool.config_enableGeocoderOverlay, 417c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun com.android.internal.R.string.config_geocoderProviderPackageName, 418c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun com.android.internal.R.array.config_locationProviderPackageNames, 41903cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease mLocationHandler); 4206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (mGeocodeProvider == null) { 4216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Slog.e(TAG, "no geocoder provider found"); 4226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 4238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 4241af4b0280af406cfc7eb46810f6b76e57b983e11destradaa // bind to fused provider 4251af4b0280af406cfc7eb46810f6b76e57b983e11destradaa FlpHardwareProvider flpHardwareProvider = FlpHardwareProvider.getInstance(mContext); 4261af4b0280af406cfc7eb46810f6b76e57b983e11destradaa FusedProxy fusedProxy = FusedProxy.createAndBind( 4271af4b0280af406cfc7eb46810f6b76e57b983e11destradaa mContext, 4281af4b0280af406cfc7eb46810f6b76e57b983e11destradaa mLocationHandler, 42964be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa flpHardwareProvider.getLocationHardware(), 43064be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa com.android.internal.R.bool.config_enableFusedLocationOverlay, 43164be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa com.android.internal.R.string.config_fusedLocationProviderPackageName, 43264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa com.android.internal.R.array.config_locationProviderPackageNames); 4331af4b0280af406cfc7eb46810f6b76e57b983e11destradaa if(fusedProxy == null) { 4341af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Slog.e(TAG, "No FusedProvider found."); 4351af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 4360682809ad08db284d7110aab44108d5e9c310e6bdestradaa 4370682809ad08db284d7110aab44108d5e9c310e6bdestradaa // bind to geofence provider 4380682809ad08db284d7110aab44108d5e9c310e6bdestradaa GeofenceProxy provider = GeofenceProxy.createAndBind(mContext, 4390682809ad08db284d7110aab44108d5e9c310e6bdestradaa com.android.internal.R.bool.config_enableGeofenceOverlay, 4400682809ad08db284d7110aab44108d5e9c310e6bdestradaa com.android.internal.R.string.config_geofenceProviderPackageName, 4410682809ad08db284d7110aab44108d5e9c310e6bdestradaa com.android.internal.R.array.config_locationProviderPackageNames, 4420682809ad08db284d7110aab44108d5e9c310e6bdestradaa mLocationHandler, 4430682809ad08db284d7110aab44108d5e9c310e6bdestradaa gpsProvider.getGpsGeofenceProxy(), 4440682809ad08db284d7110aab44108d5e9c310e6bdestradaa flpHardwareProvider.getGeofenceHardware()); 4450682809ad08db284d7110aab44108d5e9c310e6bdestradaa if (provider == null) { 4460682809ad08db284d7110aab44108d5e9c310e6bdestradaa Slog.e(TAG, "no geofence provider found"); 4470682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 4486fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 4499637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 45138389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease * Called when the device's active user changes. 45238389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease * @param userId the new active user's UserId 45338389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease */ 45438389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease private void switchUser(int userId) { 45583762d22c9bde92d412cf5a263a228d705606721Victoria Lease mBlacklist.switchUser(userId); 45603cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease mLocationHandler.removeMessages(MSG_LOCATION_CHANGED); 45738389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease synchronized (mLock) { 458b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease mLastLocation.clear(); 4591b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie mLastLocationCoarseInterval.clear(); 460b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease for (LocationProviderInterface p : mProviders) { 461b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease updateProviderListenersLocked(p.getName(), false, mCurrentUserId); 462b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 46338389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease mCurrentUserId = userId; 464b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease updateProvidersLocked(); 46538389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease } 46638389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease } 46738389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease 46838389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease /** 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A wrapper class holding either an ILocationListener or a PendingIntent to receive 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * location updates. 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 47248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private final class Receiver implements IBinder.DeathRecipient, PendingIntent.OnFinished { 4736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int mUid; // uid of receiver 4746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int mPid; // pid of receiver 4756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final String mPackageName; // package name of receiver 47637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease final int mAllowedResolutionLevel; // resolution level allowed to receiver 4776fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ILocationListener mListener; 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PendingIntent mPendingIntent; 48082edc9b3482307a8e93655aadabb4f9ad24efe46David Christie final WorkSource mWorkSource; // WorkSource for battery blame, or null to assign to caller. 48140e5782f5c79ea660b98b8875086f592367bc1d2David Christie final boolean mHideFromAppOps; // True if AppOps should not monitor this receiver. 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Object mKey; 4836fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 4842f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>(); 485f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly 4860b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie // True if app ops has started monitoring this receiver for locations. 4871304f4ae32cf7121fe11e95f2a7151ea208b6ccaDianne Hackborn boolean mOpMonitoring; 4880b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie // True if app ops has started monitoring this receiver for high power (gps) locations. 4890b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie boolean mOpHighPowerMonitoring; 49048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood int mPendingBroadcasts; 4910aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease PowerManager.WakeLock mWakeLock; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Receiver(ILocationListener listener, PendingIntent intent, int pid, int uid, 49440e5782f5c79ea660b98b8875086f592367bc1d2David Christie String packageName, WorkSource workSource, boolean hideFromAppOps) { 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingIntent = intent; 4976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (listener != null) { 4986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mKey = listener.asBinder(); 4996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 5006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mKey = intent; 5016fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 50237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease mAllowedResolutionLevel = getAllowedResolutionLevel(pid, uid); 5036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mUid = uid; 5046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mPid = pid; 5056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mPackageName = packageName; 50682edc9b3482307a8e93655aadabb4f9ad24efe46David Christie if (workSource != null && workSource.size() <= 0) { 50782edc9b3482307a8e93655aadabb4f9ad24efe46David Christie workSource = null; 50882edc9b3482307a8e93655aadabb4f9ad24efe46David Christie } 50982edc9b3482307a8e93655aadabb4f9ad24efe46David Christie mWorkSource = workSource; 51040e5782f5c79ea660b98b8875086f592367bc1d2David Christie mHideFromAppOps = hideFromAppOps; 5110aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease 5121304f4ae32cf7121fe11e95f2a7151ea208b6ccaDianne Hackborn updateMonitoring(true); 5131304f4ae32cf7121fe11e95f2a7151ea208b6ccaDianne Hackborn 5140aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease // construct/configure wakelock 5150aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); 51682edc9b3482307a8e93655aadabb4f9ad24efe46David Christie if (workSource == null) { 51782edc9b3482307a8e93655aadabb4f9ad24efe46David Christie workSource = new WorkSource(mUid, mPackageName); 51882edc9b3482307a8e93655aadabb4f9ad24efe46David Christie } 51982edc9b3482307a8e93655aadabb4f9ad24efe46David Christie mWakeLock.setWorkSource(workSource); 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean equals(Object otherObj) { 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (otherObj instanceof Receiver) { 5256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return mKey.equals(((Receiver)otherObj).mKey); 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int hashCode() { 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mKey.hashCode(); 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5343681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 5376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly StringBuilder s = new StringBuilder(); 5386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append("Reciever["); 5396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(Integer.toHexString(System.identityHashCode(this))); 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 5416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(" listener"); 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(" intent"); 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (String p : mUpdateRecords.keySet()) { 5466fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(" ").append(mUpdateRecords.get(p).toString()); 5476fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 5486fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append("]"); 5496fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return s.toString(); 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 55215b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie /** 55315b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie * Update AppOp monitoring for this receiver. 55415b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie * 55515b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie * @param allow If true receiver is currently active, if false it's been removed. 55615b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie */ 5571304f4ae32cf7121fe11e95f2a7151ea208b6ccaDianne Hackborn public void updateMonitoring(boolean allow) { 55840e5782f5c79ea660b98b8875086f592367bc1d2David Christie if (mHideFromAppOps) { 55940e5782f5c79ea660b98b8875086f592367bc1d2David Christie return; 56040e5782f5c79ea660b98b8875086f592367bc1d2David Christie } 56140e5782f5c79ea660b98b8875086f592367bc1d2David Christie 56215b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie boolean requestingLocation = false; 56315b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie boolean requestingHighPowerLocation = false; 56415b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie if (allow) { 56515b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie // See if receiver has any enabled update records. Also note if any update records 56615b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie // are high power (has a high power provider with an interval under a threshold). 56715b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie for (UpdateRecord updateRecord : mUpdateRecords.values()) { 56815b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie if (isAllowedByCurrentUserSettingsLocked(updateRecord.mProvider)) { 56915b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie requestingLocation = true; 57015b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie LocationProviderInterface locationProvider 57115b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie = mProvidersByName.get(updateRecord.mProvider); 57215b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie ProviderProperties properties = locationProvider != null 57315b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie ? locationProvider.getProperties() : null; 57415b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie if (properties != null 57515b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie && properties.mPowerRequirement == Criteria.POWER_HIGH 57615b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie && updateRecord.mRequest.getInterval() < HIGH_POWER_INTERVAL_MS) { 57715b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie requestingHighPowerLocation = true; 57815b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie break; 57915b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie } 58015b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie } 58115b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie } 58215b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie } 58315b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie 5840b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie // First update monitoring of any location request (including high power). 58515b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie mOpMonitoring = updateMonitoring( 58615b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie requestingLocation, 58715b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie mOpMonitoring, 5880b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie AppOpsManager.OP_MONITOR_LOCATION); 5890b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie 5900b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie // Now update monitoring of high power requests only. 591c750c1fb83fbdec895e236dda7207db4da14ec49David Christie boolean wasHighPowerMonitoring = mOpHighPowerMonitoring; 59215b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie mOpHighPowerMonitoring = updateMonitoring( 59315b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie requestingHighPowerLocation, 59415b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie mOpHighPowerMonitoring, 5950b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie AppOpsManager.OP_MONITOR_HIGH_POWER_LOCATION); 596c750c1fb83fbdec895e236dda7207db4da14ec49David Christie if (mOpHighPowerMonitoring != wasHighPowerMonitoring) { 59715b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie // Send an intent to notify that a high power request has been added/removed. 598c750c1fb83fbdec895e236dda7207db4da14ec49David Christie Intent intent = new Intent(LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION); 599c750c1fb83fbdec895e236dda7207db4da14ec49David Christie mContext.sendBroadcastAsUser(intent, UserHandle.ALL); 600c750c1fb83fbdec895e236dda7207db4da14ec49David Christie } 6010b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie } 6020b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie 6030b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie /** 6040b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie * Update AppOps monitoring for a single location request and op type. 6050b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie * 6060b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie * @param allowMonitoring True if monitoring is allowed for this request/op. 6070b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie * @param currentlyMonitoring True if AppOps is currently monitoring this request/op. 6080b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie * @param op AppOps code for the op to update. 6090b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie * @return True if monitoring is on for this request/op after updating. 6100b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie */ 6110b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie private boolean updateMonitoring(boolean allowMonitoring, boolean currentlyMonitoring, 6120b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie int op) { 6130b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie if (!currentlyMonitoring) { 6140b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie if (allowMonitoring) { 6150b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie return mAppOps.startOpNoThrow(op, mUid, mPackageName) 6160b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie == AppOpsManager.MODE_ALLOWED; 6171304f4ae32cf7121fe11e95f2a7151ea208b6ccaDianne Hackborn } 6181304f4ae32cf7121fe11e95f2a7151ea208b6ccaDianne Hackborn } else { 6190b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie if (!allowMonitoring || mAppOps.checkOpNoThrow(op, mUid, mPackageName) 6200b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie != AppOpsManager.MODE_ALLOWED) { 6210b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie mAppOps.finishOp(op, mUid, mPackageName); 6220b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie return false; 6231304f4ae32cf7121fe11e95f2a7151ea208b6ccaDianne Hackborn } 6241304f4ae32cf7121fe11e95f2a7151ea208b6ccaDianne Hackborn } 6250b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie 6260b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie return currentlyMonitoring; 6271304f4ae32cf7121fe11e95f2a7151ea208b6ccaDianne Hackborn } 6281304f4ae32cf7121fe11e95f2a7151ea208b6ccaDianne Hackborn 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isListener() { 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mListener != null; 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isPendingIntent() { 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPendingIntent != null; 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ILocationListener getListener() { 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mListener; 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("Request for non-existent listener"); 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean callStatusChangedLocked(String provider, int status, Bundle extras) { 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 64748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 64848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 64948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 65048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onStatusChanged(provider, status, extras); 651e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // call this after broadcasting so we do not increment 652e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // if we throw an exeption. 653e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly incrementPendingBroadcastsLocked(); 65448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent statusChanged = new Intent(); 66061ecb02f544d9abd098506afb50cb514818f4eb4Victoria Lease statusChanged.putExtras(new Bundle(extras)); 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project statusChanged.putExtra(LocationManager.KEY_STATUS_CHANGED, status); 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 66348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 66448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 66548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 6666c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn mPendingIntent.send(mContext, 0, statusChanged, this, mLocationHandler, 66737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease getResolutionPermission(mAllowedResolutionLevel)); 66848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 66948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 67048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 67148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean callLocationChangedLocked(Location location) { 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 68248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 68348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 68448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 6856c5406acd72eed31f2b4e12f5eddc0e2d2a951e2Dianne Hackborn mListener.onLocationChanged(new Location(location)); 686e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // call this after broadcasting so we do not increment 687e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // if we throw an exeption. 688e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly incrementPendingBroadcastsLocked(); 68948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent locationChanged = new Intent(); 69561ecb02f544d9abd098506afb50cb514818f4eb4Victoria Lease locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED, new Location(location)); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 69748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 69848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 69948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 7006c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn mPendingIntent.send(mContext, 0, locationChanged, this, mLocationHandler, 70137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease getResolutionPermission(mAllowedResolutionLevel)); 70248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 70348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 70448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 70548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 70648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } catch (PendingIntent.CanceledException e) { 70748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return false; 70848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 70948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 71048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return true; 71148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 71248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 71348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public boolean callProviderEnabledLocked(String provider, boolean enabled) { 71415b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie // First update AppOp monitoring. 71515b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie // An app may get/lose location access as providers are enabled/disabled. 71615b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie updateMonitoring(true); 71715b3191f913091e686e9e1f3708b7f8240a07e8bDavid Christie 71848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mListener != null) { 71948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood try { 72048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 72148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 72248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 72348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (enabled) { 72448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onProviderEnabled(provider); 72548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } else { 72648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onProviderDisabled(provider); 72748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 728e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // call this after broadcasting so we do not increment 729e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // if we throw an exeption. 730e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly incrementPendingBroadcastsLocked(); 73148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 73248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } catch (RemoteException e) { 73348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return false; 73448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 73548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } else { 73648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood Intent providerIntent = new Intent(); 73748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood providerIntent.putExtra(LocationManager.KEY_PROVIDER_ENABLED, enabled); 73848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood try { 73948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 74048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 74148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 7426c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn mPendingIntent.send(mContext, 0, providerIntent, this, mLocationHandler, 74337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease getResolutionPermission(mAllowedResolutionLevel)); 74448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 74548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 74648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 74748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 755f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly @Override 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 7576fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "Location listener died"); 7586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 7592f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeUpdatesLocked(this); 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 76248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 7630aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease clearPendingBroadcastsLocked(); 76448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 76548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 76648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 767e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 76848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public void onSendFinished(PendingIntent pendingIntent, Intent intent, 76948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood int resultCode, String resultData, Bundle resultExtras) { 7700528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (this) { 7710528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood decrementPendingBroadcastsLocked(); 7720528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 77348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 77448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 7750528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // this must be called while synchronized by caller in a synchronized block 77648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // containing the sending of the broadcaset 77748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private void incrementPendingBroadcastsLocked() { 77848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mPendingBroadcasts++ == 0) { 7790aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease mWakeLock.acquire(); 78048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 78148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 78248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 7830528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private void decrementPendingBroadcastsLocked() { 7840528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (--mPendingBroadcasts == 0) { 7850aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease if (mWakeLock.isHeld()) { 7860aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease mWakeLock.release(); 7870aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease } 7880aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease } 7890aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease } 7900aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease 7910aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease public void clearPendingBroadcastsLocked() { 7920aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease if (mPendingBroadcasts > 0) { 7930aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease mPendingBroadcasts = 0; 7940aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease if (mWakeLock.isHeld()) { 7950aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease mWakeLock.release(); 7960aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease } 79748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 79848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 79948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 80048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 801e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 80248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public void locationCallbackFinished(ILocationListener listener) { 803f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn //Do not use getReceiverLocked here as that will add the ILocationListener to 804080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //the receiver list if it is not found. If it is not found then the 805080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //LocationListener was removed when it had a pending broadcast and should 806080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //not be added back. 807f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn synchronized (mLock) { 808f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn IBinder binder = listener.asBinder(); 809f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn Receiver receiver = mReceivers.get(binder); 810f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn if (receiver != null) { 811f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn synchronized (receiver) { 812f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn // so wakelock calls will succeed 813f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn long identity = Binder.clearCallingIdentity(); 814f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn receiver.decrementPendingBroadcastsLocked(); 815f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn Binder.restoreCallingIdentity(identity); 816f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn } 817f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn } 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void addProviderLocked(LocationProviderInterface provider) { 82215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProviders.add(provider); 82315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProvidersByName.put(provider.getName(), provider); 82415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 82515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 8266fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void removeProviderLocked(LocationProviderInterface provider) { 8276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly provider.disable(); 82815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProviders.remove(provider); 82915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProvidersByName.remove(provider.getName()); 83015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 83115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 83203cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease /** 83309eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease * Returns "true" if access to the specified location provider is allowed by the current 83409eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease * user's settings. Access to all location providers is forbidden to non-location-provider 83509eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease * processes belonging to background users. 83603cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease * 83703cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease * @param provider the name of the location provider 83803cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease * @return 83903cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease */ 84009eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease private boolean isAllowedByCurrentUserSettingsLocked(String provider) { 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabledProviders.contains(provider)) { 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDisabledProviders.contains(provider)) { 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Use system settings 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver resolver = mContext.getContentResolver(); 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 850b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease return Settings.Secure.isLocationProviderEnabledForUser(resolver, provider, mCurrentUserId); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8536fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly /** 85409eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease * Returns "true" if access to the specified location provider is allowed by the specified 85509eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease * user's settings. Access to all location providers is forbidden to non-location-provider 85609eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease * processes belonging to background users. 85709eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease * 85809eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease * @param provider the name of the location provider 85909eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease * @param uid the requestor's UID 86009eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease * @return 86109eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease */ 86209eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease private boolean isAllowedByUserSettingsLocked(String provider, int uid) { 86309eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease if (UserHandle.getUserId(uid) != mCurrentUserId && !isUidALocationProvider(uid)) { 86409eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease return false; 86509eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease } 86609eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease return isAllowedByCurrentUserSettingsLocked(provider); 86709eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease } 86809eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease 86909eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease /** 87037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Returns the permission string associated with the specified resolution level. 87137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 87237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param resolutionLevel the resolution level 87337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @return the permission string 8746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly */ 87537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private String getResolutionPermission(int resolutionLevel) { 87637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease switch (resolutionLevel) { 87737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease case RESOLUTION_LEVEL_FINE: 87837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return android.Manifest.permission.ACCESS_FINE_LOCATION; 87937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease case RESOLUTION_LEVEL_COARSE: 88037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return android.Manifest.permission.ACCESS_COARSE_LOCATION; 88137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease default: 88237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return null; 8836c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn } 884da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease } 8856c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn 886da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease /** 88737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Returns the resolution level allowed to the given PID/UID pair. 88837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 88937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param pid the PID 89037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param uid the UID 89137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @return resolution level allowed to the pid/uid pair 892da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease */ 89337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private int getAllowedResolutionLevel(int pid, int uid) { 89437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (mContext.checkPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, 89537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease pid, uid) == PackageManager.PERMISSION_GRANTED) { 89637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_FINE; 89737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease } else if (mContext.checkPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION, 89837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease pid, uid) == PackageManager.PERMISSION_GRANTED) { 89937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_COARSE; 90037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease } else { 90137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_NONE; 902da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease } 9034fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease } 9044fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease 9054fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease /** 90637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Returns the resolution level allowed to the caller 90737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 90837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @return resolution level allowed to caller 90937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease */ 91037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private int getCallerAllowedResolutionLevel() { 91137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return getAllowedResolutionLevel(Binder.getCallingPid(), Binder.getCallingUid()); 91237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease } 91337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease 91437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease /** 91537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Throw SecurityException if specified resolution level is insufficient to use geofences. 91637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 91737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param allowedResolutionLevel resolution level allowed to caller 9184fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease */ 91937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private void checkResolutionLevelIsSufficientForGeofenceUse(int allowedResolutionLevel) { 92037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) { 9214fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease throw new SecurityException("Geofence usage requires ACCESS_FINE_LOCATION permission"); 9224fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease } 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 92537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease /** 92637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Return the minimum resolution level required to use the specified location provider. 92737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 92837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param provider the name of the location provider 92937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @return minimum resolution level required for provider 93037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease */ 93137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private int getMinimumResolutionLevelForProviderUse(String provider) { 9328dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease if (LocationManager.GPS_PROVIDER.equals(provider) || 9338dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease LocationManager.PASSIVE_PROVIDER.equals(provider)) { 9348dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease // gps and passive providers require FINE permission 93537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_FINE; 9368dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease } else if (LocationManager.NETWORK_PROVIDER.equals(provider) || 9378dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease LocationManager.FUSED_PROVIDER.equals(provider)) { 9388dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease // network and fused providers are ok with COARSE or FINE 93937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_COARSE; 940941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu } else { 941941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu // mock providers 942941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu LocationProviderInterface lp = mMockProviders.get(provider); 943941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu if (lp != null) { 944941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu ProviderProperties properties = lp.getProperties(); 945941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu if (properties != null) { 946941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu if (properties.mRequiresSatellite) { 947941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu // provider requiring satellites require FINE permission 94837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_FINE; 949941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu } else if (properties.mRequiresNetwork || properties.mRequiresCell) { 950941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu // provider requiring network and or cell require COARSE or FINE 95137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_COARSE; 952941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu } 953941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu } 954941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu } 9558dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease } 95637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_FINE; // if in doubt, require FINE 957da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease } 958da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease 95937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease /** 96037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Throw SecurityException if specified resolution level is insufficient to use the named 96137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * location provider. 96237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 96337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param allowedResolutionLevel resolution level allowed to caller 96437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param providerName the name of the location provider 96537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease */ 96637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private void checkResolutionLevelIsSufficientForProviderUse(int allowedResolutionLevel, 96737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease String providerName) { 96837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease int requiredResolutionLevel = getMinimumResolutionLevelForProviderUse(providerName); 96937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (allowedResolutionLevel < requiredResolutionLevel) { 97037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease switch (requiredResolutionLevel) { 97137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease case RESOLUTION_LEVEL_FINE: 97237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease throw new SecurityException("\"" + providerName + "\" location provider " + 97337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease "requires ACCESS_FINE_LOCATION permission."); 97437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease case RESOLUTION_LEVEL_COARSE: 97537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease throw new SecurityException("\"" + providerName + "\" location provider " + 97637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease "requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission."); 97737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease default: 97837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease throw new SecurityException("Insufficient permission for \"" + providerName + 97937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease "\" location provider."); 980da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease } 981da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease } 9828dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease } 9838dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease 98482edc9b3482307a8e93655aadabb4f9ad24efe46David Christie /** 98582edc9b3482307a8e93655aadabb4f9ad24efe46David Christie * Throw SecurityException if WorkSource use is not allowed (i.e. can't blame other packages 98682edc9b3482307a8e93655aadabb4f9ad24efe46David Christie * for battery). 98782edc9b3482307a8e93655aadabb4f9ad24efe46David Christie */ 98840e5782f5c79ea660b98b8875086f592367bc1d2David Christie private void checkDeviceStatsAllowed() { 98982edc9b3482307a8e93655aadabb4f9ad24efe46David Christie mContext.enforceCallingOrSelfPermission( 99082edc9b3482307a8e93655aadabb4f9ad24efe46David Christie android.Manifest.permission.UPDATE_DEVICE_STATS, null); 99182edc9b3482307a8e93655aadabb4f9ad24efe46David Christie } 99282edc9b3482307a8e93655aadabb4f9ad24efe46David Christie 99340e5782f5c79ea660b98b8875086f592367bc1d2David Christie private void checkUpdateAppOpsAllowed() { 99440e5782f5c79ea660b98b8875086f592367bc1d2David Christie mContext.enforceCallingOrSelfPermission( 99540e5782f5c79ea660b98b8875086f592367bc1d2David Christie android.Manifest.permission.UPDATE_APP_OPS_STATS, null); 99640e5782f5c79ea660b98b8875086f592367bc1d2David Christie } 99740e5782f5c79ea660b98b8875086f592367bc1d2David Christie 9985e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn public static int resolutionLevelToOp(int allowedResolutionLevel) { 99935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (allowedResolutionLevel != RESOLUTION_LEVEL_NONE) { 100035654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (allowedResolutionLevel == RESOLUTION_LEVEL_COARSE) { 10015e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return AppOpsManager.OP_COARSE_LOCATION; 100235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } else { 10035e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return AppOpsManager.OP_FINE_LOCATION; 100435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 10055e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 10065e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return -1; 10075e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 10085e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 10095e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn boolean reportLocationAccessNoThrow(int uid, String packageName, int allowedResolutionLevel) { 10105e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn int op = resolutionLevelToOp(allowedResolutionLevel); 10115e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op >= 0) { 101235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (mAppOps.noteOpNoThrow(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) { 101335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return false; 101435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 101535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 101635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return true; 101735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 101835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 101935654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn boolean checkLocationAccess(int uid, String packageName, int allowedResolutionLevel) { 10205e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn int op = resolutionLevelToOp(allowedResolutionLevel); 10215e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (op >= 0) { 102235654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn if (mAppOps.checkOp(op, uid, packageName) != AppOpsManager.MODE_ALLOWED) { 102335654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return false; 102435654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 102535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 102635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn return true; 102735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn } 102835654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn 10296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly /** 10306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Returns all providers by name, including passive, but excluding 10310d21e2161f8542db0a54bf80b74b7fd33afef6f6Laurent Tu * fused, also including ones that are not permitted to 10320d21e2161f8542db0a54bf80b74b7fd33afef6f6Laurent Tu * be accessed by the calling activity or are currently disabled. 10336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly */ 1034e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<String> getAllProviders() { 10366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<String> out; 10376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 10386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly out = new ArrayList<String>(mProviders.size()); 10396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (LocationProviderInterface provider : mProviders) { 10406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String name = provider.getName(); 10416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (LocationManager.FUSED_PROVIDER.equals(name)) { 10426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly continue; 10436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 10446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly out.add(name); 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10486fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getAllProviders()=" + out); 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return out; 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly /** 10536fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Return all providers by name, that match criteria and are optionally 10546fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * enabled. 10556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Can return passive provider, but never returns fused provider. 10566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly */ 1057e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 105803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public List<String> getProviders(Criteria criteria, boolean enabledOnly) { 105937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease int allowedResolutionLevel = getCallerAllowedResolutionLevel(); 10606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<String> out; 106103cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease int uid = Binder.getCallingUid();; 1062269518e83efc01b387235d6194dcf93726e384ffVictoria Lease long identity = Binder.clearCallingIdentity(); 1063b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease try { 1064b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease synchronized (mLock) { 1065b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease out = new ArrayList<String>(mProviders.size()); 1066b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease for (LocationProviderInterface provider : mProviders) { 1067b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease String name = provider.getName(); 1068b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (LocationManager.FUSED_PROVIDER.equals(name)) { 10698dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease continue; 10708dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease } 107137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (allowedResolutionLevel >= getMinimumResolutionLevelForProviderUse(name)) { 107209eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease if (enabledOnly && !isAllowedByUserSettingsLocked(name, uid)) { 1073b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease continue; 1074b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 1075b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (criteria != null && !LocationProvider.propertiesMeetCriteria( 1076b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease name, provider.getProperties(), criteria)) { 1077b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease continue; 1078b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 1079b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease out.add(name); 10808dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease } 108103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1083b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } finally { 1084b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease Binder.restoreCallingIdentity(identity); 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 108603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 10876fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getProviders()=" + out); 10886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return out; 108903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 109003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 109103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood /** 10926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Return the name of the best provider given a Criteria object. 10936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * This method has been deprecated from the public API, 10948dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease * and the whole LocationProvider (including #meetsCriteria) 10956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * has been deprecated as well. So this method now uses 10966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * some simplified logic. 109703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood */ 1098e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 109903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public String getBestProvider(Criteria criteria, boolean enabledOnly) { 11006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String result = null; 110103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 11026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly List<String> providers = getProviders(criteria, enabledOnly); 11038dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease if (!providers.isEmpty()) { 11046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly result = pickBest(providers); 11056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getBestProvider(" + criteria + ", " + enabledOnly + ")=" + result); 11066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return result; 110703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 11086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly providers = getProviders(null, enabledOnly); 11098dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease if (!providers.isEmpty()) { 11106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly result = pickBest(providers); 11116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getBestProvider(" + criteria + ", " + enabledOnly + ")=" + result); 11126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return result; 111303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 111403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 11156fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getBestProvider(" + criteria + ", " + enabledOnly + ")=" + result); 11166fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return null; 11176fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 111803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 11196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private String pickBest(List<String> providers) { 11201925e290e7ac2801311cb4e732d1bc5a5f3e0c44Victoria Lease if (providers.contains(LocationManager.GPS_PROVIDER)) { 11216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return LocationManager.GPS_PROVIDER; 11221925e290e7ac2801311cb4e732d1bc5a5f3e0c44Victoria Lease } else if (providers.contains(LocationManager.NETWORK_PROVIDER)) { 11231925e290e7ac2801311cb4e732d1bc5a5f3e0c44Victoria Lease return LocationManager.NETWORK_PROVIDER; 11246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 11256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return providers.get(0); 112603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 112703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 112803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 1129e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 113003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public boolean providerMeetsCriteria(String provider, Criteria criteria) { 113103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 113203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (p == null) { 113303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood throw new IllegalArgumentException("provider=" + provider); 113403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 11356fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 11366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly boolean result = LocationProvider.propertiesMeetCriteria( 11376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly p.getName(), p.getProperties(), criteria); 11386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "providerMeetsCriteria(" + provider + ", " + criteria + ")=" + result); 11396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return result; 114003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 114103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateProvidersLocked() { 11430c5a04014d3833c9a82772a832d3bc6410fc52acBrad Fitzpatrick boolean changesMade = false; 114415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 1145d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProviders.get(i); 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isEnabled = p.isEnabled(); 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = p.getName(); 114809eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease boolean shouldBeEnabled = isAllowedByCurrentUserSettingsLocked(name); 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isEnabled && !shouldBeEnabled) { 1150b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease updateProviderListenersLocked(name, false, mCurrentUserId); 115175c55f92f5ca00ced05b6778389454ae50beed61David Christie // If any provider has been disabled, clear all last locations for all providers. 115275c55f92f5ca00ced05b6778389454ae50beed61David Christie // This is to be on the safe side in case a provider has location derived from 115375c55f92f5ca00ced05b6778389454ae50beed61David Christie // this disabled provider. 115475c55f92f5ca00ced05b6778389454ae50beed61David Christie mLastLocation.clear(); 115575c55f92f5ca00ced05b6778389454ae50beed61David Christie mLastLocationCoarseInterval.clear(); 11560c5a04014d3833c9a82772a832d3bc6410fc52acBrad Fitzpatrick changesMade = true; 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!isEnabled && shouldBeEnabled) { 1158b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease updateProviderListenersLocked(name, true, mCurrentUserId); 11590c5a04014d3833c9a82772a832d3bc6410fc52acBrad Fitzpatrick changesMade = true; 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11610c5a04014d3833c9a82772a832d3bc6410fc52acBrad Fitzpatrick } 11620c5a04014d3833c9a82772a832d3bc6410fc52acBrad Fitzpatrick if (changesMade) { 11635ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn mContext.sendBroadcastAsUser(new Intent(LocationManager.PROVIDERS_CHANGED_ACTION), 11645ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn UserHandle.ALL); 116540a86c24d2601df4966c57573a5bf58b30a41990Tom O'Neill mContext.sendBroadcastAsUser(new Intent(LocationManager.MODE_CHANGED_ACTION), 116640a86c24d2601df4966c57573a5bf58b30a41990Tom O'Neill UserHandle.ALL); 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1170b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease private void updateProviderListenersLocked(String provider, boolean enabled, int userId) { 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int listeners = 0; 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1173d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 11746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (p == null) return; 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Receiver> deadReceivers = null; 1177e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records != null) { 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = records.size(); 11816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (int i = 0; i < N; i++) { 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UpdateRecord record = records.get(i); 1183269518e83efc01b387235d6194dcf93726e384ffVictoria Lease if (UserHandle.getUserId(record.mReceiver.mUid) == userId) { 1184b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease // Sends a notification message to the receiver 1185b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) { 1186b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (deadReceivers == null) { 1187b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease deadReceivers = new ArrayList<Receiver>(); 1188b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 1189b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease deadReceivers.add(record.mReceiver); 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1191b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease listeners++; 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (deadReceivers != null) { 11976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (int i = deadReceivers.size() - 1; i >= 0; i--) { 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeUpdatesLocked(deadReceivers.get(i)); 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1201e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enabled) { 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.enable(); 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listeners > 0) { 12056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly applyRequirementsLocked(provider); 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.disable(); 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void applyRequirementsLocked(String provider) { 12136fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderInterface p = mProvidersByName.get(provider); 12146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (p == null) return; 12156fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 12176fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly WorkSource worksource = new WorkSource(); 12186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ProviderRequest providerRequest = new ProviderRequest(); 12196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records != null) { 12216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord record : records) { 1222269518e83efc01b387235d6194dcf93726e384ffVictoria Lease if (UserHandle.getUserId(record.mReceiver.mUid) == mCurrentUserId) { 12235e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (checkLocationAccess(record.mReceiver.mUid, record.mReceiver.mPackageName, 12245e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn record.mReceiver.mAllowedResolutionLevel)) { 12255e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn LocationRequest locationRequest = record.mRequest; 12265e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn providerRequest.locationRequests.add(locationRequest); 12275e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (locationRequest.getInterval() < providerRequest.interval) { 12285e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn providerRequest.reportLocation = true; 12295e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn providerRequest.interval = locationRequest.getInterval(); 12305e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 1231b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 12327e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 12337e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 12346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 12356fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (providerRequest.reportLocation) { 12366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // calculate who to blame for power 12376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // This is somewhat arbitrary. We pick a threshold interval 12386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // that is slightly higher that the minimum interval, and 12396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // spread the blame across all applications with a request 12406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // under that threshold. 12416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly long thresholdInterval = (providerRequest.interval + 1000) * 3 / 2; 12426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord record : records) { 1243269518e83efc01b387235d6194dcf93726e384ffVictoria Lease if (UserHandle.getUserId(record.mReceiver.mUid) == mCurrentUserId) { 1244b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease LocationRequest locationRequest = record.mRequest; 1245b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (locationRequest.getInterval() <= thresholdInterval) { 1246e55c9686a180cc81e8aac1eeadad12271d8e41caDavid Christie if (record.mReceiver.mWorkSource != null 1247e55c9686a180cc81e8aac1eeadad12271d8e41caDavid Christie && record.mReceiver.mWorkSource.size() > 0 1248e55c9686a180cc81e8aac1eeadad12271d8e41caDavid Christie && record.mReceiver.mWorkSource.getName(0) != null) { 124982edc9b3482307a8e93655aadabb4f9ad24efe46David Christie // Assign blame to another work source. 1250e55c9686a180cc81e8aac1eeadad12271d8e41caDavid Christie // Can only assign blame if the WorkSource contains names. 125182edc9b3482307a8e93655aadabb4f9ad24efe46David Christie worksource.add(record.mReceiver.mWorkSource); 125282edc9b3482307a8e93655aadabb4f9ad24efe46David Christie } else { 125382edc9b3482307a8e93655aadabb4f9ad24efe46David Christie // Assign blame to caller. 125482edc9b3482307a8e93655aadabb4f9ad24efe46David Christie worksource.add( 125582edc9b3482307a8e93655aadabb4f9ad24efe46David Christie record.mReceiver.mUid, 125682edc9b3482307a8e93655aadabb4f9ad24efe46David Christie record.mReceiver.mPackageName); 125782edc9b3482307a8e93655aadabb4f9ad24efe46David Christie } 1258b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 12596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 12607e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 12646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "provider request: " + provider + " " + providerRequest); 12656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly p.setRequest(providerRequest, worksource); 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class UpdateRecord { 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String mProvider; 12706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final LocationRequest mRequest; 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Receiver mReceiver; 12722f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Location mLastFixBroadcast; 12732f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood long mLastStatusBroadcast; 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Note: must be constructed with lock held. 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly UpdateRecord(String provider, LocationRequest request, Receiver receiver) { 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProvider = provider; 12806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mRequest = request; 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReceiver = receiver; 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records == null) { 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project records = new ArrayList<UpdateRecord>(); 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecordsByProvider.put(provider, records); 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!records.contains(this)) { 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project records.add(this); 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Method to be called when a record will no longer be used. Calling this multiple times 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * must have the same effect as calling it once. 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly void disposeLocked(boolean removeReceiver) { 12986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // remove from mRecordsByProvider 12996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<UpdateRecord> globalRecords = mRecordsByProvider.get(this.mProvider); 13006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (globalRecords != null) { 13016fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly globalRecords.remove(this); 13026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 13036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 13046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (!removeReceiver) return; // the caller will handle the rest 13056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 13066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // remove from Receiver#mUpdateRecords 13076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly HashMap<String, UpdateRecord> receiverRecords = mReceiver.mUpdateRecords; 13086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (receiverRecords != null) { 13096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiverRecords.remove(this.mProvider); 13106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 13116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // and also remove the Receiver if it has no more update records 13126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (removeReceiver && receiverRecords.size() == 0) { 13136fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeUpdatesLocked(mReceiver); 13146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 13153a76fd627945c1df59aa0318867401e0e53da022Mike Lockwood } 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 13206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly StringBuilder s = new StringBuilder(); 13216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append("UpdateRecord["); 13226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(mProvider); 13236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(' ').append(mReceiver.mPackageName).append('('); 13246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(mReceiver.mUid).append(')'); 13256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(' ').append(mRequest); 13266fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(']'); 13276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return s.toString(); 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1331f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn private Receiver getReceiverLocked(ILocationListener listener, int pid, int uid, 133240e5782f5c79ea660b98b8875086f592367bc1d2David Christie String packageName, WorkSource workSource, boolean hideFromAppOps) { 13332f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood IBinder binder = listener.asBinder(); 13342f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver receiver = mReceivers.get(binder); 13352f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (receiver == null) { 133640e5782f5c79ea660b98b8875086f592367bc1d2David Christie receiver = new Receiver(listener, null, pid, uid, packageName, workSource, 133740e5782f5c79ea660b98b8875086f592367bc1d2David Christie hideFromAppOps); 13382f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mReceivers.put(binder, receiver); 13392f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 13402f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood try { 13416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiver.getListener().asBinder().linkToDeath(receiver, 0); 13422f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } catch (RemoteException e) { 13438a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "linkToDeath failed:", e); 13442f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return null; 13452f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 13462f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 13472f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return receiver; 13482f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 13492f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 135082edc9b3482307a8e93655aadabb4f9ad24efe46David Christie private Receiver getReceiverLocked(PendingIntent intent, int pid, int uid, String packageName, 135140e5782f5c79ea660b98b8875086f592367bc1d2David Christie WorkSource workSource, boolean hideFromAppOps) { 13522f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver receiver = mReceivers.get(intent); 13532f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (receiver == null) { 135440e5782f5c79ea660b98b8875086f592367bc1d2David Christie receiver = new Receiver(null, intent, pid, uid, packageName, workSource, 135540e5782f5c79ea660b98b8875086f592367bc1d2David Christie hideFromAppOps); 13562f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mReceivers.put(intent, receiver); 13572f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 13582f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return receiver; 13592f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 13602f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 136137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease /** 136237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Creates a LocationRequest based upon the supplied LocationRequest that to meets resolution 136337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * and consistency requirements. 136437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 136537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param request the LocationRequest from which to create a sanitized version 136637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @return a version of request that meets the given resolution and consistency requirements 136737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @hide 136837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease */ 136937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private LocationRequest createSanitizedRequest(LocationRequest request, int resolutionLevel) { 137037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease LocationRequest sanitizedRequest = new LocationRequest(request); 137137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (resolutionLevel < RESOLUTION_LEVEL_FINE) { 137237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease switch (sanitizedRequest.getQuality()) { 137309016ab4dd056a16809419d612cb865a14980880Victoria Lease case LocationRequest.ACCURACY_FINE: 137437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease sanitizedRequest.setQuality(LocationRequest.ACCURACY_BLOCK); 137509016ab4dd056a16809419d612cb865a14980880Victoria Lease break; 137609016ab4dd056a16809419d612cb865a14980880Victoria Lease case LocationRequest.POWER_HIGH: 137737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease sanitizedRequest.setQuality(LocationRequest.POWER_LOW); 137809016ab4dd056a16809419d612cb865a14980880Victoria Lease break; 137909016ab4dd056a16809419d612cb865a14980880Victoria Lease } 138009016ab4dd056a16809419d612cb865a14980880Victoria Lease // throttle 138137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (sanitizedRequest.getInterval() < LocationFudger.FASTEST_INTERVAL_MS) { 138237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease sanitizedRequest.setInterval(LocationFudger.FASTEST_INTERVAL_MS); 138309016ab4dd056a16809419d612cb865a14980880Victoria Lease } 138437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (sanitizedRequest.getFastestInterval() < LocationFudger.FASTEST_INTERVAL_MS) { 138537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease sanitizedRequest.setFastestInterval(LocationFudger.FASTEST_INTERVAL_MS); 138609016ab4dd056a16809419d612cb865a14980880Victoria Lease } 138774fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pelly } 13884e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly // make getFastestInterval() the minimum of interval and fastest interval 138937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (sanitizedRequest.getFastestInterval() > sanitizedRequest.getInterval()) { 13904e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly request.setFastestInterval(request.getInterval()); 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 139237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return sanitizedRequest; 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void checkPackageName(String packageName) { 1396e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly if (packageName == null) { 13976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new SecurityException("invalid package name: " + packageName); 1398e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 13996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly int uid = Binder.getCallingUid(); 1400e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly String[] packages = mPackageManager.getPackagesForUid(uid); 1401e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly if (packages == null) { 1402e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly throw new SecurityException("invalid UID " + uid); 1403e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 1404e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly for (String pkg : packages) { 1405e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly if (packageName.equals(pkg)) return; 1406e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 14076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new SecurityException("invalid package name: " + packageName); 1408e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 1409e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 14106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void checkPendingIntent(PendingIntent intent) { 14116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (intent == null) { 14126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new IllegalArgumentException("invalid pending intent: " + intent); 14136c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn } 14146c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn } 14156c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn 1416f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn private Receiver checkListenerOrIntentLocked(ILocationListener listener, PendingIntent intent, 141740e5782f5c79ea660b98b8875086f592367bc1d2David Christie int pid, int uid, String packageName, WorkSource workSource, boolean hideFromAppOps) { 14186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (intent == null && listener == null) { 1419a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn throw new IllegalArgumentException("need either listener or intent"); 14206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else if (intent != null && listener != null) { 14216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new IllegalArgumentException("cannot register both listener and intent"); 14226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else if (intent != null) { 14236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPendingIntent(intent); 142440e5782f5c79ea660b98b8875086f592367bc1d2David Christie return getReceiverLocked(intent, pid, uid, packageName, workSource, hideFromAppOps); 14256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 142640e5782f5c79ea660b98b8875086f592367bc1d2David Christie return getReceiverLocked(listener, pid, uid, packageName, workSource, hideFromAppOps); 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 14316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void requestLocationUpdates(LocationRequest request, ILocationListener listener, 14326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly PendingIntent intent, String packageName) { 14336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (request == null) request = DEFAULT_LOCATION_REQUEST; 14346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPackageName(packageName); 143537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease int allowedResolutionLevel = getCallerAllowedResolutionLevel(); 143637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, 143737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease request.getProvider()); 143882edc9b3482307a8e93655aadabb4f9ad24efe46David Christie WorkSource workSource = request.getWorkSource(); 143982edc9b3482307a8e93655aadabb4f9ad24efe46David Christie if (workSource != null && workSource.size() > 0) { 144040e5782f5c79ea660b98b8875086f592367bc1d2David Christie checkDeviceStatsAllowed(); 144140e5782f5c79ea660b98b8875086f592367bc1d2David Christie } 144240e5782f5c79ea660b98b8875086f592367bc1d2David Christie boolean hideFromAppOps = request.getHideFromAppOps(); 144340e5782f5c79ea660b98b8875086f592367bc1d2David Christie if (hideFromAppOps) { 144440e5782f5c79ea660b98b8875086f592367bc1d2David Christie checkUpdateAppOpsAllowed(); 144582edc9b3482307a8e93655aadabb4f9ad24efe46David Christie } 144637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel); 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14486fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int pid = Binder.getCallingPid(); 14496fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int uid = Binder.getCallingUid(); 14502b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly // providers may use public location API's, need to clear identity 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identity = Binder.clearCallingIdentity(); 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 1453a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn // We don't check for MODE_IGNORED here; we will do that when we go to deliver 1454a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn // a location. 145535654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn checkLocationAccess(uid, packageName, allowedResolutionLevel); 1456a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 14576fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 1458f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn Receiver recevier = checkListenerOrIntentLocked(listener, intent, pid, uid, 145940e5782f5c79ea660b98b8875086f592367bc1d2David Christie packageName, workSource, hideFromAppOps); 146037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease requestLocationUpdatesLocked(sanitizedRequest, recevier, pid, uid, packageName); 14612d4d1bf14b531de9d4238b1e41b53c77f8976405Mike Lockwood } 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(identity); 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14676fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void requestLocationUpdatesLocked(LocationRequest request, Receiver receiver, 14686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly int pid, int uid, String packageName) { 14696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Figure out the provider. Either its explicitly request (legacy use cases), or 14706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // use the fused provider 14716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (request == null) request = DEFAULT_LOCATION_REQUEST; 14726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String name = request.getProvider(); 147309016ab4dd056a16809419d612cb865a14980880Victoria Lease if (name == null) { 147409016ab4dd056a16809419d612cb865a14980880Victoria Lease throw new IllegalArgumentException("provider name must not be null"); 147509016ab4dd056a16809419d612cb865a14980880Victoria Lease } 1476c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun 1477c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun if (D) Log.d(TAG, "request " + Integer.toHexString(System.identityHashCode(receiver)) 1478c5fc9988f11acc58229fb6ae80d346277318ada4Zhentao Sun + " " + name + " " + request + " from " + packageName + "(" + uid + ")"); 14796fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderInterface provider = mProvidersByName.get(name); 14806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (provider == null) { 1481b30f38383e4691bf23311f62649aa504832731dbVictoria Lease throw new IllegalArgumentException("provider doesn't exist: " + name); 14826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 14836fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 14846fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly UpdateRecord record = new UpdateRecord(name, request, receiver); 14856fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly UpdateRecord oldRecord = receiver.mUpdateRecords.put(name, record); 14866fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (oldRecord != null) { 14876fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly oldRecord.disposeLocked(false); 14886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 14896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 149009eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease boolean isProviderEnabled = isAllowedByUserSettingsLocked(name, uid); 14916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (isProviderEnabled) { 14926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly applyRequirementsLocked(name); 14936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 14946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Notify the listener that updates are currently disabled 14956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiver.callProviderEnabledLocked(name, false); 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14970b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie // Update the monitoring here just in case multiple location requests were added to the 14980b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie // same receiver (this request may be high power and the initial might not have been). 14990b8374501975aecd7a628336e2f7e53c272ebeeaDavid Christie receiver.updateMonitoring(true); 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1502e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 15036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void removeUpdates(ILocationListener listener, PendingIntent intent, 15046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String packageName) { 15056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPackageName(packageName); 150637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease 15076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int pid = Binder.getCallingPid(); 15086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int uid = Binder.getCallingUid(); 15096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1510f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn synchronized (mLock) { 151182edc9b3482307a8e93655aadabb4f9ad24efe46David Christie WorkSource workSource = null; 151240e5782f5c79ea660b98b8875086f592367bc1d2David Christie boolean hideFromAppOps = false; 151340e5782f5c79ea660b98b8875086f592367bc1d2David Christie Receiver receiver = checkListenerOrIntentLocked(listener, intent, pid, uid, 151440e5782f5c79ea660b98b8875086f592367bc1d2David Christie packageName, workSource, hideFromAppOps); 1515f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn 1516f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn // providers may use public location API's, need to clear identity 1517f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn long identity = Binder.clearCallingIdentity(); 1518f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn try { 15196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeUpdatesLocked(receiver); 1520f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn } finally { 1521f5fdca9dc1528a7f5acec04c2f2a1b99e8f4b338Dianne Hackborn Binder.restoreCallingIdentity(identity); 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeUpdatesLocked(Receiver receiver) { 15277ff30113de68539ec840c524b8f1561f938f96c5Dianne Hackborn if (D) Log.i(TAG, "remove " + Integer.toHexString(System.identityHashCode(receiver))); 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) { 15306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiver.getListener().asBinder().unlinkToDeath(receiver, 0); 15316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (receiver) { 15320aa28602d51bf41e46d18ffefe724ebc3ff7a704Victoria Lease receiver.clearPendingBroadcastsLocked(); 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15361304f4ae32cf7121fe11e95f2a7151ea208b6ccaDianne Hackborn receiver.updateMonitoring(false); 15371304f4ae32cf7121fe11e95f2a7151ea208b6ccaDianne Hackborn 15386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Record which providers were associated with this listener 15396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly HashSet<String> providers = new HashSet<String>(); 15406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly HashMap<String, UpdateRecord> oldRecords = receiver.mUpdateRecords; 15416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (oldRecords != null) { 15426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Call dispose() on the obsolete update records. 15436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord record : oldRecords.values()) { 15446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly record.disposeLocked(false); 15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15466fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Accumulate providers 15476fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly providers.addAll(oldRecords.keySet()); 15486fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 15499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // update provider 15516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (String provider : providers) { 15526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // If provider is already disabled, don't need to do anything 155309eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease if (!isAllowedByCurrentUserSettingsLocked(provider)) { 15546fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly continue; 15556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15576fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly applyRequirementsLocked(provider); 15586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 15596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1561c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn private void applyAllProviderRequirementsLocked() { 1562c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn for (LocationProviderInterface p : mProviders) { 1563c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn // If provider is already disabled, don't need to do anything 156464d41d7391e57886978e94e86cf01a167226dbfeDianne Hackborn if (!isAllowedByCurrentUserSettingsLocked(p.getName())) { 1565c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn continue; 1566c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1567c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 1568c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn applyRequirementsLocked(p.getName()); 1569c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1570c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn } 1571c2293025a25e04b26bf53713d71f85fd9ca5e8e9Dianne Hackborn 15726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 15734035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly public Location getLastLocation(LocationRequest request, String packageName) { 15746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getLastLocation: " + request); 15756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (request == null) request = DEFAULT_LOCATION_REQUEST; 157637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease int allowedResolutionLevel = getCallerAllowedResolutionLevel(); 15774035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly checkPackageName(packageName); 157837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, 157937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease request.getProvider()); 158037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease // no need to sanitize this request, as only the provider name is used 15814035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly 1582a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn final int uid = Binder.getCallingUid(); 1583a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn final long identity = Binder.clearCallingIdentity(); 1584b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease try { 1585b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (mBlacklist.isBlacklisted(packageName)) { 1586b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (D) Log.d(TAG, "not returning last loc for blacklisted app: " + 1587b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease packageName); 158809016ab4dd056a16809419d612cb865a14980880Victoria Lease return null; 158909016ab4dd056a16809419d612cb865a14980880Victoria Lease } 1590b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease 15915e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (!reportLocationAccessNoThrow(uid, packageName, allowedResolutionLevel)) { 15925e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (D) Log.d(TAG, "not returning last loc for no op app: " + 15935e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn packageName); 15945e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn return null; 15955e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 15965e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 1597b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease synchronized (mLock) { 1598b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease // Figure out the provider. Either its explicitly request (deprecated API's), 1599b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease // or use the fused provider 1600b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease String name = request.getProvider(); 1601b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (name == null) name = LocationManager.FUSED_PROVIDER; 1602b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease LocationProviderInterface provider = mProvidersByName.get(name); 1603b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (provider == null) return null; 1604b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease 160509eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease if (!isAllowedByUserSettingsLocked(name, uid)) return null; 1606b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease 16071b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie Location location; 16081b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) { 16091b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie // Make sure that an app with coarse permissions can't get frequent location 16101b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie // updates by calling LocationManager.getLastKnownLocation repeatedly. 16111b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie location = mLastLocationCoarseInterval.get(name); 16121b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie } else { 16131b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie location = mLastLocation.get(name); 16141b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie } 1615b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (location == null) { 1616b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease return null; 1617b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 161837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) { 1619b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); 1620b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (noGPSLocation != null) { 16216c5406acd72eed31f2b4e12f5eddc0e2d2a951e2Dianne Hackborn return new Location(mLocationFudger.getOrCreate(noGPSLocation)); 1622b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 162337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease } else { 16246c5406acd72eed31f2b4e12f5eddc0e2d2a951e2Dianne Hackborn return new Location(location); 162509016ab4dd056a16809419d612cb865a14980880Victoria Lease } 16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1627b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease return null; 1628b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } finally { 1629b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease Binder.restoreCallingIdentity(identity); 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1633e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 16346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void requestGeofence(LocationRequest request, Geofence geofence, PendingIntent intent, 16356fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String packageName) { 16366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (request == null) request = DEFAULT_LOCATION_REQUEST; 163737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease int allowedResolutionLevel = getCallerAllowedResolutionLevel(); 163837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForGeofenceUse(allowedResolutionLevel); 16396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPendingIntent(intent); 16406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPackageName(packageName); 164137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, 164237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease request.getProvider()); 164337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel); 16446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 164537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (D) Log.d(TAG, "requestGeofence: " + sanitizedRequest + " " + geofence + " " + intent); 16466fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 16472b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly // geo-fence manager uses the public location API, need to clear identity 16482b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly int uid = Binder.getCallingUid(); 164956e675b3a1c351de34de68a149762d3ad1b308c5Victoria Lease if (UserHandle.getUserId(uid) != UserHandle.USER_OWNER) { 165056e675b3a1c351de34de68a149762d3ad1b308c5Victoria Lease // temporary measure until geofences work for secondary users 165156e675b3a1c351de34de68a149762d3ad1b308c5Victoria Lease Log.w(TAG, "proximity alerts are currently available only to the primary user"); 165256e675b3a1c351de34de68a149762d3ad1b308c5Victoria Lease return; 165356e675b3a1c351de34de68a149762d3ad1b308c5Victoria Lease } 16542b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly long identity = Binder.clearCallingIdentity(); 16552b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly try { 16565e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mGeofenceManager.addFence(sanitizedRequest, geofence, intent, allowedResolutionLevel, 16575e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn uid, packageName); 16582b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly } finally { 16592b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly Binder.restoreCallingIdentity(identity); 16602b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly } 16616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 16626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 16636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 16646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void removeGeofence(Geofence geofence, PendingIntent intent, String packageName) { 166537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForGeofenceUse(getCallerAllowedResolutionLevel()); 16666fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPendingIntent(intent); 16676fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPackageName(packageName); 16686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 16696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "removeGeofence: " + geofence + " " + intent); 16706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 16712b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly // geo-fence manager uses the public location API, need to clear identity 16722b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly long identity = Binder.clearCallingIdentity(); 16732b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly try { 16742b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly mGeofenceManager.removeFence(geofence, intent); 16752b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly } finally { 16762b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly Binder.restoreCallingIdentity(identity); 16772b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly } 16786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 16796fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 16806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 16816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 1682a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn public boolean addGpsStatusListener(IGpsStatusListener listener, String packageName) { 168315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mGpsStatusProvider == null) { 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 168635654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn int allowedResolutionLevel = getCallerAllowedResolutionLevel(); 168735654b61e8fe7bc85afcb076ddbb590d51c5865fDianne Hackborn checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, 168837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease LocationManager.GPS_PROVIDER); 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1690a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn final int uid = Binder.getCallingUid(); 1691a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn final long ident = Binder.clearCallingIdentity(); 1692a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn try { 16933d5173deea9d74b0476739c7108f9b77bcd8a495Victoria Lease if (!checkLocationAccess(uid, packageName, allowedResolutionLevel)) { 1694a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn return false; 1695a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1696a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } finally { 1697a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn Binder.restoreCallingIdentity(ident); 1698a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn } 1699a06de0f29b58df9246779cc4bfd8f06f7205ddb6Dianne Hackborn 17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 170115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mGpsStatusProvider.addGpsStatusListener(listener); 17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 17038a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "mGpsStatusProvider.addGpsStatusListener failed", e); 17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1709e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeGpsStatusListener(IGpsStatusListener listener) { 17112f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 171215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood try { 171315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mGpsStatusProvider.removeGpsStatusListener(listener); 171415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } catch (Exception e) { 17158a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "mGpsStatusProvider.removeGpsStatusListener failed", e); 171615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1720e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String provider, String command, Bundle extras) { 1722c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood if (provider == null) { 1723c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood // throw NullPointerException to remain compatible with previous implementation 1724c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood throw new NullPointerException(); 1725c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood } 172637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(), 172737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease provider); 1728c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood 17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and check for ACCESS_LOCATION_EXTRA_COMMANDS 1730b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood if ((mContext.checkCallingOrSelfPermission(ACCESS_LOCATION_EXTRA_COMMANDS) 17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_LOCATION_EXTRA_COMMANDS permission"); 17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17352f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 1736d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 17376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (p == null) return false; 1738e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 1739d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return p.sendExtraCommand(command, extras); 17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1743e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 17446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public boolean sendNiResponse(int notifId, int userResponse) { 174518ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood if (Binder.getCallingUid() != Process.myUid()) { 174618ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood throw new SecurityException( 174718ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood "calling sendNiResponse from outside of the system is not allowed"); 174818ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood } 174922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie try { 175022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return mNetInitiatedListener.sendNiResponse(notifId, userResponse); 17516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } catch (RemoteException e) { 17528a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "RemoteException in LocationManagerService.sendNiResponse"); 175322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return false; 175422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 175522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 175622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1758628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood * @return null if the provider does not exist 1759f2db9fb0f877057a9ef56908d54f3c95fc3fd552Alexey Tarasov * @throws SecurityException if the provider is not allowed to be 17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * accessed by the caller 17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1762e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 17636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public ProviderProperties getProviderProperties(String provider) { 1764b7f9d254978b285bf04613f6e69a1afa89240ca9Laurent Tu if (mProvidersByName.get(provider) == null) { 1765b7f9d254978b285bf04613f6e69a1afa89240ca9Laurent Tu return null; 1766b7f9d254978b285bf04613f6e69a1afa89240ca9Laurent Tu } 1767b7f9d254978b285bf04613f6e69a1afa89240ca9Laurent Tu 176837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(), 176937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease provider); 17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderInterface p; 17726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 17736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly p = mProvidersByName.get(provider); 17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17766fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (p == null) return null; 17776fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return p.getProperties(); 17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1780e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isProviderEnabled(String provider) { 1782d5759437eeb3137e4a05471ff0f4681c0254e81aTom O'Neill // TODO: remove this check in next release, see b/10696351 178337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(), 178437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease provider); 1785d5759437eeb3137e4a05471ff0f4681c0254e81aTom O'Neill 1786d5759437eeb3137e4a05471ff0f4681c0254e81aTom O'Neill // Fused provider is accessed indirectly via criteria rather than the provider-based APIs, 1787d5759437eeb3137e4a05471ff0f4681c0254e81aTom O'Neill // so we discourage its use 17886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (LocationManager.FUSED_PROVIDER.equals(provider)) return false; 17896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 179009eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease int uid = Binder.getCallingUid(); 1791269518e83efc01b387235d6194dcf93726e384ffVictoria Lease long identity = Binder.clearCallingIdentity(); 1792b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease try { 1793b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease synchronized (mLock) { 1794b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease LocationProviderInterface p = mProvidersByName.get(provider); 1795b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (p == null) return false; 17966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 179709eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease return isAllowedByUserSettingsLocked(provider, uid); 1798b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 1799b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } finally { 1800b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease Binder.restoreCallingIdentity(identity); 18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 180403cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease /** 180503cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease * Returns "true" if the UID belongs to a bound location provider. 180603cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease * 180703cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease * @param uid the uid 180803cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease * @return true if uid belongs to a bound location provider 180903cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease */ 181003cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease private boolean isUidALocationProvider(int uid) { 181103cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease if (uid == Process.SYSTEM_UID) { 181203cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease return true; 181303cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease } 181403cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease if (mGeocodeProvider != null) { 181503cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease if (doesPackageHaveUid(uid, mGeocodeProvider.getConnectedPackageName())) return true; 181603cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease } 181703cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease for (LocationProviderProxy proxy : mProxyProviders) { 181803cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease if (doesPackageHaveUid(uid, proxy.getConnectedPackageName())) return true; 181903cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease } 182003cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease return false; 182103cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease } 182203cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease 18236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void checkCallerIsProvider() { 1824275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER) 18256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly == PackageManager.PERMISSION_GRANTED) { 18262eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly return; 18272eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly } 18282eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly 18296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Previously we only used the INSTALL_LOCATION_PROVIDER 18306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // check. But that is system or signature 18316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // protection level which is not flexible enough for 18326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // providers installed oustide the system image. So 18336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // also allow providers with a UID matching the 18346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // currently bound package name 18354e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood 183603cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease if (isUidALocationProvider(Binder.getCallingUid())) { 183703cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease return; 18386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 183903cdd3d275499df3ef1059905899dcc5aaf2ab01Victoria Lease 18406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new SecurityException("need INSTALL_LOCATION_PROVIDER permission, " + 18416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly "or UID of a currently bound location provider"); 18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private boolean doesPackageHaveUid(int uid, String packageName) { 18456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (packageName == null) { 18466fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return false; 18474a7b65e0d544ef1feff8e1e5789f469f89ebb85cMike Lockwood } 18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 18496fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ApplicationInfo appInfo = mPackageManager.getApplicationInfo(packageName, 0); 18506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (appInfo.uid != uid) { 18516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return false; 18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18536fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } catch (NameNotFoundException e) { 18546fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return false; 18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return true; 18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 18606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void reportLocation(Location location, boolean passive) { 18616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkCallerIsProvider(); 18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (!location.isComplete()) { 18646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Log.w(TAG, "Dropping incomplete location: " + location); 18656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return; 18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLocationHandler.removeMessages(MSG_LOCATION_CHANGED, location); 18696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Message m = Message.obtain(mLocationHandler, MSG_LOCATION_CHANGED, location); 18706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly m.arg1 = (passive ? 1 : 0); 18716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLocationHandler.sendMessageAtFrontOfQueue(m); 18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 187575defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu private static boolean shouldBroadcastSafe( 187675defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu Location loc, Location lastLoc, UpdateRecord record, long now) { 18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Always broadcast the first update 18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lastLoc == null) { 18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1882f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly // Check whether sufficient time has passed 18836fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly long minTime = record.mRequest.getFastestInterval(); 18841b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie long delta = (loc.getElapsedRealtimeNanos() - lastLoc.getElapsedRealtimeNanos()) 18851b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie / NANOS_PER_MILLI; 18866fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (delta < minTime - MAX_PROVIDER_SCHEDULING_JITTER_MS) { 18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check whether sufficient distance has been traveled 18916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly double minDistance = record.mRequest.getSmallestDisplacement(); 18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (minDistance > 0.0) { 18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (loc.distanceTo(lastLoc) <= minDistance) { 18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189875defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu // Check whether sufficient number of udpates is left 189975defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu if (record.mRequest.getNumUpdates() <= 0) { 190075defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu return false; 190175defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu } 190275defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu 190375defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu // Check whether the expiry date has passed 190475defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu if (record.mRequest.getExpireAt() < now) { 190575defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu return false; 190675defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu } 190775defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu 19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1911a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood private void handleLocationChangedLocked(Location location, boolean passive) { 19124e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly if (D) Log.d(TAG, "incoming location: " + location); 19134e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly 19146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly long now = SystemClock.elapsedRealtime(); 1915a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood String provider = (passive ? LocationManager.PASSIVE_PROVIDER : location.getProvider()); 19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 191760ec50a850ac7265b662df3c872583b6ef581ef8Laurent Tu // Skip if the provider is unknown. 1918d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 19196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (p == null) return; 19206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 19216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Update last known locations 192209016ab4dd056a16809419d612cb865a14980880Victoria Lease Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); 192309016ab4dd056a16809419d612cb865a14980880Victoria Lease Location lastNoGPSLocation = null; 19246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Location lastLocation = mLastLocation.get(provider); 19254e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood if (lastLocation == null) { 19266fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly lastLocation = new Location(provider); 19276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLastLocation.put(provider, lastLocation); 192809016ab4dd056a16809419d612cb865a14980880Victoria Lease } else { 192909016ab4dd056a16809419d612cb865a14980880Victoria Lease lastNoGPSLocation = lastLocation.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); 193009016ab4dd056a16809419d612cb865a14980880Victoria Lease if (noGPSLocation == null && lastNoGPSLocation != null) { 193109016ab4dd056a16809419d612cb865a14980880Victoria Lease // New location has no no-GPS location: adopt last no-GPS location. This is set 193209016ab4dd056a16809419d612cb865a14980880Victoria Lease // directly into location because we do not want to notify COARSE clients. 193309016ab4dd056a16809419d612cb865a14980880Victoria Lease location.setExtraLocation(Location.EXTRA_NO_GPS_LOCATION, lastNoGPSLocation); 193409016ab4dd056a16809419d612cb865a14980880Victoria Lease } 19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly lastLocation.set(location); 19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19381b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie // Update last known coarse interval location if enough time has passed. 19391b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie Location lastLocationCoarseInterval = mLastLocationCoarseInterval.get(provider); 19401b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie if (lastLocationCoarseInterval == null) { 19411b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie lastLocationCoarseInterval = new Location(location); 19421b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie mLastLocationCoarseInterval.put(provider, lastLocationCoarseInterval); 19431b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie } 19441b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie long timeDiffNanos = location.getElapsedRealtimeNanos() 19451b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie - lastLocationCoarseInterval.getElapsedRealtimeNanos(); 19461b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie if (timeDiffNanos > LocationFudger.FASTEST_INTERVAL_MS * NANOS_PER_MILLI) { 19471b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie lastLocationCoarseInterval.set(location); 19481b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie } 19491b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie // Don't ever return a coarse location that is more recent than the allowed update 19501b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie // interval (i.e. don't allow an app to keep registering and unregistering for 19511b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie // location updates to overcome the minimum interval). 19521b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie noGPSLocation = 19531b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie lastLocationCoarseInterval.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); 19541b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie 195560ec50a850ac7265b662df3c872583b6ef581ef8Laurent Tu // Skip if there are no UpdateRecords for this provider. 195660ec50a850ac7265b662df3c872583b6ef581ef8Laurent Tu ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 195760ec50a850ac7265b662df3c872583b6ef581ef8Laurent Tu if (records == null || records.size() == 0) return; 195860ec50a850ac7265b662df3c872583b6ef581ef8Laurent Tu 195909016ab4dd056a16809419d612cb865a14980880Victoria Lease // Fetch coarse location 196009016ab4dd056a16809419d612cb865a14980880Victoria Lease Location coarseLocation = null; 19611b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie if (noGPSLocation != null) { 196209016ab4dd056a16809419d612cb865a14980880Victoria Lease coarseLocation = mLocationFudger.getOrCreate(noGPSLocation); 196309016ab4dd056a16809419d612cb865a14980880Victoria Lease } 196409016ab4dd056a16809419d612cb865a14980880Victoria Lease 19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Fetch latest status update time 19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long newStatusUpdateTime = p.getStatusUpdateTime(); 19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19687ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood // Get latest status 19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Bundle extras = new Bundle(); 19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int status = p.getStatus(extras); 19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Receiver> deadReceivers = null; 19736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<UpdateRecord> deadUpdateRecords = null; 1974e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 19759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Broadcast location or status to all listeners 19766fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord r : records) { 19779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Receiver receiver = r.mReceiver; 197803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood boolean receiverDead = false; 19794035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly 1980269518e83efc01b387235d6194dcf93726e384ffVictoria Lease int receiverUserId = UserHandle.getUserId(receiver.mUid); 19812f5b97c518f6b6ab89e19d3a335c148400f03268Victoria Lease if (receiverUserId != mCurrentUserId && !isUidALocationProvider(receiver.mUid)) { 1982b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (D) { 1983269518e83efc01b387235d6194dcf93726e384ffVictoria Lease Log.d(TAG, "skipping loc update for background user " + receiverUserId + 1984b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease " (current user: " + mCurrentUserId + ", app: " + 1985b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease receiver.mPackageName + ")"); 1986b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 1987b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease continue; 1988b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 1989b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease 19904035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly if (mBlacklist.isBlacklisted(receiver.mPackageName)) { 19914035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly if (D) Log.d(TAG, "skipping loc update for blacklisted app: " + 19924035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly receiver.mPackageName); 19934035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly continue; 19944035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly } 19954035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly 19965e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (!reportLocationAccessNoThrow(receiver.mUid, receiver.mPackageName, 19975e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn receiver.mAllowedResolutionLevel)) { 19985e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn if (D) Log.d(TAG, "skipping loc update for no op app: " + 19995e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn receiver.mPackageName); 20005e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn continue; 20015e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn } 20025e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn 200309016ab4dd056a16809419d612cb865a14980880Victoria Lease Location notifyLocation = null; 200437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (receiver.mAllowedResolutionLevel < RESOLUTION_LEVEL_FINE) { 200537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease notifyLocation = coarseLocation; // use coarse location 20066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 200737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease notifyLocation = lastLocation; // use fine location 20086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 200909016ab4dd056a16809419d612cb865a14980880Victoria Lease if (notifyLocation != null) { 201009016ab4dd056a16809419d612cb865a14980880Victoria Lease Location lastLoc = r.mLastFixBroadcast; 201175defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu if ((lastLoc == null) || shouldBroadcastSafe(notifyLocation, lastLoc, r, now)) { 201209016ab4dd056a16809419d612cb865a14980880Victoria Lease if (lastLoc == null) { 201309016ab4dd056a16809419d612cb865a14980880Victoria Lease lastLoc = new Location(notifyLocation); 201409016ab4dd056a16809419d612cb865a14980880Victoria Lease r.mLastFixBroadcast = lastLoc; 201509016ab4dd056a16809419d612cb865a14980880Victoria Lease } else { 201609016ab4dd056a16809419d612cb865a14980880Victoria Lease lastLoc.set(notifyLocation); 201709016ab4dd056a16809419d612cb865a14980880Victoria Lease } 201809016ab4dd056a16809419d612cb865a14980880Victoria Lease if (!receiver.callLocationChangedLocked(notifyLocation)) { 201909016ab4dd056a16809419d612cb865a14980880Victoria Lease Slog.w(TAG, "RemoteException calling onLocationChanged on " + receiver); 202009016ab4dd056a16809419d612cb865a14980880Victoria Lease receiverDead = true; 202109016ab4dd056a16809419d612cb865a14980880Victoria Lease } 202275defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu r.mRequest.decrementNumUpdates(); 20239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20262f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood long prevStatusUpdateTime = r.mLastStatusBroadcast; 20279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((newStatusUpdateTime > prevStatusUpdateTime) && 202809016ab4dd056a16809419d612cb865a14980880Victoria Lease (prevStatusUpdateTime != 0 || status != LocationProvider.AVAILABLE)) { 20299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20302f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood r.mLastStatusBroadcast = newStatusUpdateTime; 20319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!receiver.callStatusChangedLocked(provider, status, extras)) { 203203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood receiverDead = true; 20338a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "RemoteException calling onStatusChanged on " + receiver); 203403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 203503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 203603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 20376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // track expired records 203875defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu if (r.mRequest.getNumUpdates() <= 0 || r.mRequest.getExpireAt() < now) { 20396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (deadUpdateRecords == null) { 20406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly deadUpdateRecords = new ArrayList<UpdateRecord>(); 20416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 20426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly deadUpdateRecords.add(r); 20436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 20446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // track dead receivers 20456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (receiverDead) { 204603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (deadReceivers == null) { 204703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood deadReceivers = new ArrayList<Receiver>(); 204803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 204903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (!deadReceivers.contains(receiver)) { 205003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood deadReceivers.add(receiver); 20519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2054e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 20556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // remove dead records and receivers outside the loop 20569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (deadReceivers != null) { 20576fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Receiver receiver : deadReceivers) { 20586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeUpdatesLocked(receiver); 20596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 20606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 20616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (deadUpdateRecords != null) { 20626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord r : deadUpdateRecords) { 20636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly r.disposeLocked(true); 20649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20658b38b29b5213c429d1e9802d02549b5638f40706Victoria Lease applyRequirementsLocked(provider); 20668b38b29b5213c429d1e9802d02549b5638f40706Victoria Lease } 20679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class LocationWorkerHandler extends Handler { 20705cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease public LocationWorkerHandler(Looper looper) { 20715cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease super(looper, null, true); 20725cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease } 20735cd731a2333479d85b1bdf6dbf8a185df2877146Victoria Lease 20749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 20759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 20766fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly switch (msg.what) { 20776fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly case MSG_LOCATION_CHANGED: 20786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly handleLocationChanged((Location) msg.obj, msg.arg1 == 1); 20796fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly break; 20806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 20816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 20826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 208398cb66797422c4ccdee6f1a07636146d784a471bMike Lockwood 208454ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease private boolean isMockProvider(String provider) { 208554ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease synchronized (mLock) { 208654ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease return mMockProviders.containsKey(provider); 208754ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease } 208854ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease } 208954ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease 20906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void handleLocationChanged(Location location, boolean passive) { 209154ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease // create a working copy of the incoming Location so that the service can modify it without 209254ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease // disturbing the caller's copy 209354ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease Location myLocation = new Location(location); 209454ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease String provider = myLocation.getProvider(); 209554ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease 209654ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease // set "isFromMockProvider" bit if location came from a mock provider. we do not clear this 209754ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease // bit if location did not come from a mock provider because passive/fused providers can 209854ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease // forward locations from mock providers, and should not grant them legitimacy in doing so. 209954ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease if (!myLocation.isFromMockProvider() && isMockProvider(provider)) { 210054ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease myLocation.setIsFromMockProvider(true); 210154ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease } 21026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 21036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 210409eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease if (isAllowedByCurrentUserSettingsLocked(provider)) { 210509eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease if (!passive) { 210609eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease // notify passive provider of the new location 210709eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease mPassiveProvider.updateLocation(myLocation); 210809eeaecf7440ff63c937337bb2f50079ebbbf9a2Victoria Lease } 210954ca7aef2e12b240caa6fb1a1e65abd234bea337Victoria Lease handleLocationChangedLocked(myLocation, passive); 21109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final PackageMonitor mPackageMonitor = new PackageMonitor() { 21150528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood @Override 21166fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void onPackageDisappeared(String packageName, int reason) { 21176fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // remove all receivers associated with this package name 21186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 21196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<Receiver> deadReceivers = null; 21206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 21216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Receiver receiver : mReceivers.values()) { 21226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (receiver.mPackageName.equals(packageName)) { 21236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (deadReceivers == null) { 21246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly deadReceivers = new ArrayList<Receiver>(); 21259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21266fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly deadReceivers.add(receiver); 21279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // perform removal outside of mReceivers loop 21316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (deadReceivers != null) { 21326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Receiver receiver : deadReceivers) { 21336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeUpdatesLocked(receiver); 21349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21380528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood }; 21399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Geocoder 21419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2142e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 2143e15735a9e0c0b1448b68f2d6b3247404fc1df417Mike Lockwood public boolean geocoderIsPresent() { 214401ac80b715881db22bde8b31633dd8a4dc375389Mark Vandevoorde return mGeocodeProvider != null; 214501ac80b715881db22bde8b31633dd8a4dc375389Mark Vandevoorde } 214601ac80b715881db22bde8b31633dd8a4dc375389Mark Vandevoorde 2147e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 21489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getFromLocation(double latitude, double longitude, int maxResults, 214934901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwood GeocoderParams params, List<Address> addrs) { 2150a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood if (mGeocodeProvider != null) { 2151628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood return mGeocodeProvider.getFromLocation(latitude, longitude, maxResults, 2152628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood params, addrs); 21539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2154a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood return null; 21559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2157a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 2158e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 21599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getFromLocationName(String locationName, 2160a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood double lowerLeftLatitude, double lowerLeftLongitude, 2161a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood double upperRightLatitude, double upperRightLongitude, int maxResults, 216234901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwood GeocoderParams params, List<Address> addrs) { 2163a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 2164a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood if (mGeocodeProvider != null) { 2165628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood return mGeocodeProvider.getFromLocationName(locationName, lowerLeftLatitude, 2166628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood lowerLeftLongitude, upperRightLatitude, upperRightLongitude, 2167628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood maxResults, params, addrs); 21689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2169a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood return null; 21709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Mock Providers 21739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void checkMockPermissionsSafe() { 21759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean allowMocks = Settings.Secure.getInt(mContext.getContentResolver(), 21769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 1; 21779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allowMocks) { 21789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_MOCK_LOCATION secure setting"); 21799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) != 21829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageManager.PERMISSION_GRANTED) { 21839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission"); 2184e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 21859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 21869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2187e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 21886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void addTestProvider(String name, ProviderProperties properties) { 21899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 21909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2191a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood if (LocationManager.PASSIVE_PROVIDER.equals(name)) { 2192a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood throw new IllegalArgumentException("Cannot mock the passive location provider"); 2193a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood } 2194a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood 219586328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 21962f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 21976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly MockProvider provider = new MockProvider(name, this, properties); 21987566c1debebe072af76411e11d96810fd1409482Mike Lockwood // remove the real provider if we are replacing GPS or network provider 21997566c1debebe072af76411e11d96810fd1409482Mike Lockwood if (LocationManager.GPS_PROVIDER.equals(name) 22001332b53522e281012fefb34bfbcc68a03028f516Nick Pelly || LocationManager.NETWORK_PROVIDER.equals(name) 22011332b53522e281012fefb34bfbcc68a03028f516Nick Pelly || LocationManager.FUSED_PROVIDER.equals(name)) { 2202d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(name); 2203d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood if (p != null) { 22046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeProviderLocked(p); 22057566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 22067566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 220715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mProvidersByName.get(name) != null) { 22089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + name + "\" already exists"); 22099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly addProviderLocked(provider); 22117ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mMockProviders.put(name, provider); 22126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLastLocation.put(name, null); 22131b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie mLastLocationCoarseInterval.put(name, null); 22149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 22159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 221686328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 22179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2219e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 22209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeTestProvider(String provider) { 22219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 22222f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 2223a6d0b6f8518c7ee110c907166d53a8d46ead97f1You Kim MockProvider mockProvider = mMockProviders.remove(provider); 22247ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 22259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 22269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 222786328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 22286fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeProviderLocked(mProvidersByName.get(provider)); 22296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 22306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // reinstate real provider if available 22316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderInterface realProvider = mRealProviders.get(provider); 22326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (realProvider != null) { 22336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly addProviderLocked(realProvider); 22346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 22356fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLastLocation.put(provider, null); 22361b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie mLastLocationCoarseInterval.put(provider, null); 22379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 223886328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 22399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2242e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 22439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderLocation(String provider, Location loc) { 22449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 22452f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 22467ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 22477ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 22489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 22499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 225095427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood // clear calling identity so INSTALL_LOCATION_PROVIDER permission is not required 225195427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood long identity = Binder.clearCallingIdentity(); 22527ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.setLocation(loc); 225395427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood Binder.restoreCallingIdentity(identity); 22549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2257e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 22589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderLocation(String provider) { 22599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 22602f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 22617ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 22627ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 22639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 22649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22657ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.clearLocation(); 22669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 22709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderEnabled(String provider, boolean enabled) { 22719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 22722f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 22737ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 22747ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 22759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 22769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 227786328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 22789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enabled) { 22797ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.enable(); 22809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.add(provider); 22819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.remove(provider); 22829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 22837ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.disable(); 22849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.remove(provider); 22859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.add(provider); 22869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 228886328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 22899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 22919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2292e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 22939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderEnabled(String provider) { 22949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 22952f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 22967ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 22977ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 22989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 22999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 230086328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 23019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.remove(provider); 23029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.remove(provider); 23039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 230486328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 23059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2308e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 23099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) { 23109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 23112f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 23127ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 23137ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 23149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 23159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23167ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.setStatus(status, extras, updateTime); 23179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2320e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 23219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderStatus(String provider) { 23229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 23232f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 23247ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 23257ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 23269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 23279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23287ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.clearStatus(); 23299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void log(String log) { 23339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 23348a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.d(TAG, log); 23359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2337e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 2338e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 23399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 23409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 23419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 23420528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood pw.println("Permission Denial: can't dump LocationManagerService from from pid=" 23439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Binder.getCallingPid() 23449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 23459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 23469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2347e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 23482f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 23499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Current Location Manager state:"); 23509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Location Listeners:"); 23516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Receiver receiver : mReceivers.values()) { 23526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.println(" " + receiver); 23539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Records by Provider:"); 23556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Map.Entry<String, ArrayList<UpdateRecord>> entry : mRecordsByProvider.entrySet()) { 23566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.println(" " + entry.getKey() + ":"); 23576fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord record : entry.getValue()) { 23586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.println(" " + record); 23599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Last Known Locations:"); 23626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Map.Entry<String, Location> entry : mLastLocation.entrySet()) { 23636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String provider = entry.getKey(); 23646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Location location = entry.getValue(); 23656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.println(" " + provider + ": " + location); 23669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23676fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 23681b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie pw.println(" Last Known Locations Coarse Intervals:"); 23691b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie for (Map.Entry<String, Location> entry : mLastLocationCoarseInterval.entrySet()) { 23701b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie String provider = entry.getKey(); 23711b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie Location location = entry.getValue(); 23721b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie pw.println(" " + provider + ": " + location); 23731b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie } 23741b9b7b1f1b4479cc1c7003c75f9c05dfba8c56acDavid Christie 2375e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly mGeofenceManager.dump(pw); 23766fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 23779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabledProviders.size() > 0) { 23789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Enabled Providers:"); 23799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String i : mEnabledProviders) { 23809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i); 23819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2382e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 23839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDisabledProviders.size() > 0) { 23859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Disabled Providers:"); 23869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String i : mDisabledProviders) { 23879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i); 23889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23904035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly pw.append(" "); 23914035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly mBlacklist.dump(pw); 23929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMockProviders.size() > 0) { 23939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Mock Providers:"); 23949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, MockProvider> i : mMockProviders.entrySet()) { 23957ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood i.getValue().dump(pw, " "); 23969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 23986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 239974fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pelly pw.append(" fudger: "); 240074fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pelly mLocationFudger.dump(fd, pw, args); 240174fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pelly 24026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (args.length > 0 && "short".equals(args[0])) { 24036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return; 24046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 24053c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger for (LocationProviderInterface provider: mProviders) { 24066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.print(provider.getName() + " Internal State"); 24076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (provider instanceof LocationProviderProxy) { 24086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderProxy proxy = (LocationProviderProxy) provider; 24096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.print(" (" + proxy.getConnectedPackageName() + ")"); 24103c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 24116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.println(":"); 24126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly provider.dump(fd, pw, args); 24133c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 24149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 24169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2417