From 2f82c4eb0b4d315481ad79725ad6f52c5ec69685 Mon Sep 17 00:00:00 2001 From: Mike Lockwood Date: Fri, 17 Apr 2009 08:24:10 -0400 Subject: location: Generalize support for location provider usage tracking. This replaces two different mechanisms that were used for GPS and Netork location provider tracking. Move BatteryStats logging of GPS usage from LocationManagerService to GpsLocationProvider. Clean up tracking of location listeners in LocationManagerService and remove some HashMaps that are no longer needed. Signed-off-by: Mike Lockwood --- .../java/android/location/ILocationProvider.aidl | 6 +- .../android/location/LocationProviderImpl.java | 16 + .../internal/location/GpsLocationProvider.java | 49 ++- .../internal/location/LocationProviderProxy.java | 8 +- .../com/android/server/LocationManagerService.java | 405 +++++++-------------- 5 files changed, 202 insertions(+), 282 deletions(-) diff --git a/location/java/android/location/ILocationProvider.aidl b/location/java/android/location/ILocationProvider.aidl index 08b9246..d43fd6e 100644 --- a/location/java/android/location/ILocationProvider.aidl +++ b/location/java/android/location/ILocationProvider.aidl @@ -46,9 +46,9 @@ interface ILocationProvider { void setMinTime(long minTime); void updateNetworkState(int state); boolean sendExtraCommand(String command, inout Bundle extras); + void addListener(int uid); + void removeListener(int uid); - /* the following are only used for NetworkLocationProvider */ + /* the following is used only for NetworkLocationProvider */ void updateCellLockStatus(boolean acquired); - void addListener(in String[] applications); - void removeListener(in String[] applications); } diff --git a/location/java/android/location/LocationProviderImpl.java b/location/java/android/location/LocationProviderImpl.java index 2a9199e..fa0cd2d 100644 --- a/location/java/android/location/LocationProviderImpl.java +++ b/location/java/android/location/LocationProviderImpl.java @@ -249,4 +249,20 @@ public abstract class LocationProviderImpl extends LocationProvider { public boolean sendExtraCommand(String command, Bundle extras) { return false; } + + /** + * Informs the location provider when a new client is listening for location information + * + * @param uid the uid of the client proces + */ + public void addListener(int uid) { + } + + /** + * Informs the location provider when a client is no longerlistening for location information + * + * @param uid the uid of the client proces + */ + public void removeListener(int uid) { + } } diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java index d56594e..f133b4f 100644 --- a/location/java/com/android/internal/location/GpsLocationProvider.java +++ b/location/java/com/android/internal/location/GpsLocationProvider.java @@ -33,10 +33,13 @@ import android.net.SntpClient; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; +import android.os.ServiceManager; import android.os.SystemClock; import android.util.Config; import android.util.Log; +import android.util.SparseIntArray; +import com.android.internal.app.IBatteryStats; import com.android.internal.telephony.Phone; import com.android.internal.telephony.TelephonyIntents; @@ -192,7 +195,10 @@ public class GpsLocationProvider extends LocationProviderImpl { private boolean mSetSuplServer; private String mSuplApn; private int mSuplDataConnectionState; - private ConnectivityManager mConnMgr; + private final ConnectivityManager mConnMgr; + + private final IBatteryStats mBatteryStats; + private final SparseIntArray mClientUids = new SparseIntArray(); // how often to request NTP time, in milliseconds // current setting 4 hours @@ -241,6 +247,9 @@ public class GpsLocationProvider extends LocationProviderImpl { mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); + // Battery statistics service to be notified when GPS turns on or off + mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo")); + mProperties = new Properties(); try { File file = new File(PROPERTIES_FILE); @@ -568,6 +577,30 @@ public class GpsLocationProvider extends LocationProviderImpl { } @Override + public void addListener(int uid) { + mClientUids.put(uid, 0); + if (mNavigating) { + try { + mBatteryStats.noteStartGps(uid); + } catch (RemoteException e) { + Log.w(TAG, "RemoteException in addListener"); + } + } + } + + @Override + public void removeListener(int uid) { + mClientUids.delete(uid); + if (mNavigating) { + try { + mBatteryStats.noteStopGps(uid); + } catch (RemoteException e) { + Log.w(TAG, "RemoteException in removeListener"); + } + } + } + + @Override public boolean sendExtraCommand(String command, Bundle extras) { if ("delete_aiding_data".equals(command)) { @@ -746,6 +779,20 @@ public class GpsLocationProvider extends LocationProviderImpl { } } + try { + // update battery stats + for (int i=mClientUids.size() - 1; i >= 0; i--) { + int uid = mClientUids.keyAt(i); + if (mNavigating) { + mBatteryStats.noteStartGps(uid); + } else { + mBatteryStats.noteStopGps(uid); + } + } + } catch (RemoteException e) { + Log.w(TAG, "RemoteException in reportStatus"); + } + // send an intent to notify that the GPS has been enabled or disabled. Intent intent = new Intent(GPS_ENABLED_CHANGE_ACTION); intent.putExtra(EXTRA_ENABLED, mNavigating); diff --git a/location/java/com/android/internal/location/LocationProviderProxy.java b/location/java/com/android/internal/location/LocationProviderProxy.java index 5b5b27a..84462b2 100644 --- a/location/java/com/android/internal/location/LocationProviderProxy.java +++ b/location/java/com/android/internal/location/LocationProviderProxy.java @@ -230,17 +230,17 @@ public class LocationProviderProxy extends LocationProviderImpl { } } - public void addListener(String[] applications) { + public void addListener(int uid) { try { - mProvider.addListener(applications); + mProvider.addListener(uid); } catch (RemoteException e) { Log.e(TAG, "addListener failed", e); } } - public void removeListener(String[] applications) { + public void removeListener(int uid) { try { - mProvider.removeListener(applications); + mProvider.removeListener(uid); } catch (RemoteException e) { Log.e(TAG, "removeListener failed", e); } diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index 75b59ee..c91e21c 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -73,7 +73,6 @@ import android.util.Log; import android.util.PrintWriterPrinter; import android.util.SparseIntArray; -import com.android.internal.app.IBatteryStats; import com.android.internal.location.GpsLocationProvider; import com.android.internal.location.LocationProviderProxy; import com.android.internal.location.MockProvider; @@ -152,34 +151,15 @@ public class LocationManagerService extends ILocationManager.Stub { private boolean mWifiWakeLockAcquired = false; private boolean mCellWakeLockAcquired = false; - private final IBatteryStats mBatteryStats; - - /** - * Mapping from listener IBinder/PendingIntent to local Listener wrappers. - */ - private final ArrayList mListeners = new ArrayList(); - - /** - * Used for reporting which UIDs are causing the GPS to run. - */ - private final SparseIntArray mReportedGpsUids = new SparseIntArray(); - private int mReportedGpsSeq = 0; - /** - * Mapping from listener IBinder/PendingIntent to a map from provider name to UpdateRecord. - * This also serves as the lock for our state. + * List of all receivers. */ - private final HashMap> mLocationListeners = - new HashMap>(); + private final HashMap mReceivers = new HashMap(); /** - * Mapping from listener IBinder/PendingIntent to a map from provider name to last broadcast - * location. + * Object used internally for synchronization */ - private final HashMap> mLastFixBroadcast = - new HashMap>(); - private final HashMap> mLastStatusBroadcast = - new HashMap>(); + private final Object mLock = new Object(); /** * Mapping from provider name to all its UpdateRecords @@ -219,20 +199,18 @@ public class LocationManagerService extends ILocationManager.Stub { private final class Receiver implements IBinder.DeathRecipient { final ILocationListener mListener; final PendingIntent mPendingIntent; - final int mUid; final Object mKey; + final HashMap mUpdateRecords = new HashMap(); - Receiver(ILocationListener listener, int uid) { + Receiver(ILocationListener listener) { mListener = listener; mPendingIntent = null; - mUid = uid; mKey = listener.asBinder(); } - Receiver(PendingIntent intent, int uid) { + Receiver(PendingIntent intent) { mPendingIntent = intent; mListener = null; - mUid = uid; mKey = intent; } @@ -256,11 +234,11 @@ public class LocationManagerService extends ILocationManager.Stub { if (mListener != null) { return "Receiver{" + Integer.toHexString(System.identityHashCode(this)) - + " uid " + mUid + " Listener " + mKey + "}"; + + " Listener " + mKey + "}"; } else { return "Receiver{" + Integer.toHexString(System.identityHashCode(this)) - + " uid " + mUid + " Intent " + mKey + "}"; + + " Intent " + mKey + "}"; } } @@ -329,7 +307,7 @@ public class LocationManagerService extends ILocationManager.Stub { if (LOCAL_LOGV) { Log.v(TAG, "Location listener died"); } - synchronized (mLocationListeners) { + synchronized (mLock) { removeUpdatesLocked(this); } } @@ -337,7 +315,7 @@ public class LocationManagerService extends ILocationManager.Stub { private final class SettingsObserver implements Observer { public void update(Observable o, Object arg) { - synchronized (mLocationListeners) { + synchronized (mLock) { updateProvidersLocked(); } } @@ -444,7 +422,7 @@ public class LocationManagerService extends ILocationManager.Stub { * properties */ private void loadProviders() { - synchronized (mLocationListeners) { + synchronized (mLock) { if (sProvidersLoaded) { return; } @@ -558,9 +536,6 @@ public class LocationManagerService extends ILocationManager.Stub { PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); - // Battery statistics service to be notified when GPS turns on or off - mBatteryStats = BatteryStatsService.getService(); - // Load providers loadProviders(); @@ -607,10 +582,9 @@ public class LocationManagerService extends ILocationManager.Stub { "Installing location providers outside of the system is not supported"); } - synchronized (mLocationListeners) { + synchronized (mLock) { mNetworkLocationProvider = new LocationProviderProxy(LocationManager.NETWORK_PROVIDER, this, provider); - mNetworkLocationProvider.addListener(getPackageNames()); LocationProviderImpl.addProvider(mNetworkLocationProvider); updateProvidersLocked(); @@ -626,7 +600,7 @@ public class LocationManagerService extends ILocationManager.Stub { "Installing location collectors outside of the system is not supported"); } - synchronized (mLocationListeners) { + synchronized (mLock) { mCollector = collector; if (mGpsLocationProvider != null) { mGpsLocationProvider.setLocationCollector(mCollector); @@ -699,15 +673,9 @@ public class LocationManagerService extends ILocationManager.Stub { return true; } - private String[] getPackageNames() { - // Since a single UID may correspond to multiple packages, this can only be used as an - // approximation for tracking - return mContext.getPackageManager().getPackagesForUid(Binder.getCallingUid()); - } - public List getAllProviders() { try { - synchronized (mLocationListeners) { + synchronized (mLock) { return _getAllProvidersLocked(); } } catch (SecurityException se) { @@ -733,7 +701,7 @@ public class LocationManagerService extends ILocationManager.Stub { public List getProviders(boolean enabledOnly) { try { - synchronized (mLocationListeners) { + synchronized (mLock) { return _getProvidersLocked(enabledOnly); } } catch (SecurityException se) { @@ -839,7 +807,6 @@ public class LocationManagerService extends ILocationManager.Stub { p.enableLocationTracking(false); if (p == mGpsLocationProvider) { mGpsNavigating = false; - reportStopGpsLocked(); } p.disable(); updateWakelockStatusLocked(mScreenOn); @@ -863,19 +830,19 @@ public class LocationManagerService extends ILocationManager.Stub { final long mMinTime; final float mMinDistance; final int mUid; - final String[] mPackages; + Location mLastFixBroadcast; + long mLastStatusBroadcast; /** * Note: must be constructed with lock held. */ UpdateRecord(String provider, long minTime, float minDistance, - Receiver receiver, int uid, String[] packages) { + Receiver receiver, int uid) { mProvider = provider; mReceiver = receiver; mMinTime = minTime; mMinDistance = minDistance; mUid = uid; - mPackages = packages; ArrayList records = mRecordsByProvider.get(provider); if (records == null) { @@ -907,33 +874,77 @@ public class LocationManagerService extends ILocationManager.Stub { pw.println(prefix + this); pw.println(prefix + "mProvider=" + mProvider + " mReceiver=" + mReceiver); pw.println(prefix + "mMinTime=" + mMinTime + " mMinDistance=" + mMinDistance); - StringBuilder sb = new StringBuilder(); - if (mPackages != null) { - for (int i=0; i 0) sb.append(", "); - sb.append(mPackages[i]); - } - } - pw.println(prefix + "mUid=" + mUid + " mPackages=" + sb); + pw.println(prefix + "mUid=" + mUid); + pw.println(prefix + "mLastFixBroadcast:"); + mLastFixBroadcast.dump(new PrintWriterPrinter(pw), prefix + " "); + pw.println(prefix + "mLastStatusBroadcast=" + mLastStatusBroadcast); } /** * Calls dispose(). */ @Override protected void finalize() { - synchronized (mLocationListeners) { + synchronized (mLock) { disposeLocked(); } } } + private Receiver getReceiver(ILocationListener listener) { + IBinder binder = listener.asBinder(); + Receiver receiver = mReceivers.get(binder); + if (receiver == null) { + receiver = new Receiver(listener); + mReceivers.put(binder, receiver); + + try { + if (receiver.isListener()) { + receiver.getListener().asBinder().linkToDeath(receiver, 0); + } + } catch (RemoteException e) { + Log.e(TAG, "linkToDeath failed:", e); + return null; + } + } + return receiver; + } + + private Receiver getReceiver(PendingIntent intent) { + Receiver receiver = mReceivers.get(intent); + if (receiver == null) { + receiver = new Receiver(intent); + mReceivers.put(intent, receiver); + } + return receiver; + } + + private boolean providerHasListener(String provider, int uid, Receiver excludedReceiver) { + ArrayList records = mRecordsByProvider.get(provider); + if (records != null) { + for (int i = records.size() - 1; i >= 0; i--) { + UpdateRecord record = records.get(i); + if (record.mUid == uid && record.mReceiver != excludedReceiver) { + return true; + } + } + } + if (LocationManager.GPS_PROVIDER.equals(provider) || + LocationManager.NETWORK_PROVIDER.equals(provider)) { + for (ProximityAlert alert : mProximityAlerts.values()) { + if (alert.mUid == uid) { + return true; + } + } + } + return false; + } + public void requestLocationUpdates(String provider, long minTime, float minDistance, ILocationListener listener) { try { - synchronized (mLocationListeners) { - requestLocationUpdatesLocked(provider, minTime, minDistance, - new Receiver(listener, Binder.getCallingUid())); + synchronized (mLock) { + requestLocationUpdatesLocked(provider, minTime, minDistance, getReceiver(listener)); } } catch (SecurityException se) { throw se; @@ -945,9 +956,8 @@ public class LocationManagerService extends ILocationManager.Stub { public void requestLocationUpdatesPI(String provider, long minTime, float minDistance, PendingIntent intent) { try { - synchronized (mLocationListeners) { - requestLocationUpdatesLocked(provider, minTime, minDistance, - new Receiver(intent, Binder.getCallingUid())); + synchronized (mLock) { + requestLocationUpdatesLocked(provider, minTime, minDistance, getReceiver(intent)); } } catch (SecurityException se) { throw se; @@ -969,47 +979,27 @@ public class LocationManagerService extends ILocationManager.Stub { checkPermissionsSafe(provider); - String[] packages = getPackageNames(); - // so wakelock calls will succeed final int callingUid = Binder.getCallingUid(); + boolean newUid = !providerHasListener(provider, callingUid, null); long identity = Binder.clearCallingIdentity(); try { - UpdateRecord r = new UpdateRecord(provider, minTime, minDistance, - receiver, callingUid, packages); - if (!mListeners.contains(receiver)) { - try { - if (receiver.isListener()) { - receiver.getListener().asBinder().linkToDeath(receiver, 0); - } - mListeners.add(receiver); - } catch (RemoteException e) { - return; - } - } - - HashMap records = mLocationListeners.get(receiver); - if (records == null) { - records = new HashMap(); - mLocationListeners.put(receiver, records); - } - UpdateRecord oldRecord = records.put(provider, r); + UpdateRecord r = new UpdateRecord(provider, minTime, minDistance, receiver, callingUid); + UpdateRecord oldRecord = receiver.mUpdateRecords.put(provider, r); if (oldRecord != null) { oldRecord.disposeLocked(); } + if (newUid) { + impl.addListener(callingUid); + } + boolean isProviderEnabled = isAllowedBySettingsLocked(provider); if (isProviderEnabled) { long minTimeForProvider = getMinTimeLocked(provider); impl.setMinTime(minTimeForProvider); impl.enableLocationTracking(true); updateWakelockStatusLocked(mScreenOn); - - if (provider.equals(LocationManager.GPS_PROVIDER)) { - if (mGpsNavigating) { - updateReportedGpsLocked(); - } - } } else { try { // Notify the listener that updates are currently disabled @@ -1028,8 +1018,8 @@ public class LocationManagerService extends ILocationManager.Stub { public void removeUpdates(ILocationListener listener) { try { - synchronized (mLocationListeners) { - removeUpdatesLocked(new Receiver(listener, Binder.getCallingUid())); + synchronized (mLock) { + removeUpdatesLocked(getReceiver(listener)); } } catch (SecurityException se) { throw se; @@ -1040,8 +1030,8 @@ public class LocationManagerService extends ILocationManager.Stub { public void removeUpdatesPI(PendingIntent intent) { try { - synchronized (mLocationListeners) { - removeUpdatesLocked(new Receiver(intent, Binder.getCallingUid())); + synchronized (mLock) { + removeUpdatesLocked(getReceiver(intent)); } } catch (SecurityException se) { throw se; @@ -1059,23 +1049,21 @@ public class LocationManagerService extends ILocationManager.Stub { final int callingUid = Binder.getCallingUid(); long identity = Binder.clearCallingIdentity(); try { - int idx = mListeners.indexOf(receiver); - if (idx >= 0) { - Receiver myReceiver = mListeners.remove(idx); - if (myReceiver.isListener()) { - myReceiver.getListener().asBinder().unlinkToDeath(myReceiver, 0); - } + if (mReceivers.remove(receiver.mKey) != null && receiver.isListener()) { + receiver.getListener().asBinder().unlinkToDeath(receiver, 0); } // Record which providers were associated with this listener HashSet providers = new HashSet(); - HashMap oldRecords = mLocationListeners.get(receiver); + HashMap oldRecords = receiver.mUpdateRecords; if (oldRecords != null) { // Call dispose() on the obsolete update records. for (UpdateRecord record : oldRecords.values()) { - if (record.mProvider.equals(LocationManager.NETWORK_PROVIDER)) { - if (mNetworkLocationProvider != null) { - mNetworkLocationProvider.removeListener(record.mPackages); + if (!providerHasListener(record.mProvider, callingUid, receiver)) { + LocationProviderImpl impl = + LocationProviderImpl.getProvider(record.mProvider); + if (impl != null) { + impl.removeListener(callingUid); } } record.disposeLocked(); @@ -1083,10 +1071,6 @@ public class LocationManagerService extends ILocationManager.Stub { // Accumulate providers providers.addAll(oldRecords.keySet()); } - - mLocationListeners.remove(receiver); - mLastFixBroadcast.remove(receiver); - mLastStatusBroadcast.remove(receiver); // See if the providers associated with this listener have any // other listeners; if one does, inform it of the new smallest minTime @@ -1110,10 +1094,6 @@ public class LocationManagerService extends ILocationManager.Stub { } else { p.enableLocationTracking(false); } - - if (p == mGpsLocationProvider && mGpsNavigating) { - updateReportedGpsLocked(); - } } } @@ -1142,7 +1122,7 @@ public class LocationManagerService extends ILocationManager.Stub { } public void removeGpsStatusListener(IGpsStatusListener listener) { - synchronized (mLocationListeners) { + synchronized (mLock) { mGpsLocationProvider.removeGpsStatusListener(listener); } } @@ -1156,7 +1136,7 @@ public class LocationManagerService extends ILocationManager.Stub { throw new SecurityException("Requires ACCESS_LOCATION_EXTRA_COMMANDS permission"); } - synchronized (mLocationListeners) { + synchronized (mLock) { LocationProviderImpl impl = LocationProviderImpl.getProvider(provider); if (provider == null) { return false; @@ -1337,7 +1317,7 @@ public class LocationManagerService extends ILocationManager.Stub { public void addProximityAlert(double latitude, double longitude, float radius, long expiration, PendingIntent intent) { try { - synchronized (mLocationListeners) { + synchronized (mLock) { addProximityAlertLocked(latitude, longitude, radius, expiration, intent); } } catch (SecurityException se) { @@ -1370,7 +1350,7 @@ public class LocationManagerService extends ILocationManager.Stub { mProximityAlerts.put(intent, alert); if (mProximityListener == null) { - mProximityListener = new Receiver(new ProximityListener(), -1); + mProximityListener = new Receiver(new ProximityListener()); LocationProvider provider = LocationProviderImpl.getProvider( LocationManager.GPS_PROVIDER); @@ -1383,14 +1363,12 @@ public class LocationManagerService extends ILocationManager.Stub { if (provider != null) { requestLocationUpdatesLocked(provider.getName(), 1000L, 1.0f, mProximityListener); } - } else if (mGpsNavigating) { - updateReportedGpsLocked(); } } public void removeProximityAlert(PendingIntent intent) { try { - synchronized (mLocationListeners) { + synchronized (mLock) { removeProximityAlertLocked(intent); } } catch (SecurityException se) { @@ -1409,8 +1387,6 @@ public class LocationManagerService extends ILocationManager.Stub { if (mProximityAlerts.size() == 0) { removeUpdatesLocked(mProximityListener); mProximityListener = null; - } else if (mGpsNavigating) { - updateReportedGpsLocked(); } } @@ -1421,7 +1397,7 @@ public class LocationManagerService extends ILocationManager.Stub { */ public Bundle getProviderInfo(String provider) { try { - synchronized (mLocationListeners) { + synchronized (mLock) { return _getProviderInfoLocked(provider); } } catch (SecurityException se) { @@ -1456,7 +1432,7 @@ public class LocationManagerService extends ILocationManager.Stub { public boolean isProviderEnabled(String provider) { try { - synchronized (mLocationListeners) { + synchronized (mLock) { return _isProviderEnabledLocked(provider); } } catch (SecurityException se) { @@ -1485,7 +1461,7 @@ public class LocationManagerService extends ILocationManager.Stub { public Location getLastKnownLocation(String provider) { try { - synchronized (mLocationListeners) { + synchronized (mLock) { return _getLastKnownLocationLocked(provider); } } catch (SecurityException se) { @@ -1585,16 +1561,11 @@ public class LocationManagerService extends ILocationManager.Stub { UpdateRecord r = records.get(i); Receiver receiver = r.mReceiver; - HashMap map = mLastFixBroadcast.get(receiver); - if (map == null) { - map = new HashMap(); - mLastFixBroadcast.put(receiver, map); - } - Location lastLoc = map.get(provider); + Location lastLoc = r.mLastFixBroadcast; if ((lastLoc == null) || shouldBroadcastSafe(location, lastLoc, r)) { if (lastLoc == null) { lastLoc = new Location(location); - map.put(provider, lastLoc); + r.mLastFixBroadcast = lastLoc; } else { lastLoc.set(location); } @@ -1607,19 +1578,11 @@ public class LocationManagerService extends ILocationManager.Stub { } } - // Broadcast status message - HashMap statusMap = mLastStatusBroadcast.get(receiver); - if (statusMap == null) { - statusMap = new HashMap(); - mLastStatusBroadcast.put(receiver, statusMap); - } - long prevStatusUpdateTime = - (statusMap.get(provider) != null) ? statusMap.get(provider) : 0; - + long prevStatusUpdateTime = r.mLastStatusBroadcast; if ((newStatusUpdateTime > prevStatusUpdateTime) && (prevStatusUpdateTime != 0 || status != LocationProvider.AVAILABLE)) { - statusMap.put(provider, newStatusUpdateTime); + r.mLastStatusBroadcast = newStatusUpdateTime; if (!receiver.callStatusChangedLocked(provider, status, extras)) { Log.w(TAG, "RemoteException calling onStatusChanged on " + receiver); if (deadReceivers == null) { @@ -1647,7 +1610,7 @@ public class LocationManagerService extends ILocationManager.Stub { if (msg.what == MESSAGE_LOCATION_CHANGED) { // log("LocationWorkerHandler: MESSAGE_LOCATION_CHANGED!"); - synchronized (mLocationListeners) { + synchronized (mLock) { Location location = (Location) msg.obj; String provider = location.getProvider(); if (!isAllowedBySettingsLocked(provider)) { @@ -1685,14 +1648,14 @@ public class LocationManagerService extends ILocationManager.Stub { } else if (msg.what == MESSAGE_ACQUIRE_WAKE_LOCK) { log("LocationWorkerHandler: Acquire"); - synchronized (mLocationListeners) { + synchronized (mLock) { acquireWakeLockLocked(); } } else if (msg.what == MESSAGE_RELEASE_WAKE_LOCK) { log("LocationWorkerHandler: Release"); // Update wakelock status so the next alarm is set before releasing wakelock - synchronized (mLocationListeners) { + synchronized (mLock) { updateWakelockStatusLocked(mScreenOn); releaseWakeLockLocked(); } @@ -1709,7 +1672,7 @@ public class LocationManagerService extends ILocationManager.Stub { String action = intent.getAction(); if (action.equals(ALARM_INTENT)) { - synchronized (mLocationListeners) { + synchronized (mLock) { log("PowerStateBroadcastReceiver: Alarm received"); mLocationHandler.removeMessages(MESSAGE_ACQUIRE_WAKE_LOCK); // Have to do this immediately, rather than posting a @@ -1721,18 +1684,18 @@ public class LocationManagerService extends ILocationManager.Stub { } else if (action.equals(Intent.ACTION_SCREEN_OFF)) { log("PowerStateBroadcastReceiver: Screen off"); - synchronized (mLocationListeners) { + synchronized (mLock) { updateWakelockStatusLocked(false); } } else if (action.equals(Intent.ACTION_SCREEN_ON)) { log("PowerStateBroadcastReceiver: Screen on"); - synchronized (mLocationListeners) { + synchronized (mLock) { updateWakelockStatusLocked(true); } } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED) || action.equals(Intent.ACTION_PACKAGE_RESTARTED)) { - synchronized (mLocationListeners) { + synchronized (mLock) { int uid = intent.getIntExtra(Intent.EXTRA_UID, -1); if (uid >= 0) { ArrayList removedRecs = null; @@ -1790,7 +1753,7 @@ public class LocationManagerService extends ILocationManager.Stub { } // Notify location providers of current network state - synchronized (mLocationListeners) { + synchronized (mLock) { List providers = LocationProviderImpl.getProviders(); for (LocationProviderImpl provider : providers) { if (provider.requiresNetwork()) { @@ -1803,12 +1766,10 @@ public class LocationManagerService extends ILocationManager.Stub { final boolean enabled = intent.getBooleanExtra(GpsLocationProvider.EXTRA_ENABLED, false); - synchronized (mLocationListeners) { + synchronized (mLock) { if (enabled) { - updateReportedGpsLocked(); mGpsNavigating = true; } else { - reportStopGpsLocked(); mGpsNavigating = false; // When GPS is disabled, we are OK to release wake-lock mWakeLockGpsReceived = true; @@ -1941,85 +1902,6 @@ public class LocationManagerService extends ILocationManager.Stub { } } - private boolean reportGpsUidLocked(int curSeq, int nextSeq, int uid) { - int seq = mReportedGpsUids.get(uid, -1); - if (seq == curSeq) { - // Already reported; propagate to next sequence. - mReportedGpsUids.put(uid, nextSeq); - return true; - } else if (seq != nextSeq) { - try { - // New UID; report it. - mBatteryStats.noteStartGps(uid); - mReportedGpsUids.put(uid, nextSeq); - return true; - } catch (RemoteException e) { - } - } - return false; - } - - private void updateReportedGpsLocked() { - if (mGpsLocationProvider == null) { - return; - } - - final String name = mGpsLocationProvider.getName(); - final int curSeq = mReportedGpsSeq; - final int nextSeq = (curSeq+1) >= 0 ? (curSeq+1) : 0; - mReportedGpsSeq = nextSeq; - - ArrayList urs = mRecordsByProvider.get(name); - int num = 0; - final int N = urs.size(); - for (int i=0; i=0; i--) { - if (mReportedGpsUids.valueAt(i) != nextSeq) { - try { - mBatteryStats.noteStopGps(mReportedGpsUids.keyAt(i)); - } catch (RemoteException e) { - } - mReportedGpsUids.removeAt(i); - } - } - } - } - - private void reportStopGpsLocked() { - int curSeq = mReportedGpsSeq; - for (int i=mReportedGpsUids.size()-1; i>=0; i--) { - if (mReportedGpsUids.valueAt(i) == curSeq) { - try { - mBatteryStats.noteStopGps(mReportedGpsUids.keyAt(i)); - } catch (RemoteException e) { - } - } - } - curSeq++; - if (curSeq < 0) curSeq = 0; - mReportedGpsSeq = curSeq; - mReportedGpsUids.clear(); - } - private void startGpsLocked() { boolean gpsActive = (mGpsLocationProvider != null) && mGpsLocationProvider.isLocationTracking(); @@ -2135,7 +2017,7 @@ public class LocationManagerService extends ILocationManager.Stub { boolean supportsSpeed, boolean supportsBearing, int powerRequirement, int accuracy) { checkMockPermissionsSafe(); - synchronized (mLocationListeners) { + synchronized (mLock) { MockProvider provider = new MockProvider(name, this, requiresNetwork, requiresSatellite, requiresCell, hasMonetaryCost, supportsAltitude, @@ -2151,7 +2033,7 @@ public class LocationManagerService extends ILocationManager.Stub { public void removeTestProvider(String provider) { checkMockPermissionsSafe(); - synchronized (mLocationListeners) { + synchronized (mLock) { MockProvider mockProvider = mMockProviders.get(provider); if (mockProvider == null) { throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); @@ -2164,7 +2046,7 @@ public class LocationManagerService extends ILocationManager.Stub { public void setTestProviderLocation(String provider, Location loc) { checkMockPermissionsSafe(); - synchronized (mLocationListeners) { + synchronized (mLock) { MockProvider mockProvider = mMockProviders.get(provider); if (mockProvider == null) { throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); @@ -2175,7 +2057,7 @@ public class LocationManagerService extends ILocationManager.Stub { public void clearTestProviderLocation(String provider) { checkMockPermissionsSafe(); - synchronized (mLocationListeners) { + synchronized (mLock) { MockProvider mockProvider = mMockProviders.get(provider); if (mockProvider == null) { throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); @@ -2186,7 +2068,7 @@ public class LocationManagerService extends ILocationManager.Stub { public void setTestProviderEnabled(String provider, boolean enabled) { checkMockPermissionsSafe(); - synchronized (mLocationListeners) { + synchronized (mLock) { MockProvider mockProvider = mMockProviders.get(provider); if (mockProvider == null) { throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); @@ -2206,7 +2088,7 @@ public class LocationManagerService extends ILocationManager.Stub { public void clearTestProviderEnabled(String provider) { checkMockPermissionsSafe(); - synchronized (mLocationListeners) { + synchronized (mLock) { MockProvider mockProvider = mMockProviders.get(provider); if (mockProvider == null) { throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); @@ -2219,7 +2101,7 @@ public class LocationManagerService extends ILocationManager.Stub { public void setTestProviderStatus(String provider, int status, Bundle extras, long updateTime) { checkMockPermissionsSafe(); - synchronized (mLocationListeners) { + synchronized (mLock) { MockProvider mockProvider = mMockProviders.get(provider); if (mockProvider == null) { throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); @@ -2230,7 +2112,7 @@ public class LocationManagerService extends ILocationManager.Stub { public void clearTestProviderStatus(String provider) { checkMockPermissionsSafe(); - synchronized (mLocationListeners) { + synchronized (mLock) { MockProvider mockProvider = mMockProviders.get(provider); if (mockProvider == null) { throw new IllegalArgumentException("Provider \"" + provider + "\" unknown"); @@ -2254,7 +2136,7 @@ public class LocationManagerService extends ILocationManager.Stub { return; } - synchronized (mLocationListeners) { + synchronized (mLock) { pw.println("Current Location Manager state:"); pw.println(" sProvidersLoaded=" + sProvidersLoaded); pw.println(" mGpsLocationProvider=" + mGpsLocationProvider); @@ -2269,37 +2151,18 @@ public class LocationManagerService extends ILocationManager.Stub { pw.println(" mWifiWakeLockAcquired=" + mWifiWakeLockAcquired + " mCellWakeLockAcquired=" + mCellWakeLockAcquired); pw.println(" Listeners:"); - int N = mListeners.size(); + int N = mReceivers.size(); for (int i=0; i> i - : mLocationListeners.entrySet()) { - pw.println(" " + i.getKey() + ":"); - for (Map.Entry j : i.getValue().entrySet()) { + for (Receiver i : mReceivers.values()) { + pw.println(" " + i + ":"); + for (Map.Entry j : i.mUpdateRecords.entrySet()) { pw.println(" " + j.getKey() + ":"); j.getValue().dump(pw, " "); } } - pw.println(" Last Fix Broadcasts:"); - for (Map.Entry> i - : mLastFixBroadcast.entrySet()) { - pw.println(" " + i.getKey() + ":"); - for (Map.Entry j : i.getValue().entrySet()) { - pw.println(" " + j.getKey() + ":"); - j.getValue().dump(new PrintWriterPrinter(pw), " "); - } - } - pw.println(" Last Status Broadcasts:"); - for (Map.Entry> i - : mLastStatusBroadcast.entrySet()) { - pw.println(" " + i.getKey() + ":"); - for (Map.Entry j : i.getValue().entrySet()) { - pw.println(" " + j.getKey() + " -> 0x" - + Long.toHexString(j.getValue())); - } - } pw.println(" Records by Provider:"); for (Map.Entry> i : mRecordsByProvider.entrySet()) { @@ -2351,12 +2214,6 @@ public class LocationManagerService extends ILocationManager.Stub { i.getValue().dump(pw, " "); } } - pw.println(" Reported GPS UIDs @ seq " + mReportedGpsSeq + ":"); - N = mReportedGpsUids.size(); - for (int i=0; i