LocationManagerService.java revision 37425c3475877f2fdadb78f669ec57fecf82dca7
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; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.content.pm.PackageManager.NameNotFoundException; 28628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwoodimport android.content.res.Resources; 29bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsuimport android.database.ContentObserver; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Address; 3103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwoodimport android.location.Criteria; 3234901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwoodimport android.location.GeocoderParams; 336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.location.Geofence; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.IGpsStatusListener; 3515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwoodimport android.location.IGpsStatusProvider; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.ILocationListener; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.ILocationManager; 3822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.location.INetInitiatedListener; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Location; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationManager; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationProvider; 426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.location.LocationRequest; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 473d12b51ee38537f6760a833618948f936e75561dMike Lockwoodimport android.os.Looper; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.PowerManager; 50e932f7f2a47b770c636443d411436bd29cc4bb43Mike Lockwoodimport android.os.Process; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.os.SystemClock; 535ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackbornimport android.os.UserHandle; 547e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackbornimport android.os.WorkSource; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 578a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 59e97ae40dffe7d7f8917c51c4f3f6c1b18c238565Mike Lockwoodimport com.android.internal.content.PackageMonitor; 606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport com.android.internal.location.ProviderProperties; 616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport com.android.internal.location.ProviderRequest; 6243e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.GeocoderProxy; 63e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pellyimport com.android.server.location.GeofenceManager; 6443e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.GpsLocationProvider; 654035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pellyimport com.android.server.location.LocationBlacklist; 6674fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pellyimport com.android.server.location.LocationFudger; 6743e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.LocationProviderInterface; 6843e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.LocationProviderProxy; 6943e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.MockProvider; 7043e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport com.android.server.location.PassiveProvider; 7143e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwood 7243e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.io.FileDescriptor; 7343e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.io.PrintWriter; 7443e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.ArrayList; 756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport java.util.Arrays; 7643e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.HashMap; 7743e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.HashSet; 7843e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.List; 7943e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.Map; 8043e33f28721e4759d4edb0fad08d330bba74f25eMike Lockwoodimport java.util.Set; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The service class that manages LocationProviders and issues location 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * updates and alerts. 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 86bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsupublic class LocationManagerService extends ILocationManager.Stub implements Runnable { 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "LocationManagerService"; 886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public static final boolean D = false; 896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final String WAKELOCK_KEY = TAG; 916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final String THREAD_NAME = TAG; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease // Location resolution level: no location data whatsoever 9437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private static final int RESOLUTION_LEVEL_NONE = 0; 9537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease // Location resolution level: coarse location data only 9637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private static final int RESOLUTION_LEVEL_COARSE = 1; 9737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease // Location resolution level: fine location data 9837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private static final int RESOLUTION_LEVEL_FINE = 2; 9937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_MOCK_LOCATION = 1016fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly android.Manifest.permission.ACCESS_MOCK_LOCATION; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_LOCATION_EXTRA_COMMANDS = 1036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly android.Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS; 104275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood private static final String INSTALL_LOCATION_PROVIDER = 1056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly android.Manifest.permission.INSTALL_LOCATION_PROVIDER; 1066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final String NETWORK_LOCATION_SERVICE_ACTION = 1086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly "com.android.location.service.v2.NetworkLocationProvider"; 1096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final String FUSED_LOCATION_SERVICE_ACTION = 1106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly "com.android.location.service.FusedLocationProvider"; 1116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final int MSG_LOCATION_CHANGED = 1; 1136fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 114f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly // Location Providers may sometimes deliver location updates 115f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly // slightly faster that requested - provide grace period so 116f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly // we don't unnecessarily filter events that are otherwise on 117f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly // time 1186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final int MAX_PROVIDER_SCHEDULING_JITTER_MS = 100; 119f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly 1206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final LocationRequest DEFAULT_LOCATION_REQUEST = new LocationRequest(); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final Context mContext; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // used internally for synchronization 1256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final Object mLock = new Object(); 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // --- fields below are final after init() --- 12874fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pelly private LocationFudger mLocationFudger; 1296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private GeofenceManager mGeofenceManager; 1306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private PowerManager.WakeLock mWakeLock; 1316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private PackageManager mPackageManager; 132628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood private GeocoderProxy mGeocodeProvider; 13315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private IGpsStatusProvider mGpsStatusProvider; 13422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private INetInitiatedListener mNetInitiatedListener; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private LocationWorkerHandler mLocationHandler; 1364035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly private PassiveProvider mPassiveProvider; // track passive provider for special cases 1374035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly private LocationBlacklist mBlacklist; 1386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // --- fields below are protected by mWakeLock --- 1406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private int mPendingBroadcasts; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // --- fields below are protected by mLock --- 1436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Set of providers that are explicitly enabled 1446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final Set<String> mEnabledProviders = new HashSet<String>(); 1457566c1debebe072af76411e11d96810fd1409482Mike Lockwood 1466fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Set of providers that are explicitly disabled 1476fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final Set<String> mDisabledProviders = new HashSet<String>(); 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1496fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Mock (test) providers 1506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final HashMap<String, MockProvider> mMockProviders = 1516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new HashMap<String, MockProvider>(); 152e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 1536fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // all receivers 1542f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final HashMap<Object, Receiver> mReceivers = new HashMap<Object, Receiver>(); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // currently installed providers (with mocks replacing real providers) 157d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood private final ArrayList<LocationProviderInterface> mProviders = 1586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new ArrayList<LocationProviderInterface>(); 15915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 1606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // real providers, saved here when mocked out 1616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final HashMap<String, LocationProviderInterface> mRealProviders = 1626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new HashMap<String, LocationProviderInterface>(); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // mapping from provider name to provider 1656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final HashMap<String, LocationProviderInterface> mProvidersByName = 1666fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new HashMap<String, LocationProviderInterface>(); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // mapping from provider name to all its UpdateRecords 1696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final HashMap<String, ArrayList<UpdateRecord>> mRecordsByProvider = 1706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new HashMap<String, ArrayList<UpdateRecord>>(); 1716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // mapping from provider name to last known location 1736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final HashMap<String, Location> mLastLocation = new HashMap<String, Location>(); 1747e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn 1756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // all providers that operate over proxy, for authorizing incoming location 1766fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final ArrayList<LocationProviderProxy> mProxyProviders = 1776fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new ArrayList<LocationProviderProxy>(); 1786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 17938389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease // current active user on the device - other users are denied location data 18038389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease private int mCurrentUserId = UserHandle.USER_OWNER; 18138389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease 1826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public LocationManagerService(Context context) { 1836fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly super(); 1846fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mContext = context; 1856fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1866fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "Constructed"); 1876fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // most startup is deferred until systemReady() 1896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 1906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void systemReady() { 1926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Thread thread = new Thread(null, this, THREAD_NAME); 1936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly thread.start(); 1946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 1956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 1976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void run() { 1986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 1996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Looper.prepare(); 2006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLocationHandler = new LocationWorkerHandler(); 2016fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly init(); 2026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Looper.loop(); 2036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 2046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 2056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void init() { 2066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "init()"); 2076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 2086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 2096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); 2106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mPackageManager = mContext.getPackageManager(); 2116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 212bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu mBlacklist = new LocationBlacklist(mContext, mLocationHandler); 213bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu mBlacklist.init(); 214df9ec6171f6b7f3075d7f8174e9ae6ecf080c917Victoria Lease mLocationFudger = new LocationFudger(mContext, mLocationHandler); 215bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu 2166fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 2176fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly loadProvidersLocked(); 2186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 219bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu 2204035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly mGeofenceManager = new GeofenceManager(mContext, mBlacklist); 2216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 2226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // listen for settings changes 223bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu mContext.getContentResolver().registerContentObserver( 224bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu Settings.Secure.getUriFor(Settings.Secure.LOCATION_PROVIDERS_ALLOWED), true, 225bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu new ContentObserver(mLocationHandler) { 226bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu @Override 227bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu public void onChange(boolean selfChange) { 228bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu synchronized (mLock) { 229bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu updateProvidersLocked(); 230bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu } 231bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu } 232b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease }, UserHandle.USER_ALL); 2336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mPackageMonitor.register(mContext, Looper.myLooper(), true); 234bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu 23538389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease // listen for user change 23638389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease IntentFilter intentFilter = new IntentFilter(); 23738389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease intentFilter.addAction(Intent.ACTION_USER_SWITCHED); 23838389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease 23938389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease mContext.registerReceiverAsUser(new BroadcastReceiver() { 24038389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease @Override 24138389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease public void onReceive(Context context, Intent intent) { 24238389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease String action = intent.getAction(); 24338389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease if (Intent.ACTION_USER_SWITCHED.equals(action)) { 24438389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease switchUser(intent.getIntExtra(Intent.EXTRA_USER_HANDLE, 0)); 24538389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease } 24638389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease } 24738389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease }, UserHandle.ALL, intentFilter, null, null); 24838389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease 249bb95cb9f997afc34d54f3d5bcb247c44f368b62bBrian Muramatsu updateProvidersLocked(); 2506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 2516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 2526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void loadProvidersLocked() { 2535c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease // create a passive location provider, which is always enabled 2545c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease PassiveProvider passiveProvider = new PassiveProvider(this); 2555c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease addProviderLocked(passiveProvider); 2565c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease mEnabledProviders.add(passiveProvider.getName()); 2575c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease mPassiveProvider = passiveProvider; 2585c24fd03426db58b63e1a792c2595447cb722d46Victoria Lease 2596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (GpsLocationProvider.isSupported()) { 2606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Create a gps location provider 2616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this); 2626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mGpsStatusProvider = gpsProvider.getGpsStatusProvider(); 2636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mNetInitiatedListener = gpsProvider.getNetInitiatedListener(); 2646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly addProviderLocked(gpsProvider); 2656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mRealProviders.put(LocationManager.GPS_PROVIDER, gpsProvider); 2666fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly /* 2696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Load package name(s) containing location provider support. 2706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly These packages can contain services implementing location providers: 2716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Geocoder Provider, Network Location Provider, and 2726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Fused Location Provider. They will each be searched for 2736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly service components implementing these providers. 2746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly The location framework also has support for installation 2756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly of new location providers at run-time. The new package does not 2766fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly have to be explicitly listed here, however it must have a signature 2776fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly that matches the signature of at least one package on this list. 2786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly */ 2796fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Resources resources = mContext.getResources(); 2806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<String> providerPackageNames = new ArrayList<String>(); 2816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String[] pkgs1 = resources.getStringArray( 2826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly com.android.internal.R.array.config_locationProviderPackageNames); 2836fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String[] pkgs2 = resources.getStringArray( 2846fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly com.android.internal.R.array.config_overlay_locationProviderPackageNames); 2856fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "built-in location providers: " + Arrays.toString(pkgs1)); 2866fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "overlay location providers: " + Arrays.toString(pkgs2)); 2876fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (pkgs1 != null) providerPackageNames.addAll(Arrays.asList(pkgs1)); 2886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (pkgs2 != null) providerPackageNames.addAll(Arrays.asList(pkgs2)); 2896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 2906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // bind to network provider 2916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderProxy networkProvider = LocationProviderProxy.createAndBind( 2926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mContext, 2936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationManager.NETWORK_PROVIDER, 2946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly NETWORK_LOCATION_SERVICE_ACTION, 295b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease providerPackageNames, mLocationHandler, mCurrentUserId); 2966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (networkProvider != null) { 2976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mRealProviders.put(LocationManager.NETWORK_PROVIDER, networkProvider); 2986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mProxyProviders.add(networkProvider); 2996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly addProviderLocked(networkProvider); 3006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 3016fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Slog.w(TAG, "no network location provider found"); 3026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 3036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 3046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // bind to fused provider 3056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderProxy fusedLocationProvider = LocationProviderProxy.createAndBind( 3066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mContext, 3076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationManager.FUSED_PROVIDER, 3086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly FUSED_LOCATION_SERVICE_ACTION, 309b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease providerPackageNames, mLocationHandler, mCurrentUserId); 3106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (fusedLocationProvider != null) { 3116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly addProviderLocked(fusedLocationProvider); 3126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mProxyProviders.add(fusedLocationProvider); 3136fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mEnabledProviders.add(fusedLocationProvider.getName()); 314c3575188c2f2ad27b1f03b9b9c0705a686a5e42fKenny Root mRealProviders.put(LocationManager.FUSED_PROVIDER, fusedLocationProvider); 3156fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 3166fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Slog.e(TAG, "no fused location provider found", 3176fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly new IllegalStateException("Location service needs a fused location provider")); 3186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // bind to geocoder provider 321b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease mGeocodeProvider = GeocoderProxy.createAndBind(mContext, providerPackageNames, 322b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease mCurrentUserId); 3236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (mGeocodeProvider == null) { 3246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Slog.e(TAG, "no geocoder provider found"); 3256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 3266fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 3279637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 32938389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease * Called when the device's active user changes. 33038389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease * @param userId the new active user's UserId 33138389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease */ 33238389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease private void switchUser(int userId) { 33383762d22c9bde92d412cf5a263a228d705606721Victoria Lease mBlacklist.switchUser(userId); 33438389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease synchronized (mLock) { 335b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease mLastLocation.clear(); 336b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease for (LocationProviderInterface p : mProviders) { 337b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease updateProviderListenersLocked(p.getName(), false, mCurrentUserId); 338b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease p.switchUser(userId); 339b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 34038389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease mCurrentUserId = userId; 341b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease updateProvidersLocked(); 34238389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease } 34338389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease } 34438389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease 34538389b6cf7bd2ef49d2bd20ff1bca8677596590eVictoria Lease /** 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A wrapper class holding either an ILocationListener or a PendingIntent to receive 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * location updates. 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 34948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private final class Receiver implements IBinder.DeathRecipient, PendingIntent.OnFinished { 3506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int mUid; // uid of receiver 3516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int mPid; // pid of receiver 3526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final String mPackageName; // package name of receiver 35337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease final int mAllowedResolutionLevel; // resolution level allowed to receiver 3546fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ILocationListener mListener; 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PendingIntent mPendingIntent; 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Object mKey; 3586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 3592f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>(); 360f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly 36148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood int mPendingBroadcasts; 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Receiver(ILocationListener listener, PendingIntent intent, int pid, int uid, 3646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String packageName) { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingIntent = intent; 3676fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (listener != null) { 3686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mKey = listener.asBinder(); 3696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 3706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mKey = intent; 3716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 37237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease mAllowedResolutionLevel = getAllowedResolutionLevel(pid, uid); 3736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mUid = uid; 3746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mPid = pid; 3756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mPackageName = packageName; 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean equals(Object otherObj) { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (otherObj instanceof Receiver) { 3816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return mKey.equals(((Receiver)otherObj).mKey); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int hashCode() { 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mKey.hashCode(); 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3903681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 3936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly StringBuilder s = new StringBuilder(); 3946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append("Reciever["); 3956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(Integer.toHexString(System.identityHashCode(this))); 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 3976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(" listener"); 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(" intent"); 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4016fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (String p : mUpdateRecords.keySet()) { 4026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(" ").append(mUpdateRecords.get(p).toString()); 4036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 4046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append("]"); 4056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return s.toString(); 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isListener() { 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mListener != null; 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isPendingIntent() { 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPendingIntent != null; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ILocationListener getListener() { 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mListener; 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("Request for non-existent listener"); 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean callStatusChangedLocked(String provider, int status, Bundle extras) { 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 42648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 42748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 42848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 42948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onStatusChanged(provider, status, extras); 430e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // call this after broadcasting so we do not increment 431e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // if we throw an exeption. 432e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly incrementPendingBroadcastsLocked(); 43348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent statusChanged = new Intent(); 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project statusChanged.putExtras(extras); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project statusChanged.putExtra(LocationManager.KEY_STATUS_CHANGED, status); 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 44248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 44348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 44448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 4456c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn mPendingIntent.send(mContext, 0, statusChanged, this, mLocationHandler, 44637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease getResolutionPermission(mAllowedResolutionLevel)); 44748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 44848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 44948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 45048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean callLocationChangedLocked(Location location) { 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 46148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 46248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 46348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 46448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onLocationChanged(location); 465e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // call this after broadcasting so we do not increment 466e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // if we throw an exeption. 467e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly incrementPendingBroadcastsLocked(); 46848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent locationChanged = new Intent(); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED, location); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 47648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 47748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 47848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 4796c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn mPendingIntent.send(mContext, 0, locationChanged, this, mLocationHandler, 48037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease getResolutionPermission(mAllowedResolutionLevel)); 48148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 48248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 48348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 48448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 48548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } catch (PendingIntent.CanceledException e) { 48648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return false; 48748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 48848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 48948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return true; 49048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 49148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 49248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public boolean callProviderEnabledLocked(String provider, boolean enabled) { 49348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mListener != null) { 49448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood try { 49548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 49648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 49748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 49848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (enabled) { 49948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onProviderEnabled(provider); 50048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } else { 50148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onProviderDisabled(provider); 50248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 503e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // call this after broadcasting so we do not increment 504e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly // if we throw an exeption. 505e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly incrementPendingBroadcastsLocked(); 50648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 50748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } catch (RemoteException e) { 50848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return false; 50948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 51048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } else { 51148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood Intent providerIntent = new Intent(); 51248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood providerIntent.putExtra(LocationManager.KEY_PROVIDER_ENABLED, enabled); 51348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood try { 51448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 51548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 51648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 5176c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn mPendingIntent.send(mContext, 0, providerIntent, this, mLocationHandler, 51837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease getResolutionPermission(mAllowedResolutionLevel)); 51948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 52048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 52148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 52248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 530f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly @Override 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 5326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "Location listener died"); 5336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 5342f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeUpdatesLocked(this); 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 53748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 53848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mPendingBroadcasts > 0) { 53948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood LocationManagerService.this.decrementPendingBroadcasts(); 54048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mPendingBroadcasts = 0; 54148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 54248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 54348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 54448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 545e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 54648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public void onSendFinished(PendingIntent pendingIntent, Intent intent, 54748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood int resultCode, String resultData, Bundle resultExtras) { 5480528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (this) { 5490528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood decrementPendingBroadcastsLocked(); 5500528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 55148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 55248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 5530528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // this must be called while synchronized by caller in a synchronized block 55448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // containing the sending of the broadcaset 55548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private void incrementPendingBroadcastsLocked() { 55648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mPendingBroadcasts++ == 0) { 5570528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood LocationManagerService.this.incrementPendingBroadcasts(); 55848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 55948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 56048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 5610528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private void decrementPendingBroadcastsLocked() { 5620528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (--mPendingBroadcasts == 0) { 5630528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood LocationManagerService.this.decrementPendingBroadcasts(); 56448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 56548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 56648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 56748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 568e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 56948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public void locationCallbackFinished(ILocationListener listener) { 570080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //Do not use getReceiver here as that will add the ILocationListener to 571080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //the receiver list if it is not found. If it is not found then the 572080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //LocationListener was removed when it had a pending broadcast and should 573080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //not be added back. 574080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel IBinder binder = listener.asBinder(); 575080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel Receiver receiver = mReceivers.get(binder); 57648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (receiver != null) { 5770528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (receiver) { 5780528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // so wakelock calls will succeed 5790528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood long identity = Binder.clearCallingIdentity(); 5800528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood receiver.decrementPendingBroadcastsLocked(); 5810528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood Binder.restoreCallingIdentity(identity); 5820528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5866fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void addProviderLocked(LocationProviderInterface provider) { 58715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProviders.add(provider); 58815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProvidersByName.put(provider.getName(), provider); 58915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 59015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 5916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void removeProviderLocked(LocationProviderInterface provider) { 5926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly provider.disable(); 59315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProviders.remove(provider); 59415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProvidersByName.remove(provider.getName()); 59515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 59615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 5973d12b51ee38537f6760a833618948f936e75561dMike Lockwood 598b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease private boolean isAllowedBySettingsLocked(String provider, int userId) { 599b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (userId != mCurrentUserId) { 600b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease return false; 601b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabledProviders.contains(provider)) { 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDisabledProviders.contains(provider)) { 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Use system settings 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver resolver = mContext.getContentResolver(); 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 611b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease return Settings.Secure.isLocationProviderEnabledForUser(resolver, provider, mCurrentUserId); 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly /** 61537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Returns the permission string associated with the specified resolution level. 61637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 61737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param resolutionLevel the resolution level 61837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @return the permission string 6196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly */ 62037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private String getResolutionPermission(int resolutionLevel) { 62137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease switch (resolutionLevel) { 62237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease case RESOLUTION_LEVEL_FINE: 62337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return android.Manifest.permission.ACCESS_FINE_LOCATION; 62437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease case RESOLUTION_LEVEL_COARSE: 62537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return android.Manifest.permission.ACCESS_COARSE_LOCATION; 62637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease default: 62737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return null; 6286c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn } 629da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease } 6306c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn 631da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease /** 63237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Returns the resolution level allowed to the given PID/UID pair. 63337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 63437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param pid the PID 63537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param uid the UID 63637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @return resolution level allowed to the pid/uid pair 637da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease */ 63837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private int getAllowedResolutionLevel(int pid, int uid) { 63937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (mContext.checkPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, 64037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease pid, uid) == PackageManager.PERMISSION_GRANTED) { 64137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_FINE; 64237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease } else if (mContext.checkPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION, 64337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease pid, uid) == PackageManager.PERMISSION_GRANTED) { 64437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_COARSE; 64537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease } else { 64637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_NONE; 647da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease } 6484fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease } 6494fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease 6504fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease /** 65137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Returns the resolution level allowed to the caller 65237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 65337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @return resolution level allowed to caller 65437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease */ 65537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private int getCallerAllowedResolutionLevel() { 65637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return getAllowedResolutionLevel(Binder.getCallingPid(), Binder.getCallingUid()); 65737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease } 65837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease 65937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease /** 66037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Throw SecurityException if specified resolution level is insufficient to use geofences. 66137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 66237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param allowedResolutionLevel resolution level allowed to caller 6634fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease */ 66437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private void checkResolutionLevelIsSufficientForGeofenceUse(int allowedResolutionLevel) { 66537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) { 6664fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease throw new SecurityException("Geofence usage requires ACCESS_FINE_LOCATION permission"); 6674fab68b5324e1f9b6765cdc33e66d1f074623dc2Victoria Lease } 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 67037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease /** 67137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Return the minimum resolution level required to use the specified location provider. 67237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 67337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param provider the name of the location provider 67437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @return minimum resolution level required for provider 67537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease */ 67637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private int getMinimumResolutionLevelForProviderUse(String provider) { 6778dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease if (LocationManager.GPS_PROVIDER.equals(provider) || 6788dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease LocationManager.PASSIVE_PROVIDER.equals(provider)) { 6798dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease // gps and passive providers require FINE permission 68037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_FINE; 6818dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease } else if (LocationManager.NETWORK_PROVIDER.equals(provider) || 6828dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease LocationManager.FUSED_PROVIDER.equals(provider)) { 6838dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease // network and fused providers are ok with COARSE or FINE 68437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_COARSE; 685941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu } else { 686941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu // mock providers 687941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu LocationProviderInterface lp = mMockProviders.get(provider); 688941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu if (lp != null) { 689941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu ProviderProperties properties = lp.getProperties(); 690941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu if (properties != null) { 691941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu if (properties.mRequiresSatellite) { 692941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu // provider requiring satellites require FINE permission 69337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_FINE; 694941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu } else if (properties.mRequiresNetwork || properties.mRequiresCell) { 695941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu // provider requiring network and or cell require COARSE or FINE 69637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_COARSE; 697941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu } 698941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu } 699941221c1577a34c922c03b30be7ef0a4afda4278Laurent Tu } 7008dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease } 70137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return RESOLUTION_LEVEL_FINE; // if in doubt, require FINE 702da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease } 703da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease 70437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease /** 70537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Throw SecurityException if specified resolution level is insufficient to use the named 70637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * location provider. 70737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 70837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param allowedResolutionLevel resolution level allowed to caller 70937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param providerName the name of the location provider 71037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease */ 71137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private void checkResolutionLevelIsSufficientForProviderUse(int allowedResolutionLevel, 71237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease String providerName) { 71337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease int requiredResolutionLevel = getMinimumResolutionLevelForProviderUse(providerName); 71437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (allowedResolutionLevel < requiredResolutionLevel) { 71537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease switch (requiredResolutionLevel) { 71637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease case RESOLUTION_LEVEL_FINE: 71737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease throw new SecurityException("\"" + providerName + "\" location provider " + 71837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease "requires ACCESS_FINE_LOCATION permission."); 71937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease case RESOLUTION_LEVEL_COARSE: 72037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease throw new SecurityException("\"" + providerName + "\" location provider " + 72137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease "requires ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission."); 72237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease default: 72337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease throw new SecurityException("Insufficient permission for \"" + providerName + 72437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease "\" location provider."); 725da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease } 726da479c5f8c9675dc11b3d6c4024749064d54bb67Victoria Lease } 7278dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease } 7288dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease 7296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly /** 7306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Returns all providers by name, including passive, but excluding 7310d21e2161f8542db0a54bf80b74b7fd33afef6f6Laurent Tu * fused, also including ones that are not permitted to 7320d21e2161f8542db0a54bf80b74b7fd33afef6f6Laurent Tu * be accessed by the calling activity or are currently disabled. 7336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly */ 734e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<String> getAllProviders() { 7366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<String> out; 7376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 7386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly out = new ArrayList<String>(mProviders.size()); 7396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (LocationProviderInterface provider : mProviders) { 7406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String name = provider.getName(); 7416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (LocationManager.FUSED_PROVIDER.equals(name)) { 7426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly continue; 7436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 7446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly out.add(name); 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7486fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getAllProviders()=" + out); 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return out; 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly /** 7536fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Return all providers by name, that match criteria and are optionally 7546fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * enabled. 7556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Can return passive provider, but never returns fused provider. 7566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly */ 757e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 75803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public List<String> getProviders(Criteria criteria, boolean enabledOnly) { 75937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease int allowedResolutionLevel = getCallerAllowedResolutionLevel(); 7606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<String> out; 761b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease int callingUserId = UserHandle.getCallingUserId(); 762b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease long identity = Binder.clearCallingIdentity(); 763b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease try { 764b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease synchronized (mLock) { 765b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease out = new ArrayList<String>(mProviders.size()); 766b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease for (LocationProviderInterface provider : mProviders) { 767b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease String name = provider.getName(); 768b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (LocationManager.FUSED_PROVIDER.equals(name)) { 7698dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease continue; 7708dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease } 77137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (allowedResolutionLevel >= getMinimumResolutionLevelForProviderUse(name)) { 772b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (enabledOnly && !isAllowedBySettingsLocked(name, callingUserId)) { 773b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease continue; 774b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 775b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (criteria != null && !LocationProvider.propertiesMeetCriteria( 776b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease name, provider.getProperties(), criteria)) { 777b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease continue; 778b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 779b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease out.add(name); 7808dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease } 78103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 783b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } finally { 784b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease Binder.restoreCallingIdentity(identity); 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 78603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 7876fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getProviders()=" + out); 7886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return out; 78903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 79003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 79103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood /** 7926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Return the name of the best provider given a Criteria object. 7936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * This method has been deprecated from the public API, 7948dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease * and the whole LocationProvider (including #meetsCriteria) 7956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * has been deprecated as well. So this method now uses 7966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * some simplified logic. 79703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood */ 798e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 79903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public String getBestProvider(Criteria criteria, boolean enabledOnly) { 8006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String result = null; 80103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 8026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly List<String> providers = getProviders(criteria, enabledOnly); 8038dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease if (!providers.isEmpty()) { 8046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly result = pickBest(providers); 8056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getBestProvider(" + criteria + ", " + enabledOnly + ")=" + result); 8066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return result; 80703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 8086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly providers = getProviders(null, enabledOnly); 8098dbb63419bef8678cf92ebae1d43f549f50987c7Victoria Lease if (!providers.isEmpty()) { 8106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly result = pickBest(providers); 8116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getBestProvider(" + criteria + ", " + enabledOnly + ")=" + result); 8126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return result; 81303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 81403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 8156fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getBestProvider(" + criteria + ", " + enabledOnly + ")=" + result); 8166fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return null; 8176fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 81803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 8196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private String pickBest(List<String> providers) { 8201925e290e7ac2801311cb4e732d1bc5a5f3e0c44Victoria Lease if (providers.contains(LocationManager.GPS_PROVIDER)) { 8216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return LocationManager.GPS_PROVIDER; 8221925e290e7ac2801311cb4e732d1bc5a5f3e0c44Victoria Lease } else if (providers.contains(LocationManager.NETWORK_PROVIDER)) { 8231925e290e7ac2801311cb4e732d1bc5a5f3e0c44Victoria Lease return LocationManager.NETWORK_PROVIDER; 8246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 8256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return providers.get(0); 82603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 82703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 82803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 829e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 83003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public boolean providerMeetsCriteria(String provider, Criteria criteria) { 83103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 83203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (p == null) { 83303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood throw new IllegalArgumentException("provider=" + provider); 83403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 8356fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 8366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly boolean result = LocationProvider.propertiesMeetCriteria( 8376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly p.getName(), p.getProperties(), criteria); 8386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "providerMeetsCriteria(" + provider + ", " + criteria + ")=" + result); 8396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return result; 84003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 84103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateProvidersLocked() { 8430c5a04014d3833c9a82772a832d3bc6410fc52acBrad Fitzpatrick boolean changesMade = false; 84415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 845d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProviders.get(i); 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isEnabled = p.isEnabled(); 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = p.getName(); 848b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease boolean shouldBeEnabled = isAllowedBySettingsLocked(name, mCurrentUserId); 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isEnabled && !shouldBeEnabled) { 850b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease updateProviderListenersLocked(name, false, mCurrentUserId); 8510c5a04014d3833c9a82772a832d3bc6410fc52acBrad Fitzpatrick changesMade = true; 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!isEnabled && shouldBeEnabled) { 853b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease updateProviderListenersLocked(name, true, mCurrentUserId); 8540c5a04014d3833c9a82772a832d3bc6410fc52acBrad Fitzpatrick changesMade = true; 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8560c5a04014d3833c9a82772a832d3bc6410fc52acBrad Fitzpatrick } 8570c5a04014d3833c9a82772a832d3bc6410fc52acBrad Fitzpatrick if (changesMade) { 8585ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn mContext.sendBroadcastAsUser(new Intent(LocationManager.PROVIDERS_CHANGED_ACTION), 8595ac72a29593ab9a20337a2225df52bdf4754be02Dianne Hackborn UserHandle.ALL); 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 863b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease private void updateProviderListenersLocked(String provider, boolean enabled, int userId) { 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int listeners = 0; 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 866d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 8676fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (p == null) return; 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Receiver> deadReceivers = null; 870e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records != null) { 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = records.size(); 8746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (int i = 0; i < N; i++) { 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UpdateRecord record = records.get(i); 876b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (UserHandle.getUserId(record.mReceiver.mUid) == userId) { 877b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease // Sends a notification message to the receiver 878b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) { 879b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (deadReceivers == null) { 880b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease deadReceivers = new ArrayList<Receiver>(); 881b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 882b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease deadReceivers.add(record.mReceiver); 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 884b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease listeners++; 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (deadReceivers != null) { 8906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (int i = deadReceivers.size() - 1; i >= 0; i--) { 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeUpdatesLocked(deadReceivers.get(i)); 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 894e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enabled) { 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.enable(); 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listeners > 0) { 8986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly applyRequirementsLocked(provider); 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.disable(); 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void applyRequirementsLocked(String provider) { 9066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderInterface p = mProvidersByName.get(provider); 9076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (p == null) return; 9086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 9106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly WorkSource worksource = new WorkSource(); 9116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ProviderRequest providerRequest = new ProviderRequest(); 9126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records != null) { 9146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord record : records) { 915b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (UserHandle.getUserId(record.mReceiver.mUid) == mCurrentUserId) { 916b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease LocationRequest locationRequest = record.mRequest; 917b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease providerRequest.locationRequests.add(locationRequest); 918b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (locationRequest.getInterval() < providerRequest.interval) { 919b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease providerRequest.reportLocation = true; 920b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease providerRequest.interval = locationRequest.getInterval(); 921b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 9227e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 9237e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 9246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 9256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (providerRequest.reportLocation) { 9266fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // calculate who to blame for power 9276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // This is somewhat arbitrary. We pick a threshold interval 9286fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // that is slightly higher that the minimum interval, and 9296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // spread the blame across all applications with a request 9306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // under that threshold. 9316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly long thresholdInterval = (providerRequest.interval + 1000) * 3 / 2; 9326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord record : records) { 933b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (UserHandle.getUserId(record.mReceiver.mUid) == mCurrentUserId) { 934b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease LocationRequest locationRequest = record.mRequest; 935b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (locationRequest.getInterval() <= thresholdInterval) { 936b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease worksource.add(record.mReceiver.mUid); 937b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 9386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 9397e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn } 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 9436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "provider request: " + provider + " " + providerRequest); 9446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly p.setRequest(providerRequest, worksource); 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class UpdateRecord { 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String mProvider; 9496fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final LocationRequest mRequest; 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Receiver mReceiver; 9512f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Location mLastFixBroadcast; 9522f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood long mLastStatusBroadcast; 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Note: must be constructed with lock held. 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9576fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly UpdateRecord(String provider, LocationRequest request, Receiver receiver) { 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProvider = provider; 9596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mRequest = request; 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReceiver = receiver; 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records == null) { 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project records = new ArrayList<UpdateRecord>(); 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecordsByProvider.put(provider, records); 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!records.contains(this)) { 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project records.add(this); 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Method to be called when a record will no longer be used. Calling this multiple times 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * must have the same effect as calling it once. 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9766fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly void disposeLocked(boolean removeReceiver) { 9776fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // remove from mRecordsByProvider 9786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<UpdateRecord> globalRecords = mRecordsByProvider.get(this.mProvider); 9796fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (globalRecords != null) { 9806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly globalRecords.remove(this); 9816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 9826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 9836fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (!removeReceiver) return; // the caller will handle the rest 9846fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 9856fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // remove from Receiver#mUpdateRecords 9866fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly HashMap<String, UpdateRecord> receiverRecords = mReceiver.mUpdateRecords; 9876fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (receiverRecords != null) { 9886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiverRecords.remove(this.mProvider); 9896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 9906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // and also remove the Receiver if it has no more update records 9916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (removeReceiver && receiverRecords.size() == 0) { 9926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeUpdatesLocked(mReceiver); 9936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 9943a76fd627945c1df59aa0318867401e0e53da022Mike Lockwood } 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 9996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly StringBuilder s = new StringBuilder(); 10006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append("UpdateRecord["); 10016fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(mProvider); 10026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(' ').append(mReceiver.mPackageName).append('('); 10036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(mReceiver.mUid).append(')'); 10046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(' ').append(mRequest); 10056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly s.append(']'); 10066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return s.toString(); 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private Receiver getReceiver(ILocationListener listener, int pid, int uid, String packageName) { 10112f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood IBinder binder = listener.asBinder(); 10122f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver receiver = mReceivers.get(binder); 10132f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (receiver == null) { 10146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiver = new Receiver(listener, null, pid, uid, packageName); 10152f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mReceivers.put(binder, receiver); 10162f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 10172f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood try { 10186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiver.getListener().asBinder().linkToDeath(receiver, 0); 10192f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } catch (RemoteException e) { 10208a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "linkToDeath failed:", e); 10212f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return null; 10222f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 10232f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 10242f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return receiver; 10252f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 10262f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 10276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private Receiver getReceiver(PendingIntent intent, int pid, int uid, String packageName) { 10282f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver receiver = mReceivers.get(intent); 10292f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (receiver == null) { 10306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiver = new Receiver(null, intent, pid, uid, packageName); 10312f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mReceivers.put(intent, receiver); 10322f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 10332f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return receiver; 10342f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 10352f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 103637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease /** 103737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * Creates a LocationRequest based upon the supplied LocationRequest that to meets resolution 103837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * and consistency requirements. 103937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * 104037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param request the LocationRequest from which to create a sanitized version 104137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param shouldBeCoarse whether the sanitized version should be held to coarse resolution 104237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * constraints 104337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @param fastestCoarseIntervalMS minimum interval allowed for coarse resolution 104437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @return a version of request that meets the given resolution and consistency requirements 104537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease * @hide 104637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease */ 104737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease private LocationRequest createSanitizedRequest(LocationRequest request, int resolutionLevel) { 104837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease LocationRequest sanitizedRequest = new LocationRequest(request); 104937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (resolutionLevel < RESOLUTION_LEVEL_FINE) { 105037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease switch (sanitizedRequest.getQuality()) { 105109016ab4dd056a16809419d612cb865a14980880Victoria Lease case LocationRequest.ACCURACY_FINE: 105237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease sanitizedRequest.setQuality(LocationRequest.ACCURACY_BLOCK); 105309016ab4dd056a16809419d612cb865a14980880Victoria Lease break; 105409016ab4dd056a16809419d612cb865a14980880Victoria Lease case LocationRequest.POWER_HIGH: 105537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease sanitizedRequest.setQuality(LocationRequest.POWER_LOW); 105609016ab4dd056a16809419d612cb865a14980880Victoria Lease break; 105709016ab4dd056a16809419d612cb865a14980880Victoria Lease } 105809016ab4dd056a16809419d612cb865a14980880Victoria Lease // throttle 105937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (sanitizedRequest.getInterval() < LocationFudger.FASTEST_INTERVAL_MS) { 106037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease sanitizedRequest.setInterval(LocationFudger.FASTEST_INTERVAL_MS); 106109016ab4dd056a16809419d612cb865a14980880Victoria Lease } 106237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (sanitizedRequest.getFastestInterval() < LocationFudger.FASTEST_INTERVAL_MS) { 106337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease sanitizedRequest.setFastestInterval(LocationFudger.FASTEST_INTERVAL_MS); 106409016ab4dd056a16809419d612cb865a14980880Victoria Lease } 106574fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pelly } 10664e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly // make getFastestInterval() the minimum of interval and fastest interval 106737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (sanitizedRequest.getFastestInterval() > sanitizedRequest.getInterval()) { 10684e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly request.setFastestInterval(request.getInterval()); 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 107037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return sanitizedRequest; 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void checkPackageName(String packageName) { 1074e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly if (packageName == null) { 10756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new SecurityException("invalid package name: " + packageName); 1076e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 10776fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly int uid = Binder.getCallingUid(); 1078e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly String[] packages = mPackageManager.getPackagesForUid(uid); 1079e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly if (packages == null) { 1080e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly throw new SecurityException("invalid UID " + uid); 1081e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 1082e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly for (String pkg : packages) { 1083e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly if (packageName.equals(pkg)) return; 1084e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 10856fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new SecurityException("invalid package name: " + packageName); 1086e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 1087e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 10886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void checkPendingIntent(PendingIntent intent) { 10896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (intent == null) { 10906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new IllegalArgumentException("invalid pending intent: " + intent); 10916c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn } 10926c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn } 10936c418d585e0a91054b168fde3130188afd006c98Dianne Hackborn 10946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private Receiver checkListenerOrIntent(ILocationListener listener, PendingIntent intent, 10956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly int pid, int uid, String packageName) { 10966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (intent == null && listener == null) { 10976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new IllegalArgumentException("need eiter listener or intent"); 10986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else if (intent != null && listener != null) { 10996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new IllegalArgumentException("cannot register both listener and intent"); 11006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else if (intent != null) { 11016fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPendingIntent(intent); 11026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return getReceiver(intent, pid, uid, packageName); 11036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 11046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return getReceiver(listener, pid, uid, packageName); 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 11096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void requestLocationUpdates(LocationRequest request, ILocationListener listener, 11106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly PendingIntent intent, String packageName) { 11116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (request == null) request = DEFAULT_LOCATION_REQUEST; 11126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPackageName(packageName); 111337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease int allowedResolutionLevel = getCallerAllowedResolutionLevel(); 111437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, 111537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease request.getProvider()); 111637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel); 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int pid = Binder.getCallingPid(); 11196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int uid = Binder.getCallingUid(); 11206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Receiver recevier = checkListenerOrIntent(listener, intent, pid, uid, packageName); 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11222b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly // providers may use public location API's, need to clear identity 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identity = Binder.clearCallingIdentity(); 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 112637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease requestLocationUpdatesLocked(sanitizedRequest, recevier, pid, uid, packageName); 11272d4d1bf14b531de9d4238b1e41b53c77f8976405Mike Lockwood } 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(identity); 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void requestLocationUpdatesLocked(LocationRequest request, Receiver receiver, 11346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly int pid, int uid, String packageName) { 11356fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Figure out the provider. Either its explicitly request (legacy use cases), or 11366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // use the fused provider 11376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (request == null) request = DEFAULT_LOCATION_REQUEST; 11386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String name = request.getProvider(); 113909016ab4dd056a16809419d612cb865a14980880Victoria Lease if (name == null) { 114009016ab4dd056a16809419d612cb865a14980880Victoria Lease throw new IllegalArgumentException("provider name must not be null"); 114109016ab4dd056a16809419d612cb865a14980880Victoria Lease } 11426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderInterface provider = mProvidersByName.get(name); 11436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (provider == null) { 11446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new IllegalArgumentException("provider doesn't exisit: " + provider); 11456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 11466fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 11476fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Log.i(TAG, "request " + Integer.toHexString(System.identityHashCode(receiver)) + " " + 11486fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly name + " " + request + " from " + packageName + "(" + uid + ")"); 11496fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 11506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly UpdateRecord record = new UpdateRecord(name, request, receiver); 11516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly UpdateRecord oldRecord = receiver.mUpdateRecords.put(name, record); 11526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (oldRecord != null) { 11536fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly oldRecord.disposeLocked(false); 11546fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 11556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1156b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease boolean isProviderEnabled = isAllowedBySettingsLocked(name, UserHandle.getUserId(uid)); 11576fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (isProviderEnabled) { 11586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly applyRequirementsLocked(name); 11596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 11606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Notify the listener that updates are currently disabled 11616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiver.callProviderEnabledLocked(name, false); 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1165e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 11666fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void removeUpdates(ILocationListener listener, PendingIntent intent, 11676fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String packageName) { 11686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPackageName(packageName); 116937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease 11706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int pid = Binder.getCallingPid(); 11716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly final int uid = Binder.getCallingUid(); 11726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Receiver receiver = checkListenerOrIntent(listener, intent, pid, uid, packageName); 11736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 11742b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly // providers may use public location API's, need to clear identity 11756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly long identity = Binder.clearCallingIdentity(); 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11772f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 11786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeUpdatesLocked(receiver); 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } finally { 11816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Binder.restoreCallingIdentity(identity); 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeUpdatesLocked(Receiver receiver) { 11866fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Log.i(TAG, "remove " + Integer.toHexString(System.identityHashCode(receiver))); 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) { 11896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiver.getListener().asBinder().unlinkToDeath(receiver, 0); 11906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (receiver) { 11916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (receiver.mPendingBroadcasts > 0) { 11926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly decrementPendingBroadcasts(); 11936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly receiver.mPendingBroadcasts = 0; 1194080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel } 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Record which providers were associated with this listener 11996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly HashSet<String> providers = new HashSet<String>(); 12006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly HashMap<String, UpdateRecord> oldRecords = receiver.mUpdateRecords; 12016fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (oldRecords != null) { 12026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Call dispose() on the obsolete update records. 12036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord record : oldRecords.values()) { 12046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly record.disposeLocked(false); 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Accumulate providers 12076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly providers.addAll(oldRecords.keySet()); 12086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // update provider 12116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (String provider : providers) { 12126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // If provider is already disabled, don't need to do anything 1213b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (!isAllowedBySettingsLocked(provider, mCurrentUserId)) { 12146fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly continue; 12156fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12176fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly applyRequirementsLocked(provider); 12186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 12196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 12224035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly public Location getLastLocation(LocationRequest request, String packageName) { 12236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "getLastLocation: " + request); 12246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (request == null) request = DEFAULT_LOCATION_REQUEST; 122537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease int allowedResolutionLevel = getCallerAllowedResolutionLevel(); 12264035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly checkPackageName(packageName); 122737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, 122837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease request.getProvider()); 122937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease // no need to sanitize this request, as only the provider name is used 12304035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly 1231b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease long identity = Binder.clearCallingIdentity(); 1232b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease try { 1233b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (mBlacklist.isBlacklisted(packageName)) { 1234b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (D) Log.d(TAG, "not returning last loc for blacklisted app: " + 1235b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease packageName); 123609016ab4dd056a16809419d612cb865a14980880Victoria Lease return null; 123709016ab4dd056a16809419d612cb865a14980880Victoria Lease } 1238b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease 1239b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease synchronized (mLock) { 1240b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease // Figure out the provider. Either its explicitly request (deprecated API's), 1241b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease // or use the fused provider 1242b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease String name = request.getProvider(); 1243b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (name == null) name = LocationManager.FUSED_PROVIDER; 1244b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease LocationProviderInterface provider = mProvidersByName.get(name); 1245b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (provider == null) return null; 1246b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease 1247b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (!isAllowedBySettingsLocked(name, mCurrentUserId)) return null; 1248b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease 1249b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease Location location = mLastLocation.get(name); 1250b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (location == null) { 1251b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease return null; 1252b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 125337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (allowedResolutionLevel < RESOLUTION_LEVEL_FINE) { 1254b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); 1255b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (noGPSLocation != null) { 1256b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease return mLocationFudger.getOrCreate(noGPSLocation); 1257b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 125837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease } else { 125937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease return location; 126009016ab4dd056a16809419d612cb865a14980880Victoria Lease } 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1262b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease return null; 1263b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } finally { 1264b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease Binder.restoreCallingIdentity(identity); 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1268e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 12696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void requestGeofence(LocationRequest request, Geofence geofence, PendingIntent intent, 12706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String packageName) { 12716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (request == null) request = DEFAULT_LOCATION_REQUEST; 127237425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease int allowedResolutionLevel = getCallerAllowedResolutionLevel(); 127337425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForGeofenceUse(allowedResolutionLevel); 12746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPendingIntent(intent); 12756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPackageName(packageName); 127637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(allowedResolutionLevel, 127737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease request.getProvider()); 127837425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease LocationRequest sanitizedRequest = createSanitizedRequest(request, allowedResolutionLevel); 12796fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 128037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (D) Log.d(TAG, "requestGeofence: " + sanitizedRequest + " " + geofence + " " + intent); 12816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 12822b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly // geo-fence manager uses the public location API, need to clear identity 12832b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly int uid = Binder.getCallingUid(); 12842b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly long identity = Binder.clearCallingIdentity(); 12852b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly try { 128637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease mGeofenceManager.addFence(sanitizedRequest, geofence, intent, uid, packageName); 12872b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly } finally { 12882b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly Binder.restoreCallingIdentity(identity); 12892b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly } 12906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 12916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 12926fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 12936fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void removeGeofence(Geofence geofence, PendingIntent intent, String packageName) { 129437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForGeofenceUse(getCallerAllowedResolutionLevel()); 12956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPendingIntent(intent); 12966fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkPackageName(packageName); 12976fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 12986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (D) Log.d(TAG, "removeGeofence: " + geofence + " " + intent); 12996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 13002b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly // geo-fence manager uses the public location API, need to clear identity 13012b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly long identity = Binder.clearCallingIdentity(); 13022b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly try { 13032b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly mGeofenceManager.removeFence(geofence, intent); 13042b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly } finally { 13052b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly Binder.restoreCallingIdentity(identity); 13062b7a0d00426218523629e4e8dd2e9197d445c09bNick Pelly } 13076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 13086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 13096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 13106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean addGpsStatusListener(IGpsStatusListener listener) { 131215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mGpsStatusProvider == null) { 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 131537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(), 131637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease LocationManager.GPS_PROVIDER); 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 131915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mGpsStatusProvider.addGpsStatusListener(listener); 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 13218a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "mGpsStatusProvider.addGpsStatusListener failed", e); 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1327e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeGpsStatusListener(IGpsStatusListener listener) { 13292f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 133015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood try { 133115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mGpsStatusProvider.removeGpsStatusListener(listener); 133215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } catch (Exception e) { 13338a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "mGpsStatusProvider.removeGpsStatusListener failed", e); 133415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1338e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String provider, String command, Bundle extras) { 1340c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood if (provider == null) { 1341c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood // throw NullPointerException to remain compatible with previous implementation 1342c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood throw new NullPointerException(); 1343c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood } 134437425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(), 134537425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease provider); 1346c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and check for ACCESS_LOCATION_EXTRA_COMMANDS 1348b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood if ((mContext.checkCallingOrSelfPermission(ACCESS_LOCATION_EXTRA_COMMANDS) 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_LOCATION_EXTRA_COMMANDS permission"); 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13532f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 1354d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 13556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (p == null) return false; 1356e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 1357d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return p.sendExtraCommand(command, extras); 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1361e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 13626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public boolean sendNiResponse(int notifId, int userResponse) { 136318ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood if (Binder.getCallingUid() != Process.myUid()) { 136418ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood throw new SecurityException( 136518ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood "calling sendNiResponse from outside of the system is not allowed"); 136618ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood } 136722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie try { 136822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return mNetInitiatedListener.sendNiResponse(notifId, userResponse); 13696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } catch (RemoteException e) { 13708a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "RemoteException in LocationManagerService.sendNiResponse"); 137122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return false; 137222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 137322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 137422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1376628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood * @return null if the provider does not exist 1377f2db9fb0f877057a9ef56908d54f3c95fc3fd552Alexey Tarasov * @throws SecurityException if the provider is not allowed to be 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * accessed by the caller 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1380e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 13816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public ProviderProperties getProviderProperties(String provider) { 1382b7f9d254978b285bf04613f6e69a1afa89240ca9Laurent Tu if (mProvidersByName.get(provider) == null) { 1383b7f9d254978b285bf04613f6e69a1afa89240ca9Laurent Tu return null; 1384b7f9d254978b285bf04613f6e69a1afa89240ca9Laurent Tu } 1385b7f9d254978b285bf04613f6e69a1afa89240ca9Laurent Tu 138637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(), 138737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease provider); 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13896fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderInterface p; 13906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 13916fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly p = mProvidersByName.get(provider); 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13946fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (p == null) return null; 13956fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return p.getProperties(); 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1398e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isProviderEnabled(String provider) { 140037425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(), 140137425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease provider); 14026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (LocationManager.FUSED_PROVIDER.equals(provider)) return false; 14036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1404b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease long identity = Binder.clearCallingIdentity(); 1405b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease try { 1406b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease synchronized (mLock) { 1407b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease LocationProviderInterface p = mProvidersByName.get(provider); 1408b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (p == null) return false; 14096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1410b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease return isAllowedBySettingsLocked(provider, mCurrentUserId); 1411b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 1412b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } finally { 1413b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease Binder.restoreCallingIdentity(identity); 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14176fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void checkCallerIsProvider() { 1418275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER) 14196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly == PackageManager.PERMISSION_GRANTED) { 14202eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly return; 14212eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly } 14222eeeec248a38ff33999c83f4b8d5bab7d50e79d2Nick Pelly 14236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Previously we only used the INSTALL_LOCATION_PROVIDER 14246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // check. But that is system or signature 14256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // protection level which is not flexible enough for 14266fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // providers installed oustide the system image. So 14276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // also allow providers with a UID matching the 14286fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // currently bound package name 14294e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood 14306fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly int uid = Binder.getCallingUid(); 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (mGeocodeProvider != null) { 14336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (doesPackageHaveUid(uid, mGeocodeProvider.getConnectedPackageName())) return; 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14356fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (LocationProviderProxy proxy : mProxyProviders) { 14366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (doesPackageHaveUid(uid, proxy.getConnectedPackageName())) return; 14376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 14386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly throw new SecurityException("need INSTALL_LOCATION_PROVIDER permission, " + 14396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly "or UID of a currently bound location provider"); 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private boolean doesPackageHaveUid(int uid, String packageName) { 14436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (packageName == null) { 14446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return false; 14454a7b65e0d544ef1feff8e1e5789f469f89ebb85cMike Lockwood } 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 14476fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ApplicationInfo appInfo = mPackageManager.getApplicationInfo(packageName, 0); 14486fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (appInfo.uid != uid) { 14496fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return false; 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } catch (NameNotFoundException e) { 14526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return false; 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14546fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return true; 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14576fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly @Override 14586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void reportLocation(Location location, boolean passive) { 14596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly checkCallerIsProvider(); 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (!location.isComplete()) { 14626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Log.w(TAG, "Dropping incomplete location: " + location); 14636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return; 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14666fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLocationHandler.removeMessages(MSG_LOCATION_CHANGED, location); 14676fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Message m = Message.obtain(mLocationHandler, MSG_LOCATION_CHANGED, location); 14686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly m.arg1 = (passive ? 1 : 0); 14696fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLocationHandler.sendMessageAtFrontOfQueue(m); 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean shouldBroadcastSafe(Location loc, Location lastLoc, UpdateRecord record) { 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Always broadcast the first update 14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lastLoc == null) { 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 14779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1479f1be6861daea57ba0a1595739a899d05229d6d15Nick Pelly // Check whether sufficient time has passed 14806fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly long minTime = record.mRequest.getFastestInterval(); 14814118012da9a22694b3353040a485f8cdc27e2f17Philip Milne long delta = (loc.getElapsedRealtimeNanos() - lastLoc.getElapsedRealtimeNanos()) / 1000000L; 14826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (delta < minTime - MAX_PROVIDER_SCHEDULING_JITTER_MS) { 14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check whether sufficient distance has been traveled 14876fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly double minDistance = record.mRequest.getSmallestDisplacement(); 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (minDistance > 0.0) { 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (loc.distanceTo(lastLoc) <= minDistance) { 14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1497a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood private void handleLocationChangedLocked(Location location, boolean passive) { 14984e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly if (D) Log.d(TAG, "incoming location: " + location); 14994e31c4fffbc42b4c2b5dca6431cfeef9e078f5b4Nick Pelly 15006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly long now = SystemClock.elapsedRealtime(); 1501a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood String provider = (passive ? LocationManager.PASSIVE_PROVIDER : location.getProvider()); 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 150360ec50a850ac7265b662df3c872583b6ef581ef8Laurent Tu // Skip if the provider is unknown. 1504d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 15056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (p == null) return; 15066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 15076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // Update last known locations 150809016ab4dd056a16809419d612cb865a14980880Victoria Lease Location noGPSLocation = location.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); 150909016ab4dd056a16809419d612cb865a14980880Victoria Lease Location lastNoGPSLocation = null; 15106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Location lastLocation = mLastLocation.get(provider); 15114e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood if (lastLocation == null) { 15126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly lastLocation = new Location(provider); 15136fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLastLocation.put(provider, lastLocation); 151409016ab4dd056a16809419d612cb865a14980880Victoria Lease } else { 151509016ab4dd056a16809419d612cb865a14980880Victoria Lease lastNoGPSLocation = lastLocation.getExtraLocation(Location.EXTRA_NO_GPS_LOCATION); 151609016ab4dd056a16809419d612cb865a14980880Victoria Lease if (noGPSLocation == null && lastNoGPSLocation != null) { 151709016ab4dd056a16809419d612cb865a14980880Victoria Lease // New location has no no-GPS location: adopt last no-GPS location. This is set 151809016ab4dd056a16809419d612cb865a14980880Victoria Lease // directly into location because we do not want to notify COARSE clients. 151909016ab4dd056a16809419d612cb865a14980880Victoria Lease location.setExtraLocation(Location.EXTRA_NO_GPS_LOCATION, lastNoGPSLocation); 152009016ab4dd056a16809419d612cb865a14980880Victoria Lease } 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly lastLocation.set(location); 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 152460ec50a850ac7265b662df3c872583b6ef581ef8Laurent Tu // Skip if there are no UpdateRecords for this provider. 152560ec50a850ac7265b662df3c872583b6ef581ef8Laurent Tu ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 152660ec50a850ac7265b662df3c872583b6ef581ef8Laurent Tu if (records == null || records.size() == 0) return; 152760ec50a850ac7265b662df3c872583b6ef581ef8Laurent Tu 152809016ab4dd056a16809419d612cb865a14980880Victoria Lease // Fetch coarse location 152909016ab4dd056a16809419d612cb865a14980880Victoria Lease Location coarseLocation = null; 153009016ab4dd056a16809419d612cb865a14980880Victoria Lease if (noGPSLocation != null && !noGPSLocation.equals(lastNoGPSLocation)) { 153109016ab4dd056a16809419d612cb865a14980880Victoria Lease coarseLocation = mLocationFudger.getOrCreate(noGPSLocation); 153209016ab4dd056a16809419d612cb865a14980880Victoria Lease } 153309016ab4dd056a16809419d612cb865a14980880Victoria Lease 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Fetch latest status update time 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long newStatusUpdateTime = p.getStatusUpdateTime(); 15369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15377ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood // Get latest status 15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Bundle extras = new Bundle(); 15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int status = p.getStatus(extras); 15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Receiver> deadReceivers = null; 15426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<UpdateRecord> deadUpdateRecords = null; 1543e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Broadcast location or status to all listeners 15456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord r : records) { 15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Receiver receiver = r.mReceiver; 154703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood boolean receiverDead = false; 15484035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly 1549b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease int receiverUserId = UserHandle.getUserId(receiver.mUid); 1550b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (receiverUserId != mCurrentUserId) { 1551b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (D) { 1552b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease Log.d(TAG, "skipping loc update for background user " + receiverUserId + 1553b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease " (current user: " + mCurrentUserId + ", app: " + 1554b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease receiver.mPackageName + ")"); 1555b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 1556b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease continue; 1557b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease } 1558b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease 15594035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly if (mBlacklist.isBlacklisted(receiver.mPackageName)) { 15604035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly if (D) Log.d(TAG, "skipping loc update for blacklisted app: " + 15614035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly receiver.mPackageName); 15624035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly continue; 15634035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly } 15644035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly 156509016ab4dd056a16809419d612cb865a14980880Victoria Lease Location notifyLocation = null; 156637425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease if (receiver.mAllowedResolutionLevel < RESOLUTION_LEVEL_FINE) { 156737425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease notifyLocation = coarseLocation; // use coarse location 15686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } else { 156937425c3475877f2fdadb78f669ec57fecf82dca7Victoria Lease notifyLocation = lastLocation; // use fine location 15706fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 157109016ab4dd056a16809419d612cb865a14980880Victoria Lease if (notifyLocation != null) { 157209016ab4dd056a16809419d612cb865a14980880Victoria Lease Location lastLoc = r.mLastFixBroadcast; 157309016ab4dd056a16809419d612cb865a14980880Victoria Lease if ((lastLoc == null) || shouldBroadcastSafe(notifyLocation, lastLoc, r)) { 157409016ab4dd056a16809419d612cb865a14980880Victoria Lease if (lastLoc == null) { 157509016ab4dd056a16809419d612cb865a14980880Victoria Lease lastLoc = new Location(notifyLocation); 157609016ab4dd056a16809419d612cb865a14980880Victoria Lease r.mLastFixBroadcast = lastLoc; 157709016ab4dd056a16809419d612cb865a14980880Victoria Lease } else { 157809016ab4dd056a16809419d612cb865a14980880Victoria Lease lastLoc.set(notifyLocation); 157909016ab4dd056a16809419d612cb865a14980880Victoria Lease } 158009016ab4dd056a16809419d612cb865a14980880Victoria Lease if (!receiver.callLocationChangedLocked(notifyLocation)) { 158109016ab4dd056a16809419d612cb865a14980880Victoria Lease Slog.w(TAG, "RemoteException calling onLocationChanged on " + receiver); 158209016ab4dd056a16809419d612cb865a14980880Victoria Lease receiverDead = true; 158309016ab4dd056a16809419d612cb865a14980880Victoria Lease } 15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15872f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood long prevStatusUpdateTime = r.mLastStatusBroadcast; 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((newStatusUpdateTime > prevStatusUpdateTime) && 158909016ab4dd056a16809419d612cb865a14980880Victoria Lease (prevStatusUpdateTime != 0 || status != LocationProvider.AVAILABLE)) { 15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15912f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood r.mLastStatusBroadcast = newStatusUpdateTime; 15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!receiver.callStatusChangedLocked(provider, status, extras)) { 159303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood receiverDead = true; 15948a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "RemoteException calling onStatusChanged on " + receiver); 159503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 159603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 159703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 15986fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // track expired records 15996fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (r.mRequest.getNumUpdates() == 0 || r.mRequest.getExpireAt() < now) { 16006fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (deadUpdateRecords == null) { 16016fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly deadUpdateRecords = new ArrayList<UpdateRecord>(); 16026fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 16036fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly deadUpdateRecords.add(r); 16046fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 16056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // track dead receivers 16066fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (receiverDead) { 160703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (deadReceivers == null) { 160803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood deadReceivers = new ArrayList<Receiver>(); 160903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 161003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (!deadReceivers.contains(receiver)) { 161103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood deadReceivers.add(receiver); 16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1615e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 16166fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // remove dead records and receivers outside the loop 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (deadReceivers != null) { 16186fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Receiver receiver : deadReceivers) { 16196fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeUpdatesLocked(receiver); 16206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 16216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 16226fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (deadUpdateRecords != null) { 16236fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord r : deadUpdateRecords) { 16246fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly r.disposeLocked(true); 16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class LocationWorkerHandler extends Handler { 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 16326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly switch (msg.what) { 16336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly case MSG_LOCATION_CHANGED: 16346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly handleLocationChanged((Location) msg.obj, msg.arg1 == 1); 16356fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly break; 16366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 16376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 16386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 163998cb66797422c4ccdee6f1a07636146d784a471bMike Lockwood 16406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private void handleLocationChanged(Location location, boolean passive) { 16416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String provider = location.getProvider(); 16426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 16436fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (!passive) { 16446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // notify passive provider of the new location 16456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mPassiveProvider.updateLocation(location); 16466fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 16476fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 16486fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 1649b711d57ca4e2c6a1befbfa1a41f4b8094755a93fVictoria Lease if (isAllowedBySettingsLocked(provider, mCurrentUserId)) { 16506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly handleLocationChangedLocked(location, passive); 16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final PackageMonitor mPackageMonitor = new PackageMonitor() { 16560528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood @Override 16576fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void onPackageDisappeared(String packageName, int reason) { 16586fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // remove all receivers associated with this package name 16596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly synchronized (mLock) { 16606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly ArrayList<Receiver> deadReceivers = null; 16616fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 16626fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Receiver receiver : mReceivers.values()) { 16636fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (receiver.mPackageName.equals(packageName)) { 16646fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (deadReceivers == null) { 16656fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly deadReceivers = new ArrayList<Receiver>(); 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16676fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly deadReceivers.add(receiver); 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16716fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // perform removal outside of mReceivers loop 16726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (deadReceivers != null) { 16736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Receiver receiver : deadReceivers) { 16746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeUpdatesLocked(receiver); 16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16790528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood }; 16809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Wake locks 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16830528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private void incrementPendingBroadcasts() { 16840528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (mWakeLock) { 16850528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (mPendingBroadcasts++ == 0) { 16860528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood try { 16870528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.acquire(); 16880528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood log("Acquired wakelock"); 16890528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } catch (Exception e) { 16900528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // This is to catch a runtime exception thrown when we try to release an 16910528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // already released lock. 16928a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "exception in acquireWakeLock()", e); 16930528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 16940528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 169548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 169648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 169748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 169848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private void decrementPendingBroadcasts() { 16990528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (mWakeLock) { 170048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (--mPendingBroadcasts == 0) { 17010528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood try { 17020528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Release wake lock 17030528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (mWakeLock.isHeld()) { 17040528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.release(); 17050528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood log("Released wakelock"); 17060528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } else { 17070528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood log("Can't release wakelock again!"); 17080528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 17090528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } catch (Exception e) { 17100528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // This is to catch a runtime exception thrown when we try to release an 17110528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // already released lock. 17128a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "exception in releaseWakeLock()", e); 17130528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 171448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 171548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 171648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 171748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Geocoder 17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1720e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 1721e15735a9e0c0b1448b68f2d6b3247404fc1df417Mike Lockwood public boolean geocoderIsPresent() { 172201ac80b715881db22bde8b31633dd8a4dc375389Mark Vandevoorde return mGeocodeProvider != null; 172301ac80b715881db22bde8b31633dd8a4dc375389Mark Vandevoorde } 172401ac80b715881db22bde8b31633dd8a4dc375389Mark Vandevoorde 1725e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getFromLocation(double latitude, double longitude, int maxResults, 172734901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwood GeocoderParams params, List<Address> addrs) { 1728a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood if (mGeocodeProvider != null) { 1729628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood return mGeocodeProvider.getFromLocation(latitude, longitude, maxResults, 1730628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood params, addrs); 17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1732a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood return null; 17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1735a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 1736e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getFromLocationName(String locationName, 1738a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood double lowerLeftLatitude, double lowerLeftLongitude, 1739a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood double upperRightLatitude, double upperRightLongitude, int maxResults, 174034901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwood GeocoderParams params, List<Address> addrs) { 1741a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 1742a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood if (mGeocodeProvider != null) { 1743628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood return mGeocodeProvider.getFromLocationName(locationName, lowerLeftLatitude, 1744628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood lowerLeftLongitude, upperRightLatitude, upperRightLongitude, 1745628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood maxResults, params, addrs); 17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1747a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood return null; 17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Mock Providers 17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void checkMockPermissionsSafe() { 17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean allowMocks = Settings.Secure.getInt(mContext.getContentResolver(), 17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 1; 17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allowMocks) { 17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_MOCK_LOCATION secure setting"); 17579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) != 17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageManager.PERMISSION_GRANTED) { 17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission"); 1762e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1765e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 17666fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public void addTestProvider(String name, ProviderProperties properties) { 17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 17689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood if (LocationManager.PASSIVE_PROVIDER.equals(name)) { 1770a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood throw new IllegalArgumentException("Cannot mock the passive location provider"); 1771a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood } 1772a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood 177386328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 17742f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 17756fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly MockProvider provider = new MockProvider(name, this, properties); 17767566c1debebe072af76411e11d96810fd1409482Mike Lockwood // remove the real provider if we are replacing GPS or network provider 17777566c1debebe072af76411e11d96810fd1409482Mike Lockwood if (LocationManager.GPS_PROVIDER.equals(name) 17781332b53522e281012fefb34bfbcc68a03028f516Nick Pelly || LocationManager.NETWORK_PROVIDER.equals(name) 17791332b53522e281012fefb34bfbcc68a03028f516Nick Pelly || LocationManager.FUSED_PROVIDER.equals(name)) { 1780d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(name); 1781d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood if (p != null) { 17826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeProviderLocked(p); 17837566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 17847566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 178515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mProvidersByName.get(name) != null) { 17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + name + "\" already exists"); 17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17886fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly addProviderLocked(provider); 17897ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mMockProviders.put(name, provider); 17906fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLastLocation.put(name, null); 17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 179386328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1796e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeTestProvider(String provider) { 17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 17992f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18007ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18017ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 180486328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 18056fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly removeProviderLocked(mProvidersByName.get(provider)); 18067ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mMockProviders.remove(mockProvider); 18076fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 18086fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly // reinstate real provider if available 18096fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderInterface realProvider = mRealProviders.get(provider); 18106fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (realProvider != null) { 18116fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly addProviderLocked(realProvider); 18126fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 18136fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLastLocation.put(provider, null); 18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 181586328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1819e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderLocation(String provider, Location loc) { 18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18222f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18237ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18247ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 182795427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood // clear calling identity so INSTALL_LOCATION_PROVIDER permission is not required 182895427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood long identity = Binder.clearCallingIdentity(); 18297ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.setLocation(loc); 183095427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood Binder.restoreCallingIdentity(identity); 18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1834e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderLocation(String provider) { 18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18372f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18387ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18397ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18427ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.clearLocation(); 18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1846e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderEnabled(String provider, boolean enabled) { 18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18492f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18507ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18517ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 185486328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enabled) { 18567ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.enable(); 18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.add(provider); 18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.remove(provider); 18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 18607ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.disable(); 18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.remove(provider); 18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.add(provider); 18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 186586328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1869e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderEnabled(String provider) { 18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18722f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18737ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18747ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 187786328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.remove(provider); 18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.remove(provider); 18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 188186328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1885e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) { 18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18882f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18897ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18907ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18937ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.setStatus(status, extras, updateTime); 18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1897e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderStatus(String provider) { 18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 19002f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 19017ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 19027ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19057ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.clearStatus(); 19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void log(String log) { 19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 19118a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.d(TAG, log); 19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1914e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 1915e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 19190528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood pw.println("Permission Denial: can't dump LocationManagerService from from pid=" 19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Binder.getCallingPid() 19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1924e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 19252f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Current Location Manager state:"); 19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Location Listeners:"); 19286fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Receiver receiver : mReceivers.values()) { 19296fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.println(" " + receiver); 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Records by Provider:"); 19326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Map.Entry<String, ArrayList<UpdateRecord>> entry : mRecordsByProvider.entrySet()) { 19336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.println(" " + entry.getKey() + ":"); 19346fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (UpdateRecord record : entry.getValue()) { 19356fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.println(" " + record); 19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Last Known Locations:"); 19396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly for (Map.Entry<String, Location> entry : mLastLocation.entrySet()) { 19406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String provider = entry.getKey(); 19416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly Location location = entry.getValue(); 19426fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.println(" " + provider + ": " + location); 19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19446fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 1945e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly mGeofenceManager.dump(pw); 19466fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabledProviders.size() > 0) { 19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Enabled Providers:"); 19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String i : mEnabledProviders) { 19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i); 19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1952e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDisabledProviders.size() > 0) { 19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Disabled Providers:"); 19569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String i : mDisabledProviders) { 19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i); 19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19604035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly pw.append(" "); 19614035f5a7c191a68bc9a5912ce44c43c82e9e5dbfNick Pelly mBlacklist.dump(pw); 19629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMockProviders.size() > 0) { 19639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Mock Providers:"); 19649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, MockProvider> i : mMockProviders.entrySet()) { 19657ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood i.getValue().dump(pw, " "); 19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19686fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly 196974fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pelly pw.append(" fudger: "); 197074fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pelly mLocationFudger.dump(fd, pw, args); 197174fa7eabda3d0c1a85e0b568e3fc4230ed4fe7a4Nick Pelly 19726fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (args.length > 0 && "short".equals(args[0])) { 19736fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly return; 19746fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly } 19753c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger for (LocationProviderInterface provider: mProviders) { 19766fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.print(provider.getName() + " Internal State"); 19776fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly if (provider instanceof LocationProviderProxy) { 19786fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly LocationProviderProxy proxy = (LocationProviderProxy) provider; 19796fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.print(" (" + proxy.getConnectedPackageName() + ")"); 19803c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 19816fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly pw.println(":"); 19826fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly provider.dump(fd, pw, args); 19833c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 19849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1987