LocationManagerService.java revision 08675a3376819a82aa5ab344bc3e7b1635c30b05
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; 4034901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwoodimport android.location.GeocoderParams; 41a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwoodimport android.location.IGeocodeProvider; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.IGpsStatusListener; 4315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwoodimport android.location.IGpsStatusProvider; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.ILocationListener; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.ILocationManager; 46e932f7f2a47b770c636443d411436bd29cc4bb43Mike Lockwoodimport android.location.ILocationProvider; 4722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.location.INetInitiatedListener; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Location; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationManager; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationProvider; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.ConnectivityManager; 5203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwoodimport android.net.NetworkInfo; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.Uri; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Binder; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Handler; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 583d12b51ee38537f6760a833618948f936e75561dMike Lockwoodimport android.os.Looper; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Message; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.PowerManager; 61e932f7f2a47b770c636443d411436bd29cc4bb43Mike Lockwoodimport android.os.Process; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.provider.Settings; 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.PrintWriterPrinter; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport com.android.internal.location.GpsLocationProvider; 68e932f7f2a47b770c636443d411436bd29cc4bb43Mike Lockwoodimport com.android.internal.location.LocationProviderProxy; 697ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwoodimport com.android.internal.location.MockProvider; 7022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport com.android.internal.location.GpsNetInitiatedHandler; 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The service class that manages LocationProviders and issues location 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * updates and alerts. 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 783d12b51ee38537f6760a833618948f936e75561dMike Lockwoodpublic class LocationManagerService extends ILocationManager.Stub implements Runnable { 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "LocationManagerService"; 80105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final boolean LOCAL_LOGV = false; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // The last time a location was written, by provider name. 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashMap<String,Long> mLastWriteTime = new HashMap<String,Long>(); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_FINE_LOCATION = 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.ACCESS_FINE_LOCATION; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_COARSE_LOCATION = 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.ACCESS_COARSE_LOCATION; 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_MOCK_LOCATION = 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.ACCESS_MOCK_LOCATION; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String ACCESS_LOCATION_EXTRA_COMMANDS = 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project android.Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS; 93275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood private static final String INSTALL_LOCATION_PROVIDER = 94275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood android.Manifest.permission.INSTALL_LOCATION_PROVIDER; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set of providers that are explicitly enabled 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Set<String> mEnabledProviders = new HashSet<String>(); 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Set of providers that are explicitly disabled 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Set<String> mDisabledProviders = new HashSet<String>(); 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Locations, status values, and extras for mock providers 1037ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood private final HashMap<String,MockProvider> mMockProviders = new HashMap<String,MockProvider>(); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static boolean sProvidersLoaded = false; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final Context mContext; 108a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood private IGeocodeProvider mGeocodeProvider; 10915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private IGpsStatusProvider mGpsStatusProvider; 11022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private INetInitiatedListener mNetInitiatedListener; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private LocationWorkerHandler mLocationHandler; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1137566c1debebe072af76411e11d96810fd1409482Mike Lockwood // Cache the real providers for use in addTestProvider() and removeTestProvider() 1147566c1debebe072af76411e11d96810fd1409482Mike Lockwood LocationProviderProxy mNetworkLocationProvider; 1157566c1debebe072af76411e11d96810fd1409482Mike Lockwood LocationProviderProxy mGpsLocationProvider; 1167566c1debebe072af76411e11d96810fd1409482Mike Lockwood 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Handler messages 1184e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood private static final int MESSAGE_LOCATION_CHANGED = 1; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1200528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // wakelock variables 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final static String WAKELOCK_KEY = "LocationManagerService"; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private PowerManager.WakeLock mWakeLock = null; 12348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private int mPendingBroadcasts; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1262f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood * List of all receivers. 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1282f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final HashMap<Object, Receiver> mReceivers = new HashMap<Object, Receiver>(); 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 13115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood /** 13215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood * List of location providers. 13315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood */ 13415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final ArrayList<LocationProviderProxy> mProviders = 13515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood new ArrayList<LocationProviderProxy>(); 13615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final HashMap<String, LocationProviderProxy> mProvidersByName 13715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood = new HashMap<String, LocationProviderProxy>(); 13815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1402f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood * Object used internally for synchronization 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1422f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final Object mLock = new Object(); 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Mapping from provider name to all its UpdateRecords 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final HashMap<String,ArrayList<UpdateRecord>> mRecordsByProvider = 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashMap<String,ArrayList<UpdateRecord>>(); 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Proximity listeners 15148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private Receiver mProximityReceiver = null; 15248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private ILocationListener mProximityListener = null; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashMap<PendingIntent,ProximityAlert> mProximityAlerts = 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashMap<PendingIntent,ProximityAlert>(); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashSet<ProximityAlert> mProximitiesEntered = 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashSet<ProximityAlert>(); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Last known location for each provider 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private HashMap<String,Location> mLastKnownLocation = 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project new HashMap<String,Location>(); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1624df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project private int mNetworkState = LocationProvider.TEMPORARILY_UNAVAILABLE; 1634df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project 1649637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood // for Settings change notification 1659637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood private ContentQueryMap mSettings; 1669637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A wrapper class holding either an ILocationListener or a PendingIntent to receive 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * location updates. 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 17148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private final class Receiver implements IBinder.DeathRecipient, PendingIntent.OnFinished { 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final ILocationListener mListener; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PendingIntent mPendingIntent; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Object mKey; 1752f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood final HashMap<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>(); 17648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood int mPendingBroadcasts; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1782f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver(ILocationListener listener) { 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingIntent = null; 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mKey = listener.asBinder(); 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1842f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver(PendingIntent intent) { 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mPendingIntent = intent; 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = null; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mKey = intent; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean equals(Object otherObj) { 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (otherObj instanceof Receiver) { 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mKey.equals( 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((Receiver)otherObj).mKey); 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int hashCode() { 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mKey.hashCode(); 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2033681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "Receiver{" 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(System.identityHashCode(this)) 2092f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood + " Listener " + mKey + "}"; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "Receiver{" 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(System.identityHashCode(this)) 2132f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood + " Intent " + mKey + "}"; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isListener() { 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mListener != null; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isPendingIntent() { 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPendingIntent != null; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ILocationListener getListener() { 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mListener; 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("Request for non-existent listener"); 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public PendingIntent getPendingIntent() { 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mPendingIntent != null) { 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mPendingIntent; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalStateException("Request for non-existent intent"); 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean callStatusChangedLocked(String provider, int status, Bundle extras) { 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 24248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 24348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 24448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 24548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onStatusChanged(provider, status, extras); 24648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mListener != mProximityListener) { 24748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 24848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 24948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 25048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 25148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent statusChanged = new Intent(); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project statusChanged.putExtras(extras); 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project statusChanged.putExtra(LocationManager.KEY_STATUS_CHANGED, status); 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 26048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 26148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 26248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 26348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mPendingIntent.send(mContext, 0, statusChanged, this, mLocationHandler); 26448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 26548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 26648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 26748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean callLocationChangedLocked(Location location) { 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mListener != null) { 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 27848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 27948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 28048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 28148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onLocationChanged(location); 28248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mListener != mProximityListener) { 28348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 28448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 28548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 28648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 28748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent locationChanged = new Intent(); 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED, location); 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 29548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 29648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 29748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 29848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mPendingIntent.send(mContext, 0, locationChanged, this, mLocationHandler); 29948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 30048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 30148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 30248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 30348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } catch (PendingIntent.CanceledException e) { 30448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return false; 30548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 30648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 30748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return true; 30848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 30948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 31048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public boolean callProviderEnabledLocked(String provider, boolean enabled) { 31148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mListener != null) { 31248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood try { 31348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 31448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 31548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 31648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (enabled) { 31748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onProviderEnabled(provider); 31848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } else { 31948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mListener.onProviderDisabled(provider); 32048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 32148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mListener != mProximityListener) { 32248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 32348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 32448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 32548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 32648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 32748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } catch (RemoteException e) { 32848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood return false; 32948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 33048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } else { 33148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood Intent providerIntent = new Intent(); 33248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood providerIntent.putExtra(LocationManager.KEY_PROVIDER_ENABLED, enabled); 33348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood try { 33448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 33548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // synchronize to ensure incrementPendingBroadcastsLocked() 33648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 33748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mPendingIntent.send(mContext, 0, providerIntent, this, mLocationHandler); 33848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 33948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 34048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood incrementPendingBroadcastsLocked(); 34148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 350105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 351105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "Location listener died"); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3532f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeUpdatesLocked(this); 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 35648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood synchronized (this) { 35748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mPendingBroadcasts > 0) { 35848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood LocationManagerService.this.decrementPendingBroadcasts(); 35948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood mPendingBroadcasts = 0; 36048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 36148f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 36248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 36348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 36448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public void onSendFinished(PendingIntent pendingIntent, Intent intent, 36548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood int resultCode, String resultData, Bundle resultExtras) { 3660528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (this) { 3670528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood decrementPendingBroadcastsLocked(); 3680528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 36948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 37048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 3710528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // this must be called while synchronized by caller in a synchronized block 37248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // containing the sending of the broadcaset 37348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private void incrementPendingBroadcastsLocked() { 37448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (mPendingBroadcasts++ == 0) { 3750528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood LocationManagerService.this.incrementPendingBroadcasts(); 37648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 37748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 37848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 3790528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private void decrementPendingBroadcastsLocked() { 3800528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (--mPendingBroadcasts == 0) { 3810528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood LocationManagerService.this.decrementPendingBroadcasts(); 38248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 38348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 38448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 38548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 38648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood public void locationCallbackFinished(ILocationListener listener) { 387080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //Do not use getReceiver here as that will add the ILocationListener to 388080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //the receiver list if it is not found. If it is not found then the 389080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //LocationListener was removed when it had a pending broadcast and should 390080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel //not be added back. 391080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel IBinder binder = listener.asBinder(); 392080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel Receiver receiver = mReceivers.get(binder); 39348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (receiver != null) { 3940528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (receiver) { 3950528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // so wakelock calls will succeed 3960528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood long identity = Binder.clearCallingIdentity(); 3970528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood receiver.decrementPendingBroadcastsLocked(); 3980528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood Binder.restoreCallingIdentity(identity); 3990528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4039637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood private final class SettingsObserver implements Observer { 4049637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood public void update(Observable o, Object arg) { 4052f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 4069637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood updateProvidersLocked(); 4079637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood } 4089637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood } 4099637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood } 4109637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood 41115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private void addProvider(LocationProviderProxy provider) { 41215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProviders.add(provider); 41315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProvidersByName.put(provider.getName(), provider); 41415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 41515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 41615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private void removeProvider(LocationProviderProxy provider) { 41715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProviders.remove(provider); 418fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu provider.unlinkProvider(); 41915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mProvidersByName.remove(provider.getName()); 42015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 42115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void loadProviders() { 4232f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sProvidersLoaded) { 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Load providers 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loadProvidersLocked(); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sProvidersLoaded = true; 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void loadProvidersLocked() { 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project _loadProvidersLocked(); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "Exception loading providers:", e); 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void _loadProvidersLocked() { 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Attempt to load "real" providers first 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (GpsLocationProvider.isSupported()) { 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Create a gps location provider 44615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood GpsLocationProvider provider = new GpsLocationProvider(mContext, this); 44715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mGpsStatusProvider = provider.getGpsStatusProvider(); 44822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie mNetInitiatedListener = provider.getNetInitiatedListener(); 4498dfe5d8c6ba9cb165994f09843abaa6302d63c1dMike Lockwood LocationProviderProxy proxy = new LocationProviderProxy(LocationManager.GPS_PROVIDER, provider); 4508dfe5d8c6ba9cb165994f09843abaa6302d63c1dMike Lockwood addProvider(proxy); 4517566c1debebe072af76411e11d96810fd1409482Mike Lockwood mGpsLocationProvider = proxy; 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @param context the context that the LocationManagerService runs in 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public LocationManagerService(Context context) { 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super(); 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 4633d12b51ee38537f6760a833618948f936e75561dMike Lockwood 4643d12b51ee38537f6760a833618948f936e75561dMike Lockwood Thread thread = new Thread(null, this, "LocationManagerService"); 4653d12b51ee38537f6760a833618948f936e75561dMike Lockwood thread.start(); 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 467105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 468105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "Constructed LocationManager Service"); 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4703d12b51ee38537f6760a833618948f936e75561dMike Lockwood } 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4723d12b51ee38537f6760a833618948f936e75561dMike Lockwood private void initialize() { 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Create a wake lock, needs to be done before calling loadProviders() below 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); 4760528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Load providers 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loadProviders(); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Register for Network (Wifi or Mobile) updates 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IntentFilter intentFilter = new IntentFilter(); 4820528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 4830528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Register for Package Manager updates 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED); 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED); 4860528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mContext.registerReceiver(mBroadcastReceiver, intentFilter); 48708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu IntentFilter sdFilter = new IntentFilter(Intent.ACTION_MEDIA_RESOURCES_UNAVAILABLE); 48808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu mContext.registerReceiver(mBroadcastReceiver, sdFilter); 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4909637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood // listen for settings changes 4919637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood ContentResolver resolver = mContext.getContentResolver(); 4929637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood Cursor settingsCursor = resolver.query(Settings.Secure.CONTENT_URI, null, 4939637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood "(" + Settings.System.NAME + "=?)", 4949637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood new String[]{Settings.Secure.LOCATION_PROVIDERS_ALLOWED}, 4959637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood null); 4969637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood mSettings = new ContentQueryMap(settingsCursor, Settings.System.NAME, true, mLocationHandler); 4979637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood SettingsObserver settingsObserver = new SettingsObserver(); 4989637d474899d9725da8a41fdf92b9bd1a15d301eMike Lockwood mSettings.addObserver(settingsObserver); 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5013d12b51ee38537f6760a833618948f936e75561dMike Lockwood public void run() 5023d12b51ee38537f6760a833618948f936e75561dMike Lockwood { 5033d12b51ee38537f6760a833618948f936e75561dMike Lockwood Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 5043d12b51ee38537f6760a833618948f936e75561dMike Lockwood Looper.prepare(); 5053d12b51ee38537f6760a833618948f936e75561dMike Lockwood mLocationHandler = new LocationWorkerHandler(); 5063d12b51ee38537f6760a833618948f936e75561dMike Lockwood initialize(); 5073d12b51ee38537f6760a833618948f936e75561dMike Lockwood Looper.loop(); 5083d12b51ee38537f6760a833618948f936e75561dMike Lockwood } 5093d12b51ee38537f6760a833618948f936e75561dMike Lockwood 510275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood public void installLocationProvider(String name, ILocationProvider provider) { 511275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER) 512275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood != PackageManager.PERMISSION_GRANTED) { 513275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood throw new SecurityException("Requires INSTALL_LOCATION_PROVIDER permission"); 514e932f7f2a47b770c636443d411436bd29cc4bb43Mike Lockwood } 515e932f7f2a47b770c636443d411436bd29cc4bb43Mike Lockwood 5162f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 5173681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood // check to see if we are reinstalling a dead provider 5183681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood LocationProviderProxy oldProvider = mProvidersByName.get(name); 5193681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood if (oldProvider != null) { 5203681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood if (oldProvider.isDead()) { 5213681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood Log.d(TAG, "replacing dead provider"); 5223681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood removeProvider(oldProvider); 5233681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood } else { 5243681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood throw new IllegalArgumentException("Provider \"" + name + "\" already exists"); 5253681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood } 5263681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood } 5273681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood 5288dfe5d8c6ba9cb165994f09843abaa6302d63c1dMike Lockwood LocationProviderProxy proxy = new LocationProviderProxy(name, provider); 5298dfe5d8c6ba9cb165994f09843abaa6302d63c1dMike Lockwood addProvider(proxy); 5308dfe5d8c6ba9cb165994f09843abaa6302d63c1dMike Lockwood updateProvidersLocked(); 5317566c1debebe072af76411e11d96810fd1409482Mike Lockwood if (LocationManager.NETWORK_PROVIDER.equals(name)) { 5327566c1debebe072af76411e11d96810fd1409482Mike Lockwood mNetworkLocationProvider = proxy; 5337566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 534275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood 5358dfe5d8c6ba9cb165994f09843abaa6302d63c1dMike Lockwood // notify provider of current network state 53603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood proxy.updateNetworkState(mNetworkState, null); 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 540275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood public void installGeocodeProvider(IGeocodeProvider provider) { 541275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER) 542275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood != PackageManager.PERMISSION_GRANTED) { 543275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood throw new SecurityException("Requires INSTALL_LOCATION_PROVIDER permission"); 544a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood } 545a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 546a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood mGeocodeProvider = provider; 547a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood } 548a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean isAllowedBySettingsLocked(String provider) { 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabledProviders.contains(provider)) { 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDisabledProviders.contains(provider)) { 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Use system settings 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ContentResolver resolver = mContext.getContentResolver(); 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5598eb3ea659761edc2cd5db3acf448059f19389e5eBrad Larson return Settings.Secure.isLocationProviderEnabled(resolver, provider); 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void checkPermissionsSafe(String provider) { 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LocationManager.GPS_PROVIDER.equals(provider) 564b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_FINE_LOCATION permission"); 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LocationManager.NETWORK_PROVIDER.equals(provider) 569b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) 571b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION) 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException( 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "Requires ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permission"); 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean isAllowedProviderSafe(String provider) { 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LocationManager.GPS_PROVIDER.equals(provider) 580b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (LocationManager.NETWORK_PROVIDER.equals(provider) 585b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) 587b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood && (mContext.checkCallingOrSelfPermission(ACCESS_COARSE_LOCATION) 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<String> getAllProviders() { 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5972f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return _getAllProvidersLocked(); 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "getAllProviders got exception:", e); 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private List<String> _getAllProvidersLocked() { 609105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 610105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "getAllProviders"); 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 61215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood ArrayList<String> out = new ArrayList<String>(mProviders.size()); 61315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 61415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy p = mProviders.get(i); 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.add(p.getName()); 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return out; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public List<String> getProviders(boolean enabledOnly) { 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6222f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return _getProvidersLocked(enabledOnly); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 628105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.e(TAG, "getProviders got exception:", e); 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return null; 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private List<String> _getProvidersLocked(boolean enabledOnly) { 634105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 635105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "getProviders"); 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 63715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood ArrayList<String> out = new ArrayList<String>(mProviders.size()); 63815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 63915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy p = mProviders.get(i); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = p.getName(); 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isAllowedProviderSafe(name)) { 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enabledOnly && !isAllowedBySettingsLocked(name)) { 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project out.add(name); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return out; 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateProvidersLocked() { 65215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 65315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy p = mProviders.get(i); 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isEnabled = p.isEnabled(); 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project String name = p.getName(); 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean shouldBeEnabled = isAllowedBySettingsLocked(name); 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isEnabled && !shouldBeEnabled) { 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProviderListenersLocked(name, false); 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (!isEnabled && shouldBeEnabled) { 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProviderListenersLocked(name, true); 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateProviderListenersLocked(String provider, boolean enabled) { 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int listeners = 0; 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 67015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy p = mProvidersByName.get(provider); 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p == null) { 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<Receiver> deadReceivers = null; 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records != null) { 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int N = records.size(); 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UpdateRecord record = records.get(i); 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Sends a notification message to the receiver 68348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (!record.mReceiver.callProviderEnabledLocked(provider, enabled)) { 68448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (deadReceivers == null) { 68548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood deadReceivers = new ArrayList<Receiver>(); 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6874686657cee6411eb00235d49b4a8663a96361a00Simon Schoar deadReceivers.add(record.mReceiver); 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listeners++; 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (deadReceivers != null) { 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=deadReceivers.size()-1; i>=0; i--) { 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project removeUpdatesLocked(deadReceivers.get(i)); 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enabled) { 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.enable(); 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listeners > 0) { 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.setMinTime(getMinTimeLocked(provider)); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.enableLocationTracking(true); 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.enableLocationTracking(false); 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.disable(); 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long getMinTimeLocked(String provider) { 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long minTime = Long.MAX_VALUE; 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records != null) { 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=records.size()-1; i>=0; i--) { 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project minTime = Math.min(minTime, records.get(i).mMinTime); 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return minTime; 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class UpdateRecord { 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final String mProvider; 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Receiver mReceiver; 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long mMinTime; 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float mMinDistance; 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int mUid; 7282f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Location mLastFixBroadcast; 7292f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood long mLastStatusBroadcast; 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Note: must be constructed with lock held. 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project UpdateRecord(String provider, long minTime, float minDistance, 7352f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver receiver, int uid) { 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProvider = provider; 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mReceiver = receiver; 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMinTime = minTime; 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mMinDistance = minDistance; 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUid = uid; 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (records == null) { 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project records = new ArrayList<UpdateRecord>(); 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRecordsByProvider.put(provider, records); 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!records.contains(this)) { 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project records.add(this); 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Method to be called when a record will no longer be used. Calling this multiple times 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * must have the same effect as calling it once. 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void disposeLocked() { 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> records = mRecordsByProvider.get(this.mProvider); 7583a76fd627945c1df59aa0318867401e0e53da022Mike Lockwood if (records != null) { 7593a76fd627945c1df59aa0318867401e0e53da022Mike Lockwood records.remove(this); 7603a76fd627945c1df59aa0318867401e0e53da022Mike Lockwood } 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "UpdateRecord{" 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(System.identityHashCode(this)) 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " " + mProvider + " " + mReceiver + "}"; 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void dump(PrintWriter pw, String prefix) { 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + this); 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mProvider=" + mProvider + " mReceiver=" + mReceiver); 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mMinTime=" + mMinTime + " mMinDistance=" + mMinDistance); 7742f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood pw.println(prefix + "mUid=" + mUid); 7752f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood pw.println(prefix + "mLastFixBroadcast:"); 7762f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mLastFixBroadcast.dump(new PrintWriterPrinter(pw), prefix + " "); 7772f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood pw.println(prefix + "mLastStatusBroadcast=" + mLastStatusBroadcast); 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7812f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private Receiver getReceiver(ILocationListener listener) { 7822f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood IBinder binder = listener.asBinder(); 7832f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver receiver = mReceivers.get(binder); 7842f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (receiver == null) { 7852f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood receiver = new Receiver(listener); 7862f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mReceivers.put(binder, receiver); 7872f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 7882f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood try { 7892f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (receiver.isListener()) { 7902f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood receiver.getListener().asBinder().linkToDeath(receiver, 0); 7912f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 7922f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } catch (RemoteException e) { 7932f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Log.e(TAG, "linkToDeath failed:", e); 7942f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return null; 7952f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 7962f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 7972f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return receiver; 7982f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 7992f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8002f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private Receiver getReceiver(PendingIntent intent) { 8012f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Receiver receiver = mReceivers.get(intent); 8022f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (receiver == null) { 8032f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood receiver = new Receiver(intent); 8042f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mReceivers.put(intent, receiver); 8052f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8062f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return receiver; 8072f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8082f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8092f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private boolean providerHasListener(String provider, int uid, Receiver excludedReceiver) { 8102f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider); 8112f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (records != null) { 8122f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood for (int i = records.size() - 1; i >= 0; i--) { 8132f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood UpdateRecord record = records.get(i); 8142f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (record.mUid == uid && record.mReceiver != excludedReceiver) { 8152f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return true; 8162f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8172f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8182f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 81995427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood for (ProximityAlert alert : mProximityAlerts.values()) { 82095427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood if (alert.mUid == uid) { 82195427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood return true; 8222f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8232f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8242f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood return false; 8252f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8262f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void requestLocationUpdates(String provider, 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long minTime, float minDistance, ILocationListener listener) { 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8312f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 8322f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood requestLocationUpdatesLocked(provider, minTime, minDistance, getReceiver(listener)); 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "requestUpdates got exception:", e); 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void requestLocationUpdatesPI(String provider, 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long minTime, float minDistance, PendingIntent intent) { 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8442f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 8452f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood requestLocationUpdatesLocked(provider, minTime, minDistance, getReceiver(intent)); 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "requestUpdates got exception:", e); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void requestLocationUpdatesLocked(String provider, 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long minTime, float minDistance, Receiver receiver) { 856105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 857105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "_requestLocationUpdates: listener = " + receiver); 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 86015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy proxy = mProvidersByName.get(provider); 86115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (proxy == null) { 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("provider=" + provider); 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkPermissionsSafe(provider); 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // so wakelock calls will succeed 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int callingUid = Binder.getCallingUid(); 8692f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood boolean newUid = !providerHasListener(provider, callingUid, null); 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identity = Binder.clearCallingIdentity(); 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8722f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood UpdateRecord r = new UpdateRecord(provider, minTime, minDistance, receiver, callingUid); 8732f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood UpdateRecord oldRecord = receiver.mUpdateRecords.put(provider, r); 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (oldRecord != null) { 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project oldRecord.disposeLocked(); 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8782f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (newUid) { 87915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood proxy.addListener(callingUid); 8802f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8812f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isProviderEnabled = isAllowedBySettingsLocked(provider); 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isProviderEnabled) { 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long minTimeForProvider = getMinTimeLocked(provider); 88515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood proxy.setMinTime(minTimeForProvider); 88615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood proxy.enableLocationTracking(true); 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 88848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // Notify the listener that updates are currently disabled 88948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood receiver.callProviderEnabledLocked(provider, false); 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(identity); 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeUpdates(ILocationListener listener) { 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8982f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 8992f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood removeUpdatesLocked(getReceiver(listener)); 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "removeUpdates got exception:", e); 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeUpdatesPI(PendingIntent intent) { 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9102f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 9112f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood removeUpdatesLocked(getReceiver(intent)); 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (SecurityException se) { 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw se; 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (Exception e) { 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "removeUpdates got exception:", e); 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void removeUpdatesLocked(Receiver receiver) { 921105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 922105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "_removeUpdates: listener = " + receiver); 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // so wakelock calls will succeed 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int callingUid = Binder.getCallingUid(); 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long identity = Binder.clearCallingIdentity(); 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9292f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) { 9302f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood receiver.getListener().asBinder().unlinkToDeath(receiver, 0); 931080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel synchronized(receiver) { 932080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel if(receiver.mPendingBroadcasts > 0) { 933080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel decrementPendingBroadcasts(); 934080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel receiver.mPendingBroadcasts = 0; 935080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel } 936080b61ba17014b8c93914f642ccbe05c76dc611dJoshua Bartel } 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Record which providers were associated with this listener 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project HashSet<String> providers = new HashSet<String>(); 9412f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood HashMap<String,UpdateRecord> oldRecords = receiver.mUpdateRecords; 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (oldRecords != null) { 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Call dispose() on the obsolete update records. 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (UpdateRecord record : oldRecords.values()) { 9452f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (!providerHasListener(record.mProvider, callingUid, receiver)) { 94615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy proxy = mProvidersByName.get(record.mProvider); 94715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (proxy != null) { 94815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood proxy.removeListener(callingUid); 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project record.disposeLocked(); 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Accumulate providers 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project providers.addAll(oldRecords.keySet()); 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // See if the providers associated with this listener have any 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // other listeners; if one does, inform it of the new smallest minTime 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // value; if one does not, disable location tracking for it 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String provider : providers) { 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If provider is already disabled, don't need to do anything 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!isAllowedBySettingsLocked(provider)) { 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project continue; 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean hasOtherListener = false; 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<UpdateRecord> recordsForProvider = mRecordsByProvider.get(provider); 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (recordsForProvider != null && recordsForProvider.size() > 0) { 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasOtherListener = true; 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 97215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy p = mProvidersByName.get(provider); 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (p != null) { 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hasOtherListener) { 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.setMinTime(getMinTimeLocked(provider)); 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project p.enableLocationTracking(false); 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } finally { 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Binder.restoreCallingIdentity(identity); 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean addGpsStatusListener(IGpsStatusListener listener) { 98715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mGpsStatusProvider == null) { 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 990b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood if (mContext.checkCallingOrSelfPermission(ACCESS_FINE_LOCATION) != 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageManager.PERMISSION_GRANTED) { 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_FINE_LOCATION permission"); 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 99615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mGpsStatusProvider.addGpsStatusListener(listener); 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 99815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Log.e(TAG, "mGpsStatusProvider.addGpsStatusListener failed", e); 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeGpsStatusListener(IGpsStatusListener listener) { 10052f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 100615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood try { 100715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mGpsStatusProvider.removeGpsStatusListener(listener); 100815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } catch (Exception e) { 100915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Log.e(TAG, "mGpsStatusProvider.removeGpsStatusListener failed", e); 101015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String provider, String command, Bundle extras) { 1015c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood if (provider == null) { 1016c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood // throw NullPointerException to remain compatible with previous implementation 1017c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood throw new NullPointerException(); 1018c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood } 1019c6cc836f88349e871c2aa7579223c9220e95e5b0Mike Lockwood 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // first check for permission to the provider 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkPermissionsSafe(provider); 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // and check for ACCESS_LOCATION_EXTRA_COMMANDS 1023b7e9922722f50dbf1911eb12e3ee8023c1450086Mike Lockwood if ((mContext.checkCallingOrSelfPermission(ACCESS_LOCATION_EXTRA_COMMANDS) 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED)) { 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_LOCATION_EXTRA_COMMANDS permission"); 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10282f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 102915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy proxy = mProvidersByName.get(provider); 10306ba7ae1e4c3c04f6a71380b913ad79f83b00a628Mike Lockwood if (proxy == null) { 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 103415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return proxy.sendExtraCommand(command, extras); 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 103822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public boolean sendNiResponse(int notifId, int userResponse) 103922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 104018ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood if (Binder.getCallingUid() != Process.myUid()) { 104118ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood throw new SecurityException( 104218ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood "calling sendNiResponse from outside of the system is not allowed"); 104318ad9f657bda79069233c0b8e1476888ffd894d4Mike Lockwood } 104422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie try { 104522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return mNetInitiatedListener.sendNiResponse(notifId, userResponse); 104622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 104722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie catch (RemoteException e) 104822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 104922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Log.e(TAG, "RemoteException in LocationManagerService.sendNiResponse"); 105022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return false; 105122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 105222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 105322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project class ProximityAlert { 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final int mUid; 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final double mLatitude; 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final double mLongitude; 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final float mRadius; 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final long mExpiration; 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final PendingIntent mIntent; 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final Location mLocation; 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public ProximityAlert(int uid, double latitude, double longitude, 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float radius, long expiration, PendingIntent intent) { 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUid = uid; 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLatitude = latitude; 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLongitude = longitude; 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRadius = radius; 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExpiration = expiration; 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mIntent = intent; 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation = new Location(""); 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLatitude(latitude); 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLongitude(longitude); 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long getExpiration() { 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mExpiration; 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent getIntent() { 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mIntent; 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10852d2078aa1d6e31063f565a20b717f3b8908fff02Yusuf T. Mobile boolean isInProximity(double latitude, double longitude, float accuracy) { 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Location loc = new Location(""); 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loc.setLatitude(latitude); 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project loc.setLongitude(longitude); 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project double radius = loc.distanceTo(mLocation); 10912d2078aa1d6e31063f565a20b717f3b8908fff02Yusuf T. Mobile return radius <= Math.max(mRadius,accuracy); 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String toString() { 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return "ProximityAlert{" 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Integer.toHexString(System.identityHashCode(this)) 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " uid " + mUid + mIntent + "}"; 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project void dump(PrintWriter pw, String prefix) { 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + this); 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mLatitude=" + mLatitude + " mLongitude=" + mLongitude); 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mRadius=" + mRadius + " mExpiration=" + mExpiration); 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mIntent=" + mIntent); 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(prefix + "mLocation:"); 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.dump(new PrintWriterPrinter(pw), prefix + " "); 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Listener for receiving locations to trigger proximity alerts 111248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood class ProximityListener extends ILocationListener.Stub implements PendingIntent.OnFinished { 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean isGpsAvailable = false; 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Note: this is called with the lock held. 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void onLocationChanged(Location loc) { 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // If Gps is available, then ignore updates from NetworkLocationProvider 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (loc.getProvider().equals(LocationManager.GPS_PROVIDER)) { 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project isGpsAvailable = true; 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (isGpsAvailable && loc.getProvider().equals(LocationManager.NETWORK_PROVIDER)) { 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Process proximity alerts 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now = System.currentTimeMillis(); 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project double latitude = loc.getLatitude(); 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project double longitude = loc.getLongitude(); 11312d2078aa1d6e31063f565a20b717f3b8908fff02Yusuf T. Mobile float accuracy = loc.getAccuracy(); 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ArrayList<PendingIntent> intentsToRemove = null; 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ProximityAlert alert : mProximityAlerts.values()) { 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PendingIntent intent = alert.getIntent(); 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long expiration = alert.getExpiration(); 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((expiration == -1) || (now <= expiration)) { 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean entered = mProximitiesEntered.contains(alert); 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean inProximity = 11412d2078aa1d6e31063f565a20b717f3b8908fff02Yusuf T. Mobile alert.isInProximity(latitude, longitude, accuracy); 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!entered && inProximity) { 1143105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 1144105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "Entered alert"); 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximitiesEntered.add(alert); 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent enteredIntent = new Intent(); 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project enteredIntent.putExtra(LocationManager.KEY_PROXIMITY_ENTERING, true); 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11500528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (this) { 11510528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // synchronize to ensure incrementPendingBroadcasts() 115248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 115348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood intent.send(mContext, 0, enteredIntent, this, mLocationHandler); 115448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 115548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 11560528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood incrementPendingBroadcasts(); 115748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 1159105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 1160105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "Canceled proximity alert: " + alert, e); 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intentsToRemove == null) { 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove = new ArrayList<PendingIntent>(); 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove.add(intent); 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (entered && !inProximity) { 1168105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 1169105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "Exited alert"); 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximitiesEntered.remove(alert); 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent exitedIntent = new Intent(); 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project exitedIntent.putExtra(LocationManager.KEY_PROXIMITY_ENTERING, false); 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11750528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (this) { 11760528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // synchronize to ensure incrementPendingBroadcasts() 117748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // is called before decrementPendingBroadcasts() 117848f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood intent.send(mContext, 0, exitedIntent, this, mLocationHandler); 117948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // call this after broadcasting so we do not increment 118048f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood // if we throw an exeption. 11810528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood incrementPendingBroadcasts(); 118248f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (PendingIntent.CanceledException e) { 1184105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 1185105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "Canceled proximity alert: " + alert, e); 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intentsToRemove == null) { 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove = new ArrayList<PendingIntent>(); 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove.add(intent); 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Mark alert for expiration 1195105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (LOCAL_LOGV) { 1196105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.v(TAG, "Expiring proximity alert: " + alert); 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intentsToRemove == null) { 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove = new ArrayList<PendingIntent>(); 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intentsToRemove.add(alert.getIntent()); 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Remove expired alerts 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (intentsToRemove != null) { 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (PendingIntent i : intentsToRemove) { 12080dac8c0f7ec00d94b09f92823fa238142163aba8Mike Lockwood ProximityAlert alert = mProximityAlerts.remove(i); 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProximitiesEntered.remove(alert); 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 1317f2db9fb0f877057a9ef56908d54f3c95fc3fd552Alexey Tarasov * @throws 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) 155408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu || action.equals(Intent.ACTION_PACKAGE_RESTARTED) 155508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu || action.equals(Intent.ACTION_MEDIA_RESOURCES_UNAVAILABLE)) { 15562f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 155708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu int uidList[] = null; 155808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (action.equals(Intent.ACTION_MEDIA_RESOURCES_UNAVAILABLE)) { 155908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu uidList = intent.getIntArrayExtra(Intent.EXTRA_CHANGED_UID_LIST); 156008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } else { 156108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu uidList = new int[]{intent.getIntExtra(Intent.EXTRA_UID, -1)}; 156208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 156308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (uidList == null || uidList.length == 0) { 156408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu return; 156508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 156608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (int uid : uidList) { 156708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (uid >= 0) { 156808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu ArrayList<Receiver> removedRecs = null; 156908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (ArrayList<UpdateRecord> i : mRecordsByProvider.values()) { 157008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (int j=i.size()-1; j>=0; j--) { 157108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu UpdateRecord ur = i.get(j); 157208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (ur.mReceiver.isPendingIntent() && ur.mUid == uid) { 157308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (removedRecs == null) { 157408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removedRecs = new ArrayList<Receiver>(); 157508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 157608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (!removedRecs.contains(ur.mReceiver)) { 157708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removedRecs.add(ur.mReceiver); 157808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 158208675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu ArrayList<ProximityAlert> removedAlerts = null; 158308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (ProximityAlert i : mProximityAlerts.values()) { 158408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (i.mUid == uid) { 158508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (removedAlerts == null) { 158608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removedAlerts = new ArrayList<ProximityAlert>(); 158708675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 158808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (!removedAlerts.contains(i)) { 158908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removedAlerts.add(i); 159008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 159308675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (removedRecs != null) { 159408675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (int i=removedRecs.size()-1; i>=0; i--) { 159508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removeUpdatesLocked(removedRecs.get(i)); 159608675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 159808675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu if (removedAlerts != null) { 159908675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu for (int i=removedAlerts.size()-1; i>=0; i--) { 160008675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu removeProximityAlertLocked(removedAlerts.get(i).mIntent); 160108675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu } 16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16060528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 16079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean noConnectivity = 16089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false); 16099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!noConnectivity) { 16104df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mNetworkState = LocationProvider.AVAILABLE; 16114df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project } else { 16124df2423a947bcd3f024cc3d3a1a315a8dc428598The Android Open Source Project mNetworkState = LocationProvider.TEMPORARILY_UNAVAILABLE; 16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 161403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood NetworkInfo info = 161508675a3376819a82aa5ab344bc3e7b1635c30b05Suchi Amalapurapu (NetworkInfo)intent.getExtra(ConnectivityManager.EXTRA_NETWORK_INFO); 16169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Notify location providers of current network state 16182f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 161915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = mProviders.size() - 1; i >= 0; i--) { 162015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood LocationProviderProxy provider = mProviders.get(i); 16219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (provider.requiresNetwork()) { 162203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood provider.updateNetworkState(mNetworkState, info); 16239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16280528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood }; 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Wake locks 16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16320528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private void incrementPendingBroadcasts() { 16330528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (mWakeLock) { 16340528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (mPendingBroadcasts++ == 0) { 16350528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood try { 16360528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.acquire(); 16370528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood log("Acquired wakelock"); 16380528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } catch (Exception e) { 16390528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // This is to catch a runtime exception thrown when we try to release an 16400528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // already released lock. 16410528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood Log.e(TAG, "exception in acquireWakeLock()", e); 16420528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 16430528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 164448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 164548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 164648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 164748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood private void decrementPendingBroadcasts() { 16480528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood synchronized (mWakeLock) { 164948f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood if (--mPendingBroadcasts == 0) { 16500528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood try { 16510528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Release wake lock 16520528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (mWakeLock.isHeld()) { 16530528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.release(); 16540528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood log("Released wakelock"); 16550528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } else { 16560528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood log("Can't release wakelock again!"); 16570528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 16580528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } catch (Exception e) { 16590528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // This is to catch a runtime exception thrown when we try to release an 16600528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // already released lock. 16610528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood Log.e(TAG, "exception in releaseWakeLock()", e); 16620528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 166348f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 166448f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 166548f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood } 166648f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood 16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Geocoder 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getFromLocation(double latitude, double longitude, int maxResults, 167034901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwood GeocoderParams params, List<Address> addrs) { 1671a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood if (mGeocodeProvider != null) { 1672a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood try { 167334901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwood return mGeocodeProvider.getFromLocation(latitude, longitude, maxResults, 167434901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwood params, addrs); 1675a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood } catch (RemoteException e) { 1676a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood Log.e(TAG, "getFromLocation failed", e); 16773681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood mGeocodeProvider = null; 16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1680a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood return null; 16819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1683a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public String getFromLocationName(String locationName, 1685a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood double lowerLeftLatitude, double lowerLeftLongitude, 1686a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood double upperRightLatitude, double upperRightLongitude, int maxResults, 168734901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwood GeocoderParams params, List<Address> addrs) { 1688a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood 1689a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood if (mGeocodeProvider != null) { 1690a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood try { 1691a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood return mGeocodeProvider.getFromLocationName(locationName, lowerLeftLatitude, 1692a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood lowerLeftLongitude, upperRightLatitude, upperRightLongitude, 169334901409a404c8c66914c5a8ad0f29b1bcde0e78Mike Lockwood maxResults, params, addrs); 1694a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood } catch (RemoteException e) { 1695a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood Log.e(TAG, "getFromLocationName failed", e); 16963681f2614fa8c10560c790f6b4287f65d6fd2663Mike Lockwood mGeocodeProvider = null; 16979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1699a55c321329ae52a2db7a4f2bd36673a20b8f271dMike Lockwood return null; 17009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Mock Providers 17039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void checkMockPermissionsSafe() { 17059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean allowMocks = Settings.Secure.getInt(mContext.getContentResolver(), 17069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 1; 17079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!allowMocks) { 17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_MOCK_LOCATION secure setting"); 17099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) != 17129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project PackageManager.PERMISSION_GRANTED) { 17139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission"); 17149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite, 17189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude, 17199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) { 17209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 17219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 172286328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 17232f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 17244e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood MockProvider provider = new MockProvider(name, this, 17254e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood requiresNetwork, requiresSatellite, 17269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project requiresCell, hasMonetaryCost, supportsAltitude, 17279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project supportsSpeed, supportsBearing, powerRequirement, accuracy); 17287566c1debebe072af76411e11d96810fd1409482Mike Lockwood // remove the real provider if we are replacing GPS or network provider 17297566c1debebe072af76411e11d96810fd1409482Mike Lockwood if (LocationManager.GPS_PROVIDER.equals(name) 17307566c1debebe072af76411e11d96810fd1409482Mike Lockwood || LocationManager.NETWORK_PROVIDER.equals(name)) { 17317566c1debebe072af76411e11d96810fd1409482Mike Lockwood LocationProviderProxy proxy = mProvidersByName.get(name); 17327566c1debebe072af76411e11d96810fd1409482Mike Lockwood if (proxy != null) { 17337566c1debebe072af76411e11d96810fd1409482Mike Lockwood proxy.enableLocationTracking(false); 17347566c1debebe072af76411e11d96810fd1409482Mike Lockwood removeProvider(proxy); 17357566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 17367566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 173715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mProvidersByName.get(name) != null) { 17389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + name + "\" already exists"); 17399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 174015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood addProvider(new LocationProviderProxy(name, provider)); 17417ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mMockProviders.put(name, provider); 17427566c1debebe072af76411e11d96810fd1409482Mike Lockwood mLastKnownLocation.put(name, null); 17439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 17449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 174586328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 17469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeTestProvider(String provider) { 17499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 17502f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 17517ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 17527ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 17539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 17549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 175586328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 175615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood removeProvider(mProvidersByName.get(provider)); 17577ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mMockProviders.remove(mockProvider); 17587566c1debebe072af76411e11d96810fd1409482Mike Lockwood // reinstall real provider if we were mocking GPS or network provider 17597566c1debebe072af76411e11d96810fd1409482Mike Lockwood if (LocationManager.GPS_PROVIDER.equals(provider) && 17607566c1debebe072af76411e11d96810fd1409482Mike Lockwood mGpsLocationProvider != null) { 17617566c1debebe072af76411e11d96810fd1409482Mike Lockwood addProvider(mGpsLocationProvider); 17627566c1debebe072af76411e11d96810fd1409482Mike Lockwood } else if (LocationManager.NETWORK_PROVIDER.equals(provider) && 17637566c1debebe072af76411e11d96810fd1409482Mike Lockwood mNetworkLocationProvider != null) { 17647566c1debebe072af76411e11d96810fd1409482Mike Lockwood addProvider(mNetworkLocationProvider); 17657566c1debebe072af76411e11d96810fd1409482Mike Lockwood } 17667566c1debebe072af76411e11d96810fd1409482Mike Lockwood mLastKnownLocation.put(provider, null); 17679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 176886328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 17699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderLocation(String provider, Location loc) { 17739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 17742f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 17757ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 17767ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 17779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 17789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 177995427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood // clear calling identity so INSTALL_LOCATION_PROVIDER permission is not required 178095427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood long identity = Binder.clearCallingIdentity(); 17817ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.setLocation(loc); 178295427cdbd802f7cb529d62bb79953c45b36a8fcfMike Lockwood Binder.restoreCallingIdentity(identity); 17839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderLocation(String provider) { 17879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 17882f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 17897ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 17907ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 17919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 17929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17937ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.clearLocation(); 17949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 17969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderEnabled(String provider, boolean enabled) { 17989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 17992f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18007ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18017ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 180486328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 18059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enabled) { 18067ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.enable(); 18079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.add(provider); 18089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.remove(provider); 18099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 18107ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.disable(); 18119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.remove(provider); 18129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.add(provider); 18139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 181586328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 18169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderEnabled(String provider) { 18209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18212f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18227ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18237ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 182686328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood long identity = Binder.clearCallingIdentity(); 18279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabledProviders.remove(provider); 18289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDisabledProviders.remove(provider); 18299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateProvidersLocked(); 183086328a99bd55532e318441d48ee9eb96cdc42403Mike Lockwood Binder.restoreCallingIdentity(identity); 18319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) { 18359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18362f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18377ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18387ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18417ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.setStatus(status, extras, updateTime); 18429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void clearTestProviderStatus(String provider) { 18469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project checkMockPermissionsSafe(); 18472f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18487ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood MockProvider mockProvider = mMockProviders.get(provider); 18497ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood if (mockProvider == null) { 18509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); 18519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18527ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood mockProvider.clearStatus(); 18539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void log(String log) { 18579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Log.isLoggable(TAG, Log.VERBOSE)) { 18589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, log); 18599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 18639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 18649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project != PackageManager.PERMISSION_GRANTED) { 18650528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood pw.println("Permission Denial: can't dump LocationManagerService from from pid=" 18669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + Binder.getCallingPid() 18679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + ", uid=" + Binder.getCallingUid()); 18689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 18699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18712f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood synchronized (mLock) { 18729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println("Current Location Manager state:"); 18739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" sProvidersLoaded=" + sProvidersLoaded); 18749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Listeners:"); 18752f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood int N = mReceivers.size(); 18769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i=0; i<N; i++) { 18772f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood pw.println(" " + mReceivers.get(i)); 18789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Location Listeners:"); 18802f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood for (Receiver i : mReceivers.values()) { 18812f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood pw.println(" " + i + ":"); 18822f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood for (Map.Entry<String,UpdateRecord> j : i.mUpdateRecords.entrySet()) { 18839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + j.getKey() + ":"); 18849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project j.getValue().dump(pw, " "); 18859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Records by Provider:"); 18889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, ArrayList<UpdateRecord>> i 18899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mRecordsByProvider.entrySet()) { 18909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i.getKey() + ":"); 18919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (UpdateRecord j : i.getValue()) { 18929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + j + ":"); 18939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project j.dump(pw, " "); 18949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 18969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Last Known Locations:"); 18979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, Location> i 18989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mLastKnownLocation.entrySet()) { 18999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i.getKey() + ":"); 19009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i.getValue().dump(new PrintWriterPrinter(pw), " "); 19019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProximityAlerts.size() > 0) { 19039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Proximity Alerts:"); 19049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<PendingIntent, ProximityAlert> i 19059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project : mProximityAlerts.entrySet()) { 19069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i.getKey() + ":"); 19079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i.getValue().dump(pw, " "); 19089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mProximitiesEntered.size() > 0) { 19119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Proximities Entered:"); 19129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (ProximityAlert i : mProximitiesEntered) { 19139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i + ":"); 19149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project i.dump(pw, " "); 19159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 191748f17518223a2917fd82195004fbb206cb9a05a3Mike Lockwood pw.println(" mProximityReceiver=" + mProximityReceiver); 19189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" mProximityListener=" + mProximityListener); 19199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabledProviders.size() > 0) { 19209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Enabled Providers:"); 19219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String i : mEnabledProviders) { 19229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i); 19239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mDisabledProviders.size() > 0) { 19279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Disabled Providers:"); 19289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (String i : mDisabledProviders) { 19299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" " + i); 19309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mMockProviders.size() > 0) { 19349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pw.println(" Mock Providers:"); 19359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (Map.Entry<String, MockProvider> i : mMockProviders.entrySet()) { 19367ec434e2e179776d75c8a4da66dcfd2ee630c5d8Mike Lockwood i.getValue().dump(pw, " "); 19379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 19419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1942