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 java.io.FileDescriptor; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.PrintWriter; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashMap; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.HashSet; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.List; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Map; 269637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwoodimport java.util.Observable; 279637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwoodimport java.util.Observer; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Set; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackbornimport android.app.Activity; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.PendingIntent; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.BroadcastReceiver; 33628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwoodimport android.content.ComponentName; 349637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwoodimport android.content.ContentQueryMap; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter; 39628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwoodimport android.content.ServiceConnection; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 41628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwoodimport android.content.res.Resources; 429637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwoodimport android.database.Cursor; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Address; 4434901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwoodimport android.location.GeocoderParams; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.IGpsStatusListener; 4615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwoodimport android.location.IGpsStatusProvider; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.ILocationListener; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.ILocationManager; 4922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.location.INetInitiatedListener; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Location; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationManager; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationProvider; 53d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwoodimport android.location.LocationProviderInterface; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.ConnectivityManager; 5503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwoodimport android.net.NetworkInfo; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 613d12b51ee38537f6760a833618948f936e75561dMike Lockwoodimport android.os.Looper; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.PowerManager; 64e932f7f2a47b770c636443d411436bd29cc4bb43Mike Lockwoodimport android.os.Process; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings; 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 688a9b22056b13477f59df934928c00c58b5871c95Joe Onoratoimport android.util.Slog; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.PrintWriterPrinter; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 71628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwoodimport com.android.internal.location.GeocoderProxy; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.location.GpsLocationProvider; 73628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwoodimport com.android.internal.location.GpsNetInitiatedHandler; 74e932f7f2a47b770c636443d411436bd29cc4bb43Mike Lockwoodimport com.android.internal.location.LocationProviderProxy; 757ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwoodimport com.android.internal.location.MockProvider; 76a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwoodimport com.android.internal.location.PassiveProvider; 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The service class that manages LocationProviders and issues location 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * updates and alerts. 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 843d12b51ee38537f6760a833618948f936e75561dMike Lockwoodpublic class LocationManagerService extends ILocationManager.Stub implements Runnable { 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "LocationManagerService"; 86105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final boolean LOCAL_LOGV = false; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The last time a location was written, by provider name. 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashMap<String,Long> mLastWriteTime = new HashMap<String,Long>(); 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_FINE_LOCATION = 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.ACCESS_FINE_LOCATION; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_COARSE_LOCATION = 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.ACCESS_COARSE_LOCATION; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_MOCK_LOCATION = 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.ACCESS_MOCK_LOCATION; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_LOCATION_EXTRA_COMMANDS = 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS; 99275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood private static final String INSTALL_LOCATION_PROVIDER = 100275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood android.Manifest.permission.INSTALL_LOCATION_PROVIDER; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set of providers that are explicitly enabled 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Set<String> mEnabledProviders = new HashSet<String>(); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set of providers that are explicitly disabled 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Set<String> mDisabledProviders = new HashSet<String>(); 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Locations, status values, and extras for mock providers 1097ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood private final HashMap<String,MockProvider> mMockProviders = new HashMap<String,MockProvider>(); 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean sProvidersLoaded = false; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 114628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood private GeocoderProxy mGeocodeProvider; 11515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private IGpsStatusProvider mGpsStatusProvider; 11622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private INetInitiatedListener mNetInitiatedListener; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private LocationWorkerHandler mLocationHandler; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1197566c1debebe072af76411e11d96810fd1409482Mike Lockwood // Cache the real providers for use in addTestProvider() and removeTestProvider() 120d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface mNetworkLocationProvider; 121d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface mGpsLocationProvider; 1227566c1debebe072af76411e11d96810fd1409482Mike Lockwood 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Handler messages 1244e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood private static final int MESSAGE_LOCATION_CHANGED = 1; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1260528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // wakelock variables 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final static String WAKELOCK_KEY = "LocationManagerService"; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private PowerManager.WakeLock mWakeLock = null; 12948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private int mPendingBroadcasts; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1322f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood * List of all receivers. 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1342f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final HashMap<Object, Receiver> mReceivers = new HashMap<Object, Receiver>(); 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 13715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood /** 13815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood * List of location providers. 13915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood */ 140d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood private final ArrayList<LocationProviderInterface> mProviders = 141d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood new ArrayList<LocationProviderInterface>(); 142d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood private final HashMap<String, LocationProviderInterface> mProvidersByName 143d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood = new HashMap<String, LocationProviderInterface>(); 14415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1462f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood * Object used internally for synchronization 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1482f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final Object mLock = new Object(); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Mapping from provider name to all its UpdateRecords 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HashMap<String,ArrayList<UpdateRecord>> mRecordsByProvider = 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashMap<String,ArrayList<UpdateRecord>>(); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Proximity listeners 15748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private Receiver mProximityReceiver = null; 15848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private ILocationListener mProximityListener = null; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashMap<PendingIntent,ProximityAlert> mProximityAlerts = 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashMap<PendingIntent,ProximityAlert>(); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashSet<ProximityAlert> mProximitiesEntered = 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashSet<ProximityAlert>(); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Last known location for each provider 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashMap<String,Location> mLastKnownLocation = 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashMap<String,Location>(); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1684df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project private int mNetworkState = LocationProvider.TEMPORARILY_UNAVAILABLE; 1694df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 1709637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood // for Settings change notification 1719637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood private ContentQueryMap mSettings; 1729637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A wrapper class holding either an ILocationListener or a PendingIntent to receive 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * location updates. 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private final class Receiver implements IBinder.DeathRecipient, PendingIntent.OnFinished { 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ILocationListener mListener; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PendingIntent mPendingIntent; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Object mKey; 1812f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>(); 18248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood int mPendingBroadcasts; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1842f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver(ILocationListener listener) { 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingIntent = null; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mKey = listener.asBinder(); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1902f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver(PendingIntent intent) { 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingIntent = intent; 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = null; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mKey = intent; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean equals(Object otherObj) { 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (otherObj instanceof Receiver) { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mKey.equals( 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((Receiver)otherObj).mKey); 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int hashCode() { 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mKey.hashCode(); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2093681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "Receiver{" 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(System.identityHashCode(this)) 2152f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood + " Listener " + mKey + "}"; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "Receiver{" 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(System.identityHashCode(this)) 2192f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood + " Intent " + mKey + "}"; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isListener() { 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mListener != null; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isPendingIntent() { 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPendingIntent != null; 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ILocationListener getListener() { 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mListener; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("Request for non-existent listener"); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PendingIntent getPendingIntent() { 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPendingIntent != null) { 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPendingIntent; 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("Request for non-existent intent"); 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean callStatusChangedLocked(String provider, int status, Bundle extras) { 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 24848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 24948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 25048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 25148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onStatusChanged(provider, status, extras); 25248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mListener != mProximityListener) { 25348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 25448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 25548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 25648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 25748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent statusChanged = new Intent(); 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project statusChanged.putExtras(extras); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project statusChanged.putExtra(LocationManager.KEY_STATUS_CHANGED, status); 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 26648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 26748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 26848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 26948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mPendingIntent.send(mContext, 0, statusChanged, this, mLocationHandler); 27048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 27148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 27248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 27348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean callLocationChangedLocked(Location location) { 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 28448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 28548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 28648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 28748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onLocationChanged(location); 28848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mListener != mProximityListener) { 28948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 29048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 29148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 29248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 29348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent locationChanged = new Intent(); 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED, location); 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 30148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 30248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 30348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 30448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mPendingIntent.send(mContext, 0, locationChanged, this, mLocationHandler); 30548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 30648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 30748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 30848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 30948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } catch (PendingIntent.CanceledException e) { 31048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return false; 31148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 31248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 31348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return true; 31448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 31548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 31648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public boolean callProviderEnabledLocked(String provider, boolean enabled) { 31748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mListener != null) { 31848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood try { 31948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 32048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 32148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 32248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (enabled) { 32348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onProviderEnabled(provider); 32448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } else { 32548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onProviderDisabled(provider); 32648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 32748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mListener != mProximityListener) { 32848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 32948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 33048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 33148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 33248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 33348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } catch (RemoteException e) { 33448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return false; 33548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 33648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } else { 33748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood Intent providerIntent = new Intent(); 33848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood providerIntent.putExtra(LocationManager.KEY_PROVIDER_ENABLED, enabled); 33948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood try { 34048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 34148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 34248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 34348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mPendingIntent.send(mContext, 0, providerIntent, this, mLocationHandler); 34448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 34548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 34648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 34748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 356105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 3578a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Location listener died"); 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3592f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeUpdatesLocked(this); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 36248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 36348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mPendingBroadcasts > 0) { 36448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood LocationManagerService.this.decrementPendingBroadcasts(); 36548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mPendingBroadcasts = 0; 36648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 36748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 36848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 36948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 37048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public void onSendFinished(PendingIntent pendingIntent, Intent intent, 37148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood int resultCode, String resultData, Bundle resultExtras) { 3720528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (this) { 3730528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood decrementPendingBroadcastsLocked(); 3740528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 37548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 37648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 3770528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // this must be called while synchronized by caller in a synchronized block 37848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // containing the sending of the broadcaset 37948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private void incrementPendingBroadcastsLocked() { 38048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mPendingBroadcasts++ == 0) { 3810528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood LocationManagerService.this.incrementPendingBroadcasts(); 38248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 38348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 38448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 3850528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private void decrementPendingBroadcastsLocked() { 3860528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (--mPendingBroadcasts == 0) { 3870528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood LocationManagerService.this.decrementPendingBroadcasts(); 38848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 38948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 39048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 39148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 39248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public void locationCallbackFinished(ILocationListener listener) { 393080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //Do not use getReceiver here as that will add the ILocationListener to 394080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //the receiver list if it is not found. If it is not found then the 395080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //LocationListener was removed when it had a pending broadcast and should 396080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //not be added back. 397080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel IBinder binder = listener.asBinder(); 398080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel Receiver receiver = mReceivers.get(binder); 39948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (receiver != null) { 4000528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (receiver) { 4010528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // so wakelock calls will succeed 4020528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood long identity = Binder.clearCallingIdentity(); 4030528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood receiver.decrementPendingBroadcastsLocked(); 4040528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood Binder.restoreCallingIdentity(identity); 4050528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4099637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood private final class SettingsObserver implements Observer { 4109637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood public void update(Observable o, Object arg) { 4112f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 4129637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood updateProvidersLocked(); 4139637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood } 4149637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood } 4159637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood } 4169637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood 417d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood private void addProvider(LocationProviderInterface provider) { 41815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProviders.add(provider); 41915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProvidersByName.put(provider.getName(), provider); 42015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 42115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 422d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood private void removeProvider(LocationProviderInterface provider) { 42315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProviders.remove(provider); 42415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProvidersByName.remove(provider.getName()); 42515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 42615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void loadProviders() { 4282f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sProvidersLoaded) { 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Load providers 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loadProvidersLocked(); 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sProvidersLoaded = true; 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void loadProvidersLocked() { 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project _loadProvidersLocked(); 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 4438a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "Exception loading providers:", e); 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void _loadProvidersLocked() { 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Attempt to load "real" providers first 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (GpsLocationProvider.isSupported()) { 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Create a gps location provider 451d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood GpsLocationProvider gpsProvider = new GpsLocationProvider(mContext, this); 452d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood mGpsStatusProvider = gpsProvider.getGpsStatusProvider(); 453d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood mNetInitiatedListener = gpsProvider.getNetInitiatedListener(); 454d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood addProvider(gpsProvider); 455d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood mGpsLocationProvider = gpsProvider; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 458a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood // create a passive location provider, which is always enabled 459a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood PassiveProvider passiveProvider = new PassiveProvider(this); 460a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood addProvider(passiveProvider); 461a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood mEnabledProviders.add(passiveProvider.getName()); 462a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood 463628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood // initialize external network location and geocoder services 464628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood Resources resources = mContext.getResources(); 465628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood String serviceName = resources.getString( 466628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood com.android.internal.R.string.config_networkLocationProvider); 467628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood if (serviceName != null) { 468628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood mNetworkLocationProvider = 469628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood new LocationProviderProxy(mContext, LocationManager.NETWORK_PROVIDER, 470628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood serviceName, mLocationHandler); 471628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood addProvider(mNetworkLocationProvider); 472628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood } 473628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood 474628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood serviceName = resources.getString(com.android.internal.R.string.config_geocodeProvider); 475628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood if (serviceName != null) { 476628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood mGeocodeProvider = new GeocoderProxy(mContext, serviceName); 477628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood } 478628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the context that the LocationManagerService runs in 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LocationManagerService(Context context) { 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(); 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 4883d12b51ee38537f6760a833618948f936e75561dMike Lockwood 489105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 4908a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Constructed LocationManager Service"); 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4923d12b51ee38537f6760a833618948f936e75561dMike Lockwood } 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 49446db504de583d7d644a28a4e7adae43eed5df1baMike Lockwood void systemReady() { 49546db504de583d7d644a28a4e7adae43eed5df1baMike Lockwood // we defer starting up the service until the system is ready 49646db504de583d7d644a28a4e7adae43eed5df1baMike Lockwood Thread thread = new Thread(null, this, "LocationManagerService"); 49746db504de583d7d644a28a4e7adae43eed5df1baMike Lockwood thread.start(); 49846db504de583d7d644a28a4e7adae43eed5df1baMike Lockwood } 49946db504de583d7d644a28a4e7adae43eed5df1baMike Lockwood 5003d12b51ee38537f6760a833618948f936e75561dMike Lockwood private void initialize() { 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Create a wake lock, needs to be done before calling loadProviders() below 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); 5040528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Load providers 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loadProviders(); 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Register for Network (Wifi or Mobile) updates 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntentFilter intentFilter = new IntentFilter(); 5100528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 5110528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Register for Package Manager updates 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED); 51421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn intentFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART); 5150528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mContext.registerReceiver(mBroadcastReceiver, intentFilter); 516b56ae20b22fd7283df32072a431ab6d4965f3c1bSuchi Amalapurapu IntentFilter sdFilter = new IntentFilter(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE); 51708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu mContext.registerReceiver(mBroadcastReceiver, sdFilter); 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5199637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood // listen for settings changes 5209637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood ContentResolver resolver = mContext.getContentResolver(); 5219637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood Cursor settingsCursor = resolver.query(Settings.Secure.CONTENT_URI, null, 5229637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood "(" + Settings.System.NAME + "=?)", 5239637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood new String[]{Settings.Secure.LOCATION_PROVIDERS_ALLOWED}, 5249637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood null); 5259637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mLocationHandler); 5269637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood SettingsObserver settingsObserver = new SettingsObserver(); 5279637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood mSettings.addObserver(settingsObserver); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5303d12b51ee38537f6760a833618948f936e75561dMike Lockwood public void run() 5313d12b51ee38537f6760a833618948f936e75561dMike Lockwood { 5323d12b51ee38537f6760a833618948f936e75561dMike Lockwood Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 5333d12b51ee38537f6760a833618948f936e75561dMike Lockwood Looper.prepare(); 5343d12b51ee38537f6760a833618948f936e75561dMike Lockwood mLocationHandler = new LocationWorkerHandler(); 5353d12b51ee38537f6760a833618948f936e75561dMike Lockwood initialize(); 5363d12b51ee38537f6760a833618948f936e75561dMike Lockwood Looper.loop(); 5373d12b51ee38537f6760a833618948f936e75561dMike Lockwood } 5383d12b51ee38537f6760a833618948f936e75561dMike Lockwood 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean isAllowedBySettingsLocked(String provider) { 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabledProviders.contains(provider)) { 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDisabledProviders.contains(provider)) { 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Use system settings 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver resolver = mContext.getContentResolver(); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5498eb3ea659761edc2cd5db3acf448059f19389e5eBrad Larson return Settings.Secure.isLocationProviderEnabled(resolver, provider); 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void checkPermissionsSafe(String provider) { 553a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood if ((LocationManager.GPS_PROVIDER.equals(provider) 554a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood || LocationManager.PASSIVE_PROVIDER.equals(provider)) 555b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_FINE_LOCATION permission"); 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LocationManager.NETWORK_PROVIDER.equals(provider) 560b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) 562b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION) 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException( 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Requires ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission"); 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean isAllowedProviderSafe(String provider) { 57043cc4696bfa7c3839931f3360c9660a9e41050b3Bryan Mawhinney if ((LocationManager.GPS_PROVIDER.equals(provider) 57143cc4696bfa7c3839931f3360c9660a9e41050b3Bryan Mawhinney || LocationManager.PASSIVE_PROVIDER.equals(provider)) 572b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LocationManager.NETWORK_PROVIDER.equals(provider) 577b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) 579b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION) 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<String> getAllProviders() { 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5892f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return _getAllProvidersLocked(); 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 5958a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "getAllProviders got exception:", e); 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private List<String> _getAllProvidersLocked() { 601105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 6028a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "getAllProviders"); 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 60415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood ArrayList<String> out = new ArrayList<String>(mProviders.size()); 60515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 606d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProviders.get(i); 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.add(p.getName()); 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return out; 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<String> getProviders(boolean enabledOnly) { 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6142f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return _getProvidersLocked(enabledOnly); 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 6208a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "getProviders got exception:", e); 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private List<String> _getProvidersLocked(boolean enabledOnly) { 626105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 6278a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "getProviders"); 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 62915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood ArrayList<String> out = new ArrayList<String>(mProviders.size()); 63015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 631d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProviders.get(i); 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = p.getName(); 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isAllowedProviderSafe(name)) { 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enabledOnly && !isAllowedBySettingsLocked(name)) { 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.add(name); 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return out; 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateProvidersLocked() { 64415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 645d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProviders.get(i); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isEnabled = p.isEnabled(); 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = p.getName(); 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean shouldBeEnabled = isAllowedBySettingsLocked(name); 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isEnabled && !shouldBeEnabled) { 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProviderListenersLocked(name, false); 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!isEnabled && shouldBeEnabled) { 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProviderListenersLocked(name, true); 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateProviderListenersLocked(String provider, boolean enabled) { 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int listeners = 0; 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 662d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null) { 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Receiver> deadReceivers = null; 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records != null) { 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = records.size(); 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UpdateRecord record = records.get(i); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Sends a notification message to the receiver 67548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) { 67648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (deadReceivers == null) { 67748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood deadReceivers = new ArrayList<Receiver>(); 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6794686657cee6411eb00235d49b4a8663a96361a00Simon Schoar deadReceivers.add(record.mReceiver); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listeners++; 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (deadReceivers != null) { 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=deadReceivers.size()-1; i>=0; i--) { 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeUpdatesLocked(deadReceivers.get(i)); 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enabled) { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.enable(); 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listeners > 0) { 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.setMinTime(getMinTimeLocked(provider)); 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.enableLocationTracking(true); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.enableLocationTracking(false); 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.disable(); 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long getMinTimeLocked(String provider) { 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long minTime = Long.MAX_VALUE; 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records != null) { 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=records.size()-1; i>=0; i--) { 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project minTime = Math.min(minTime, records.get(i).mMinTime); 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return minTime; 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class UpdateRecord { 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String mProvider; 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Receiver mReceiver; 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long mMinTime; 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float mMinDistance; 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int mUid; 7202f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Location mLastFixBroadcast; 7212f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood long mLastStatusBroadcast; 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Note: must be constructed with lock held. 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UpdateRecord(String provider, long minTime, float minDistance, 7272f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver receiver, int uid) { 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProvider = provider; 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReceiver = receiver; 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMinTime = minTime; 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMinDistance = minDistance; 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUid = uid; 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records == null) { 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project records = new ArrayList<UpdateRecord>(); 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecordsByProvider.put(provider, records); 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!records.contains(this)) { 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project records.add(this); 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Method to be called when a record will no longer be used. Calling this multiple times 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * must have the same effect as calling it once. 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void disposeLocked() { 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(this.mProvider); 7503a76fd627945c1df59aa0318867401e0e53da022Mike Lockwood if (records != null) { 7513a76fd627945c1df59aa0318867401e0e53da022Mike Lockwood records.remove(this); 7523a76fd627945c1df59aa0318867401e0e53da022Mike Lockwood } 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "UpdateRecord{" 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(System.identityHashCode(this)) 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " " + mProvider + " " + mReceiver + "}"; 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void dump(PrintWriter pw, String prefix) { 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + this); 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mProvider=" + mProvider + " mReceiver=" + mReceiver); 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mMinTime=" + mMinTime + " mMinDistance=" + mMinDistance); 7662f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood pw.println(prefix + "mUid=" + mUid); 7672f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood pw.println(prefix + "mLastFixBroadcast:"); 7683c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger if (mLastFixBroadcast != null) { 7693c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger mLastFixBroadcast.dump(new PrintWriterPrinter(pw), prefix + " "); 7703c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 7712f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood pw.println(prefix + "mLastStatusBroadcast=" + mLastStatusBroadcast); 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7752f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private Receiver getReceiver(ILocationListener listener) { 7762f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood IBinder binder = listener.asBinder(); 7772f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver receiver = mReceivers.get(binder); 7782f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (receiver == null) { 7792f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood receiver = new Receiver(listener); 7802f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mReceivers.put(binder, receiver); 7812f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 7822f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood try { 7832f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (receiver.isListener()) { 7842f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood receiver.getListener().asBinder().linkToDeath(receiver, 0); 7852f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 7862f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } catch (RemoteException e) { 7878a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "linkToDeath failed:", e); 7882f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return null; 7892f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 7902f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 7912f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return receiver; 7922f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 7932f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 7942f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private Receiver getReceiver(PendingIntent intent) { 7952f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver receiver = mReceivers.get(intent); 7962f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (receiver == null) { 7972f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood receiver = new Receiver(intent); 7982f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mReceivers.put(intent, receiver); 7992f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8002f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return receiver; 8012f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8022f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8032f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private boolean providerHasListener(String provider, int uid, Receiver excludedReceiver) { 8042f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 8052f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (records != null) { 8062f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood for (int i = records.size() - 1; i >= 0; i--) { 8072f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood UpdateRecord record = records.get(i); 8082f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (record.mUid == uid && record.mReceiver != excludedReceiver) { 8092f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return true; 8102f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8112f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8122f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 81395427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood for (ProximityAlert alert : mProximityAlerts.values()) { 81495427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood if (alert.mUid == uid) { 81595427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood return true; 8162f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8172f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8182f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return false; 8192f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8202f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void requestLocationUpdates(String provider, 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long minTime, float minDistance, ILocationListener listener) { 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8252f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 8262f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood requestLocationUpdatesLocked(provider, minTime, minDistance, getReceiver(listener)); 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 8303b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood } catch (IllegalArgumentException iae) { 8313b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood throw iae; 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 8338a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "requestUpdates got exception:", e); 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void requestLocationUpdatesPI(String provider, 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long minTime, float minDistance, PendingIntent intent) { 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8402f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 8412f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood requestLocationUpdatesLocked(provider, minTime, minDistance, getReceiver(intent)); 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 8453b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood } catch (IllegalArgumentException iae) { 8463b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood throw iae; 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 8488a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "requestUpdates got exception:", e); 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void requestLocationUpdatesLocked(String provider, 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long minTime, float minDistance, Receiver receiver) { 854105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 8558a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "_requestLocationUpdates: listener = " + receiver); 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 858d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 859d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood if (p == null) { 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("provider=" + provider); 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkPermissionsSafe(provider); 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // so wakelock calls will succeed 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int callingUid = Binder.getCallingUid(); 8672f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood boolean newUid = !providerHasListener(provider, callingUid, null); 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identity = Binder.clearCallingIdentity(); 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8702f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood UpdateRecord r = new UpdateRecord(provider, minTime, minDistance, receiver, callingUid); 8712f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood UpdateRecord oldRecord = receiver.mUpdateRecords.put(provider, r); 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (oldRecord != null) { 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project oldRecord.disposeLocked(); 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8762f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (newUid) { 877d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood p.addListener(callingUid); 8782f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8792f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isProviderEnabled = isAllowedBySettingsLocked(provider); 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isProviderEnabled) { 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long minTimeForProvider = getMinTimeLocked(provider); 883d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood p.setMinTime(minTimeForProvider); 884d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood p.enableLocationTracking(true); 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 88648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // Notify the listener that updates are currently disabled 88748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood receiver.callProviderEnabledLocked(provider, false); 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(identity); 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeUpdates(ILocationListener listener) { 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8962f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 8972f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood removeUpdatesLocked(getReceiver(listener)); 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 9013b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood } catch (IllegalArgumentException iae) { 9023b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood throw iae; 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 9048a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "removeUpdates got exception:", e); 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeUpdatesPI(PendingIntent intent) { 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9102f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 9112f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood removeUpdatesLocked(getReceiver(intent)); 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 9153b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood } catch (IllegalArgumentException iae) { 9163b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood throw iae; 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 9188a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "removeUpdates got exception:", e); 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeUpdatesLocked(Receiver receiver) { 923105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 9248a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "_removeUpdates: listener = " + receiver); 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // so wakelock calls will succeed 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int callingUid = Binder.getCallingUid(); 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identity = Binder.clearCallingIdentity(); 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9312f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) { 9322f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood receiver.getListener().asBinder().unlinkToDeath(receiver, 0); 933080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel synchronized(receiver) { 934080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel if(receiver.mPendingBroadcasts > 0) { 935080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel decrementPendingBroadcasts(); 936080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel receiver.mPendingBroadcasts = 0; 937080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel } 938080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel } 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Record which providers were associated with this listener 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HashSet<String> providers = new HashSet<String>(); 9432f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood HashMap<String,UpdateRecord> oldRecords = receiver.mUpdateRecords; 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (oldRecords != null) { 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Call dispose() on the obsolete update records. 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (UpdateRecord record : oldRecords.values()) { 9472f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (!providerHasListener(record.mProvider, callingUid, receiver)) { 948d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(record.mProvider); 949d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood if (p != null) { 950d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood p.removeListener(callingUid); 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project record.disposeLocked(); 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Accumulate providers 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project providers.addAll(oldRecords.keySet()); 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // See if the providers associated with this listener have any 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // other listeners; if one does, inform it of the new smallest minTime 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // value; if one does not, disable location tracking for it 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String provider : providers) { 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If provider is already disabled, don't need to do anything 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isAllowedBySettingsLocked(provider)) { 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hasOtherListener = false; 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> recordsForProvider = mRecordsByProvider.get(provider); 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (recordsForProvider != null && recordsForProvider.size() > 0) { 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasOtherListener = true; 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 974d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p != null) { 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hasOtherListener) { 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.setMinTime(getMinTimeLocked(provider)); 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.enableLocationTracking(false); 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(identity); 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean addGpsStatusListener(IGpsStatusListener listener) { 98915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mGpsStatusProvider == null) { 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 992b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood if (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) != 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageManager.PERMISSION_GRANTED) { 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_FINE_LOCATION permission"); 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 99815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mGpsStatusProvider.addGpsStatusListener(listener); 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 10008a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "mGpsStatusProvider.addGpsStatusListener failed", e); 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeGpsStatusListener(IGpsStatusListener listener) { 10072f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 100815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood try { 100915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mGpsStatusProvider.removeGpsStatusListener(listener); 101015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } catch (Exception e) { 10118a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "mGpsStatusProvider.removeGpsStatusListener failed", e); 101215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String provider, String command, Bundle extras) { 1017c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood if (provider == null) { 1018c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood // throw NullPointerException to remain compatible with previous implementation 1019c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood throw new NullPointerException(); 1020c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood } 1021c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // first check for permission to the provider 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkPermissionsSafe(provider); 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and check for ACCESS_LOCATION_EXTRA_COMMANDS 1025b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood if ((mContext.checkCallingOrSelfPermission(ACCESS_LOCATION_EXTRA_COMMANDS) 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_LOCATION_EXTRA_COMMANDS permission"); 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10302f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 1031d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 1032d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood if (p == null) { 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1036d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return p.sendExtraCommand(command, extras); 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 104022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public boolean sendNiResponse(int notifId, int userResponse) 104122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 104218ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood if (Binder.getCallingUid() != Process.myUid()) { 104318ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood throw new SecurityException( 104418ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood "calling sendNiResponse from outside of the system is not allowed"); 104518ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood } 104622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie try { 104722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return mNetInitiatedListener.sendNiResponse(notifId, userResponse); 104822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 104922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie catch (RemoteException e) 105022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 10518a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "RemoteException in LocationManagerService.sendNiResponse"); 105222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return false; 105322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 105422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 105522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class ProximityAlert { 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int mUid; 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final double mLatitude; 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final double mLongitude; 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float mRadius; 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long mExpiration; 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PendingIntent mIntent; 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Location mLocation; 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ProximityAlert(int uid, double latitude, double longitude, 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float radius, long expiration, PendingIntent intent) { 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUid = uid; 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLatitude = latitude; 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLongitude = longitude; 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadius = radius; 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExpiration = expiration; 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIntent = intent; 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation = new Location(""); 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLatitude(latitude); 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLongitude(longitude); 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long getExpiration() { 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mExpiration; 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent getIntent() { 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mIntent; 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10872d2078aa1d6e31063f565a20b717f3b8908fff02Yusuf T. Mobile boolean isInProximity(double latitude, double longitude, float accuracy) { 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Location loc = new Location(""); 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loc.setLatitude(latitude); 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loc.setLongitude(longitude); 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project double radius = loc.distanceTo(mLocation); 10932d2078aa1d6e31063f565a20b717f3b8908fff02Yusuf T. Mobile return radius <= Math.max(mRadius,accuracy); 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "ProximityAlert{" 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(System.identityHashCode(this)) 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " uid " + mUid + mIntent + "}"; 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void dump(PrintWriter pw, String prefix) { 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + this); 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mLatitude=" + mLatitude + " mLongitude=" + mLongitude); 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mRadius=" + mRadius + " mExpiration=" + mExpiration); 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mIntent=" + mIntent); 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mLocation:"); 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.dump(new PrintWriterPrinter(pw), prefix + " "); 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Listener for receiving locations to trigger proximity alerts 111448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood class ProximityListener extends ILocationListener.Stub implements PendingIntent.OnFinished { 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isGpsAvailable = false; 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: this is called with the lock held. 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onLocationChanged(Location loc) { 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If Gps is available, then ignore updates from NetworkLocationProvider 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (loc.getProvider().equals(LocationManager.GPS_PROVIDER)) { 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project isGpsAvailable = true; 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isGpsAvailable && loc.getProvider().equals(LocationManager.NETWORK_PROVIDER)) { 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Process proximity alerts 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now = System.currentTimeMillis(); 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project double latitude = loc.getLatitude(); 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project double longitude = loc.getLongitude(); 11332d2078aa1d6e31063f565a20b717f3b8908fff02Yusuf T. Mobile float accuracy = loc.getAccuracy(); 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<PendingIntent> intentsToRemove = null; 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ProximityAlert alert : mProximityAlerts.values()) { 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent intent = alert.getIntent(); 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long expiration = alert.getExpiration(); 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((expiration == -1) || (now <= expiration)) { 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean entered = mProximitiesEntered.contains(alert); 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean inProximity = 11432d2078aa1d6e31063f565a20b717f3b8908fff02Yusuf T. Mobile alert.isInProximity(latitude, longitude, accuracy); 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!entered && inProximity) { 1145105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 11468a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Entered alert"); 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximitiesEntered.add(alert); 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent enteredIntent = new Intent(); 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enteredIntent.putExtra(LocationManager.KEY_PROXIMITY_ENTERING, true); 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11520528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (this) { 11530528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // synchronize to ensure incrementPendingBroadcasts() 115448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 115548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood intent.send(mContext, 0, enteredIntent, this, mLocationHandler); 115648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 115748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 11580528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood incrementPendingBroadcasts(); 115948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 1161105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 11628a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Canceled proximity alert: " + alert, e); 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intentsToRemove == null) { 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove = new ArrayList<PendingIntent>(); 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove.add(intent); 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (entered && !inProximity) { 1170105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 11718a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Exited alert"); 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximitiesEntered.remove(alert); 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent exitedIntent = new Intent(); 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project exitedIntent.putExtra(LocationManager.KEY_PROXIMITY_ENTERING, false); 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11770528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (this) { 11780528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // synchronize to ensure incrementPendingBroadcasts() 117948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 118048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood intent.send(mContext, 0, exitedIntent, this, mLocationHandler); 118148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 118248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 11830528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood incrementPendingBroadcasts(); 118448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 1186105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 11878a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Canceled proximity alert: " + alert, e); 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intentsToRemove == null) { 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove = new ArrayList<PendingIntent>(); 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove.add(intent); 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Mark alert for expiration 1197105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 11988a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "Expiring proximity alert: " + alert); 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intentsToRemove == null) { 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove = new ArrayList<PendingIntent>(); 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove.add(alert.getIntent()); 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove expired alerts 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intentsToRemove != null) { 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (PendingIntent i : intentsToRemove) { 12108fff6451476334fbef30a080f46f37d552257e9aSean Foy ProximityAlert alert = mProximityAlerts.get(i); 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximitiesEntered.remove(alert); 12128fff6451476334fbef30a080f46f37d552257e9aSean Foy removeProximityAlertLocked(i); 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: this is called with the lock held. 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onProviderDisabled(String provider) { 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider.equals(LocationManager.GPS_PROVIDER)) { 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project isGpsAvailable = false; 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: this is called with the lock held. 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onProviderEnabled(String provider) { 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ignore 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: this is called with the lock held. 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onStatusChanged(String provider, int status, Bundle extras) { 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((provider.equals(LocationManager.GPS_PROVIDER)) && 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (status != LocationProvider.AVAILABLE)) { 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project isGpsAvailable = false; 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 123648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 123748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public void onSendFinished(PendingIntent pendingIntent, Intent intent, 123848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood int resultCode, String resultData, Bundle resultExtras) { 12390528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // synchronize to ensure incrementPendingBroadcasts() 12400528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // is called before decrementPendingBroadcasts() 12410528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (this) { 12420528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood decrementPendingBroadcasts(); 12430528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 124448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addProximityAlert(double latitude, double longitude, 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float radius, long expiration, PendingIntent intent) { 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 12502f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addProximityAlertLocked(latitude, longitude, radius, expiration, intent); 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 12553b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood } catch (IllegalArgumentException iae) { 12563b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood throw iae; 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 12588a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "addProximityAlert got exception:", e); 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void addProximityAlertLocked(double latitude, double longitude, 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float radius, long expiration, PendingIntent intent) { 1264105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 12658a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "addProximityAlert: latitude = " + latitude + 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ", longitude = " + longitude + 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ", expiration = " + expiration + 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ", intent = " + intent); 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Require ability to access all providers for now 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isAllowedProviderSafe(LocationManager.GPS_PROVIDER) || 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project !isAllowedProviderSafe(LocationManager.NETWORK_PROVIDER)) { 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_FINE_LOCATION permission"); 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (expiration != -1) { 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project expiration += System.currentTimeMillis(); 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ProximityAlert alert = new ProximityAlert(Binder.getCallingUid(), 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project latitude, longitude, radius, expiration, intent); 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximityAlerts.put(intent, alert); 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 128448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mProximityReceiver == null) { 128548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mProximityListener = new ProximityListener(); 128648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mProximityReceiver = new Receiver(mProximityListener); 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 128895427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 1289d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface provider = mProviders.get(i); 129048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood requestLocationUpdatesLocked(provider.getName(), 1000L, 1.0f, mProximityReceiver); 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeProximityAlert(PendingIntent intent) { 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 12972f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeProximityAlertLocked(intent); 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 13023b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood } catch (IllegalArgumentException iae) { 13033b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood throw iae; 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 13058a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "removeProximityAlert got exception:", e); 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeProximityAlertLocked(PendingIntent intent) { 1310105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 13118a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.v(TAG, "removeProximityAlert: intent = " + intent); 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximityAlerts.remove(intent); 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProximityAlerts.size() == 0) { 131648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood removeUpdatesLocked(mProximityReceiver); 131748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mProximityReceiver = null; 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximityListener = null; 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1323628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood * @return null if the provider does not exist 1324f2db9fb0f877057a9ef56908d54f3c95fc3fd552Alexey Tarasov * @throws SecurityException if the provider is not allowed to be 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * accessed by the caller 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Bundle getProviderInfo(String provider) { 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 13292f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return _getProviderInfoLocked(provider); 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 13343b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood } catch (IllegalArgumentException iae) { 13353b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood throw iae; 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 13378a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "_getProviderInfo got exception:", e); 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Bundle _getProviderInfoLocked(String provider) { 1343d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 1344223e84d7336db189060f3f766a66037af8690496Mike Lockwood if (p == null) { 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkPermissionsSafe(provider); 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Bundle b = new Bundle(); 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putBoolean("network", p.requiresNetwork()); 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putBoolean("satellite", p.requiresSatellite()); 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putBoolean("cell", p.requiresCell()); 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putBoolean("cost", p.hasMonetaryCost()); 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putBoolean("altitude", p.supportsAltitude()); 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putBoolean("speed", p.supportsSpeed()); 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putBoolean("bearing", p.supportsBearing()); 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putInt("power", p.getPowerRequirement()); 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putInt("accuracy", p.getAccuracy()); 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return b; 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isProviderEnabled(String provider) { 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 13662f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return _isProviderEnabledLocked(provider); 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 13713b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood } catch (IllegalArgumentException iae) { 13723b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood throw iae; 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 13748a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "isProviderEnabled got exception:", e); 13759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood public void reportLocation(Location location, boolean passive) { 1380275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER) 1381275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood != PackageManager.PERMISSION_GRANTED) { 1382275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood throw new SecurityException("Requires INSTALL_LOCATION_PROVIDER permission"); 1383275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood } 1384275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood 13854e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood mLocationHandler.removeMessages(MESSAGE_LOCATION_CHANGED, location); 13864e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood Message m = Message.obtain(mLocationHandler, MESSAGE_LOCATION_CHANGED, location); 1387a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood m.arg1 = (passive ? 1 : 0); 13884e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood mLocationHandler.sendMessageAtFrontOfQueue(m); 13894e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood } 13904e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood 13919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean _isProviderEnabledLocked(String provider) { 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkPermissionsSafe(provider); 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1394d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null) { 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("provider=" + provider); 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return isAllowedBySettingsLocked(provider); 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Location getLastKnownLocation(String provider) { 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 14032f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return _getLastKnownLocationLocked(provider); 14059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 14083b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood } catch (IllegalArgumentException iae) { 14093b9ef08bbbdc95a609fa7883d6fff4b4fd22e33cMike Lockwood throw iae; 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 14118a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "getLastKnownLocation got exception:", e); 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Location _getLastKnownLocationLocked(String provider) { 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkPermissionsSafe(provider); 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1419d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null) { 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("provider=" + provider); 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isAllowedBySettingsLocked(provider)) { 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14289aa1fa2d3612d1d8ffeae6552d65669f4ca194d9Mike Lockwood return mLastKnownLocation.get(provider); 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean shouldBroadcastSafe(Location loc, Location lastLoc, UpdateRecord record) { 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Always broadcast the first update 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lastLoc == null) { 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Don't broadcast same location again regardless of condition 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO - we should probably still rebroadcast if user explicitly sets a minTime > 0 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (loc.getTime() == lastLoc.getTime()) { 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check whether sufficient distance has been traveled 14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project double minDistance = record.mMinDistance; 14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (minDistance > 0.0) { 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (loc.distanceTo(lastLoc) <= minDistance) { 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 14529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1454a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood private void handleLocationChangedLocked(Location location, boolean passive) { 1455a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood String provider = (passive ? LocationManager.PASSIVE_PROVIDER : location.getProvider()); 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records == null || records.size() == 0) { 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1461d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(provider); 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null) { 14639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14664e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood // Update last known location for provider 14674e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood Location lastLocation = mLastKnownLocation.get(provider); 14684e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood if (lastLocation == null) { 14694e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood mLastKnownLocation.put(provider, new Location(location)); 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14714e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood lastLocation.set(location); 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Fetch latest status update time 14759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long newStatusUpdateTime = p.getStatusUpdateTime(); 14769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14777ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood // Get latest status 14789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Bundle extras = new Bundle(); 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int status = p.getStatus(extras); 14809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Receiver> deadReceivers = null; 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Broadcast location or status to all listeners 14849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = records.size(); 14859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 14869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UpdateRecord r = records.get(i); 14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Receiver receiver = r.mReceiver; 14889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14892f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Location lastLoc = r.mLastFixBroadcast; 14904e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood if ((lastLoc == null) || shouldBroadcastSafe(location, lastLoc, r)) { 14914e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood if (lastLoc == null) { 14924e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood lastLoc = new Location(location); 14932f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood r.mLastFixBroadcast = lastLoc; 14944e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood } else { 14954e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood lastLoc.set(location); 14969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14974e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood if (!receiver.callLocationChangedLocked(location)) { 14988a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "RemoteException calling onLocationChanged on " + receiver); 14994e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood if (deadReceivers == null) { 15004e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood deadReceivers = new ArrayList<Receiver>(); 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15024e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood deadReceivers.add(receiver); 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15062f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood long prevStatusUpdateTime = r.mLastStatusBroadcast; 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((newStatusUpdateTime > prevStatusUpdateTime) && 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (prevStatusUpdateTime != 0 || status != LocationProvider.AVAILABLE)) { 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15102f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood r.mLastStatusBroadcast = newStatusUpdateTime; 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!receiver.callStatusChangedLocked(provider, status, extras)) { 15128a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.w(TAG, "RemoteException calling onStatusChanged on " + receiver); 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (deadReceivers == null) { 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deadReceivers = new ArrayList<Receiver>(); 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!deadReceivers.contains(receiver)) { 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deadReceivers.add(receiver); 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (deadReceivers != null) { 15249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=deadReceivers.size()-1; i>=0; i--) { 15259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeUpdatesLocked(deadReceivers.get(i)); 15269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class LocationWorkerHandler extends Handler { 15319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15354e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood if (msg.what == MESSAGE_LOCATION_CHANGED) { 15364e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood // log("LocationWorkerHandler: MESSAGE_LOCATION_CHANGED!"); 15379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15382f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 15394e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood Location location = (Location) msg.obj; 1540fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood String provider = location.getProvider(); 1541a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood boolean passive = (msg.arg1 == 1); 1542a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood 1543a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood if (!passive) { 1544a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood // notify other providers of the new location 1545a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 1546a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood LocationProviderInterface p = mProviders.get(i); 1547a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood if (!provider.equals(p.getName())) { 1548a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood p.updateLocation(location); 1549a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood } 155098cb66797422c4ccdee6f1a07636146d784a471bMike Lockwood } 155198cb66797422c4ccdee6f1a07636146d784a471bMike Lockwood } 155298cb66797422c4ccdee6f1a07636146d784a471bMike Lockwood 1553fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood if (isAllowedBySettingsLocked(provider)) { 1554a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood handleLocationChangedLocked(location, passive); 15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Log, don't crash! 15608a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "Exception in LocationWorkerHandler.handleMessage:", e); 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15650528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 15660528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood @Override 15670528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood public void onReceive(Context context, Intent intent) { 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String action = intent.getAction(); 156921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn boolean queryRestart = action.equals(Intent.ACTION_QUERY_PACKAGE_RESTART); 157021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (queryRestart 157121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn || action.equals(Intent.ACTION_PACKAGE_REMOVED) 157208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu || action.equals(Intent.ACTION_PACKAGE_RESTARTED) 1573b56ae20b22fd7283df32072a431ab6d4965f3c1bSuchi Amalapurapu || action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) { 15742f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 157508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu int uidList[] = null; 1576b56ae20b22fd7283df32072a431ab6d4965f3c1bSuchi Amalapurapu if (action.equals(Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE)) { 157708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu uidList = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST); 157808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } else { 157908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu uidList = new int[]{intent.getIntExtra(Intent.EXTRA_UID, -1)}; 158008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 158108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (uidList == null || uidList.length == 0) { 158208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu return; 158308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 158408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (int uid : uidList) { 158508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (uid >= 0) { 158608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu ArrayList<Receiver> removedRecs = null; 158708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (ArrayList<UpdateRecord> i : mRecordsByProvider.values()) { 158808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (int j=i.size()-1; j>=0; j--) { 158908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu UpdateRecord ur = i.get(j); 159008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (ur.mReceiver.isPendingIntent() && ur.mUid == uid) { 159121f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (queryRestart) { 159221f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn setResultCode(Activity.RESULT_OK); 159321f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return; 159421f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 159508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (removedRecs == null) { 159608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removedRecs = new ArrayList<Receiver>(); 159708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 159808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (!removedRecs.contains(ur.mReceiver)) { 159908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removedRecs.add(ur.mReceiver); 160008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 160408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu ArrayList<ProximityAlert> removedAlerts = null; 160508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (ProximityAlert i : mProximityAlerts.values()) { 160608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (i.mUid == uid) { 160721f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn if (queryRestart) { 160821f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn setResultCode(Activity.RESULT_OK); 160921f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn return; 161021f1bd17b2dfe361acbb28453b3f3b1a110932faDianne Hackborn } 161108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (removedAlerts == null) { 161208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removedAlerts = new ArrayList<ProximityAlert>(); 161308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 161408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (!removedAlerts.contains(i)) { 161508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removedAlerts.add(i); 161608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 161908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (removedRecs != null) { 162008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (int i=removedRecs.size()-1; i>=0; i--) { 162108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removeUpdatesLocked(removedRecs.get(i)); 162208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 162408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (removedAlerts != null) { 162508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (int i=removedAlerts.size()-1; i>=0; i--) { 162608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removeProximityAlertLocked(removedAlerts.get(i).mIntent); 162708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16320528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean noConnectivity = 16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); 16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!noConnectivity) { 16364df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mNetworkState = LocationProvider.AVAILABLE; 16374df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } else { 16384df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mNetworkState = LocationProvider.TEMPORARILY_UNAVAILABLE; 16399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 164003d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood NetworkInfo info = 164108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu (NetworkInfo)intent.getExtra(ConnectivityManager.EXTRA_NETWORK_INFO); 16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Notify location providers of current network state 16442f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 164515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 1646d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface provider = mProviders.get(i); 1647f19a785e15d9ffa1c1e56c254af082fc87aa1f3cMike Lockwood if (provider.requiresNetwork()) { 164803d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood provider.updateNetworkState(mNetworkState, info); 16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16540528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood }; 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Wake locks 16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16580528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private void incrementPendingBroadcasts() { 16590528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (mWakeLock) { 16600528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (mPendingBroadcasts++ == 0) { 16610528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood try { 16620528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.acquire(); 16630528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood log("Acquired wakelock"); 16640528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } catch (Exception e) { 16650528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // This is to catch a runtime exception thrown when we try to release an 16660528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // already released lock. 16678a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "exception in acquireWakeLock()", e); 16680528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 16690528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 167048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 167148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 167248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 167348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private void decrementPendingBroadcasts() { 16740528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (mWakeLock) { 167548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (--mPendingBroadcasts == 0) { 16760528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood try { 16770528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Release wake lock 16780528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (mWakeLock.isHeld()) { 16790528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.release(); 16800528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood log("Released wakelock"); 16810528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } else { 16820528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood log("Can't release wakelock again!"); 16830528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 16840528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } catch (Exception e) { 16850528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // This is to catch a runtime exception thrown when we try to release an 16860528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // already released lock. 16878a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.e(TAG, "exception in releaseWakeLock()", e); 16880528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 168948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 169048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 169148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 169248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Geocoder 16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getFromLocation(double latitude, double longitude, int maxResults, 169634901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwood GeocoderParams params, List<Address> addrs) { 1697a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood if (mGeocodeProvider != null) { 1698628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood return mGeocodeProvider.getFromLocation(latitude, longitude, maxResults, 1699628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood params, addrs); 17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1701a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood return null; 17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1704a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getFromLocationName(String locationName, 1706a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood double lowerLeftLatitude, double lowerLeftLongitude, 1707a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood double upperRightLatitude, double upperRightLongitude, int maxResults, 170834901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwood GeocoderParams params, List<Address> addrs) { 1709a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 1710a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood if (mGeocodeProvider != null) { 1711628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood return mGeocodeProvider.getFromLocationName(locationName, lowerLeftLatitude, 1712628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood lowerLeftLongitude, upperRightLatitude, upperRightLongitude, 1713628fd6d9c11ed9806abebf34bc986247c106328fMike Lockwood maxResults, params, addrs); 17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1715a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood return null; 17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Mock Providers 17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void checkMockPermissionsSafe() { 17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean allowMocks = Settings.Secure.getInt(mContext.getContentResolver(), 17229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 1; 17239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allowMocks) { 17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_MOCK_LOCATION secure setting"); 17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) != 17289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageManager.PERMISSION_GRANTED) { 17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission"); 17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite, 17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude, 17359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) { 17369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 17379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1738a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood if (LocationManager.PASSIVE_PROVIDER.equals(name)) { 1739a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood throw new IllegalArgumentException("Cannot mock the passive location provider"); 1740a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood } 1741a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood 174286328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 17432f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 17444e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood MockProvider provider = new MockProvider(name, this, 17454e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood requiresNetwork, requiresSatellite, 17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requiresCell, hasMonetaryCost, supportsAltitude, 17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project supportsSpeed, supportsBearing, powerRequirement, accuracy); 17487566c1debebe072af76411e11d96810fd1409482Mike Lockwood // remove the real provider if we are replacing GPS or network provider 17497566c1debebe072af76411e11d96810fd1409482Mike Lockwood if (LocationManager.GPS_PROVIDER.equals(name) 17507566c1debebe072af76411e11d96810fd1409482Mike Lockwood || LocationManager.NETWORK_PROVIDER.equals(name)) { 1751d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood LocationProviderInterface p = mProvidersByName.get(name); 1752d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood if (p != null) { 1753d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood p.enableLocationTracking(false); 1754d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood removeProvider(p); 17557566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 17567566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 175715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mProvidersByName.get(name) != null) { 17589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + name + "\" already exists"); 17599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1760d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood addProvider(provider); 17617ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mMockProviders.put(name, provider); 17627566c1debebe072af76411e11d96810fd1409482Mike Lockwood mLastKnownLocation.put(name, null); 17639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 17649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 176586328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeTestProvider(String provider) { 17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 17702f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 17717ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 17727ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 177586328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 177615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood removeProvider(mProvidersByName.get(provider)); 17777ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mMockProviders.remove(mockProvider); 17787566c1debebe072af76411e11d96810fd1409482Mike Lockwood // reinstall real provider if we were mocking GPS or network provider 17797566c1debebe072af76411e11d96810fd1409482Mike Lockwood if (LocationManager.GPS_PROVIDER.equals(provider) && 17807566c1debebe072af76411e11d96810fd1409482Mike Lockwood mGpsLocationProvider != null) { 17817566c1debebe072af76411e11d96810fd1409482Mike Lockwood addProvider(mGpsLocationProvider); 17827566c1debebe072af76411e11d96810fd1409482Mike Lockwood } else if (LocationManager.NETWORK_PROVIDER.equals(provider) && 17837566c1debebe072af76411e11d96810fd1409482Mike Lockwood mNetworkLocationProvider != null) { 17847566c1debebe072af76411e11d96810fd1409482Mike Lockwood addProvider(mNetworkLocationProvider); 17857566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 17867566c1debebe072af76411e11d96810fd1409482Mike Lockwood mLastKnownLocation.put(provider, null); 17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 178886328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderLocation(String provider, Location loc) { 17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 17942f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 17957ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 17967ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 179995427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood // clear calling identity so INSTALL_LOCATION_PROVIDER permission is not required 180095427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood long identity = Binder.clearCallingIdentity(); 18017ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.setLocation(loc); 180295427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood Binder.restoreCallingIdentity(identity); 18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderLocation(String provider) { 18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18082f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18097ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18107ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18137ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.clearLocation(); 18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderEnabled(String provider, boolean enabled) { 18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18192f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18207ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18217ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 182486328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enabled) { 18267ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.enable(); 18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.add(provider); 18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.remove(provider); 18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 18307ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.disable(); 18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.remove(provider); 18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.add(provider); 18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 183586328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderEnabled(String provider) { 18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18412f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18427ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18437ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 184686328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.remove(provider); 18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.remove(provider); 18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 185086328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) { 18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18562f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18577ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18587ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18617ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.setStatus(status, extras, updateTime); 18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderStatus(String provider) { 18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18672f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18687ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18697ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18727ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.clearStatus(); 18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void log(String log) { 18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 18788a9b22056b13477f59df934928c00c58b5871c95Joe Onorato Slog.d(TAG, log); 18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 18850528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood pw.println("Permission Denial: can't dump LocationManagerService from from pid=" 18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Binder.getCallingPid() 18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18912f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Current Location Manager state:"); 18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" sProvidersLoaded=" + sProvidersLoaded); 18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Listeners:"); 18952f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood int N = mReceivers.size(); 18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 18972f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood pw.println(" " + mReceivers.get(i)); 18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Location Listeners:"); 19002f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood for (Receiver i : mReceivers.values()) { 19012f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood pw.println(" " + i + ":"); 19022f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood for (Map.Entry<String,UpdateRecord> j : i.mUpdateRecords.entrySet()) { 19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + j.getKey() + ":"); 19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project j.getValue().dump(pw, " "); 19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Records by Provider:"); 19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, ArrayList<UpdateRecord>> i 19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mRecordsByProvider.entrySet()) { 19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i.getKey() + ":"); 19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (UpdateRecord j : i.getValue()) { 19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + j + ":"); 19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project j.dump(pw, " "); 19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Last Known Locations:"); 19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, Location> i 19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mLastKnownLocation.entrySet()) { 19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i.getKey() + ":"); 19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i.getValue().dump(new PrintWriterPrinter(pw), " "); 19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProximityAlerts.size() > 0) { 19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Proximity Alerts:"); 19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<PendingIntent, ProximityAlert> i 19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mProximityAlerts.entrySet()) { 19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i.getKey() + ":"); 19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i.getValue().dump(pw, " "); 19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProximitiesEntered.size() > 0) { 19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Proximities Entered:"); 19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ProximityAlert i : mProximitiesEntered) { 19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i + ":"); 19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i.dump(pw, " "); 19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 193748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood pw.println(" mProximityReceiver=" + mProximityReceiver); 19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" mProximityListener=" + mProximityListener); 19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabledProviders.size() > 0) { 19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Enabled Providers:"); 19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String i : mEnabledProviders) { 19429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i); 19439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDisabledProviders.size() > 0) { 19479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Disabled Providers:"); 19489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String i : mDisabledProviders) { 19499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i); 19509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMockProviders.size() > 0) { 19549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Mock Providers:"); 19559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, MockProvider> i : mMockProviders.entrySet()) { 19567ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood i.getValue().dump(pw, " "); 19579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19593c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger for (LocationProviderInterface provider: mProviders) { 19603c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger String state = provider.getInternalState(); 19613c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger if (state != null) { 19623c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger pw.println(provider.getName() + " Internal State:"); 19633c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger pw.write(state); 19643c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 19653c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 19669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1969