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 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.PendingIntent; 2038389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Leaseimport android.content.BroadcastReceiver; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 2438389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Leaseimport android.content.IntentFilter; 256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.content.pm.ApplicationInfo; 26fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamiltonimport android.content.pm.PackageInfo; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 286fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.content.pm.PackageManager.NameNotFoundException; 29fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamiltonimport android.content.pm.ResolveInfo; 30fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamiltonimport android.content.pm.Signature; 31628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwoodimport android.content.res.Resources; 32bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsuimport android.database.ContentObserver; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Address; 3403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwoodimport android.location.Criteria; 3534901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwoodimport android.location.GeocoderParams; 366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.location.Geofence; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.IGpsStatusListener; 3815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwoodimport android.location.IGpsStatusProvider; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.ILocationListener; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.ILocationManager; 4122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.location.INetInitiatedListener; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Location; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationManager; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationProvider; 456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.location.LocationRequest; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 503d12b51ee38537f6760a833618948f936e75561dMike Lockwoodimport android.os.Looper; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.PowerManager; 53e932f7f2a47b770c636443d411436bd29cc4bb43Mike Lockwoodimport android.os.Process; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.os.SystemClock; 565ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackbornimport android.os.UserHandle; 577e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackbornimport android.os.WorkSource; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 608a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 62e97ae40dffe7d7f8917c51c4f3f6c1b18c238565Mike Lockwoodimport com.android.internal.content.PackageMonitor; 636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport com.android.internal.location.ProviderProperties; 646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport com.android.internal.location.ProviderRequest; 6543e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.GeocoderProxy; 66e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pellyimport com.android.server.location.GeofenceManager; 6743e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.GpsLocationProvider; 684035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pellyimport com.android.server.location.LocationBlacklist; 6974fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pellyimport com.android.server.location.LocationFudger; 7043e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.LocationProviderInterface; 7143e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.LocationProviderProxy; 7243e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.MockProvider; 7343e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.PassiveProvider; 7443e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwood 7543e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.io.FileDescriptor; 7643e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.io.PrintWriter; 7743e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.ArrayList; 786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport java.util.Arrays; 7943e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.HashMap; 8043e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.HashSet; 8143e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.List; 8243e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.Map; 8343e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.Set; 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The service class that manages LocationProviders and issues location 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * updates and alerts. 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 89bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsupublic class LocationManagerService extends ILocationManager.Stub implements Runnable { 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "LocationManagerService"; 916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public static final boolean D = false; 926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final String WAKELOCK_KEY = TAG; 946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final String THREAD_NAME = TAG; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease // Location resolution level: no location data whatsoever 9737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private static final int RESOLUTION_LEVEL_NONE = 0; 9837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease // Location resolution level: coarse location data only 9937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private static final int RESOLUTION_LEVEL_COARSE = 1; 10037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease // Location resolution level: fine location data 10137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private static final int RESOLUTION_LEVEL_FINE = 2; 10237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_MOCK_LOCATION = 1046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly android.Manifest.permission.ACCESS_MOCK_LOCATION; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_LOCATION_EXTRA_COMMANDS = 1066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly android.Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS; 107275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood private static final String INSTALL_LOCATION_PROVIDER = 1086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly android.Manifest.permission.INSTALL_LOCATION_PROVIDER; 1096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final String NETWORK_LOCATION_SERVICE_ACTION = 1116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly "com.android.location.service.v2.NetworkLocationProvider"; 1126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final String FUSED_LOCATION_SERVICE_ACTION = 1136fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly "com.android.location.service.FusedLocationProvider"; 1146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1156fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final int MSG_LOCATION_CHANGED = 1; 1166fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 117f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly // Location Providers may sometimes deliver location updates 118f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly // slightly faster that requested - provide grace period so 119f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly // we don't unnecessarily filter events that are otherwise on 120f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly // time 1216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final int MAX_PROVIDER_SCHEDULING_JITTER_MS = 100; 122f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly 1236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final LocationRequest DEFAULT_LOCATION_REQUEST = new LocationRequest(); 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final Context mContext; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // used internally for synchronization 1286fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final Object mLock = new Object(); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // --- fields below are final after init() --- 13174fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pelly private LocationFudger mLocationFudger; 1326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private GeofenceManager mGeofenceManager; 1336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private PowerManager.WakeLock mWakeLock; 1346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private PackageManager mPackageManager; 135628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood private GeocoderProxy mGeocodeProvider; 13615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private IGpsStatusProvider mGpsStatusProvider; 13722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private INetInitiatedListener mNetInitiatedListener; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private LocationWorkerHandler mLocationHandler; 1394035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly private PassiveProvider mPassiveProvider; // track passive provider for special cases 1404035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly private LocationBlacklist mBlacklist; 1416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // --- fields below are protected by mWakeLock --- 1436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private int mPendingBroadcasts; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // --- fields below are protected by mLock --- 1466fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Set of providers that are explicitly enabled 1476fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final Set<String> mEnabledProviders = new HashSet<String>(); 1487566c1debebe072af76411e11d96810fd1409482Mike Lockwood 1496fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Set of providers that are explicitly disabled 1506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final Set<String> mDisabledProviders = new HashSet<String>(); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Mock (test) providers 1536fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final HashMap<String, MockProvider> mMockProviders = 1546fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new HashMap<String, MockProvider>(); 155e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 1566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // all receivers 1572f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final HashMap<Object, Receiver> mReceivers = new HashMap<Object, Receiver>(); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // currently installed providers (with mocks replacing real providers) 160d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood private final ArrayList<LocationProviderInterface> mProviders = 1616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new ArrayList<LocationProviderInterface>(); 16215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 1636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // real providers, saved here when mocked out 1646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final HashMap<String, LocationProviderInterface> mRealProviders = 1656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new HashMap<String, LocationProviderInterface>(); 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1676fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // mapping from provider name to provider 1686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final HashMap<String, LocationProviderInterface> mProvidersByName = 1696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new HashMap<String, LocationProviderInterface>(); 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // mapping from provider name to all its UpdateRecords 1726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final HashMap<String, ArrayList<UpdateRecord>> mRecordsByProvider = 1736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new HashMap<String, ArrayList<UpdateRecord>>(); 1746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // mapping from provider name to last known location 1766fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final HashMap<String, Location> mLastLocation = new HashMap<String, Location>(); 1777e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn 1786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // all providers that operate over proxy, for authorizing incoming location 1796fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final ArrayList<LocationProviderProxy> mProxyProviders = 1806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new ArrayList<LocationProviderProxy>(); 1816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 18238389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease // current active user on the device - other users are denied location data 18338389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease private int mCurrentUserId = UserHandle.USER_OWNER; 18438389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease 1856fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public LocationManagerService(Context context) { 1866fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly super(); 1876fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mContext = context; 1886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "Constructed"); 1906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // most startup is deferred until systemReady() 1926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 1936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void systemReady() { 1956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Thread thread = new Thread(null, this, THREAD_NAME); 1966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly thread.start(); 1976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 1986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 2006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void run() { 2016fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 2026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Looper.prepare(); 2036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLocationHandler = new LocationWorkerHandler(); 2046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly init(); 2056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Looper.loop(); 2066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 2076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 2086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void init() { 2096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "init()"); 2106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 2116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 2126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); 2136fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mPackageManager = mContext.getPackageManager(); 2146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 215bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu mBlacklist = new LocationBlacklist(mContext, mLocationHandler); 216bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu mBlacklist.init(); 217df9ec6171f6b7f3075d7f8174e9ae6ecf080c917Victoria Lease mLocationFudger = new LocationFudger(mContext, mLocationHandler); 218bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu 2196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 2206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly loadProvidersLocked(); 2216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 222bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu 2234035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly mGeofenceManager = new GeofenceManager(mContext, mBlacklist); 2246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 2256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // listen for settings changes 226bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu mContext.getContentResolver().registerContentObserver( 22775defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu Settings.Secure.getUriFor(Settings.Secure.LOCATION_PROVIDERS_ALLOWED), true, 228bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu new ContentObserver(mLocationHandler) { 229bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu @Override 230bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu public void onChange(boolean selfChange) { 231bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu synchronized (mLock) { 232bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu updateProvidersLocked(); 233bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu } 234bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu } 235b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease }, UserHandle.USER_ALL); 2366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mPackageMonitor.register(mContext, Looper.myLooper(), true); 237bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu 23838389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease // listen for user change 23938389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease IntentFilter intentFilter = new IntentFilter(); 24038389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease intentFilter.addAction(Intent.ACTION_USER_SWITCHED); 24138389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease 24238389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease mContext.registerReceiverAsUser(new BroadcastReceiver() { 24338389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease @Override 24438389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease public void onReceive(Context context, Intent intent) { 24538389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease String action = intent.getAction(); 24638389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease if (Intent.ACTION_USER_SWITCHED.equals(action)) { 24738389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); 24838389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease } 24938389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease } 25038389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease }, UserHandle.ALL, intentFilter, null, null); 25138389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease 252bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu updateProvidersLocked(); 2536fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 2546fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 255fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton private void ensureFallbackFusedProviderPresentLocked(ArrayList<String> pkgs) { 256fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton PackageManager pm = mContext.getPackageManager(); 257fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton String systemPackageName = mContext.getPackageName(); 258fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton ArrayList<HashSet<Signature>> sigSets = ServiceWatcher.getSignatureSets(mContext, pkgs); 259fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 260fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton List<ResolveInfo> rInfos = pm.queryIntentServicesAsUser( 261fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton new Intent(FUSED_LOCATION_SERVICE_ACTION), 262fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton PackageManager.GET_META_DATA, mCurrentUserId); 263fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton for (ResolveInfo rInfo : rInfos) { 264fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton String packageName = rInfo.serviceInfo.packageName; 265fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 266fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // Check that the signature is in the list of supported sigs. If it's not in 267fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // this list the standard provider binding logic won't bind to it. 268fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton try { 269fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton PackageInfo pInfo; 270fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton pInfo = pm.getPackageInfo(packageName, PackageManager.GET_SIGNATURES); 271fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (!ServiceWatcher.isSignatureMatch(pInfo.signatures, sigSets)) { 272fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton Log.w(TAG, packageName + " resolves service " + FUSED_LOCATION_SERVICE_ACTION + 273fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton ", but has wrong signature, ignoring"); 274fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton continue; 275fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 276fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } catch (NameNotFoundException e) { 277fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton Log.e(TAG, "missing package: " + packageName); 278fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton continue; 279fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 280fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 281fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // Get the version info 282fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (rInfo.serviceInfo.metaData == null) { 283fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton Log.w(TAG, "Found fused provider without metadata: " + packageName); 284fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton continue; 285fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 286fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 287fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton int version = rInfo.serviceInfo.metaData.getInt( 288fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton ServiceWatcher.EXTRA_SERVICE_VERSION, -1); 289fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (version == 0) { 290fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // This should be the fallback fused location provider. 291fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 292fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // Make sure it's in the system partition. 293fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if ((rInfo.serviceInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) { 294fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (D) Log.d(TAG, "Fallback candidate not in /system: " + packageName); 295fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton continue; 296fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 297fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 298fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // Check that the fallback is signed the same as the OS 299fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // as a proxy for coreApp="true" 300fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (pm.checkSignatures(systemPackageName, packageName) 301fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton != PackageManager.SIGNATURE_MATCH) { 302fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (D) Log.d(TAG, "Fallback candidate not signed the same as system: " 303fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton + packageName); 304fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton continue; 305fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 306fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 307fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton // Found a valid fallback. 308fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (D) Log.d(TAG, "Found fallback provider: " + packageName); 309fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton return; 310fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } else { 311fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (D) Log.d(TAG, "Fallback candidate not version 0: " + packageName); 312fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 313fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 314fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 315fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton throw new IllegalStateException("Unable to find a fused location provider that is in the " 316fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton + "system partition with version 0 and signed with the platform certificate. " 317fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton + "Such a package is needed to provide a default fused location provider in the " 318fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton + "event that no other fused location provider has been installed or is currently " 319fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton + "available. For example, coreOnly boot mode when decrypting the data " 320fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton + "partition. The fallback must also be marked coreApp=\"true\" in the manifest"); 321fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton } 322fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 3236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void loadProvidersLocked() { 3245c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease // create a passive location provider, which is always enabled 3255c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease PassiveProvider passiveProvider = new PassiveProvider(this); 3265c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease addProviderLocked(passiveProvider); 3275c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease mEnabledProviders.add(passiveProvider.getName()); 3285c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease mPassiveProvider = passiveProvider; 3295c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease 3306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (GpsLocationProvider.isSupported()) { 3316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Create a gps location provider 3326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this); 3336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mGpsStatusProvider = gpsProvider.getGpsStatusProvider(); 3346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mNetInitiatedListener = gpsProvider.getNetInitiatedListener(); 3356fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly addProviderLocked(gpsProvider); 3366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mRealProviders.put(LocationManager.GPS_PROVIDER, gpsProvider); 3376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly /* 3406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Load package name(s) containing location provider support. 3416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly These packages can contain services implementing location providers: 3426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Geocoder Provider, Network Location Provider, and 3436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Fused Location Provider. They will each be searched for 3446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly service components implementing these providers. 3456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly The location framework also has support for installation 3466fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly of new location providers at run-time. The new package does not 3476fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly have to be explicitly listed here, however it must have a signature 3486fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly that matches the signature of at least one package on this list. 3496fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly */ 3506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Resources resources = mContext.getResources(); 3516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<String> providerPackageNames = new ArrayList<String>(); 352fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton String[] pkgs = resources.getStringArray( 3536fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly com.android.internal.R.array.config_locationProviderPackageNames); 354fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (D) Log.d(TAG, "certificates for location providers pulled from: " + 355fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton Arrays.toString(pkgs)); 356fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton if (pkgs != null) providerPackageNames.addAll(Arrays.asList(pkgs)); 357fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton 358fbadb69978be578cea9d2bf038de7c79b0787e4fJeff Hamilton ensureFallbackFusedProviderPresentLocked(providerPackageNames); 3596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 3606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // bind to network provider 3616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderProxy networkProvider = LocationProviderProxy.createAndBind( 3626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mContext, 3636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationManager.NETWORK_PROVIDER, 3646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly NETWORK_LOCATION_SERVICE_ACTION, 365b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease providerPackageNames, mLocationHandler, mCurrentUserId); 3666fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (networkProvider != null) { 3676fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mRealProviders.put(LocationManager.NETWORK_PROVIDER, networkProvider); 3686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mProxyProviders.add(networkProvider); 3696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly addProviderLocked(networkProvider); 3706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 3716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Slog.w(TAG, "no network location provider found"); 3726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 3736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 3746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // bind to fused provider 3756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderProxy fusedLocationProvider = LocationProviderProxy.createAndBind( 3766fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mContext, 3776fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationManager.FUSED_PROVIDER, 3786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly FUSED_LOCATION_SERVICE_ACTION, 379b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease providerPackageNames, mLocationHandler, mCurrentUserId); 3806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (fusedLocationProvider != null) { 3816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly addProviderLocked(fusedLocationProvider); 3826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mProxyProviders.add(fusedLocationProvider); 3836fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mEnabledProviders.add(fusedLocationProvider.getName()); 384c3575188c2f2ad27b1f03b9b9c0705a686a5e42fKenny Root mRealProviders.put(LocationManager.FUSED_PROVIDER, fusedLocationProvider); 3856fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 3866fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Slog.e(TAG, "no fused location provider found", 3876fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new IllegalStateException("Location service needs a fused location provider")); 3886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // bind to geocoder provider 391b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease mGeocodeProvider = GeocoderProxy.createAndBind(mContext, providerPackageNames, 392b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease mCurrentUserId); 3936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (mGeocodeProvider == null) { 3946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Slog.e(TAG, "no geocoder provider found"); 3956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 3966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 3979637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 39938389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease * Called when the device's active user changes. 40038389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease * @param userId the new active user's UserId 40138389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease */ 40238389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease private void switchUser(int userId) { 40383762d22c9bde92d412cf5a263a228d705606721Victoria Lease mBlacklist.switchUser(userId); 40438389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease synchronized (mLock) { 405b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease mLastLocation.clear(); 406b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease for (LocationProviderInterface p : mProviders) { 407b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease updateProviderListenersLocked(p.getName(), false, mCurrentUserId); 408269518e83efc01b387235d6194dcf93726e384ffVictoria Lease p.switchUser(userId); 409b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 41038389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease mCurrentUserId = userId; 411b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease updateProvidersLocked(); 41238389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease } 41338389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease } 41438389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease 41538389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease /** 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A wrapper class holding either an ILocationListener or a PendingIntent to receive 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * location updates. 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 41948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private final class Receiver implements IBinder.DeathRecipient, PendingIntent.OnFinished { 4206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int mUid; // uid of receiver 4216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int mPid; // pid of receiver 4226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final String mPackageName; // package name of receiver 42337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease final int mAllowedResolutionLevel; // resolution level allowed to receiver 4246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ILocationListener mListener; 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PendingIntent mPendingIntent; 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Object mKey; 4286fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 4292f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>(); 430f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly 43148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood int mPendingBroadcasts; 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Receiver(ILocationListener listener, PendingIntent intent, int pid, int uid, 4346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String packageName) { 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingIntent = intent; 4376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (listener != null) { 4386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mKey = listener.asBinder(); 4396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 4406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mKey = intent; 4416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 44237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease mAllowedResolutionLevel = getAllowedResolutionLevel(pid, uid); 4436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mUid = uid; 4446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mPid = pid; 4456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mPackageName = packageName; 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean equals(Object otherObj) { 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (otherObj instanceof Receiver) { 4516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return mKey.equals(((Receiver)otherObj).mKey); 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int hashCode() { 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mKey.hashCode(); 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4603681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 4636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly StringBuilder s = new StringBuilder(); 4646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append("Reciever["); 4656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(Integer.toHexString(System.identityHashCode(this))); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 4676fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(" listener"); 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(" intent"); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (String p : mUpdateRecords.keySet()) { 4726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(" ").append(mUpdateRecords.get(p).toString()); 4736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 4746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append("]"); 4756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return s.toString(); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isListener() { 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mListener != null; 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isPendingIntent() { 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPendingIntent != null; 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ILocationListener getListener() { 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mListener; 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("Request for non-existent listener"); 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean callStatusChangedLocked(String provider, int status, Bundle extras) { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 49648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 49748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 49848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 49948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onStatusChanged(provider, status, extras); 500e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // call this after broadcasting so we do not increment 501e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // if we throw an exeption. 502e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly incrementPendingBroadcastsLocked(); 50348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent statusChanged = new Intent(); 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project statusChanged.putExtras(extras); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project statusChanged.putExtra(LocationManager.KEY_STATUS_CHANGED, status); 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 51248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 51348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 51448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 5156c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn mPendingIntent.send(mContext, 0, statusChanged, this, mLocationHandler, 51637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease getResolutionPermission(mAllowedResolutionLevel)); 51748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 51848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 51948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 52048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean callLocationChangedLocked(Location location) { 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 53148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 53248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 53348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 53448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onLocationChanged(location); 535e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // call this after broadcasting so we do not increment 536e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // if we throw an exeption. 537e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly incrementPendingBroadcastsLocked(); 53848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent locationChanged = new Intent(); 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED, location); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 54648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 54748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 54848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 5496c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn mPendingIntent.send(mContext, 0, locationChanged, this, mLocationHandler, 55037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease getResolutionPermission(mAllowedResolutionLevel)); 55148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 55248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 55348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 55448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 55548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } catch (PendingIntent.CanceledException e) { 55648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return false; 55748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 55848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 55948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return true; 56048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 56148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 56248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public boolean callProviderEnabledLocked(String provider, boolean enabled) { 56348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mListener != null) { 56448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood try { 56548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 56648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 56748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 56848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (enabled) { 56948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onProviderEnabled(provider); 57048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } else { 57148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onProviderDisabled(provider); 57248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 573e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // call this after broadcasting so we do not increment 574e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // if we throw an exeption. 575e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly incrementPendingBroadcastsLocked(); 57648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 57748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } catch (RemoteException e) { 57848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return false; 57948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 58048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } else { 58148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood Intent providerIntent = new Intent(); 58248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood providerIntent.putExtra(LocationManager.KEY_PROVIDER_ENABLED, enabled); 58348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood try { 58448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 58548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 58648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 5876c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn mPendingIntent.send(mContext, 0, providerIntent, this, mLocationHandler, 58837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease getResolutionPermission(mAllowedResolutionLevel)); 58948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 59048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 59148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 59248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 600f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly @Override 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 6026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "Location listener died"); 6036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 6042f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeUpdatesLocked(this); 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 60748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 60848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mPendingBroadcasts > 0) { 60948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood LocationManagerService.this.decrementPendingBroadcasts(); 61048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mPendingBroadcasts = 0; 61148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 61248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 61348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 61448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 615e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 61648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public void onSendFinished(PendingIntent pendingIntent, Intent intent, 61748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood int resultCode, String resultData, Bundle resultExtras) { 6180528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (this) { 6190528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood decrementPendingBroadcastsLocked(); 6200528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 62148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 62248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 6230528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // this must be called while synchronized by caller in a synchronized block 62448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // containing the sending of the broadcaset 62548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private void incrementPendingBroadcastsLocked() { 62648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mPendingBroadcasts++ == 0) { 6270528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood LocationManagerService.this.incrementPendingBroadcasts(); 62848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 62948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 63048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 6310528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private void decrementPendingBroadcastsLocked() { 6320528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (--mPendingBroadcasts == 0) { 6330528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood LocationManagerService.this.decrementPendingBroadcasts(); 63448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 63548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 63648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 63748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 638e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 63948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public void locationCallbackFinished(ILocationListener listener) { 640080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //Do not use getReceiver here as that will add the ILocationListener to 641080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //the receiver list if it is not found. If it is not found then the 642080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //LocationListener was removed when it had a pending broadcast and should 643080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //not be added back. 644080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel IBinder binder = listener.asBinder(); 645080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel Receiver receiver = mReceivers.get(binder); 64648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (receiver != null) { 6470528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (receiver) { 6480528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // so wakelock calls will succeed 6490528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood long identity = Binder.clearCallingIdentity(); 6500528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood receiver.decrementPendingBroadcastsLocked(); 6510528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood Binder.restoreCallingIdentity(identity); 6520528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void addProviderLocked(LocationProviderInterface provider) { 65715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProviders.add(provider); 65815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProvidersByName.put(provider.getName(), provider); 65915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 66015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 6616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void removeProviderLocked(LocationProviderInterface provider) { 6626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly provider.disable(); 66315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProviders.remove(provider); 66415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProvidersByName.remove(provider.getName()); 66515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 66615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 6673d12b51ee38537f6760a833618948f936e75561dMike Lockwood 668269518e83efc01b387235d6194dcf93726e384ffVictoria Lease private boolean isAllowedBySettingsLocked(String provider, int userId) { 669269518e83efc01b387235d6194dcf93726e384ffVictoria Lease if (userId != mCurrentUserId) { 670b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease return false; 671b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabledProviders.contains(provider)) { 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDisabledProviders.contains(provider)) { 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Use system settings 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver resolver = mContext.getContentResolver(); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 681b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease return Settings.Secure.isLocationProviderEnabledForUser(resolver, provider, mCurrentUserId); 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6846fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly /** 68537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Returns the permission string associated with the specified resolution level. 68637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 68737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param resolutionLevel the resolution level 68837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @return the permission string 6896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly */ 69037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private String getResolutionPermission(int resolutionLevel) { 69137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease switch (resolutionLevel) { 69237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease case RESOLUTION_LEVEL_FINE: 69337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return android.Manifest.permission.ACCESS_FINE_LOCATION; 69437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease case RESOLUTION_LEVEL_COARSE: 69537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return android.Manifest.permission.ACCESS_COARSE_LOCATION; 69637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease default: 69737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return null; 6986c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn } 699da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease } 7006c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn 701da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease /** 70237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Returns the resolution level allowed to the given PID/UID pair. 70337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 70437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param pid the PID 70537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param uid the UID 70637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @return resolution level allowed to the pid/uid pair 707da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease */ 70837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private int getAllowedResolutionLevel(int pid, int uid) { 70937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (mContext.checkPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, 71037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease pid, uid) == PackageManager.PERMISSION_GRANTED) { 71137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_FINE; 71237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease } else if (mContext.checkPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION, 71337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease pid, uid) == PackageManager.PERMISSION_GRANTED) { 71437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_COARSE; 71537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease } else { 71637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_NONE; 717da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease } 7184fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease } 7194fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease 7204fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease /** 72137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Returns the resolution level allowed to the caller 72237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 72337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @return resolution level allowed to caller 72437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease */ 72537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private int getCallerAllowedResolutionLevel() { 72637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return getAllowedResolutionLevel(Binder.getCallingPid(), Binder.getCallingUid()); 72737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease } 72837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease 72937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease /** 73037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Throw SecurityException if specified resolution level is insufficient to use geofences. 73137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 73237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param allowedResolutionLevel resolution level allowed to caller 7334fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease */ 73437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private void checkResolutionLevelIsSufficientForGeofenceUse(int allowedResolutionLevel) { 73537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) { 7364fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease throw new SecurityException("Geofence usage requires ACCESS_FINE_LOCATION permission"); 7374fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease } 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 74037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease /** 74137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Return the minimum resolution level required to use the specified location provider. 74237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 74337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param provider the name of the location provider 74437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @return minimum resolution level required for provider 74537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease */ 74637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private int getMinimumResolutionLevelForProviderUse(String provider) { 7478dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease if (LocationManager.GPS_PROVIDER.equals(provider) || 7488dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease LocationManager.PASSIVE_PROVIDER.equals(provider)) { 7498dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease // gps and passive providers require FINE permission 75037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_FINE; 7518dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease } else if (LocationManager.NETWORK_PROVIDER.equals(provider) || 7528dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease LocationManager.FUSED_PROVIDER.equals(provider)) { 7538dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease // network and fused providers are ok with COARSE or FINE 75437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_COARSE; 755941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu } else { 756941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu // mock providers 757941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu LocationProviderInterface lp = mMockProviders.get(provider); 758941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu if (lp != null) { 759941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu ProviderProperties properties = lp.getProperties(); 760941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu if (properties != null) { 761941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu if (properties.mRequiresSatellite) { 762941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu // provider requiring satellites require FINE permission 76337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_FINE; 764941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu } else if (properties.mRequiresNetwork || properties.mRequiresCell) { 765941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu // provider requiring network and or cell require COARSE or FINE 76637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_COARSE; 767941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu } 768941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu } 769941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu } 7708dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease } 77137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_FINE; // if in doubt, require FINE 772da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease } 773da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease 77437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease /** 77537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Throw SecurityException if specified resolution level is insufficient to use the named 77637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * location provider. 77737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 77837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param allowedResolutionLevel resolution level allowed to caller 77937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param providerName the name of the location provider 78037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease */ 78137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private void checkResolutionLevelIsSufficientForProviderUse(int allowedResolutionLevel, 78237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease String providerName) { 78337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease int requiredResolutionLevel = getMinimumResolutionLevelForProviderUse(providerName); 78437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (allowedResolutionLevel < requiredResolutionLevel) { 78537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease switch (requiredResolutionLevel) { 78637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease case RESOLUTION_LEVEL_FINE: 78737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease throw new SecurityException("\"" + providerName + "\" location provider " + 78837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease "requires ACCESS_FINE_LOCATION permission."); 78937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease case RESOLUTION_LEVEL_COARSE: 79037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease throw new SecurityException("\"" + providerName + "\" location provider " + 79137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease "requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission."); 79237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease default: 79337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease throw new SecurityException("Insufficient permission for \"" + providerName + 79437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease "\" location provider."); 795da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease } 796da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease } 7978dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease } 7988dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease 7996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly /** 8006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Returns all providers by name, including passive, but excluding 8010d21e2161f8542db0a54bf80b74b7fd33afef6f6Laurent Tu * fused, also including ones that are not permitted to 8020d21e2161f8542db0a54bf80b74b7fd33afef6f6Laurent Tu * be accessed by the calling activity or are currently disabled. 8036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly */ 804e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<String> getAllProviders() { 8066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<String> out; 8076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 8086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly out = new ArrayList<String>(mProviders.size()); 8096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (LocationProviderInterface provider : mProviders) { 8106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String name = provider.getName(); 8116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (LocationManager.FUSED_PROVIDER.equals(name)) { 8126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly continue; 8136fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 8146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly out.add(name); 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getAllProviders()=" + out); 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return out; 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly /** 8236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Return all providers by name, that match criteria and are optionally 8246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * enabled. 8256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Can return passive provider, but never returns fused provider. 8266fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly */ 827e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 82803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public List<String> getProviders(Criteria criteria, boolean enabledOnly) { 82937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease int allowedResolutionLevel = getCallerAllowedResolutionLevel(); 8306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<String> out; 831269518e83efc01b387235d6194dcf93726e384ffVictoria Lease int callingUserId = UserHandle.getCallingUserId(); 832269518e83efc01b387235d6194dcf93726e384ffVictoria Lease long identity = Binder.clearCallingIdentity(); 833b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease try { 834b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease synchronized (mLock) { 835b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease out = new ArrayList<String>(mProviders.size()); 836b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease for (LocationProviderInterface provider : mProviders) { 837b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease String name = provider.getName(); 838b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (LocationManager.FUSED_PROVIDER.equals(name)) { 8398dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease continue; 8408dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease } 84137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (allowedResolutionLevel >= getMinimumResolutionLevelForProviderUse(name)) { 842269518e83efc01b387235d6194dcf93726e384ffVictoria Lease if (enabledOnly && !isAllowedBySettingsLocked(name, callingUserId)) { 843b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease continue; 844b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 845b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (criteria != null && !LocationProvider.propertiesMeetCriteria( 846b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease name, provider.getProperties(), criteria)) { 847b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease continue; 848b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 849b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease out.add(name); 8508dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease } 85103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 853b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } finally { 854b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease Binder.restoreCallingIdentity(identity); 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 85603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 8576fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getProviders()=" + out); 8586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return out; 85903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 86003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 86103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood /** 8626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Return the name of the best provider given a Criteria object. 8636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * This method has been deprecated from the public API, 8648dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease * and the whole LocationProvider (including #meetsCriteria) 8656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * has been deprecated as well. So this method now uses 8666fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * some simplified logic. 86703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood */ 868e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 86903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public String getBestProvider(Criteria criteria, boolean enabledOnly) { 8706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String result = null; 87103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 8726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly List<String> providers = getProviders(criteria, enabledOnly); 8738dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease if (!providers.isEmpty()) { 8746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly result = pickBest(providers); 8756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getBestProvider(" + criteria + ", " + enabledOnly + ")=" + result); 8766fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return result; 87703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 8786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly providers = getProviders(null, enabledOnly); 8798dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease if (!providers.isEmpty()) { 8806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly result = pickBest(providers); 8816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getBestProvider(" + criteria + ", " + enabledOnly + ")=" + result); 8826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return result; 88303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 88403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 8856fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getBestProvider(" + criteria + ", " + enabledOnly + ")=" + result); 8866fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return null; 8876fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 88803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 8896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private String pickBest(List<String> providers) { 8901925e290e7ac2801311cb4e732d1bc5a5f3e0c44Victoria Lease if (providers.contains(LocationManager.GPS_PROVIDER)) { 8916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return LocationManager.GPS_PROVIDER; 8921925e290e7ac2801311cb4e732d1bc5a5f3e0c44Victoria Lease } else if (providers.contains(LocationManager.NETWORK_PROVIDER)) { 8931925e290e7ac2801311cb4e732d1bc5a5f3e0c44Victoria Lease return LocationManager.NETWORK_PROVIDER; 8946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 8956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return providers.get(0); 89603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 89703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 89803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 899e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 90003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public boolean providerMeetsCriteria(String provider, Criteria criteria) { 90103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 90203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (p == null) { 90303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood throw new IllegalArgumentException("provider=" + provider); 90403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 9056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 9066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly boolean result = LocationProvider.propertiesMeetCriteria( 9076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly p.getName(), p.getProperties(), criteria); 9086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "providerMeetsCriteria(" + provider + ", " + criteria + ")=" + result); 9096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return result; 91003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 91103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateProvidersLocked() { 9130c5a04014d3833c9a82772a832d3bc6410fc52acBrad Fitzpatrick boolean changesMade = false; 91415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 915d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProviders.get(i); 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isEnabled = p.isEnabled(); 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = p.getName(); 918269518e83efc01b387235d6194dcf93726e384ffVictoria Lease boolean shouldBeEnabled = isAllowedBySettingsLocked(name, mCurrentUserId); 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isEnabled && !shouldBeEnabled) { 920b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease updateProviderListenersLocked(name, false, mCurrentUserId); 9210c5a04014d3833c9a82772a832d3bc6410fc52acBrad Fitzpatrick changesMade = true; 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!isEnabled && shouldBeEnabled) { 923b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease updateProviderListenersLocked(name, true, mCurrentUserId); 9240c5a04014d3833c9a82772a832d3bc6410fc52acBrad Fitzpatrick changesMade = true; 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9260c5a04014d3833c9a82772a832d3bc6410fc52acBrad Fitzpatrick } 9270c5a04014d3833c9a82772a832d3bc6410fc52acBrad Fitzpatrick if (changesMade) { 9285ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn mContext.sendBroadcastAsUser(new Intent(LocationManager.PROVIDERS_CHANGED_ACTION), 9295ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn UserHandle.ALL); 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 933b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease private void updateProviderListenersLocked(String provider, boolean enabled, int userId) { 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int listeners = 0; 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 936d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 9376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (p == null) return; 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Receiver> deadReceivers = null; 940e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records != null) { 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = records.size(); 9446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (int i = 0; i < N; i++) { 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UpdateRecord record = records.get(i); 946269518e83efc01b387235d6194dcf93726e384ffVictoria Lease if (UserHandle.getUserId(record.mReceiver.mUid) == userId) { 947b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease // Sends a notification message to the receiver 948b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) { 949b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (deadReceivers == null) { 950b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease deadReceivers = new ArrayList<Receiver>(); 951b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 952b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease deadReceivers.add(record.mReceiver); 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 954b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease listeners++; 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (deadReceivers != null) { 9606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (int i = deadReceivers.size() - 1; i >= 0; i--) { 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeUpdatesLocked(deadReceivers.get(i)); 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 964e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enabled) { 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.enable(); 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listeners > 0) { 9686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly applyRequirementsLocked(provider); 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.disable(); 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void applyRequirementsLocked(String provider) { 9766fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderInterface p = mProvidersByName.get(provider); 9776fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (p == null) return; 9786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 9806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly WorkSource worksource = new WorkSource(); 9816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ProviderRequest providerRequest = new ProviderRequest(); 9826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records != null) { 9846fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord record : records) { 985269518e83efc01b387235d6194dcf93726e384ffVictoria Lease if (UserHandle.getUserId(record.mReceiver.mUid) == mCurrentUserId) { 986b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease LocationRequest locationRequest = record.mRequest; 987b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease providerRequest.locationRequests.add(locationRequest); 988b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (locationRequest.getInterval() < providerRequest.interval) { 989b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease providerRequest.reportLocation = true; 990b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease providerRequest.interval = locationRequest.getInterval(); 991b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 9927e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 9937e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 9946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 9956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (providerRequest.reportLocation) { 9966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // calculate who to blame for power 9976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // This is somewhat arbitrary. We pick a threshold interval 9986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // that is slightly higher that the minimum interval, and 9996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // spread the blame across all applications with a request 10006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // under that threshold. 10016fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly long thresholdInterval = (providerRequest.interval + 1000) * 3 / 2; 10026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord record : records) { 1003269518e83efc01b387235d6194dcf93726e384ffVictoria Lease if (UserHandle.getUserId(record.mReceiver.mUid) == mCurrentUserId) { 1004b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease LocationRequest locationRequest = record.mRequest; 1005b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (locationRequest.getInterval() <= thresholdInterval) { 1006b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease worksource.add(record.mReceiver.mUid); 1007b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 10086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 10097e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 10136fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "provider request: " + provider + " " + providerRequest); 10146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly p.setRequest(providerRequest, worksource); 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class UpdateRecord { 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String mProvider; 10196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final LocationRequest mRequest; 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Receiver mReceiver; 10212f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Location mLastFixBroadcast; 10222f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood long mLastStatusBroadcast; 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Note: must be constructed with lock held. 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly UpdateRecord(String provider, LocationRequest request, Receiver receiver) { 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProvider = provider; 10296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mRequest = request; 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReceiver = receiver; 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records == null) { 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project records = new ArrayList<UpdateRecord>(); 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecordsByProvider.put(provider, records); 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!records.contains(this)) { 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project records.add(this); 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Method to be called when a record will no longer be used. Calling this multiple times 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * must have the same effect as calling it once. 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10466fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly void disposeLocked(boolean removeReceiver) { 10476fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // remove from mRecordsByProvider 10486fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<UpdateRecord> globalRecords = mRecordsByProvider.get(this.mProvider); 10496fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (globalRecords != null) { 10506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly globalRecords.remove(this); 10516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 10526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 10536fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (!removeReceiver) return; // the caller will handle the rest 10546fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 10556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // remove from Receiver#mUpdateRecords 10566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly HashMap<String, UpdateRecord> receiverRecords = mReceiver.mUpdateRecords; 10576fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (receiverRecords != null) { 10586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiverRecords.remove(this.mProvider); 10596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 10606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // and also remove the Receiver if it has no more update records 10616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (removeReceiver && receiverRecords.size() == 0) { 10626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeUpdatesLocked(mReceiver); 10636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 10643a76fd627945c1df59aa0318867401e0e53da022Mike Lockwood } 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 10696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly StringBuilder s = new StringBuilder(); 10706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append("UpdateRecord["); 10716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(mProvider); 10726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(' ').append(mReceiver.mPackageName).append('('); 10736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(mReceiver.mUid).append(')'); 10746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(' ').append(mRequest); 10756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(']'); 10766fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return s.toString(); 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private Receiver getReceiver(ILocationListener listener, int pid, int uid, String packageName) { 10812f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood IBinder binder = listener.asBinder(); 10822f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver receiver = mReceivers.get(binder); 10832f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (receiver == null) { 10846fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiver = new Receiver(listener, null, pid, uid, packageName); 10852f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mReceivers.put(binder, receiver); 10862f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 10872f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood try { 10886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiver.getListener().asBinder().linkToDeath(receiver, 0); 10892f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } catch (RemoteException e) { 10908a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "linkToDeath failed:", e); 10912f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return null; 10922f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 10932f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 10942f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return receiver; 10952f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 10962f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 10976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private Receiver getReceiver(PendingIntent intent, int pid, int uid, String packageName) { 10982f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver receiver = mReceivers.get(intent); 10992f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (receiver == null) { 11006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiver = new Receiver(null, intent, pid, uid, packageName); 11012f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mReceivers.put(intent, receiver); 11022f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 11032f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return receiver; 11042f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 11052f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 110637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease /** 110737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Creates a LocationRequest based upon the supplied LocationRequest that to meets resolution 110837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * and consistency requirements. 110937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 111037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param request the LocationRequest from which to create a sanitized version 111137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param shouldBeCoarse whether the sanitized version should be held to coarse resolution 111237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * constraints 111337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param fastestCoarseIntervalMS minimum interval allowed for coarse resolution 111437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @return a version of request that meets the given resolution and consistency requirements 111537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @hide 111637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease */ 111737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private LocationRequest createSanitizedRequest(LocationRequest request, int resolutionLevel) { 111837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease LocationRequest sanitizedRequest = new LocationRequest(request); 111937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (resolutionLevel < RESOLUTION_LEVEL_FINE) { 112037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease switch (sanitizedRequest.getQuality()) { 112109016ab4dd056a16809419d612cb865a14980880Victoria Lease case LocationRequest.ACCURACY_FINE: 112237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease sanitizedRequest.setQuality(LocationRequest.ACCURACY_BLOCK); 112309016ab4dd056a16809419d612cb865a14980880Victoria Lease break; 112409016ab4dd056a16809419d612cb865a14980880Victoria Lease case LocationRequest.POWER_HIGH: 112537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease sanitizedRequest.setQuality(LocationRequest.POWER_LOW); 112609016ab4dd056a16809419d612cb865a14980880Victoria Lease break; 112709016ab4dd056a16809419d612cb865a14980880Victoria Lease } 112809016ab4dd056a16809419d612cb865a14980880Victoria Lease // throttle 112937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (sanitizedRequest.getInterval() < LocationFudger.FASTEST_INTERVAL_MS) { 113037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease sanitizedRequest.setInterval(LocationFudger.FASTEST_INTERVAL_MS); 113109016ab4dd056a16809419d612cb865a14980880Victoria Lease } 113237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (sanitizedRequest.getFastestInterval() < LocationFudger.FASTEST_INTERVAL_MS) { 113337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease sanitizedRequest.setFastestInterval(LocationFudger.FASTEST_INTERVAL_MS); 113409016ab4dd056a16809419d612cb865a14980880Victoria Lease } 113574fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pelly } 11364e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly // make getFastestInterval() the minimum of interval and fastest interval 113737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (sanitizedRequest.getFastestInterval() > sanitizedRequest.getInterval()) { 11384e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly request.setFastestInterval(request.getInterval()); 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 114037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return sanitizedRequest; 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void checkPackageName(String packageName) { 1144e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly if (packageName == null) { 11456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new SecurityException("invalid package name: " + packageName); 1146e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 11476fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly int uid = Binder.getCallingUid(); 1148e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly String[] packages = mPackageManager.getPackagesForUid(uid); 1149e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly if (packages == null) { 1150e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly throw new SecurityException("invalid UID " + uid); 1151e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 1152e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly for (String pkg : packages) { 1153e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly if (packageName.equals(pkg)) return; 1154e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 11556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new SecurityException("invalid package name: " + packageName); 1156e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 1157e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 11586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void checkPendingIntent(PendingIntent intent) { 11596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (intent == null) { 11606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new IllegalArgumentException("invalid pending intent: " + intent); 11616c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn } 11626c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn } 11636c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn 11646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private Receiver checkListenerOrIntent(ILocationListener listener, PendingIntent intent, 11656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly int pid, int uid, String packageName) { 11666fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (intent == null && listener == null) { 11676fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new IllegalArgumentException("need eiter listener or intent"); 11686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else if (intent != null && listener != null) { 11696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new IllegalArgumentException("cannot register both listener and intent"); 11706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else if (intent != null) { 11716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPendingIntent(intent); 11726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return getReceiver(intent, pid, uid, packageName); 11736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 11746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return getReceiver(listener, pid, uid, packageName); 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 11796fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void requestLocationUpdates(LocationRequest request, ILocationListener listener, 11806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly PendingIntent intent, String packageName) { 11816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (request == null) request = DEFAULT_LOCATION_REQUEST; 11826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPackageName(packageName); 118337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease int allowedResolutionLevel = getCallerAllowedResolutionLevel(); 118437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, 118537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease request.getProvider()); 118637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel); 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int pid = Binder.getCallingPid(); 11896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int uid = Binder.getCallingUid(); 11906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Receiver recevier = checkListenerOrIntent(listener, intent, pid, uid, packageName); 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11922b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly // providers may use public location API's, need to clear identity 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identity = Binder.clearCallingIdentity(); 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 119637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease requestLocationUpdatesLocked(sanitizedRequest, recevier, pid, uid, packageName); 11972d4d1bf14b531de9d4238b1e41b53c77f8976405Mike Lockwood } 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(identity); 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void requestLocationUpdatesLocked(LocationRequest request, Receiver receiver, 12046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly int pid, int uid, String packageName) { 12056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Figure out the provider. Either its explicitly request (legacy use cases), or 12066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // use the fused provider 12076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (request == null) request = DEFAULT_LOCATION_REQUEST; 12086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String name = request.getProvider(); 120909016ab4dd056a16809419d612cb865a14980880Victoria Lease if (name == null) { 121009016ab4dd056a16809419d612cb865a14980880Victoria Lease throw new IllegalArgumentException("provider name must not be null"); 121109016ab4dd056a16809419d612cb865a14980880Victoria Lease } 12126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderInterface provider = mProvidersByName.get(name); 12136fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (provider == null) { 12146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new IllegalArgumentException("provider doesn't exisit: " + provider); 12156fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 12166fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 12177ff30113de68539ec840c524b8f1561f938f96c5Dianne Hackborn if (D) Log.d(TAG, "request " + Integer.toHexString(System.identityHashCode(receiver)) 12187ff30113de68539ec840c524b8f1561f938f96c5Dianne Hackborn + " " + name + " " + request + " from " + packageName + "(" + uid + ")"); 12196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 12206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly UpdateRecord record = new UpdateRecord(name, request, receiver); 12216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly UpdateRecord oldRecord = receiver.mUpdateRecords.put(name, record); 12226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (oldRecord != null) { 12236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly oldRecord.disposeLocked(false); 12246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 12256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1226269518e83efc01b387235d6194dcf93726e384ffVictoria Lease boolean isProviderEnabled = isAllowedBySettingsLocked(name, UserHandle.getUserId(uid)); 12276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (isProviderEnabled) { 12286fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly applyRequirementsLocked(name); 12296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 12306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Notify the listener that updates are currently disabled 12316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiver.callProviderEnabledLocked(name, false); 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1235e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 12366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void removeUpdates(ILocationListener listener, PendingIntent intent, 12376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String packageName) { 12386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPackageName(packageName); 123937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease 12406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int pid = Binder.getCallingPid(); 12416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int uid = Binder.getCallingUid(); 12426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Receiver receiver = checkListenerOrIntent(listener, intent, pid, uid, packageName); 12436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 12442b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly // providers may use public location API's, need to clear identity 12456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly long identity = Binder.clearCallingIdentity(); 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 12472f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 12486fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeUpdatesLocked(receiver); 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } finally { 12516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Binder.restoreCallingIdentity(identity); 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeUpdatesLocked(Receiver receiver) { 12567ff30113de68539ec840c524b8f1561f938f96c5Dianne Hackborn if (D) Log.i(TAG, "remove " + Integer.toHexString(System.identityHashCode(receiver))); 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) { 12596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiver.getListener().asBinder().unlinkToDeath(receiver, 0); 12606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (receiver) { 12616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (receiver.mPendingBroadcasts > 0) { 12626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly decrementPendingBroadcasts(); 12636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiver.mPendingBroadcasts = 0; 1264080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel } 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12666fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Record which providers were associated with this listener 12696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly HashSet<String> providers = new HashSet<String>(); 12706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly HashMap<String, UpdateRecord> oldRecords = receiver.mUpdateRecords; 12716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (oldRecords != null) { 12726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Call dispose() on the obsolete update records. 12736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord record : oldRecords.values()) { 12746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly record.disposeLocked(false); 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12766fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Accumulate providers 12776fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly providers.addAll(oldRecords.keySet()); 12786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // update provider 12816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (String provider : providers) { 12826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // If provider is already disabled, don't need to do anything 1283269518e83efc01b387235d6194dcf93726e384ffVictoria Lease if (!isAllowedBySettingsLocked(provider, mCurrentUserId)) { 12846fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly continue; 12856fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12876fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly applyRequirementsLocked(provider); 12886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 12896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 12924035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly public Location getLastLocation(LocationRequest request, String packageName) { 12936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getLastLocation: " + request); 12946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (request == null) request = DEFAULT_LOCATION_REQUEST; 129537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease int allowedResolutionLevel = getCallerAllowedResolutionLevel(); 12964035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly checkPackageName(packageName); 129737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, 129837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease request.getProvider()); 129937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease // no need to sanitize this request, as only the provider name is used 13004035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly 1301269518e83efc01b387235d6194dcf93726e384ffVictoria Lease long identity = Binder.clearCallingIdentity(); 1302b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease try { 1303b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (mBlacklist.isBlacklisted(packageName)) { 1304b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (D) Log.d(TAG, "not returning last loc for blacklisted app: " + 1305b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease packageName); 130609016ab4dd056a16809419d612cb865a14980880Victoria Lease return null; 130709016ab4dd056a16809419d612cb865a14980880Victoria Lease } 1308b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease 1309b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease synchronized (mLock) { 1310b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease // Figure out the provider. Either its explicitly request (deprecated API's), 1311b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease // or use the fused provider 1312b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease String name = request.getProvider(); 1313b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (name == null) name = LocationManager.FUSED_PROVIDER; 1314b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease LocationProviderInterface provider = mProvidersByName.get(name); 1315b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (provider == null) return null; 1316b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease 1317269518e83efc01b387235d6194dcf93726e384ffVictoria Lease if (!isAllowedBySettingsLocked(name, mCurrentUserId)) return null; 1318b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease 1319b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease Location location = mLastLocation.get(name); 1320b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (location == null) { 1321b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease return null; 1322b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 132337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) { 1324b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); 1325b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (noGPSLocation != null) { 1326b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease return mLocationFudger.getOrCreate(noGPSLocation); 1327b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 132837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease } else { 132937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return location; 133009016ab4dd056a16809419d612cb865a14980880Victoria Lease } 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1332b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease return null; 1333b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } finally { 1334b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease Binder.restoreCallingIdentity(identity); 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1338e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 13396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void requestGeofence(LocationRequest request, Geofence geofence, PendingIntent intent, 13406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String packageName) { 13416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (request == null) request = DEFAULT_LOCATION_REQUEST; 134237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease int allowedResolutionLevel = getCallerAllowedResolutionLevel(); 134337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForGeofenceUse(allowedResolutionLevel); 13446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPendingIntent(intent); 13456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPackageName(packageName); 134637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, 134737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease request.getProvider()); 134837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel); 13496fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 135037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (D) Log.d(TAG, "requestGeofence: " + sanitizedRequest + " " + geofence + " " + intent); 13516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 13522b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly // geo-fence manager uses the public location API, need to clear identity 13532b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly int uid = Binder.getCallingUid(); 135456e675b3a1c351de34de68a149762d3ad1b308c5Victoria Lease if (UserHandle.getUserId(uid) != UserHandle.USER_OWNER) { 135556e675b3a1c351de34de68a149762d3ad1b308c5Victoria Lease // temporary measure until geofences work for secondary users 135656e675b3a1c351de34de68a149762d3ad1b308c5Victoria Lease Log.w(TAG, "proximity alerts are currently available only to the primary user"); 135756e675b3a1c351de34de68a149762d3ad1b308c5Victoria Lease return; 135856e675b3a1c351de34de68a149762d3ad1b308c5Victoria Lease } 13592b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly long identity = Binder.clearCallingIdentity(); 13602b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly try { 136137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease mGeofenceManager.addFence(sanitizedRequest, geofence, intent, uid, packageName); 13622b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly } finally { 13632b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly Binder.restoreCallingIdentity(identity); 13642b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly } 13656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 13666fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 13676fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 13686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void removeGeofence(Geofence geofence, PendingIntent intent, String packageName) { 136937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForGeofenceUse(getCallerAllowedResolutionLevel()); 13706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPendingIntent(intent); 13716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPackageName(packageName); 13726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 13736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "removeGeofence: " + geofence + " " + intent); 13746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 13752b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly // geo-fence manager uses the public location API, need to clear identity 13762b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly long identity = Binder.clearCallingIdentity(); 13772b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly try { 13782b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly mGeofenceManager.removeFence(geofence, intent); 13792b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly } finally { 13802b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly Binder.restoreCallingIdentity(identity); 13812b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly } 13826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 13836fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 13846fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 13856fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean addGpsStatusListener(IGpsStatusListener listener) { 138715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mGpsStatusProvider == null) { 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 139037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(), 139137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease LocationManager.GPS_PROVIDER); 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 139415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mGpsStatusProvider.addGpsStatusListener(listener); 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 13968a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "mGpsStatusProvider.addGpsStatusListener failed", e); 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1402e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeGpsStatusListener(IGpsStatusListener listener) { 14042f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 140515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood try { 140615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mGpsStatusProvider.removeGpsStatusListener(listener); 140715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } catch (Exception e) { 14088a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "mGpsStatusProvider.removeGpsStatusListener failed", e); 140915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1413e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String provider, String command, Bundle extras) { 1415c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood if (provider == null) { 1416c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood // throw NullPointerException to remain compatible with previous implementation 1417c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood throw new NullPointerException(); 1418c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood } 141937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(), 142037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease provider); 1421c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and check for ACCESS_LOCATION_EXTRA_COMMANDS 1423b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood if ((mContext.checkCallingOrSelfPermission(ACCESS_LOCATION_EXTRA_COMMANDS) 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_LOCATION_EXTRA_COMMANDS permission"); 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14282f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 1429d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 14306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (p == null) return false; 1431e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 1432d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return p.sendExtraCommand(command, extras); 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1436e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 14376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public boolean sendNiResponse(int notifId, int userResponse) { 143818ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood if (Binder.getCallingUid() != Process.myUid()) { 143918ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood throw new SecurityException( 144018ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood "calling sendNiResponse from outside of the system is not allowed"); 144118ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood } 144222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie try { 144322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return mNetInitiatedListener.sendNiResponse(notifId, userResponse); 14446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } catch (RemoteException e) { 14458a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "RemoteException in LocationManagerService.sendNiResponse"); 144622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return false; 144722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 144822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 144922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1451628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood * @return null if the provider does not exist 1452f2db9fb0f877057a9ef56908d54f3c95fc3fd552Alexey Tarasov * @throws SecurityException if the provider is not allowed to be 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * accessed by the caller 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1455e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 14566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public ProviderProperties getProviderProperties(String provider) { 1457b7f9d254978b285bf04613f6e69a1afa89240ca9Laurent Tu if (mProvidersByName.get(provider) == null) { 1458b7f9d254978b285bf04613f6e69a1afa89240ca9Laurent Tu return null; 1459b7f9d254978b285bf04613f6e69a1afa89240ca9Laurent Tu } 1460b7f9d254978b285bf04613f6e69a1afa89240ca9Laurent Tu 146137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(), 146237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease provider); 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderInterface p; 14656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 14666fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly p = mProvidersByName.get(provider); 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (p == null) return null; 14706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return p.getProperties(); 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1473e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isProviderEnabled(String provider) { 147537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(), 147637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease provider); 14776fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (LocationManager.FUSED_PROVIDER.equals(provider)) return false; 14786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1479269518e83efc01b387235d6194dcf93726e384ffVictoria Lease long identity = Binder.clearCallingIdentity(); 1480b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease try { 1481b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease synchronized (mLock) { 1482b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease LocationProviderInterface p = mProvidersByName.get(provider); 1483b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (p == null) return false; 14846fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1485269518e83efc01b387235d6194dcf93726e384ffVictoria Lease return isAllowedBySettingsLocked(provider, mCurrentUserId); 1486b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 1487b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } finally { 1488b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease Binder.restoreCallingIdentity(identity); 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void checkCallerIsProvider() { 1493275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER) 14946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly == PackageManager.PERMISSION_GRANTED) { 14952eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly return; 14962eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly } 14972eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly 14986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Previously we only used the INSTALL_LOCATION_PROVIDER 14996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // check. But that is system or signature 15006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // protection level which is not flexible enough for 15016fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // providers installed oustide the system image. So 15026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // also allow providers with a UID matching the 15036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // currently bound package name 15044e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood 15056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly int uid = Binder.getCallingUid(); 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (mGeocodeProvider != null) { 15086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (doesPackageHaveUid(uid, mGeocodeProvider.getConnectedPackageName())) return; 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (LocationProviderProxy proxy : mProxyProviders) { 15116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (doesPackageHaveUid(uid, proxy.getConnectedPackageName())) return; 15126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 15136fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new SecurityException("need INSTALL_LOCATION_PROVIDER permission, " + 15146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly "or UID of a currently bound location provider"); 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15176fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private boolean doesPackageHaveUid(int uid, String packageName) { 15186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (packageName == null) { 15196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return false; 15204a7b65e0d544ef1feff8e1e5789f469f89ebb85cMike Lockwood } 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ApplicationInfo appInfo = mPackageManager.getApplicationInfo(packageName, 0); 15236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (appInfo.uid != uid) { 15246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return false; 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15266fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } catch (NameNotFoundException e) { 15276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return false; 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return true; 15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 15336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void reportLocation(Location location, boolean passive) { 15346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkCallerIsProvider(); 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (!location.isComplete()) { 15376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Log.w(TAG, "Dropping incomplete location: " + location); 15386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return; 15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLocationHandler.removeMessages(MSG_LOCATION_CHANGED, location); 15426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Message m = Message.obtain(mLocationHandler, MSG_LOCATION_CHANGED, location); 15436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly m.arg1 = (passive ? 1 : 0); 15446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLocationHandler.sendMessageAtFrontOfQueue(m); 15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15476fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 154875defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu private static boolean shouldBroadcastSafe( 154975defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu Location loc, Location lastLoc, UpdateRecord record, long now) { 15509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Always broadcast the first update 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lastLoc == null) { 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1555f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly // Check whether sufficient time has passed 15566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly long minTime = record.mRequest.getFastestInterval(); 15574118012da9a22694b3353040a485f8cdc27e2f17Philip Milne long delta = (loc.getElapsedRealtimeNanos() - lastLoc.getElapsedRealtimeNanos()) / 1000000L; 15586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (delta < minTime - MAX_PROVIDER_SCHEDULING_JITTER_MS) { 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check whether sufficient distance has been traveled 15636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly double minDistance = record.mRequest.getSmallestDisplacement(); 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (minDistance > 0.0) { 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (loc.distanceTo(lastLoc) <= minDistance) { 15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 157075defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu // Check whether sufficient number of udpates is left 157175defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu if (record.mRequest.getNumUpdates() <= 0) { 157275defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu return false; 157375defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu } 157475defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu 157575defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu // Check whether the expiry date has passed 157675defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu if (record.mRequest.getExpireAt() < now) { 157775defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu return false; 157875defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu } 157975defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1583a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood private void handleLocationChangedLocked(Location location, boolean passive) { 15844e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly if (D) Log.d(TAG, "incoming location: " + location); 15854e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly 15866fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly long now = SystemClock.elapsedRealtime(); 1587a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood String provider = (passive ? LocationManager.PASSIVE_PROVIDER : location.getProvider()); 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 158960ec50a850ac7265b662df3c872583b6ef581ef8Laurent Tu // Skip if the provider is unknown. 1590d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 15916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (p == null) return; 15926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 15936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Update last known locations 159409016ab4dd056a16809419d612cb865a14980880Victoria Lease Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); 159509016ab4dd056a16809419d612cb865a14980880Victoria Lease Location lastNoGPSLocation = null; 15966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Location lastLocation = mLastLocation.get(provider); 15974e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood if (lastLocation == null) { 15986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly lastLocation = new Location(provider); 15996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLastLocation.put(provider, lastLocation); 160009016ab4dd056a16809419d612cb865a14980880Victoria Lease } else { 160109016ab4dd056a16809419d612cb865a14980880Victoria Lease lastNoGPSLocation = lastLocation.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); 160209016ab4dd056a16809419d612cb865a14980880Victoria Lease if (noGPSLocation == null && lastNoGPSLocation != null) { 160309016ab4dd056a16809419d612cb865a14980880Victoria Lease // New location has no no-GPS location: adopt last no-GPS location. This is set 160409016ab4dd056a16809419d612cb865a14980880Victoria Lease // directly into location because we do not want to notify COARSE clients. 160509016ab4dd056a16809419d612cb865a14980880Victoria Lease location.setExtraLocation(Location.EXTRA_NO_GPS_LOCATION, lastNoGPSLocation); 160609016ab4dd056a16809419d612cb865a14980880Victoria Lease } 16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly lastLocation.set(location); 16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 161060ec50a850ac7265b662df3c872583b6ef581ef8Laurent Tu // Skip if there are no UpdateRecords for this provider. 161160ec50a850ac7265b662df3c872583b6ef581ef8Laurent Tu ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 161260ec50a850ac7265b662df3c872583b6ef581ef8Laurent Tu if (records == null || records.size() == 0) return; 161360ec50a850ac7265b662df3c872583b6ef581ef8Laurent Tu 161409016ab4dd056a16809419d612cb865a14980880Victoria Lease // Fetch coarse location 161509016ab4dd056a16809419d612cb865a14980880Victoria Lease Location coarseLocation = null; 161609016ab4dd056a16809419d612cb865a14980880Victoria Lease if (noGPSLocation != null && !noGPSLocation.equals(lastNoGPSLocation)) { 161709016ab4dd056a16809419d612cb865a14980880Victoria Lease coarseLocation = mLocationFudger.getOrCreate(noGPSLocation); 161809016ab4dd056a16809419d612cb865a14980880Victoria Lease } 161909016ab4dd056a16809419d612cb865a14980880Victoria Lease 16209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Fetch latest status update time 16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long newStatusUpdateTime = p.getStatusUpdateTime(); 16229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16237ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood // Get latest status 16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Bundle extras = new Bundle(); 16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int status = p.getStatus(extras); 16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Receiver> deadReceivers = null; 16286fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<UpdateRecord> deadUpdateRecords = null; 1629e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Broadcast location or status to all listeners 16316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord r : records) { 16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Receiver receiver = r.mReceiver; 163303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood boolean receiverDead = false; 16344035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly 1635269518e83efc01b387235d6194dcf93726e384ffVictoria Lease int receiverUserId = UserHandle.getUserId(receiver.mUid); 1636269518e83efc01b387235d6194dcf93726e384ffVictoria Lease if (receiverUserId != mCurrentUserId) { 1637b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (D) { 1638269518e83efc01b387235d6194dcf93726e384ffVictoria Lease Log.d(TAG, "skipping loc update for background user " + receiverUserId + 1639b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease " (current user: " + mCurrentUserId + ", app: " + 1640b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease receiver.mPackageName + ")"); 1641b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 1642b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease continue; 1643b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 1644b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease 16454035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly if (mBlacklist.isBlacklisted(receiver.mPackageName)) { 16464035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly if (D) Log.d(TAG, "skipping loc update for blacklisted app: " + 16474035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly receiver.mPackageName); 16484035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly continue; 16494035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly } 16504035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly 165109016ab4dd056a16809419d612cb865a14980880Victoria Lease Location notifyLocation = null; 165237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (receiver.mAllowedResolutionLevel < RESOLUTION_LEVEL_FINE) { 165337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease notifyLocation = coarseLocation; // use coarse location 16546fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 165537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease notifyLocation = lastLocation; // use fine location 16566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 165709016ab4dd056a16809419d612cb865a14980880Victoria Lease if (notifyLocation != null) { 165809016ab4dd056a16809419d612cb865a14980880Victoria Lease Location lastLoc = r.mLastFixBroadcast; 165975defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu if ((lastLoc == null) || shouldBroadcastSafe(notifyLocation, lastLoc, r, now)) { 166009016ab4dd056a16809419d612cb865a14980880Victoria Lease if (lastLoc == null) { 166109016ab4dd056a16809419d612cb865a14980880Victoria Lease lastLoc = new Location(notifyLocation); 166209016ab4dd056a16809419d612cb865a14980880Victoria Lease r.mLastFixBroadcast = lastLoc; 166309016ab4dd056a16809419d612cb865a14980880Victoria Lease } else { 166409016ab4dd056a16809419d612cb865a14980880Victoria Lease lastLoc.set(notifyLocation); 166509016ab4dd056a16809419d612cb865a14980880Victoria Lease } 166609016ab4dd056a16809419d612cb865a14980880Victoria Lease if (!receiver.callLocationChangedLocked(notifyLocation)) { 166709016ab4dd056a16809419d612cb865a14980880Victoria Lease Slog.w(TAG, "RemoteException calling onLocationChanged on " + receiver); 166809016ab4dd056a16809419d612cb865a14980880Victoria Lease receiverDead = true; 166909016ab4dd056a16809419d612cb865a14980880Victoria Lease } 167075defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu r.mRequest.decrementNumUpdates(); 16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16742f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood long prevStatusUpdateTime = r.mLastStatusBroadcast; 16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((newStatusUpdateTime > prevStatusUpdateTime) && 167609016ab4dd056a16809419d612cb865a14980880Victoria Lease (prevStatusUpdateTime != 0 || status != LocationProvider.AVAILABLE)) { 16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16782f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood r.mLastStatusBroadcast = newStatusUpdateTime; 16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!receiver.callStatusChangedLocked(provider, status, extras)) { 168003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood receiverDead = true; 16818a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "RemoteException calling onStatusChanged on " + receiver); 168203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 168303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 168403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 16856fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // track expired records 168675defb6f8840dcd2aaf866a5df9d689413fbe433Laurent Tu if (r.mRequest.getNumUpdates() <= 0 || r.mRequest.getExpireAt() < now) { 16876fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (deadUpdateRecords == null) { 16886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly deadUpdateRecords = new ArrayList<UpdateRecord>(); 16896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 16906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly deadUpdateRecords.add(r); 16916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 16926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // track dead receivers 16936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (receiverDead) { 169403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (deadReceivers == null) { 169503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood deadReceivers = new ArrayList<Receiver>(); 169603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 169703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (!deadReceivers.contains(receiver)) { 169803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood deadReceivers.add(receiver); 16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1702e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 17036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // remove dead records and receivers outside the loop 17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (deadReceivers != null) { 17056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Receiver receiver : deadReceivers) { 17066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeUpdatesLocked(receiver); 17076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 17086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 17096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (deadUpdateRecords != null) { 17106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord r : deadUpdateRecords) { 17116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly r.disposeLocked(true); 17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class LocationWorkerHandler extends Handler { 17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 17196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly switch (msg.what) { 17206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly case MSG_LOCATION_CHANGED: 17216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly handleLocationChanged((Location) msg.obj, msg.arg1 == 1); 17226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly break; 17236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 17246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 17256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 172698cb66797422c4ccdee6f1a07636146d784a471bMike Lockwood 17276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void handleLocationChanged(Location location, boolean passive) { 17286fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String provider = location.getProvider(); 17296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 17306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (!passive) { 17316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // notify passive provider of the new location 17326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mPassiveProvider.updateLocation(location); 17336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 17346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 17356fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 1736269518e83efc01b387235d6194dcf93726e384ffVictoria Lease if (isAllowedBySettingsLocked(provider, mCurrentUserId)) { 17376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly handleLocationChangedLocked(location, passive); 17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final PackageMonitor mPackageMonitor = new PackageMonitor() { 17430528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood @Override 17446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void onPackageDisappeared(String packageName, int reason) { 17456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // remove all receivers associated with this package name 17466fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 17476fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<Receiver> deadReceivers = null; 17486fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 17496fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Receiver receiver : mReceivers.values()) { 17506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (receiver.mPackageName.equals(packageName)) { 17516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (deadReceivers == null) { 17526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly deadReceivers = new ArrayList<Receiver>(); 17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17546fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly deadReceivers.add(receiver); 17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // perform removal outside of mReceivers loop 17596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (deadReceivers != null) { 17606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Receiver receiver : deadReceivers) { 17616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeUpdatesLocked(receiver); 17629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17660528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood }; 17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Wake locks 17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17700528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private void incrementPendingBroadcasts() { 17710528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (mWakeLock) { 17720528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (mPendingBroadcasts++ == 0) { 17730528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood try { 17740528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.acquire(); 17750528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood log("Acquired wakelock"); 17760528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } catch (Exception e) { 17770528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // This is to catch a runtime exception thrown when we try to release an 17780528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // already released lock. 17798a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "exception in acquireWakeLock()", e); 17800528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 17810528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 178248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 178348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 178448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 178548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private void decrementPendingBroadcasts() { 17860528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (mWakeLock) { 178748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (--mPendingBroadcasts == 0) { 17880528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood try { 17890528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Release wake lock 17900528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (mWakeLock.isHeld()) { 17910528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.release(); 17920528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood log("Released wakelock"); 17930528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } else { 17940528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood log("Can't release wakelock again!"); 17950528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 17960528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } catch (Exception e) { 17970528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // This is to catch a runtime exception thrown when we try to release an 17980528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // already released lock. 17998a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "exception in releaseWakeLock()", e); 18000528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 180148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 180248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 180348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 180448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Geocoder 18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1807e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 1808e15735a9e0c0b1448b68f2d6b3247404fc1df417Mike Lockwood public boolean geocoderIsPresent() { 180901ac80b715881db22bde8b31633dd8a4dc375389Mark Vandevoorde return mGeocodeProvider != null; 181001ac80b715881db22bde8b31633dd8a4dc375389Mark Vandevoorde } 181101ac80b715881db22bde8b31633dd8a4dc375389Mark Vandevoorde 1812e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getFromLocation(double latitude, double longitude, int maxResults, 181434901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwood GeocoderParams params, List<Address> addrs) { 1815a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood if (mGeocodeProvider != null) { 1816628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood return mGeocodeProvider.getFromLocation(latitude, longitude, maxResults, 1817628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood params, addrs); 18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1819a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood return null; 18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1822a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 1823e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getFromLocationName(String locationName, 1825a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood double lowerLeftLatitude, double lowerLeftLongitude, 1826a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood double upperRightLatitude, double upperRightLongitude, int maxResults, 182734901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwood GeocoderParams params, List<Address> addrs) { 1828a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 1829a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood if (mGeocodeProvider != null) { 1830628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood return mGeocodeProvider.getFromLocationName(locationName, lowerLeftLatitude, 1831628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood lowerLeftLongitude, upperRightLatitude, upperRightLongitude, 1832628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood maxResults, params, addrs); 18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1834a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood return null; 18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Mock Providers 18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void checkMockPermissionsSafe() { 18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean allowMocks = Settings.Secure.getInt(mContext.getContentResolver(), 18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 1; 18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allowMocks) { 18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_MOCK_LOCATION secure setting"); 18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) != 18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageManager.PERMISSION_GRANTED) { 18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission"); 1849e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1852e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 18536fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void addTestProvider(String name, ProviderProperties properties) { 18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1856a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood if (LocationManager.PASSIVE_PROVIDER.equals(name)) { 1857a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood throw new IllegalArgumentException("Cannot mock the passive location provider"); 1858a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood } 1859a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood 186086328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 18612f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly MockProvider provider = new MockProvider(name, this, properties); 18637566c1debebe072af76411e11d96810fd1409482Mike Lockwood // remove the real provider if we are replacing GPS or network provider 18647566c1debebe072af76411e11d96810fd1409482Mike Lockwood if (LocationManager.GPS_PROVIDER.equals(name) 18651332b53522e281012fefb34bfbcc68a03028f516Nick Pelly || LocationManager.NETWORK_PROVIDER.equals(name) 18661332b53522e281012fefb34bfbcc68a03028f516Nick Pelly || LocationManager.FUSED_PROVIDER.equals(name)) { 1867d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(name); 1868d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood if (p != null) { 18696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeProviderLocked(p); 18707566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 18717566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 187215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mProvidersByName.get(name) != null) { 18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + name + "\" already exists"); 18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly addProviderLocked(provider); 18767ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mMockProviders.put(name, provider); 18776fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLastLocation.put(name, null); 18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 188086328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1883e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeTestProvider(String provider) { 18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18862f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18877ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18887ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 189186328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 18926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeProviderLocked(mProvidersByName.get(provider)); 18937ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mMockProviders.remove(mockProvider); 18946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 18956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // reinstate real provider if available 18966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderInterface realProvider = mRealProviders.get(provider); 18976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (realProvider != null) { 18986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly addProviderLocked(realProvider); 18996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 19006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLastLocation.put(provider, null); 19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 190286328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1906e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderLocation(String provider, Location loc) { 19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 19092f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 19107ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 19117ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 191495427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood // clear calling identity so INSTALL_LOCATION_PROVIDER permission is not required 191595427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood long identity = Binder.clearCallingIdentity(); 19167ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.setLocation(loc); 191795427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood Binder.restoreCallingIdentity(identity); 19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1921e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderLocation(String provider) { 19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 19242f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 19257ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 19267ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19297ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.clearLocation(); 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1933e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderEnabled(String provider, boolean enabled) { 19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 19362f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 19377ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 19387ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 194186328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enabled) { 19437ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.enable(); 19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.add(provider); 19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.remove(provider); 19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 19477ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.disable(); 19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.remove(provider); 19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.add(provider); 19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 195286328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1956e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderEnabled(String provider) { 19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 19592f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 19607ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 19617ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 196486328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 19659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.remove(provider); 19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.remove(provider); 19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 196886328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 19699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1972e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 19739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) { 19749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 19752f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 19767ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 19777ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 19789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 19799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19807ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.setStatus(status, extras, updateTime); 19819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1984e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 19859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderStatus(String provider) { 19869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 19872f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 19887ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 19897ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 19909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 19919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19927ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.clearStatus(); 19939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void log(String log) { 19979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 19988a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.d(TAG, log); 19999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2001e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 2002e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 20039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 20049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 20059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 20060528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood pw.println("Permission Denial: can't dump LocationManagerService from from pid=" 20079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Binder.getCallingPid() 20089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 20099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 20109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2011e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 20122f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 20139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Current Location Manager state:"); 20149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Location Listeners:"); 20156fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Receiver receiver : mReceivers.values()) { 20166fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.println(" " + receiver); 20179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Records by Provider:"); 20196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Map.Entry<String, ArrayList<UpdateRecord>> entry : mRecordsByProvider.entrySet()) { 20206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.println(" " + entry.getKey() + ":"); 20216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord record : entry.getValue()) { 20226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.println(" " + record); 20239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Last Known Locations:"); 20266fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Map.Entry<String, Location> entry : mLastLocation.entrySet()) { 20276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String provider = entry.getKey(); 20286fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Location location = entry.getValue(); 20296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.println(" " + provider + ": " + location); 20309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 2032e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly mGeofenceManager.dump(pw); 20336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 20349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabledProviders.size() > 0) { 20359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Enabled Providers:"); 20369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String i : mEnabledProviders) { 20379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i); 20389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2039e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 20409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDisabledProviders.size() > 0) { 20429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Disabled Providers:"); 20439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String i : mDisabledProviders) { 20449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i); 20459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20474035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly pw.append(" "); 20484035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly mBlacklist.dump(pw); 20499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMockProviders.size() > 0) { 20509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Mock Providers:"); 20519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, MockProvider> i : mMockProviders.entrySet()) { 20527ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood i.getValue().dump(pw, " "); 20539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 205674fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pelly pw.append(" fudger: "); 205774fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pelly mLocationFudger.dump(fd, pw, args); 205874fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pelly 20596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (args.length > 0 && "short".equals(args[0])) { 20606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return; 20616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 20623c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger for (LocationProviderInterface provider: mProviders) { 20636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.print(provider.getName() + " Internal State"); 20646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (provider instanceof LocationProviderProxy) { 20656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderProxy proxy = (LocationProviderProxy) provider; 20666fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.print(" (" + proxy.getConnectedPackageName() + ")"); 20673c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 20686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.println(":"); 20696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly provider.dump(fd, pw, args); 20703c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 20719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 20739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2074