diff options
author | Android (Google) Code Review <android-gerrit@google.com> | 2009-04-17 14:05:57 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2009-04-17 14:05:57 -0700 |
commit | 27c6109aa89a10f080d0595b1ceecb3e0c4732ea (patch) | |
tree | fd4b604e4bd4b2fb594ffc0c188b928618d6b796 | |
parent | 6440e8145441a45960a1131a9d79babd16cf8448 (diff) | |
parent | 2f82c4eb0b4d315481ad79725ad6f52c5ec69685 (diff) | |
download | frameworks_base-27c6109aa89a10f080d0595b1ceecb3e0c4732ea.zip frameworks_base-27c6109aa89a10f080d0595b1ceecb3e0c4732ea.tar.gz frameworks_base-27c6109aa89a10f080d0595b1ceecb3e0c4732ea.tar.bz2 |
Merge change 263 into donut
* changes:
location: Generalize support for location provider usage tracking.
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<Receiver> mListeners = new ArrayList<Receiver>(); - - /** - * 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<Receiver,HashMap<String,UpdateRecord>> mLocationListeners = - new HashMap<Receiver,HashMap<String,UpdateRecord>>(); + private final HashMap<Object, Receiver> mReceivers = new HashMap<Object, Receiver>(); /** - * Mapping from listener IBinder/PendingIntent to a map from provider name to last broadcast - * location. + * Object used internally for synchronization */ - private final HashMap<Receiver,HashMap<String,Location>> mLastFixBroadcast = - new HashMap<Receiver,HashMap<String,Location>>(); - private final HashMap<Receiver,HashMap<String,Long>> mLastStatusBroadcast = - new HashMap<Receiver,HashMap<String,Long>>(); + 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<String,UpdateRecord> mUpdateRecords = new HashMap<String,UpdateRecord>(); - 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<String> getAllProviders() { try { - synchronized (mLocationListeners) { + synchronized (mLock) { return _getAllProvidersLocked(); } } catch (SecurityException se) { @@ -733,7 +701,7 @@ public class LocationManagerService extends ILocationManager.Stub { public List<String> 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<UpdateRecord> 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<mPackages.length; i++) { - if (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<UpdateRecord> 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<String,UpdateRecord> records = mLocationListeners.get(receiver); - if (records == null) { - records = new HashMap<String,UpdateRecord>(); - 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<String> providers = new HashSet<String>(); - HashMap<String,UpdateRecord> oldRecords = mLocationListeners.get(receiver); + HashMap<String,UpdateRecord> 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<String,Location> map = mLastFixBroadcast.get(receiver); - if (map == null) { - map = new HashMap<String,Location>(); - 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<String,Long> statusMap = mLastStatusBroadcast.get(receiver); - if (statusMap == null) { - statusMap = new HashMap<String,Long>(); - 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<Receiver> removedRecs = null; @@ -1790,7 +1753,7 @@ public class LocationManagerService extends ILocationManager.Stub { } // Notify location providers of current network state - synchronized (mLocationListeners) { + synchronized (mLock) { List<LocationProviderImpl> 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<UpdateRecord> urs = mRecordsByProvider.get(name); - int num = 0; - final int N = urs.size(); - for (int i=0; i<N; i++) { - UpdateRecord ur = urs.get(i); - if (ur.mReceiver == mProximityListener) { - // We don't want the system to take the blame for this one. - continue; - } - if (reportGpsUidLocked(curSeq, nextSeq, ur.mUid)) { - num++; - } - } - - for (ProximityAlert pe : mProximityAlerts.values()) { - if (reportGpsUidLocked(curSeq, nextSeq, pe.mUid)) { - num++; - } - } - - if (num != mReportedGpsUids.size()) { - // The number of uids is processed is different than the - // array; report any that are no longer active. - for (int i=mReportedGpsUids.size()-1; 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<N; i++) { - pw.println(" " + mListeners.get(i)); + pw.println(" " + mReceivers.get(i)); } pw.println(" Location Listeners:"); - for (Map.Entry<Receiver, HashMap<String,UpdateRecord>> i - : mLocationListeners.entrySet()) { - pw.println(" " + i.getKey() + ":"); - for (Map.Entry<String,UpdateRecord> j : i.getValue().entrySet()) { + for (Receiver i : mReceivers.values()) { + pw.println(" " + i + ":"); + for (Map.Entry<String,UpdateRecord> j : i.mUpdateRecords.entrySet()) { pw.println(" " + j.getKey() + ":"); j.getValue().dump(pw, " "); } } - pw.println(" Last Fix Broadcasts:"); - for (Map.Entry<Receiver, HashMap<String,Location>> i - : mLastFixBroadcast.entrySet()) { - pw.println(" " + i.getKey() + ":"); - for (Map.Entry<String,Location> j : i.getValue().entrySet()) { - pw.println(" " + j.getKey() + ":"); - j.getValue().dump(new PrintWriterPrinter(pw), " "); - } - } - pw.println(" Last Status Broadcasts:"); - for (Map.Entry<Receiver, HashMap<String,Long>> i - : mLastStatusBroadcast.entrySet()) { - pw.println(" " + i.getKey() + ":"); - for (Map.Entry<String,Long> j : i.getValue().entrySet()) { - pw.println(" " + j.getKey() + " -> 0x" - + Long.toHexString(j.getValue())); - } - } pw.println(" Records by Provider:"); for (Map.Entry<String, ArrayList<UpdateRecord>> 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<N; i++) { - pw.println(" UID " + mReportedGpsUids.keyAt(i) - + " seq=" + mReportedGpsUids.valueAt(i)); - } } } } |