summaryrefslogtreecommitdiffstats
path: root/services/java/com/android/server/LocationManagerService.java
diff options
context:
space:
mode:
authorDianne Hackborn <hackbod@google.com>2010-09-10 18:43:00 -0700
committerDianne Hackborn <hackbod@google.com>2010-09-13 14:20:48 -0700
commit7e9f4eb2608148436cef36c9969bf8a599b39e72 (patch)
tree16351bff3017f948792a6308f4f6698e0a9d769c /services/java/com/android/server/LocationManagerService.java
parentcc5494c9996f809e36539b24e8b6b67683383d29 (diff)
downloadframeworks_base-7e9f4eb2608148436cef36c9969bf8a599b39e72.zip
frameworks_base-7e9f4eb2608148436cef36c9969bf8a599b39e72.tar.gz
frameworks_base-7e9f4eb2608148436cef36c9969bf8a599b39e72.tar.bz2
Track client requests through location manager.
This fixes a problem where applications could ask the location manager to do very heavy-weight things (like... say... update location every minute), which would get accounted against the system instead of the application because ultimately it is the system making the heavy calls (wake locks, etc). To solve this, we introduce a new class WorkSource representing the source of some work. Wake locks and Wifi locks allow you to set the source to use (but only if you are system code and thus can get the permission to do so), which is what will be reported to the battery stats until the actual caller. For the initial implementation, the location manager keeps track of all clients requesting periodic updates, and tells its providers about them as a WorkSource param when setting their min update time. The network location provider uses this to set the source on the wake and wifi locks it acquires, when doing work because of the update period. This should also be used elsewhere, such as in the GPS provider, but this is a good start. Change-Id: I2b6ffafad9e90ecf15d7c502e2db675fd52ae3cf
Diffstat (limited to 'services/java/com/android/server/LocationManagerService.java')
-rw-r--r--services/java/com/android/server/LocationManagerService.java27
1 files changed, 23 insertions, 4 deletions
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index a38970f..f3ce8ba 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -52,6 +52,7 @@ import android.os.Message;
import android.os.PowerManager;
import android.os.Process;
import android.os.RemoteException;
+import android.os.WorkSource;
import android.provider.Settings;
import android.util.Log;
import android.util.Slog;
@@ -157,6 +158,12 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private final HashMap<String,ArrayList<UpdateRecord>> mRecordsByProvider =
new HashMap<String,ArrayList<UpdateRecord>>();
+ /**
+ * Temporary filled in when computing min time for a provider. Access is
+ * protected by global lock mLock.
+ */
+ private final WorkSource mTmpWorkSource = new WorkSource();
+
// Proximity listeners
private Receiver mProximityReceiver = null;
private ILocationListener mProximityListener = null;
@@ -912,7 +919,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
if (enabled) {
p.enable();
if (listeners > 0) {
- p.setMinTime(getMinTimeLocked(provider));
+ p.setMinTime(getMinTimeLocked(provider), mTmpWorkSource);
p.enableLocationTracking(true);
}
} else {
@@ -924,9 +931,21 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private long getMinTimeLocked(String provider) {
long minTime = Long.MAX_VALUE;
ArrayList<UpdateRecord> records = mRecordsByProvider.get(provider);
+ mTmpWorkSource.clear();
if (records != null) {
for (int i=records.size()-1; i>=0; i--) {
- minTime = Math.min(minTime, records.get(i).mMinTime);
+ UpdateRecord ur = records.get(i);
+ long curTime = ur.mMinTime;
+ if (curTime < minTime) {
+ minTime = curTime;
+ }
+ }
+ long inclTime = (minTime*3)/2;
+ for (int i=records.size()-1; i>=0; i--) {
+ UpdateRecord ur = records.get(i);
+ if (ur.mMinTime <= inclTime) {
+ mTmpWorkSource.add(ur.mUid);
+ }
}
}
return minTime;
@@ -1124,7 +1143,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
boolean isProviderEnabled = isAllowedBySettingsLocked(provider);
if (isProviderEnabled) {
long minTimeForProvider = getMinTimeLocked(provider);
- p.setMinTime(minTimeForProvider);
+ p.setMinTime(minTimeForProvider, mTmpWorkSource);
// try requesting single shot if singleShot is true, and fall back to
// regular location tracking if requestSingleShotFix() is not supported
if (!singleShot || !p.requestSingleShotFix()) {
@@ -1222,7 +1241,7 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
LocationProviderInterface p = mProvidersByName.get(provider);
if (p != null) {
if (hasOtherListener) {
- p.setMinTime(getMinTimeLocked(provider));
+ p.setMinTime(getMinTimeLocked(provider), mTmpWorkSource);
} else {
p.enableLocationTracking(false);
}