diff options
Diffstat (limited to 'services/java/com/android/server/LocationManagerService.java')
-rw-r--r-- | services/java/com/android/server/LocationManagerService.java | 401 |
1 files changed, 273 insertions, 128 deletions
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index 1bf60d4..831d1d2 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -57,9 +57,9 @@ import android.os.PowerManager; import android.os.RemoteException; import android.os.SystemClock; import android.provider.Settings; +import android.provider.Settings.SettingNotFoundException; import android.telephony.CellLocation; import android.telephony.PhoneStateListener; -import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.util.Config; import android.util.Log; @@ -145,24 +145,25 @@ public class LocationManagerService extends ILocationManager.Stub { private boolean mCellWakeLockAcquired = false; /** - * Mapping from listener IBinder to local Listener wrappers. + * Mapping from listener IBinder/PendingIntent to local Listener wrappers. */ - private final HashMap<IBinder,Listener> mListeners = - new HashMap<IBinder,Listener>(); + private final HashMap<Object,Receiver> mListeners = + new HashMap<Object,Receiver>(); /** - * Mapping from listener IBinder to a map from provider name to UpdateRecord. + * Mapping from listener IBinder/PendingIntent to a map from provider name to UpdateRecord. */ - private final HashMap<IBinder,HashMap<String,UpdateRecord>> mLocationListeners = - new HashMap<IBinder,HashMap<String,UpdateRecord>>(); + private final HashMap<Object,HashMap<String,UpdateRecord>> mLocationListeners = + new HashMap<Object,HashMap<String,UpdateRecord>>(); /** - * Mapping from listener IBinder to a map from provider name to last broadcast location. + * Mapping from listener IBinder/PendingIntent to a map from provider name to last broadcast + * location. */ - private final HashMap<IBinder,HashMap<String,Location>> mLastFixBroadcast = - new HashMap<IBinder,HashMap<String,Location>>(); - private final HashMap<IBinder,HashMap<String,Long>> mLastStatusBroadcast = - new HashMap<IBinder,HashMap<String,Long>>(); + private final HashMap<Object,HashMap<String,Location>> mLastFixBroadcast = + new HashMap<Object,HashMap<String,Location>>(); + private final HashMap<Object,HashMap<String,Long>> mLastStatusBroadcast = + new HashMap<Object,HashMap<String,Long>>(); /** * Mapping from provider name to all its UpdateRecords @@ -178,7 +179,7 @@ public class LocationManagerService extends ILocationManager.Stub { new HashMap<String,Location>(); // Proximity listeners - private ProximityListener mProximityListener = null; + private Receiver mProximityListener = null; private HashMap<PendingIntent,ProximityAlert> mProximityAlerts = new HashMap<PendingIntent,ProximityAlert>(); private HashSet<ProximityAlert> mProximitiesEntered = @@ -195,7 +196,7 @@ public class LocationManagerService extends ILocationManager.Stub { // Last known cell service state private TelephonyManager mTelephonyManager; - private ServiceState mServiceState = new ServiceState(); + private int mSignalStrength = -1; // Location collector private LocationCollector mCollector; @@ -206,11 +207,82 @@ public class LocationManagerService extends ILocationManager.Stub { // Wifi Manager private WifiManager mWifiManager; - private final class Listener implements IBinder.DeathRecipient { + /** + * A wrapper class holding either an ILocationListener or a PendingIntent to receive + * location updates. + */ + private final class Receiver implements IBinder.DeathRecipient { final ILocationListener mListener; + final PendingIntent mPendingIntent; - Listener(ILocationListener listener) { + Receiver(ILocationListener listener) { mListener = listener; + mPendingIntent = null; + } + + Receiver(PendingIntent intent) { + mPendingIntent = intent; + mListener = null; + } + + public Object getKey() { + if (mListener != null) { + return mListener.asBinder(); + } else { + return mPendingIntent; + } + } + + public boolean isListener() { + return mListener != null; + } + + public boolean isPendingIntent() { + return mPendingIntent != null; + } + + public ILocationListener getListener() { + if (mListener != null) { + return mListener; + } + throw new IllegalStateException("Request for non-existent listener"); + } + + public PendingIntent getPendingIntent() { + if (mPendingIntent != null) { + return mPendingIntent; + } + throw new IllegalStateException("Request for non-existent intent"); + } + + public void onStatusChanged(String provider, int status, Bundle extras) + throws RemoteException { + if (mListener != null) { + mListener.onStatusChanged(provider, status, extras); + } else { + Intent statusChanged = new Intent(); + statusChanged.putExtras(extras); + statusChanged.putExtra(LocationManager.KEY_STATUS_CHANGED, status); + try { + mPendingIntent.send(mContext, 0, statusChanged, null, null); + } catch (PendingIntent.CanceledException e) { + _removeUpdates(this); + } + } + } + + public void onLocationChanged(Location location) throws RemoteException { + if (mListener != null) { + mListener.onLocationChanged(location); + } else { + Intent locationChanged = new Intent(); + locationChanged.putExtra(LocationManager.KEY_LOCATION_CHANGED, location); + try { + mPendingIntent.send(mContext, 0, locationChanged, null, null); + } catch (PendingIntent.CanceledException e) { + _removeUpdates(this); + } + } } public void binderDied() { @@ -218,7 +290,7 @@ public class LocationManagerService extends ILocationManager.Stub { Log.d(TAG, "Location listener died"); } synchronized (mLocationListeners) { - _removeUpdates(mListener); + _removeUpdates(this); } } } @@ -228,7 +300,7 @@ public class LocationManagerService extends ILocationManager.Stub { String s = null; try { File f = new File(LocationManager.SYSTEM_DIR + "/location." - + provider); + + provider); if (!f.exists()) { return null; } @@ -443,13 +515,22 @@ public class LocationManagerService extends ILocationManager.Stub { // Create location collector mCollector = new LocationCollector(mMasfClient); + // Alarm manager, needs to be done before calling loadProviders() below + mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); + + // Create a wake lock, needs to be done before calling loadProviders() below + PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); + mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); + // Load providers loadProviders(); // Listen for Radio changes mTelephonyManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); mTelephonyManager.listen(mPhoneStateListener, - PhoneStateListener.LISTEN_SERVICE_STATE | PhoneStateListener.LISTEN_CELL_LOCATION); + PhoneStateListener.LISTEN_CELL_LOCATION | + PhoneStateListener.LISTEN_SIGNAL_STRENGTH | + PhoneStateListener.LISTEN_DATA_CONNECTION_STATE); // Register for Network (Wifi or Mobile) updates NetworkStateBroadcastReceiver networkReceiver = new NetworkStateBroadcastReceiver(); @@ -460,9 +541,6 @@ public class LocationManagerService extends ILocationManager.Stub { networkIntentFilter.addAction(GpsLocationProvider.GPS_ENABLED_CHANGE_ACTION); context.registerReceiver(networkReceiver, networkIntentFilter); - // Alarm manager - mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); - // Register for power updates PowerStateBroadcastReceiver powerStateReceiver = new PowerStateBroadcastReceiver(); IntentFilter intentFilter = new IntentFilter(); @@ -472,10 +550,6 @@ public class LocationManagerService extends ILocationManager.Stub { intentFilter.addAction(Intent.ACTION_BATTERY_CHANGED); context.registerReceiver(powerStateReceiver, intentFilter); - // Create a wake lock - PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); - mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); - // Get the wifi manager mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); @@ -510,8 +584,8 @@ public class LocationManagerService extends ILocationManager.Stub { } // Use system settings ContentResolver resolver = mContext.getContentResolver(); - String allowedProviders = Settings.System.getString(resolver, - Settings.System.LOCATION_PROVIDERS_ALLOWED); + String allowedProviders = Settings.Secure.getString(resolver, + Settings.Secure.LOCATION_PROVIDERS_ALLOWED); return ((allowedProviders != null) && (allowedProviders.contains(provider))); } @@ -638,16 +712,28 @@ public class LocationManagerService extends ILocationManager.Stub { } synchronized (mRecordsByProvider) { - HashSet<UpdateRecord> records = mRecordsByProvider.get(provider); if (records != null) { for (UpdateRecord record : records) { - // Sends a notification message to the listener + // Sends a notification message to the receiver try { - if (enabled) { - record.mListener.mListener.onProviderEnabled(provider); + Receiver receiver = record.mReceiver; + if (receiver.isListener()) { + if (enabled) { + receiver.getListener().onProviderEnabled(provider); + } else { + receiver.getListener().onProviderDisabled(provider); + } } else { - record.mListener.mListener.onProviderDisabled(provider); + PendingIntent intent = receiver.getPendingIntent(); + Intent providerIntent = new Intent(); + providerIntent.putExtra(LocationManager.KEY_PROVIDER_ENABLED, enabled); + try { + receiver.getPendingIntent().send(mContext, 0, + providerIntent, null, null); + } catch (PendingIntent.CanceledException e) { + _removeUpdates(receiver); + } } } catch (RemoteException e) { // The death link will clean this up. @@ -694,15 +780,15 @@ public class LocationManagerService extends ILocationManager.Stub { private class UpdateRecord { String mProvider; - Listener mListener; + Receiver mReceiver; long mMinTime; float mMinDistance; String[] mPackages; - UpdateRecord(String provider, long minTime, float minDistance, Listener listener, - String[] packages) { + UpdateRecord(String provider, long minTime, float minDistance, + Receiver receiver, String[] packages) { mProvider = provider; - mListener = listener; + mReceiver = receiver; mMinTime = minTime; mMinDistance = minDistance; mPackages = packages; @@ -740,7 +826,20 @@ public class LocationManagerService extends ILocationManager.Stub { long minTime, float minDistance, ILocationListener listener) { try { - _requestLocationUpdates(provider, minTime, minDistance, listener); + _requestLocationUpdates(provider, minTime, minDistance, + new Receiver(listener)); + } catch (SecurityException se) { + throw se; + } catch (Exception e) { + Log.e(TAG, "requestUpdates got exception:", e); + } + } + + public void requestLocationUpdatesPI(String provider, + long minTime, float minDistance, PendingIntent intent) { + try { + _requestLocationUpdates(provider, minTime, minDistance, + new Receiver(intent)); } catch (SecurityException se) { throw se; } catch (Exception e) { @@ -749,9 +848,10 @@ public class LocationManagerService extends ILocationManager.Stub { } private void _requestLocationUpdates(String provider, - long minTime, float minDistance, ILocationListener listener) { + long minTime, float minDistance, Receiver receiver) { + Object key = receiver.getKey(); if (Config.LOGD) { - Log.d(TAG, "_requestLocationUpdates: listener = " + listener.asBinder()); + Log.d(TAG, "_requestLocationUpdates: listener = " + key); } LocationProviderImpl impl = LocationProviderImpl.getProvider(provider); @@ -766,24 +866,23 @@ public class LocationManagerService extends ILocationManager.Stub { // so wakelock calls will succeed long identity = Binder.clearCallingIdentity(); try { - Listener myListener = new Listener(listener); - UpdateRecord r = new UpdateRecord(provider, minTime, minDistance, myListener, packages); - + UpdateRecord r = new UpdateRecord(provider, minTime, minDistance, receiver, packages); synchronized (mLocationListeners) { - IBinder binder = listener.asBinder(); - if (mListeners.get(binder) == null) { + if (mListeners.get(key) == null) { try { - binder.linkToDeath(myListener, 0); - mListeners.put(binder, myListener); + if (receiver.isListener()) { + receiver.getListener().asBinder().linkToDeath(receiver, 0); + } + mListeners.put(key, receiver); } catch (RemoteException e) { return; } } - HashMap<String,UpdateRecord> records = mLocationListeners.get(binder); + HashMap<String,UpdateRecord> records = mLocationListeners.get(key); if (records == null) { records = new HashMap<String,UpdateRecord>(); - mLocationListeners.put(binder, records); + mLocationListeners.put(key, records); } UpdateRecord oldRecord = records.put(provider, r); if (oldRecord != null) { @@ -809,9 +908,12 @@ public class LocationManagerService extends ILocationManager.Stub { } else { try { // Notify the listener that updates are currently disabled - listener.onProviderDisabled(provider); + if (receiver.isListener()) { + receiver.getListener().onProviderDisabled(provider); + } } catch(RemoteException e) { - Log.w(TAG, "RemoteException calling onProviderDisabled on " + listener); + Log.w(TAG, "RemoteException calling onProviderDisabled on " + + receiver.getListener()); } } } @@ -822,7 +924,7 @@ public class LocationManagerService extends ILocationManager.Stub { public void removeUpdates(ILocationListener listener) { try { - _removeUpdates(listener); + _removeUpdates(new Receiver(listener)); } catch (SecurityException se) { throw se; } catch (Exception e) { @@ -830,24 +932,34 @@ public class LocationManagerService extends ILocationManager.Stub { } } - private void _removeUpdates(ILocationListener listener) { + public void removeUpdatesPI(PendingIntent intent) { + try { + _removeUpdates(new Receiver(intent)); + } catch (SecurityException se) { + throw se; + } catch (Exception e) { + Log.e(TAG, "removeUpdates got exception:", e); + } + } + + private void _removeUpdates(Receiver receiver) { + Object key = receiver.getKey(); if (Config.LOGD) { - Log.d(TAG, "_removeUpdates: listener = " + listener.asBinder()); + Log.d(TAG, "_removeUpdates: listener = " + key); } // so wakelock calls will succeed long identity = Binder.clearCallingIdentity(); try { synchronized (mLocationListeners) { - IBinder binder = listener.asBinder(); - Listener myListener = mListeners.remove(binder); - if (myListener != null) { - binder.unlinkToDeath(myListener, 0); + Receiver myReceiver = mListeners.remove(key); + if ((myReceiver != null) && (myReceiver.isListener())) { + myReceiver.getListener().asBinder().unlinkToDeath(myReceiver, 0); } // Record which providers were associated with this listener HashSet<String> providers = new HashSet<String>(); - HashMap<String,UpdateRecord> oldRecords = mLocationListeners.get(binder); + HashMap<String,UpdateRecord> oldRecords = mLocationListeners.get(key); if (oldRecords != null) { // Call dispose() on the obsolete update records. for (UpdateRecord record : oldRecords.values()) { @@ -862,9 +974,9 @@ public class LocationManagerService extends ILocationManager.Stub { providers.addAll(oldRecords.keySet()); } - mLocationListeners.remove(binder); - mLastFixBroadcast.remove(binder); - mLastStatusBroadcast.remove(binder); + mLocationListeners.remove(key); + mLastFixBroadcast.remove(key); + mLastStatusBroadcast.remove(key); // See if the providers associated with this listener have any // other listeners; if one does, inform it of the new smallest minTime @@ -894,7 +1006,7 @@ public class LocationManagerService extends ILocationManager.Stub { } } - updateWakelockStatus(mScreenOn); + updateWakelockStatus(mScreenOn); } } finally { Binder.restoreCallingIdentity(identity); @@ -905,6 +1017,11 @@ public class LocationManagerService extends ILocationManager.Stub { if (mGpsLocationProvider == null) { return false; } + if (mContext.checkCallingPermission(ACCESS_FINE_LOCATION) != + PackageManager.PERMISSION_GRANTED) { + throw new SecurityException("Requires ACCESS_FINE_LOCATION permission"); + } + try { mGpsLocationProvider.addGpsStatusListener(listener); } catch (RemoteException e) { @@ -996,7 +1113,6 @@ public class LocationManagerService extends ILocationManager.Stub { ArrayList<PendingIntent> intentsToRemove = null; for (ProximityAlert alert : mProximityAlerts.values()) { - PendingIntent intent = alert.getIntent(); long expiration = alert.getExpiration(); @@ -1115,7 +1231,7 @@ public class LocationManagerService extends ILocationManager.Stub { mProximityAlerts.put(intent, alert); if (mProximityListener == null) { - mProximityListener = new ProximityListener(); + mProximityListener = new Receiver(new ProximityListener()); LocationProvider provider = LocationProviderImpl.getProvider( LocationManager.GPS_PROVIDER); @@ -1345,15 +1461,15 @@ public class LocationManagerService extends ILocationManager.Stub { // Broadcast location or status to all listeners for (UpdateRecord r : records) { - ILocationListener listener = r.mListener.mListener; - IBinder binder = listener.asBinder(); + Receiver receiver = r.mReceiver; + Object key = receiver.getKey(); // Broadcast location only if it is valid if (locationValid) { - HashMap<String,Location> map = mLastFixBroadcast.get(binder); + HashMap<String,Location> map = mLastFixBroadcast.get(key); if (map == null) { map = new HashMap<String,Location>(); - mLastFixBroadcast.put(binder, map); + mLastFixBroadcast.put(key, map); } Location lastLoc = map.get(provider); if ((lastLoc == null) || shouldBroadcast(loc, lastLoc, r)) { @@ -1364,19 +1480,19 @@ public class LocationManagerService extends ILocationManager.Stub { lastLoc.set(loc); } try { - listener.onLocationChanged(loc); + receiver.onLocationChanged(loc); } catch (RemoteException doe) { - Log.w(TAG, "RemoteException calling onLocationChanged on " + listener); - _removeUpdates(listener); + Log.w(TAG, "RemoteException calling onLocationChanged on " + receiver); + _removeUpdates(receiver); } } } // Broadcast status message - HashMap<String,Long> statusMap = mLastStatusBroadcast.get(binder); + HashMap<String,Long> statusMap = mLastStatusBroadcast.get(key); if (statusMap == null) { statusMap = new HashMap<String,Long>(); - mLastStatusBroadcast.put(binder, statusMap); + mLastStatusBroadcast.put(key, statusMap); } long prevStatusUpdateTime = (statusMap.get(provider) != null) ? statusMap.get(provider) : 0; @@ -1386,10 +1502,10 @@ public class LocationManagerService extends ILocationManager.Stub { statusMap.put(provider, newStatusUpdateTime); try { - listener.onStatusChanged(provider, status, extras); + receiver.onStatusChanged(provider, status, extras); } catch (RemoteException doe) { - Log.w(TAG, "RemoteException calling onStatusChanged on " + listener); - _removeUpdates(listener); + Log.w(TAG, "RemoteException calling onStatusChanged on " + receiver); + _removeUpdates(receiver); } } } @@ -1423,7 +1539,8 @@ public class LocationManagerService extends ILocationManager.Stub { } if ((mWakeLockAcquireTime != 0) && - (SystemClock.elapsedRealtime() - mWakeLockAcquireTime > MAX_TIME_FOR_WAKE_LOCK)) { + (SystemClock.elapsedRealtime() - mWakeLockAcquireTime + > MAX_TIME_FOR_WAKE_LOCK)) { removeMessages(MESSAGE_ACQUIRE_WAKE_LOCK); removeMessages(MESSAGE_RELEASE_WAKE_LOCK); @@ -1449,7 +1566,7 @@ public class LocationManagerService extends ILocationManager.Stub { acquireWakeLock(); } else if (msg.what == MESSAGE_RELEASE_WAKE_LOCK) { log("LocationWorkerHandler: Release"); - + // Update wakelock status so the next alarm is set before releasing wakelock updateWakelockStatus(mScreenOn); releaseWakeLock(); @@ -1462,22 +1579,24 @@ public class LocationManagerService extends ILocationManager.Stub { } PhoneStateListener mPhoneStateListener = new PhoneStateListener() { + + private CellState mLastCellState = null; @Override public void onCellLocationChanged(CellLocation cellLocation) { try { - ServiceState serviceState = mServiceState; + int asu = mSignalStrength; // Gets cell state - CellState cellState = new CellState(serviceState, cellLocation); + mLastCellState = new CellState(mTelephonyManager, cellLocation, asu); // Notify collector - mCollector.updateCellState(cellState); + mCollector.updateCellState(mLastCellState); // Updates providers List<LocationProviderImpl> providers = LocationProviderImpl.getProviders(); for (LocationProviderImpl provider : providers) { if (provider.requiresCell()) { - provider.updateCellState(cellState); + provider.updateCellState(mLastCellState); } } } catch (Exception e) { @@ -1486,8 +1605,19 @@ public class LocationManagerService extends ILocationManager.Stub { } @Override - public void onServiceStateChanged(ServiceState serviceState) { - mServiceState = serviceState; + public void onSignalStrengthChanged(int asu) { + mSignalStrength = asu; + + if (mLastCellState != null) { + mLastCellState.updateSignalStrength(asu); + } + } + + @Override + public void onDataConnectionStateChanged(int state) { + if (mLastCellState != null) { + mLastCellState.updateRadioType(mTelephonyManager); + } } }; @@ -1578,7 +1708,8 @@ public class LocationManagerService extends ILocationManager.Stub { } else if (action.equals(GpsLocationProvider.GPS_ENABLED_CHANGE_ACTION)) { - final boolean enabled = intent.getBooleanExtra(GpsLocationProvider.EXTRA_ENABLED, false); + final boolean enabled = intent.getBooleanExtra(GpsLocationProvider.EXTRA_ENABLED, + false); if (!enabled) { // When GPS is disabled, we are OK to release wake-lock @@ -1608,7 +1739,7 @@ public class LocationManagerService extends ILocationManager.Stub { if (screenOn) { startGps(); } else if (mScreenOn && !screenOn) { - + // We just turned the screen off so stop navigating stopGps(); } @@ -1641,13 +1772,23 @@ public class LocationManagerService extends ILocationManager.Stub { } private void acquireWakeLock() { + try { + acquireWakeLockX(); + } catch (Exception e) { + // This is to catch a runtime exception thrown when we try to release an + // already released lock. + Log.e(TAG, "exception in acquireWakeLock()", e); + } + } + + private void acquireWakeLockX() { if (mWakeLock.isHeld()) { log("Must release wakelock before acquiring"); mWakeLockAcquireTime = 0; mWakeLock.release(); } - boolean networkActive = (mNetworkLocationProvider != null) + boolean networkActive = (mNetworkLocationProvider != null) && mNetworkLocationProvider.isLocationTracking(); boolean gpsActive = (mGpsLocationProvider != null) && mGpsLocationProvider.isLocationTracking(); @@ -1668,7 +1809,7 @@ public class LocationManagerService extends ILocationManager.Stub { // Start the gps provider startGps(); - + // Acquire cell lock if (mCellWakeLockAcquired) { // Lock is already acquired @@ -1700,7 +1841,7 @@ public class LocationManagerService extends ILocationManager.Stub { } private void startGps() { - boolean gpsActive = (mGpsLocationProvider != null) + boolean gpsActive = (mGpsLocationProvider != null) && mGpsLocationProvider.isLocationTracking(); if (gpsActive) { mGpsLocationProvider.startNavigating(); @@ -1708,7 +1849,7 @@ public class LocationManagerService extends ILocationManager.Stub { } private void stopGps() { - boolean gpsActive = mGpsLocationProvider != null + boolean gpsActive = mGpsLocationProvider != null && mGpsLocationProvider.isLocationTracking(); if (gpsActive) { mGpsLocationProvider.stopNavigating(); @@ -1716,6 +1857,16 @@ public class LocationManagerService extends ILocationManager.Stub { } private void releaseWakeLock() { + try { + releaseWakeLockX(); + } catch (Exception e) { + // This is to catch a runtime exception thrown when we try to release an + // already released lock. + Log.e(TAG, "exception in releaseWakeLock()", e); + } + } + + private void releaseWakeLockX() { // Release wifi lock WifiManager.WifiLock wifiLock = getWifiWakelock(); if (wifiLock != null) { @@ -1726,22 +1877,22 @@ public class LocationManagerService extends ILocationManager.Stub { } if (!mScreenOn) { - + // Stop the gps stopGps(); } - + // Release cell lock if (mCellWakeLockAcquired) { mTelephonyManager.disableLocationUpdates(); mCellWakeLockAcquired = false; } - + // Notify NetworkLocationProvider if (mNetworkLocationProvider != null) { mNetworkLocationProvider.updateCellLockStatus(mCellWakeLockAcquired); } - + // Release wake lock mWakeLockAcquireTime = 0; if (mWakeLock.isHeld()) { @@ -1751,7 +1902,7 @@ public class LocationManagerService extends ILocationManager.Stub { log("Can't release wakelock again!"); } } - + // Geocoder public String getFromLocation(double latitude, double longitude, int maxResults, @@ -1903,14 +2054,29 @@ public class LocationManagerService extends ILocationManager.Stub { return mSupportsSpeed; } } + + private void checkMockPermissions() { + boolean allowMocks = false; + try { + allowMocks = Settings.Secure.getInt(mContext.getContentResolver(), + Settings.Secure.ALLOW_MOCK_LOCATION) == 1; + } catch (SettingNotFoundException e) { + // Do nothing + } + if (!allowMocks) { + throw new SecurityException("Requires ACCESS_MOCK_LOCATION secure setting"); + } - public void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite, - boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude, - boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) { if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) != PackageManager.PERMISSION_GRANTED) { throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission"); - } + } + } + + public void addTestProvider(String name, boolean requiresNetwork, boolean requiresSatellite, + boolean requiresCell, boolean hasMonetaryCost, boolean supportsAltitude, + boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) { + checkMockPermissions(); MockProvider provider = new MockProvider(name, requiresNetwork, requiresSatellite, requiresCell, hasMonetaryCost, supportsAltitude, @@ -1923,10 +2089,7 @@ public class LocationManagerService extends ILocationManager.Stub { } public void removeTestProvider(String provider) { - if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) != - PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission"); - } + checkMockPermissions(); LocationProviderImpl p = LocationProviderImpl.getProvider(provider); if (p == null) { throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); @@ -1936,10 +2099,7 @@ public class LocationManagerService extends ILocationManager.Stub { } public void setTestProviderLocation(String provider, Location loc) { - if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) != - PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission"); - } + checkMockPermissions(); if (LocationProviderImpl.getProvider(provider) == null) { throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); } @@ -1947,10 +2107,7 @@ public class LocationManagerService extends ILocationManager.Stub { } public void clearTestProviderLocation(String provider) { - if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) != - PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission"); - } + checkMockPermissions(); if (LocationProviderImpl.getProvider(provider) == null) { throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); } @@ -1958,10 +2115,7 @@ public class LocationManagerService extends ILocationManager.Stub { } public void setTestProviderEnabled(String provider, boolean enabled) { - if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) != - PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission"); - } + checkMockPermissions(); if (LocationProviderImpl.getProvider(provider) == null) { throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); } @@ -1976,10 +2130,7 @@ public class LocationManagerService extends ILocationManager.Stub { } public void clearTestProviderEnabled(String provider) { - if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) != - PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission"); - } + checkMockPermissions(); if (LocationProviderImpl.getProvider(provider) == null) { throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); } @@ -1989,10 +2140,7 @@ public class LocationManagerService extends ILocationManager.Stub { } public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) { - if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) != - PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission"); - } + checkMockPermissions(); if (LocationProviderImpl.getProvider(provider) == null) { throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); } @@ -2002,10 +2150,7 @@ public class LocationManagerService extends ILocationManager.Stub { } public void clearTestProviderStatus(String provider) { - if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) != - PackageManager.PERMISSION_GRANTED) { - throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission"); - } + checkMockPermissions(); if (LocationProviderImpl.getProvider(provider) == null) { throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); } |