LocationManagerService.java revision 080b61ba17014b8c93914f642ccbe05c76dc611d
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 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.app.PendingIntent; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.BroadcastReceiver; 329637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwoodimport android.content.ContentQueryMap; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.ContentResolver; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.IntentFilter; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.pm.PackageManager; 389637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwoodimport android.database.Cursor; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Address; 40a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwoodimport android.location.IGeocodeProvider; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.IGpsStatusListener; 4215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwoodimport android.location.IGpsStatusProvider; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.ILocationListener; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.ILocationManager; 45e932f7f2a47b770c636443d411436bd29cc4bb43Mike Lockwoodimport android.location.ILocationProvider; 4622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.location.INetInitiatedListener; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Location; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationManager; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationProvider; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.ConnectivityManager; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 563d12b51ee38537f6760a833618948f936e75561dMike Lockwoodimport android.os.Looper; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.PowerManager; 59e932f7f2a47b770c636443d411436bd29cc4bb43Mike Lockwoodimport android.os.Process; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.PrintWriterPrinter; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.location.GpsLocationProvider; 66e932f7f2a47b770c636443d411436bd29cc4bb43Mike Lockwoodimport com.android.internal.location.LocationProviderProxy; 677ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwoodimport com.android.internal.location.MockProvider; 6822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport com.android.internal.location.GpsNetInitiatedHandler; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The service class that manages LocationProviders and issues location 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * updates and alerts. 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 763d12b51ee38537f6760a833618948f936e75561dMike Lockwoodpublic class LocationManagerService extends ILocationManager.Stub implements Runnable { 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "LocationManagerService"; 78105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final boolean LOCAL_LOGV = false; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The last time a location was written, by provider name. 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashMap<String,Long> mLastWriteTime = new HashMap<String,Long>(); 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_FINE_LOCATION = 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.ACCESS_FINE_LOCATION; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_COARSE_LOCATION = 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.ACCESS_COARSE_LOCATION; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_MOCK_LOCATION = 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.ACCESS_MOCK_LOCATION; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_LOCATION_EXTRA_COMMANDS = 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS; 91275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood private static final String INSTALL_LOCATION_PROVIDER = 92275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood android.Manifest.permission.INSTALL_LOCATION_PROVIDER; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set of providers that are explicitly enabled 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Set<String> mEnabledProviders = new HashSet<String>(); 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set of providers that are explicitly disabled 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Set<String> mDisabledProviders = new HashSet<String>(); 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Locations, status values, and extras for mock providers 1017ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood private final HashMap<String,MockProvider> mMockProviders = new HashMap<String,MockProvider>(); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean sProvidersLoaded = false; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 106a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood private IGeocodeProvider mGeocodeProvider; 10715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private IGpsStatusProvider mGpsStatusProvider; 10822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private INetInitiatedListener mNetInitiatedListener; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private LocationWorkerHandler mLocationHandler; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1117566c1debebe072af76411e11d96810fd1409482Mike Lockwood // Cache the real providers for use in addTestProvider() and removeTestProvider() 1127566c1debebe072af76411e11d96810fd1409482Mike Lockwood LocationProviderProxy mNetworkLocationProvider; 1137566c1debebe072af76411e11d96810fd1409482Mike Lockwood LocationProviderProxy mGpsLocationProvider; 1147566c1debebe072af76411e11d96810fd1409482Mike Lockwood 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Handler messages 1164e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood private static final int MESSAGE_LOCATION_CHANGED = 1; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1180528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // wakelock variables 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final static String WAKELOCK_KEY = "LocationManagerService"; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private PowerManager.WakeLock mWakeLock = null; 12148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private int mPendingBroadcasts; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1242f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood * List of all receivers. 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1262f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final HashMap<Object, Receiver> mReceivers = new HashMap<Object, Receiver>(); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 12915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood /** 13015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood * List of location providers. 13115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood */ 13215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final ArrayList<LocationProviderProxy> mProviders = 13315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood new ArrayList<LocationProviderProxy>(); 13415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final HashMap<String, LocationProviderProxy> mProvidersByName 13515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood = new HashMap<String, LocationProviderProxy>(); 13615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1382f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood * Object used internally for synchronization 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1402f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final Object mLock = new Object(); 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Mapping from provider name to all its UpdateRecords 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HashMap<String,ArrayList<UpdateRecord>> mRecordsByProvider = 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashMap<String,ArrayList<UpdateRecord>>(); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Proximity listeners 14948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private Receiver mProximityReceiver = null; 15048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private ILocationListener mProximityListener = null; 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashMap<PendingIntent,ProximityAlert> mProximityAlerts = 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashMap<PendingIntent,ProximityAlert>(); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashSet<ProximityAlert> mProximitiesEntered = 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashSet<ProximityAlert>(); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Last known location for each provider 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashMap<String,Location> mLastKnownLocation = 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashMap<String,Location>(); 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1604df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project private int mNetworkState = LocationProvider.TEMPORARILY_UNAVAILABLE; 1614df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 1629637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood // for Settings change notification 1639637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood private ContentQueryMap mSettings; 1649637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A wrapper class holding either an ILocationListener or a PendingIntent to receive 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * location updates. 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 16948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private final class Receiver implements IBinder.DeathRecipient, PendingIntent.OnFinished { 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ILocationListener mListener; 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PendingIntent mPendingIntent; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Object mKey; 1732f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>(); 17448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood int mPendingBroadcasts; 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1762f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver(ILocationListener listener) { 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingIntent = null; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mKey = listener.asBinder(); 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1822f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver(PendingIntent intent) { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingIntent = intent; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = null; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mKey = intent; 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean equals(Object otherObj) { 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (otherObj instanceof Receiver) { 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mKey.equals( 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((Receiver)otherObj).mKey); 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int hashCode() { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mKey.hashCode(); 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2013681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "Receiver{" 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(System.identityHashCode(this)) 2072f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood + " Listener " + mKey + "}"; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "Receiver{" 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(System.identityHashCode(this)) 2112f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood + " Intent " + mKey + "}"; 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isListener() { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mListener != null; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isPendingIntent() { 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPendingIntent != null; 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ILocationListener getListener() { 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mListener; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("Request for non-existent listener"); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PendingIntent getPendingIntent() { 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPendingIntent != null) { 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPendingIntent; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("Request for non-existent intent"); 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean callStatusChangedLocked(String provider, int status, Bundle extras) { 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 24048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 24148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 24248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 24348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onStatusChanged(provider, status, extras); 24448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mListener != mProximityListener) { 24548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 24648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 24748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 24848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 24948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent statusChanged = new Intent(); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project statusChanged.putExtras(extras); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project statusChanged.putExtra(LocationManager.KEY_STATUS_CHANGED, status); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 25848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 25948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 26048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 26148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mPendingIntent.send(mContext, 0, statusChanged, this, mLocationHandler); 26248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 26348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 26448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 26548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean callLocationChangedLocked(Location location) { 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 27648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 27748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 27848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 27948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onLocationChanged(location); 28048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mListener != mProximityListener) { 28148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 28248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 28348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 28448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 28548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent locationChanged = new Intent(); 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED, location); 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 29348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 29448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 29548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 29648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mPendingIntent.send(mContext, 0, locationChanged, this, mLocationHandler); 29748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 29848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 29948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 30048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 30148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } catch (PendingIntent.CanceledException e) { 30248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return false; 30348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 30448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 30548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return true; 30648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 30748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 30848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public boolean callProviderEnabledLocked(String provider, boolean enabled) { 30948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mListener != null) { 31048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood try { 31148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 31248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 31348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 31448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (enabled) { 31548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onProviderEnabled(provider); 31648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } else { 31748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onProviderDisabled(provider); 31848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 31948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mListener != mProximityListener) { 32048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 32148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 32248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 32348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 32448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 32548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } catch (RemoteException e) { 32648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return false; 32748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 32848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } else { 32948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood Intent providerIntent = new Intent(); 33048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood providerIntent.putExtra(LocationManager.KEY_PROVIDER_ENABLED, enabled); 33148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood try { 33248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 33348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 33448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 33548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mPendingIntent.send(mContext, 0, providerIntent, this, mLocationHandler); 33648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 33748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 33848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 33948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 348105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 349105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "Location listener died"); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3512f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeUpdatesLocked(this); 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 35548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mPendingBroadcasts > 0) { 35648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood LocationManagerService.this.decrementPendingBroadcasts(); 35748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mPendingBroadcasts = 0; 35848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 35948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 36048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 36148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 36248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public void onSendFinished(PendingIntent pendingIntent, Intent intent, 36348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood int resultCode, String resultData, Bundle resultExtras) { 3640528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (this) { 3650528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood decrementPendingBroadcastsLocked(); 3660528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 36748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 36848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 3690528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // this must be called while synchronized by caller in a synchronized block 37048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // containing the sending of the broadcaset 37148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private void incrementPendingBroadcastsLocked() { 37248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mPendingBroadcasts++ == 0) { 3730528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood LocationManagerService.this.incrementPendingBroadcasts(); 37448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 37548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 37648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 3770528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private void decrementPendingBroadcastsLocked() { 3780528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (--mPendingBroadcasts == 0) { 3790528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood LocationManagerService.this.decrementPendingBroadcasts(); 38048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 38148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 38248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 38348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 38448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public void locationCallbackFinished(ILocationListener listener) { 385080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //Do not use getReceiver here as that will add the ILocationListener to 386080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //the receiver list if it is not found. If it is not found then the 387080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //LocationListener was removed when it had a pending broadcast and should 388080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //not be added back. 389080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel IBinder binder = listener.asBinder(); 390080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel Receiver receiver = mReceivers.get(binder); 39148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (receiver != null) { 3920528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (receiver) { 3930528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // so wakelock calls will succeed 3940528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood long identity = Binder.clearCallingIdentity(); 3950528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood receiver.decrementPendingBroadcastsLocked(); 3960528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood Binder.restoreCallingIdentity(identity); 3970528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4019637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood private final class SettingsObserver implements Observer { 4029637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood public void update(Observable o, Object arg) { 4032f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 4049637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood updateProvidersLocked(); 4059637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood } 4069637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood } 4079637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood } 4089637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood 40915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private void addProvider(LocationProviderProxy provider) { 41015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProviders.add(provider); 41115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProvidersByName.put(provider.getName(), provider); 41215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 41315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 41415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private void removeProvider(LocationProviderProxy provider) { 41515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProviders.remove(provider); 416fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu provider.unlinkProvider(); 41715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProvidersByName.remove(provider.getName()); 41815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 41915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void loadProviders() { 4212f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sProvidersLoaded) { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Load providers 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loadProvidersLocked(); 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sProvidersLoaded = true; 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void loadProvidersLocked() { 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project _loadProvidersLocked(); 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Exception loading providers:", e); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void _loadProvidersLocked() { 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Attempt to load "real" providers first 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (GpsLocationProvider.isSupported()) { 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Create a gps location provider 44415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood GpsLocationProvider provider = new GpsLocationProvider(mContext, this); 44515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mGpsStatusProvider = provider.getGpsStatusProvider(); 44622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie mNetInitiatedListener = provider.getNetInitiatedListener(); 4478dfe5d8c6ba9cb165994f09843abaa6302d63c1dMike Lockwood LocationProviderProxy proxy = new LocationProviderProxy(LocationManager.GPS_PROVIDER, provider); 4488dfe5d8c6ba9cb165994f09843abaa6302d63c1dMike Lockwood addProvider(proxy); 4497566c1debebe072af76411e11d96810fd1409482Mike Lockwood mGpsLocationProvider = proxy; 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the context that the LocationManagerService runs in 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LocationManagerService(Context context) { 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 4613d12b51ee38537f6760a833618948f936e75561dMike Lockwood 4623d12b51ee38537f6760a833618948f936e75561dMike Lockwood Thread thread = new Thread(null, this, "LocationManagerService"); 4633d12b51ee38537f6760a833618948f936e75561dMike Lockwood thread.start(); 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 465105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 466105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "Constructed LocationManager Service"); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4683d12b51ee38537f6760a833618948f936e75561dMike Lockwood } 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4703d12b51ee38537f6760a833618948f936e75561dMike Lockwood private void initialize() { 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Create a wake lock, needs to be done before calling loadProviders() below 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); 4740528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Load providers 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loadProviders(); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Register for Network (Wifi or Mobile) updates 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntentFilter intentFilter = new IntentFilter(); 4800528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 4810528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Register for Package Manager updates 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED); 4840528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mContext.registerReceiver(mBroadcastReceiver, intentFilter); 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4869637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood // listen for settings changes 4879637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood ContentResolver resolver = mContext.getContentResolver(); 4889637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood Cursor settingsCursor = resolver.query(Settings.Secure.CONTENT_URI, null, 4899637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood "(" + Settings.System.NAME + "=?)", 4909637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood new String[]{Settings.Secure.LOCATION_PROVIDERS_ALLOWED}, 4919637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood null); 4929637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mLocationHandler); 4939637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood SettingsObserver settingsObserver = new SettingsObserver(); 4949637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood mSettings.addObserver(settingsObserver); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4973d12b51ee38537f6760a833618948f936e75561dMike Lockwood public void run() 4983d12b51ee38537f6760a833618948f936e75561dMike Lockwood { 4993d12b51ee38537f6760a833618948f936e75561dMike Lockwood Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 5003d12b51ee38537f6760a833618948f936e75561dMike Lockwood Looper.prepare(); 5013d12b51ee38537f6760a833618948f936e75561dMike Lockwood mLocationHandler = new LocationWorkerHandler(); 5023d12b51ee38537f6760a833618948f936e75561dMike Lockwood initialize(); 5033d12b51ee38537f6760a833618948f936e75561dMike Lockwood Looper.loop(); 5043d12b51ee38537f6760a833618948f936e75561dMike Lockwood } 5053d12b51ee38537f6760a833618948f936e75561dMike Lockwood 506275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood public void installLocationProvider(String name, ILocationProvider provider) { 507275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER) 508275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood != PackageManager.PERMISSION_GRANTED) { 509275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood throw new SecurityException("Requires INSTALL_LOCATION_PROVIDER permission"); 510e932f7f2a47b770c636443d411436bd29cc4bb43Mike Lockwood } 511e932f7f2a47b770c636443d411436bd29cc4bb43Mike Lockwood 5122f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 5133681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood // check to see if we are reinstalling a dead provider 5143681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood LocationProviderProxy oldProvider = mProvidersByName.get(name); 5153681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood if (oldProvider != null) { 5163681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood if (oldProvider.isDead()) { 5173681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood Log.d(TAG, "replacing dead provider"); 5183681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood removeProvider(oldProvider); 5193681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood } else { 5203681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood throw new IllegalArgumentException("Provider \"" + name + "\" already exists"); 5213681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood } 5223681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood } 5233681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood 5248dfe5d8c6ba9cb165994f09843abaa6302d63c1dMike Lockwood LocationProviderProxy proxy = new LocationProviderProxy(name, provider); 5258dfe5d8c6ba9cb165994f09843abaa6302d63c1dMike Lockwood addProvider(proxy); 5268dfe5d8c6ba9cb165994f09843abaa6302d63c1dMike Lockwood updateProvidersLocked(); 5277566c1debebe072af76411e11d96810fd1409482Mike Lockwood if (LocationManager.NETWORK_PROVIDER.equals(name)) { 5287566c1debebe072af76411e11d96810fd1409482Mike Lockwood mNetworkLocationProvider = proxy; 5297566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 530275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood 5318dfe5d8c6ba9cb165994f09843abaa6302d63c1dMike Lockwood // notify provider of current network state 5328dfe5d8c6ba9cb165994f09843abaa6302d63c1dMike Lockwood proxy.updateNetworkState(mNetworkState); 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 536275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood public void installGeocodeProvider(IGeocodeProvider provider) { 537275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER) 538275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood != PackageManager.PERMISSION_GRANTED) { 539275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood throw new SecurityException("Requires INSTALL_LOCATION_PROVIDER permission"); 540a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood } 541a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 542a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood mGeocodeProvider = provider; 543a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood } 544a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean isAllowedBySettingsLocked(String provider) { 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabledProviders.contains(provider)) { 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDisabledProviders.contains(provider)) { 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Use system settings 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver resolver = mContext.getContentResolver(); 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String allowedProviders = Settings.Secure.getString(resolver, 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Secure.LOCATION_PROVIDERS_ALLOWED); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return ((allowedProviders != null) && (allowedProviders.contains(provider))); 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void checkPermissionsSafe(String provider) { 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LocationManager.GPS_PROVIDER.equals(provider) 562b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_FINE_LOCATION permission"); 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LocationManager.NETWORK_PROVIDER.equals(provider) 567b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) 569b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION) 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException( 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Requires ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission"); 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean isAllowedProviderSafe(String provider) { 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LocationManager.GPS_PROVIDER.equals(provider) 578b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LocationManager.NETWORK_PROVIDER.equals(provider) 583b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) 585b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION) 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<String> getAllProviders() { 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5952f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return _getAllProvidersLocked(); 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "getAllProviders got exception:", e); 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private List<String> _getAllProvidersLocked() { 607105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 608105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "getAllProviders"); 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 61015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood ArrayList<String> out = new ArrayList<String>(mProviders.size()); 61115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 61215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy p = mProviders.get(i); 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.add(p.getName()); 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return out; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<String> getProviders(boolean enabledOnly) { 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6202f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return _getProvidersLocked(enabledOnly); 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 626105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.e(TAG, "getProviders got exception:", e); 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private List<String> _getProvidersLocked(boolean enabledOnly) { 632105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 633105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "getProviders"); 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 63515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood ArrayList<String> out = new ArrayList<String>(mProviders.size()); 63615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 63715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy p = mProviders.get(i); 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = p.getName(); 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isAllowedProviderSafe(name)) { 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enabledOnly && !isAllowedBySettingsLocked(name)) { 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.add(name); 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return out; 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateProvidersLocked() { 65015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 65115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy p = mProviders.get(i); 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isEnabled = p.isEnabled(); 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = p.getName(); 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean shouldBeEnabled = isAllowedBySettingsLocked(name); 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isEnabled && !shouldBeEnabled) { 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProviderListenersLocked(name, false); 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!isEnabled && shouldBeEnabled) { 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProviderListenersLocked(name, true); 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateProviderListenersLocked(String provider, boolean enabled) { 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int listeners = 0; 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 66815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy p = mProvidersByName.get(provider); 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null) { 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Receiver> deadReceivers = null; 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records != null) { 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = records.size(); 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UpdateRecord record = records.get(i); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Sends a notification message to the receiver 68148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) { 68248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (deadReceivers == null) { 68348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood deadReceivers = new ArrayList<Receiver>(); 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6854686657cee6411eb00235d49b4a8663a96361a00Simon Schoar deadReceivers.add(record.mReceiver); 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listeners++; 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (deadReceivers != null) { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=deadReceivers.size()-1; i>=0; i--) { 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeUpdatesLocked(deadReceivers.get(i)); 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enabled) { 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.enable(); 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listeners > 0) { 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.setMinTime(getMinTimeLocked(provider)); 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.enableLocationTracking(true); 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.enableLocationTracking(false); 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.disable(); 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long getMinTimeLocked(String provider) { 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long minTime = Long.MAX_VALUE; 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records != null) { 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=records.size()-1; i>=0; i--) { 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project minTime = Math.min(minTime, records.get(i).mMinTime); 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return minTime; 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class UpdateRecord { 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String mProvider; 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Receiver mReceiver; 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long mMinTime; 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float mMinDistance; 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int mUid; 7262f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Location mLastFixBroadcast; 7272f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood long mLastStatusBroadcast; 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Note: must be constructed with lock held. 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UpdateRecord(String provider, long minTime, float minDistance, 7332f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver receiver, int uid) { 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProvider = provider; 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReceiver = receiver; 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMinTime = minTime; 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMinDistance = minDistance; 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUid = uid; 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records == null) { 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project records = new ArrayList<UpdateRecord>(); 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecordsByProvider.put(provider, records); 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!records.contains(this)) { 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project records.add(this); 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Method to be called when a record will no longer be used. Calling this multiple times 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * must have the same effect as calling it once. 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void disposeLocked() { 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(this.mProvider); 7563a76fd627945c1df59aa0318867401e0e53da022Mike Lockwood if (records != null) { 7573a76fd627945c1df59aa0318867401e0e53da022Mike Lockwood records.remove(this); 7583a76fd627945c1df59aa0318867401e0e53da022Mike Lockwood } 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "UpdateRecord{" 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(System.identityHashCode(this)) 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " " + mProvider + " " + mReceiver + "}"; 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void dump(PrintWriter pw, String prefix) { 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + this); 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mProvider=" + mProvider + " mReceiver=" + mReceiver); 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mMinTime=" + mMinTime + " mMinDistance=" + mMinDistance); 7722f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood pw.println(prefix + "mUid=" + mUid); 7732f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood pw.println(prefix + "mLastFixBroadcast:"); 7742f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mLastFixBroadcast.dump(new PrintWriterPrinter(pw), prefix + " "); 7752f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood pw.println(prefix + "mLastStatusBroadcast=" + mLastStatusBroadcast); 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7792f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private Receiver getReceiver(ILocationListener listener) { 7802f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood IBinder binder = listener.asBinder(); 7812f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver receiver = mReceivers.get(binder); 7822f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (receiver == null) { 7832f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood receiver = new Receiver(listener); 7842f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mReceivers.put(binder, receiver); 7852f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 7862f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood try { 7872f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (receiver.isListener()) { 7882f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood receiver.getListener().asBinder().linkToDeath(receiver, 0); 7892f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 7902f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } catch (RemoteException e) { 7912f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Log.e(TAG, "linkToDeath failed:", e); 7922f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return null; 7932f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 7942f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 7952f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return receiver; 7962f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 7972f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 7982f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private Receiver getReceiver(PendingIntent intent) { 7992f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver receiver = mReceivers.get(intent); 8002f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (receiver == null) { 8012f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood receiver = new Receiver(intent); 8022f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mReceivers.put(intent, receiver); 8032f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8042f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return receiver; 8052f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8062f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8072f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private boolean providerHasListener(String provider, int uid, Receiver excludedReceiver) { 8082f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 8092f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (records != null) { 8102f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood for (int i = records.size() - 1; i >= 0; i--) { 8112f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood UpdateRecord record = records.get(i); 8122f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (record.mUid == uid && record.mReceiver != excludedReceiver) { 8132f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return true; 8142f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8152f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8162f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 81795427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood for (ProximityAlert alert : mProximityAlerts.values()) { 81895427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood if (alert.mUid == uid) { 81995427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood return true; 8202f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8212f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8222f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return false; 8232f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8242f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void requestLocationUpdates(String provider, 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long minTime, float minDistance, ILocationListener listener) { 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8292f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 8302f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood requestLocationUpdatesLocked(provider, minTime, minDistance, getReceiver(listener)); 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "requestUpdates got exception:", e); 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void requestLocationUpdatesPI(String provider, 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long minTime, float minDistance, PendingIntent intent) { 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8422f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 8432f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood requestLocationUpdatesLocked(provider, minTime, minDistance, getReceiver(intent)); 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.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) { 855105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "_requestLocationUpdates: listener = " + receiver); 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 85815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy proxy = mProvidersByName.get(provider); 85915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (proxy == 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) { 87715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood proxy.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); 88315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood proxy.setMinTime(minTimeForProvider); 88415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood proxy.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; 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "removeUpdates got exception:", e); 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeUpdatesPI(PendingIntent intent) { 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9082f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 9092f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood removeUpdatesLocked(getReceiver(intent)); 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "removeUpdates got exception:", e); 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeUpdatesLocked(Receiver receiver) { 919105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 920105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "_removeUpdates: listener = " + receiver); 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // so wakelock calls will succeed 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int callingUid = Binder.getCallingUid(); 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identity = Binder.clearCallingIdentity(); 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9272f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) { 9282f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood receiver.getListener().asBinder().unlinkToDeath(receiver, 0); 929080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel synchronized(receiver) { 930080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel if(receiver.mPendingBroadcasts > 0) { 931080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel decrementPendingBroadcasts(); 932080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel receiver.mPendingBroadcasts = 0; 933080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel } 934080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel } 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Record which providers were associated with this listener 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HashSet<String> providers = new HashSet<String>(); 9392f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood HashMap<String,UpdateRecord> oldRecords = receiver.mUpdateRecords; 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (oldRecords != null) { 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Call dispose() on the obsolete update records. 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (UpdateRecord record : oldRecords.values()) { 9432f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (!providerHasListener(record.mProvider, callingUid, receiver)) { 94415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy proxy = mProvidersByName.get(record.mProvider); 94515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (proxy != null) { 94615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood proxy.removeListener(callingUid); 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project record.disposeLocked(); 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Accumulate providers 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project providers.addAll(oldRecords.keySet()); 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // See if the providers associated with this listener have any 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // other listeners; if one does, inform it of the new smallest minTime 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // value; if one does not, disable location tracking for it 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String provider : providers) { 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If provider is already disabled, don't need to do anything 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isAllowedBySettingsLocked(provider)) { 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hasOtherListener = false; 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> recordsForProvider = mRecordsByProvider.get(provider); 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (recordsForProvider != null && recordsForProvider.size() > 0) { 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasOtherListener = true; 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 97015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy p = mProvidersByName.get(provider); 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p != null) { 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hasOtherListener) { 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.setMinTime(getMinTimeLocked(provider)); 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.enableLocationTracking(false); 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(identity); 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean addGpsStatusListener(IGpsStatusListener listener) { 98515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mGpsStatusProvider == null) { 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 988b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood if (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) != 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageManager.PERMISSION_GRANTED) { 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_FINE_LOCATION permission"); 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 99415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mGpsStatusProvider.addGpsStatusListener(listener); 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 99615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Log.e(TAG, "mGpsStatusProvider.addGpsStatusListener failed", e); 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeGpsStatusListener(IGpsStatusListener listener) { 10032f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 100415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood try { 100515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mGpsStatusProvider.removeGpsStatusListener(listener); 100615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } catch (Exception e) { 100715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Log.e(TAG, "mGpsStatusProvider.removeGpsStatusListener failed", e); 100815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String provider, String command, Bundle extras) { 1013c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood if (provider == null) { 1014c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood // throw NullPointerException to remain compatible with previous implementation 1015c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood throw new NullPointerException(); 1016c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood } 1017c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // first check for permission to the provider 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkPermissionsSafe(provider); 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and check for ACCESS_LOCATION_EXTRA_COMMANDS 1021b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood if ((mContext.checkCallingOrSelfPermission(ACCESS_LOCATION_EXTRA_COMMANDS) 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_LOCATION_EXTRA_COMMANDS permission"); 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10262f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 102715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy proxy = mProvidersByName.get(provider); 10286ba7ae1e4c3c04f6a71380b913ad79f83b00a628Mike Lockwood if (proxy == null) { 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 103215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return proxy.sendExtraCommand(command, extras); 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 103622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public boolean sendNiResponse(int notifId, int userResponse) 103722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 103818ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood if (Binder.getCallingUid() != Process.myUid()) { 103918ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood throw new SecurityException( 104018ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood "calling sendNiResponse from outside of the system is not allowed"); 104118ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood } 104222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie try { 104322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return mNetInitiatedListener.sendNiResponse(notifId, userResponse); 104422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 104522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie catch (RemoteException e) 104622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 104722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Log.e(TAG, "RemoteException in LocationManagerService.sendNiResponse"); 104822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return false; 104922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 105022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 105122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class ProximityAlert { 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int mUid; 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final double mLatitude; 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final double mLongitude; 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float mRadius; 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long mExpiration; 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PendingIntent mIntent; 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Location mLocation; 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ProximityAlert(int uid, double latitude, double longitude, 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float radius, long expiration, PendingIntent intent) { 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUid = uid; 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLatitude = latitude; 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLongitude = longitude; 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadius = radius; 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExpiration = expiration; 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIntent = intent; 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation = new Location(""); 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLatitude(latitude); 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLongitude(longitude); 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long getExpiration() { 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mExpiration; 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent getIntent() { 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mIntent; 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10832d2078aa1d6e31063f565a20b717f3b8908fff02Yusuf T. Mobile boolean isInProximity(double latitude, double longitude, float accuracy) { 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Location loc = new Location(""); 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loc.setLatitude(latitude); 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loc.setLongitude(longitude); 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project double radius = loc.distanceTo(mLocation); 10892d2078aa1d6e31063f565a20b717f3b8908fff02Yusuf T. Mobile return radius <= Math.max(mRadius,accuracy); 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "ProximityAlert{" 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(System.identityHashCode(this)) 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " uid " + mUid + mIntent + "}"; 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void dump(PrintWriter pw, String prefix) { 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + this); 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mLatitude=" + mLatitude + " mLongitude=" + mLongitude); 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mRadius=" + mRadius + " mExpiration=" + mExpiration); 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mIntent=" + mIntent); 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mLocation:"); 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.dump(new PrintWriterPrinter(pw), prefix + " "); 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Listener for receiving locations to trigger proximity alerts 111048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood class ProximityListener extends ILocationListener.Stub implements PendingIntent.OnFinished { 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isGpsAvailable = false; 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: this is called with the lock held. 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onLocationChanged(Location loc) { 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If Gps is available, then ignore updates from NetworkLocationProvider 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (loc.getProvider().equals(LocationManager.GPS_PROVIDER)) { 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project isGpsAvailable = true; 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isGpsAvailable && loc.getProvider().equals(LocationManager.NETWORK_PROVIDER)) { 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Process proximity alerts 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now = System.currentTimeMillis(); 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project double latitude = loc.getLatitude(); 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project double longitude = loc.getLongitude(); 11292d2078aa1d6e31063f565a20b717f3b8908fff02Yusuf T. Mobile float accuracy = loc.getAccuracy(); 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<PendingIntent> intentsToRemove = null; 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ProximityAlert alert : mProximityAlerts.values()) { 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent intent = alert.getIntent(); 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long expiration = alert.getExpiration(); 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((expiration == -1) || (now <= expiration)) { 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean entered = mProximitiesEntered.contains(alert); 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean inProximity = 11392d2078aa1d6e31063f565a20b717f3b8908fff02Yusuf T. Mobile alert.isInProximity(latitude, longitude, accuracy); 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!entered && inProximity) { 1141105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 1142105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "Entered alert"); 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximitiesEntered.add(alert); 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent enteredIntent = new Intent(); 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enteredIntent.putExtra(LocationManager.KEY_PROXIMITY_ENTERING, true); 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11480528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (this) { 11490528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // synchronize to ensure incrementPendingBroadcasts() 115048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 115148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood intent.send(mContext, 0, enteredIntent, this, mLocationHandler); 115248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 115348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 11540528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood incrementPendingBroadcasts(); 115548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 1157105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 1158105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "Canceled proximity alert: " + alert, e); 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intentsToRemove == null) { 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove = new ArrayList<PendingIntent>(); 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove.add(intent); 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (entered && !inProximity) { 1166105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 1167105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "Exited alert"); 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximitiesEntered.remove(alert); 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent exitedIntent = new Intent(); 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project exitedIntent.putExtra(LocationManager.KEY_PROXIMITY_ENTERING, false); 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11730528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (this) { 11740528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // synchronize to ensure incrementPendingBroadcasts() 117548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 117648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood intent.send(mContext, 0, exitedIntent, this, mLocationHandler); 117748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 117848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 11790528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood incrementPendingBroadcasts(); 118048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 1182105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 1183105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "Canceled proximity alert: " + alert, e); 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intentsToRemove == null) { 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove = new ArrayList<PendingIntent>(); 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove.add(intent); 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Mark alert for expiration 1193105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 1194105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "Expiring proximity alert: " + alert); 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intentsToRemove == null) { 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove = new ArrayList<PendingIntent>(); 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove.add(alert.getIntent()); 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove expired alerts 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intentsToRemove != null) { 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (PendingIntent i : intentsToRemove) { 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximityAlerts.remove(i); 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ProximityAlert alert = mProximityAlerts.get(i); 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximitiesEntered.remove(alert); 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: this is called with the lock held. 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onProviderDisabled(String provider) { 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider.equals(LocationManager.GPS_PROVIDER)) { 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project isGpsAvailable = false; 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: this is called with the lock held. 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onProviderEnabled(String provider) { 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // ignore 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: this is called with the lock held. 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onStatusChanged(String provider, int status, Bundle extras) { 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((provider.equals(LocationManager.GPS_PROVIDER)) && 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (status != LocationProvider.AVAILABLE)) { 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project isGpsAvailable = false; 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 123348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 123448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public void onSendFinished(PendingIntent pendingIntent, Intent intent, 123548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood int resultCode, String resultData, Bundle resultExtras) { 12360528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // synchronize to ensure incrementPendingBroadcasts() 12370528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // is called before decrementPendingBroadcasts() 12380528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (this) { 12390528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood decrementPendingBroadcasts(); 12400528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 124148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addProximityAlert(double latitude, double longitude, 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float radius, long expiration, PendingIntent intent) { 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 12472f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project addProximityAlertLocked(latitude, longitude, radius, expiration, intent); 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "addProximityAlert got exception:", e); 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void addProximityAlertLocked(double latitude, double longitude, 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float radius, long expiration, PendingIntent intent) { 1259105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 1260105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "addProximityAlert: latitude = " + latitude + 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ", longitude = " + longitude + 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ", expiration = " + expiration + 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ", intent = " + intent); 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Require ability to access all providers for now 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isAllowedProviderSafe(LocationManager.GPS_PROVIDER) || 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project !isAllowedProviderSafe(LocationManager.NETWORK_PROVIDER)) { 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_FINE_LOCATION permission"); 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (expiration != -1) { 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project expiration += System.currentTimeMillis(); 12749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ProximityAlert alert = new ProximityAlert(Binder.getCallingUid(), 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project latitude, longitude, radius, expiration, intent); 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximityAlerts.put(intent, alert); 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 127948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mProximityReceiver == null) { 128048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mProximityListener = new ProximityListener(); 128148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mProximityReceiver = new Receiver(mProximityListener); 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 128395427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 128495427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood LocationProviderProxy provider = mProviders.get(i); 128548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood requestLocationUpdatesLocked(provider.getName(), 1000L, 1.0f, mProximityReceiver); 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeProximityAlert(PendingIntent intent) { 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 12922f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeProximityAlertLocked(intent); 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "removeProximityAlert got exception:", e); 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeProximityAlertLocked(PendingIntent intent) { 1303105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 1304105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "removeProximityAlert: intent = " + intent); 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximityAlerts.remove(intent); 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProximityAlerts.size() == 0) { 130948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood removeUpdatesLocked(mProximityReceiver); 131048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mProximityReceiver = null; 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximityListener = null; 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return null if the provider does not exits 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @throw SecurityException if the provider is not allowed to be 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * accessed by the caller 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Bundle getProviderInfo(String provider) { 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 13222f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return _getProviderInfoLocked(provider); 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "_getProviderInfo got exception:", e); 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Bundle _getProviderInfoLocked(String provider) { 133415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy p = mProvidersByName.get(provider); 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null) { 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkPermissionsSafe(provider); 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Bundle b = new Bundle(); 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putBoolean("network", p.requiresNetwork()); 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putBoolean("satellite", p.requiresSatellite()); 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putBoolean("cell", p.requiresCell()); 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putBoolean("cost", p.hasMonetaryCost()); 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putBoolean("altitude", p.supportsAltitude()); 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putBoolean("speed", p.supportsSpeed()); 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putBoolean("bearing", p.supportsBearing()); 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putInt("power", p.getPowerRequirement()); 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project b.putInt("accuracy", p.getAccuracy()); 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return b; 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isProviderEnabled(String provider) { 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 13572f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return _isProviderEnabledLocked(provider); 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "isProviderEnabled got exception:", e); 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 13659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1368275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood public void reportLocation(Location location) { 1369275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER) 1370275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood != PackageManager.PERMISSION_GRANTED) { 1371275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood throw new SecurityException("Requires INSTALL_LOCATION_PROVIDER permission"); 1372275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood } 1373275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood 13744e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood mLocationHandler.removeMessages(MESSAGE_LOCATION_CHANGED, location); 13754e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood Message m = Message.obtain(mLocationHandler, MESSAGE_LOCATION_CHANGED, location); 13764e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood mLocationHandler.sendMessageAtFrontOfQueue(m); 13774e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood } 13784e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean _isProviderEnabledLocked(String provider) { 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkPermissionsSafe(provider); 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 138215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy p = mProvidersByName.get(provider); 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null) { 13849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("provider=" + provider); 13859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return isAllowedBySettingsLocked(provider); 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public Location getLastKnownLocation(String provider) { 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 13912f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 13929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return _getLastKnownLocationLocked(provider); 13939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 13959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 13969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 13979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "getLastKnownLocation got exception:", e); 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 13999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Location _getLastKnownLocationLocked(String provider) { 14039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkPermissionsSafe(provider); 14049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 140515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy p = mProvidersByName.get(provider); 14069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null) { 14079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("provider=" + provider); 14089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isAllowedBySettingsLocked(provider)) { 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 14129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14149aa1fa2d3612d1d8ffeae6552d65669f4ca194d9Mike Lockwood return mLastKnownLocation.get(provider); 14159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean shouldBroadcastSafe(Location loc, Location lastLoc, UpdateRecord record) { 14189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Always broadcast the first update 14199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (lastLoc == null) { 14209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 14219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Don't broadcast same location again regardless of condition 14249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO - we should probably still rebroadcast if user explicitly sets a minTime > 0 14259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (loc.getTime() == lastLoc.getTime()) { 14269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Check whether sufficient distance has been traveled 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project double minDistance = record.mMinDistance; 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (minDistance > 0.0) { 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (loc.distanceTo(lastLoc) <= minDistance) { 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14404e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood private void handleLocationChangedLocked(Location location) { 14414e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood String provider = location.getProvider(); 14429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 14439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records == null || records.size() == 0) { 14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 144715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy p = mProvidersByName.get(provider); 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null) { 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14524e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood // Update last known location for provider 14534e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood Location lastLocation = mLastKnownLocation.get(provider); 14544e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood if (lastLocation == null) { 14554e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood mLastKnownLocation.put(provider, new Location(location)); 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 14574e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood lastLocation.set(location); 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Fetch latest status update time 14619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long newStatusUpdateTime = p.getStatusUpdateTime(); 14629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14637ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood // Get latest status 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Bundle extras = new Bundle(); 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int status = p.getStatus(extras); 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Receiver> deadReceivers = null; 14689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Broadcast location or status to all listeners 14709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = records.size(); 14719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 14729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UpdateRecord r = records.get(i); 14739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Receiver receiver = r.mReceiver; 14749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14752f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Location lastLoc = r.mLastFixBroadcast; 14764e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood if ((lastLoc == null) || shouldBroadcastSafe(location, lastLoc, r)) { 14774e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood if (lastLoc == null) { 14784e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood lastLoc = new Location(location); 14792f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood r.mLastFixBroadcast = lastLoc; 14804e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood } else { 14814e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood lastLoc.set(location); 14829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14834e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood if (!receiver.callLocationChangedLocked(location)) { 14844e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood Log.w(TAG, "RemoteException calling onLocationChanged on " + receiver); 14854e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood if (deadReceivers == null) { 14864e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood deadReceivers = new ArrayList<Receiver>(); 14879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14884e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood deadReceivers.add(receiver); 14899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14922f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood long prevStatusUpdateTime = r.mLastStatusBroadcast; 14939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((newStatusUpdateTime > prevStatusUpdateTime) && 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (prevStatusUpdateTime != 0 || status != LocationProvider.AVAILABLE)) { 14959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14962f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood r.mLastStatusBroadcast = newStatusUpdateTime; 14979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!receiver.callStatusChangedLocked(provider, status, extras)) { 14989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException calling onStatusChanged on " + receiver); 14999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (deadReceivers == null) { 15009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deadReceivers = new ArrayList<Receiver>(); 15019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!deadReceivers.contains(receiver)) { 15039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project deadReceivers.add(receiver); 15049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (deadReceivers != null) { 15109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=deadReceivers.size()-1; i>=0; i--) { 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeUpdatesLocked(deadReceivers.get(i)); 15129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class LocationWorkerHandler extends Handler { 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 15199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void handleMessage(Message msg) { 15209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 15214e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood if (msg.what == MESSAGE_LOCATION_CHANGED) { 15224e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood // log("LocationWorkerHandler: MESSAGE_LOCATION_CHANGED!"); 15239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15242f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 15254e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood Location location = (Location) msg.obj; 1526fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood String provider = location.getProvider(); 152798cb66797422c4ccdee6f1a07636146d784a471bMike Lockwood 1528fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood // notify other providers of the new location 1529fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 1530fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood LocationProviderProxy proxy = mProviders.get(i); 1531fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood if (!provider.equals(proxy.getName())) { 1532fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood proxy.updateLocation(location); 153398cb66797422c4ccdee6f1a07636146d784a471bMike Lockwood } 153498cb66797422c4ccdee6f1a07636146d784a471bMike Lockwood } 153598cb66797422c4ccdee6f1a07636146d784a471bMike Lockwood 1536fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood if (isAllowedBySettingsLocked(provider)) { 1537fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood handleLocationChangedLocked(location); 15389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 15429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Log, don't crash! 15439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Exception in LocationWorkerHandler.handleMessage:", e); 15449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15480528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { 15490528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood @Override 15500528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood public void onReceive(Context context, Intent intent) { 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String action = intent.getAction(); 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15530528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (action.equals(Intent.ACTION_PACKAGE_REMOVED) 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || action.equals(Intent.ACTION_PACKAGE_RESTARTED)) { 15552f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (uid >= 0) { 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Receiver> removedRecs = null; 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ArrayList<UpdateRecord> i : mRecordsByProvider.values()) { 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int j=i.size()-1; j>=0; j--) { 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UpdateRecord ur = i.get(j); 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ur.mReceiver.isPendingIntent() && ur.mUid == uid) { 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (removedRecs == null) { 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removedRecs = new ArrayList<Receiver>(); 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!removedRecs.contains(ur.mReceiver)) { 15679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removedRecs.add(ur.mReceiver); 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<ProximityAlert> removedAlerts = null; 15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ProximityAlert i : mProximityAlerts.values()) { 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (i.mUid == uid) { 15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (removedAlerts == null) { 15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removedAlerts = new ArrayList<ProximityAlert>(); 15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!removedAlerts.contains(i)) { 15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removedAlerts.add(i); 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (removedRecs != null) { 15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=removedRecs.size()-1; i>=0; i--) { 15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeUpdatesLocked(removedRecs.get(i)); 15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (removedAlerts != null) { 15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=removedAlerts.size()-1; i>=0; i--) { 15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeProximityAlertLocked(removedAlerts.get(i).mIntent); 15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15950528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean noConnectivity = 15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); 15989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!noConnectivity) { 15994df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mNetworkState = LocationProvider.AVAILABLE; 16004df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } else { 16014df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mNetworkState = LocationProvider.TEMPORARILY_UNAVAILABLE; 16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Notify location providers of current network state 16052f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 160615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 160715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy provider = mProviders.get(i); 16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider.requiresNetwork()) { 16094df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project provider.updateNetworkState(mNetworkState); 16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16150528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood }; 16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Wake locks 16189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16190528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private void incrementPendingBroadcasts() { 16200528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (mWakeLock) { 16210528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (mPendingBroadcasts++ == 0) { 16220528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood try { 16230528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.acquire(); 16240528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood log("Acquired wakelock"); 16250528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } catch (Exception e) { 16260528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // This is to catch a runtime exception thrown when we try to release an 16270528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // already released lock. 16280528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood Log.e(TAG, "exception in acquireWakeLock()", e); 16290528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 16300528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 163148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 163248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 163348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 163448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private void decrementPendingBroadcasts() { 16350528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (mWakeLock) { 163648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (--mPendingBroadcasts == 0) { 16370528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood try { 16380528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Release wake lock 16390528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (mWakeLock.isHeld()) { 16400528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.release(); 16410528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood log("Released wakelock"); 16420528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } else { 16430528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood log("Can't release wakelock again!"); 16440528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 16450528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } catch (Exception e) { 16460528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // This is to catch a runtime exception thrown when we try to release an 16470528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // already released lock. 16480528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood Log.e(TAG, "exception in releaseWakeLock()", e); 16490528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 165048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 165148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 165248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 165348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Geocoder 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getFromLocation(double latitude, double longitude, int maxResults, 1657a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood String language, String country, String variant, String appName, List<Address> addrs) { 1658a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood if (mGeocodeProvider != null) { 1659a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood try { 1660a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood return mGeocodeProvider.getFromLocation(latitude, longitude, maxResults, language, country, 1661a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood variant, appName, addrs); 1662a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood } catch (RemoteException e) { 1663a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood Log.e(TAG, "getFromLocation failed", e); 16643681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood mGeocodeProvider = null; 16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1667a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood return null; 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1670a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 16719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getFromLocationName(String locationName, 1672a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood double lowerLeftLatitude, double lowerLeftLongitude, 1673a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood double upperRightLatitude, double upperRightLongitude, int maxResults, 1674a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood String language, String country, String variant, String appName, List<Address> addrs) { 1675a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 1676a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood if (mGeocodeProvider != null) { 1677a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood try { 1678a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood return mGeocodeProvider.getFromLocationName(locationName, lowerLeftLatitude, 1679a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood lowerLeftLongitude, upperRightLatitude, upperRightLongitude, 1680a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood maxResults, language, country, variant, appName, addrs); 1681a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood } catch (RemoteException e) { 1682a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood Log.e(TAG, "getFromLocationName failed", e); 16833681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood mGeocodeProvider = null; 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1686a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood return null; 16879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Mock Providers 16909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void checkMockPermissionsSafe() { 16929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean allowMocks = Settings.Secure.getInt(mContext.getContentResolver(), 16939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 1; 16949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allowMocks) { 16959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_MOCK_LOCATION secure setting"); 16969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) != 16999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageManager.PERMISSION_GRANTED) { 17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission"); 17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite, 17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude, 17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) { 17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17092f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 17104e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood MockProvider provider = new MockProvider(name, this, 17114e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood requiresNetwork, requiresSatellite, 17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requiresCell, hasMonetaryCost, supportsAltitude, 17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project supportsSpeed, supportsBearing, powerRequirement, accuracy); 17147566c1debebe072af76411e11d96810fd1409482Mike Lockwood // remove the real provider if we are replacing GPS or network provider 17157566c1debebe072af76411e11d96810fd1409482Mike Lockwood if (LocationManager.GPS_PROVIDER.equals(name) 17167566c1debebe072af76411e11d96810fd1409482Mike Lockwood || LocationManager.NETWORK_PROVIDER.equals(name)) { 17177566c1debebe072af76411e11d96810fd1409482Mike Lockwood LocationProviderProxy proxy = mProvidersByName.get(name); 17187566c1debebe072af76411e11d96810fd1409482Mike Lockwood if (proxy != null) { 17197566c1debebe072af76411e11d96810fd1409482Mike Lockwood proxy.enableLocationTracking(false); 17207566c1debebe072af76411e11d96810fd1409482Mike Lockwood removeProvider(proxy); 17217566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 17227566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 172315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mProvidersByName.get(name) != null) { 17249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + name + "\" already exists"); 17259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 172615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood addProvider(new LocationProviderProxy(name, provider)); 17277ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mMockProviders.put(name, provider); 17287566c1debebe072af76411e11d96810fd1409482Mike Lockwood mLastKnownLocation.put(name, null); 17299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 17309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeTestProvider(String provider) { 17349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 17352f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 17367ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 17377ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 174015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood removeProvider(mProvidersByName.get(provider)); 17417ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mMockProviders.remove(mockProvider); 17427566c1debebe072af76411e11d96810fd1409482Mike Lockwood // reinstall real provider if we were mocking GPS or network provider 17437566c1debebe072af76411e11d96810fd1409482Mike Lockwood if (LocationManager.GPS_PROVIDER.equals(provider) && 17447566c1debebe072af76411e11d96810fd1409482Mike Lockwood mGpsLocationProvider != null) { 17457566c1debebe072af76411e11d96810fd1409482Mike Lockwood addProvider(mGpsLocationProvider); 17467566c1debebe072af76411e11d96810fd1409482Mike Lockwood } else if (LocationManager.NETWORK_PROVIDER.equals(provider) && 17477566c1debebe072af76411e11d96810fd1409482Mike Lockwood mNetworkLocationProvider != null) { 17487566c1debebe072af76411e11d96810fd1409482Mike Lockwood addProvider(mNetworkLocationProvider); 17497566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 17507566c1debebe072af76411e11d96810fd1409482Mike Lockwood mLastKnownLocation.put(provider, null); 17519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 17529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderLocation(String provider, Location loc) { 17569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 17572f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 17587ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 17597ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 17609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 17619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 176295427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood // clear calling identity so INSTALL_LOCATION_PROVIDER permission is not required 176395427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood long identity = Binder.clearCallingIdentity(); 17647ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.setLocation(loc); 176595427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood Binder.restoreCallingIdentity(identity); 17669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderLocation(String provider) { 17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 17712f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 17727ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 17737ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 17749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 17759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17767ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.clearLocation(); 17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderEnabled(String provider, boolean enabled) { 17819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 17822f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 17837ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 17847ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enabled) { 17887ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.enable(); 17899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.add(provider); 17909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.remove(provider); 17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 17927ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.disable(); 17939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.remove(provider); 17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.add(provider); 17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderEnabled(String provider) { 18019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18022f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18037ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18047ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.remove(provider); 18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.remove(provider); 18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 18109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) { 18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18152f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18167ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18177ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18207ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.setStatus(status, extras, updateTime); 18219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderStatus(String provider) { 18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18262f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18277ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18287ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18317ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.clearStatus(); 18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void log(String log) { 18369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 18379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, log); 18389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 18440528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood pw.println("Permission Denial: can't dump LocationManagerService from from pid=" 18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Binder.getCallingPid() 18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 18479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 18489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18502f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Current Location Manager state:"); 18529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" sProvidersLoaded=" + sProvidersLoaded); 18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Listeners:"); 18542f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood int N = mReceivers.size(); 18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 18562f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood pw.println(" " + mReceivers.get(i)); 18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Location Listeners:"); 18592f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood for (Receiver i : mReceivers.values()) { 18602f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood pw.println(" " + i + ":"); 18612f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood for (Map.Entry<String,UpdateRecord> j : i.mUpdateRecords.entrySet()) { 18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + j.getKey() + ":"); 18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project j.getValue().dump(pw, " "); 18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Records by Provider:"); 18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, ArrayList<UpdateRecord>> i 18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mRecordsByProvider.entrySet()) { 18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i.getKey() + ":"); 18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (UpdateRecord j : i.getValue()) { 18719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + j + ":"); 18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project j.dump(pw, " "); 18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Last Known Locations:"); 18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, Location> i 18779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mLastKnownLocation.entrySet()) { 18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i.getKey() + ":"); 18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i.getValue().dump(new PrintWriterPrinter(pw), " "); 18809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProximityAlerts.size() > 0) { 18829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Proximity Alerts:"); 18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<PendingIntent, ProximityAlert> i 18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mProximityAlerts.entrySet()) { 18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i.getKey() + ":"); 18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i.getValue().dump(pw, " "); 18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProximitiesEntered.size() > 0) { 18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Proximities Entered:"); 18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ProximityAlert i : mProximitiesEntered) { 18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i + ":"); 18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i.dump(pw, " "); 18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 189648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood pw.println(" mProximityReceiver=" + mProximityReceiver); 18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" mProximityListener=" + mProximityListener); 18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabledProviders.size() > 0) { 18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Enabled Providers:"); 19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String i : mEnabledProviders) { 19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i); 19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDisabledProviders.size() > 0) { 19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Disabled Providers:"); 19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String i : mDisabledProviders) { 19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i); 19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMockProviders.size() > 0) { 19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Mock Providers:"); 19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, MockProvider> i : mMockProviders.entrySet()) { 19157ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood i.getValue().dump(pw, " "); 19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1921