Merge "Adding Location Request History Foreground Tracking" into pi-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
a2b4cc9ea0
@@ -424,7 +424,7 @@ public class LocationManagerService extends ILocationManager.Stub {
|
||||
Log.d(TAG, "request from uid " + uid + " is now "
|
||||
+ (foreground ? "foreground" : "background)"));
|
||||
}
|
||||
record.mIsForegroundUid = foreground;
|
||||
record.updateForeground(foreground);
|
||||
|
||||
if (!isThrottlingExemptLocked(record.mReceiver.mIdentity)) {
|
||||
affectedProviders.add(provider);
|
||||
@@ -1905,7 +1905,17 @@ public class LocationManagerService extends ILocationManager.Stub {
|
||||
|
||||
// Update statistics for historical location requests by package/provider
|
||||
mRequestStatistics.startRequesting(
|
||||
mReceiver.mIdentity.mPackageName, provider, request.getInterval());
|
||||
mReceiver.mIdentity.mPackageName, provider, request.getInterval(),
|
||||
mIsForegroundUid);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to be called when record changes foreground/background
|
||||
*/
|
||||
void updateForeground(boolean isForeground){
|
||||
mIsForegroundUid = isForeground;
|
||||
mRequestStatistics.updateForeground(
|
||||
mReceiver.mIdentity.mPackageName, mProvider, isForeground);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -24,7 +24,8 @@ public class LocationRequestStatistics {
|
||||
* @param providerName Name of provider that is requested (e.g. "gps").
|
||||
* @param intervalMs The interval that is requested in ms.
|
||||
*/
|
||||
public void startRequesting(String packageName, String providerName, long intervalMs) {
|
||||
public void startRequesting(String packageName, String providerName, long intervalMs,
|
||||
boolean isForeground) {
|
||||
PackageProviderKey key = new PackageProviderKey(packageName, providerName);
|
||||
PackageStatistics stats = statistics.get(key);
|
||||
if (stats == null) {
|
||||
@@ -32,6 +33,7 @@ public class LocationRequestStatistics {
|
||||
statistics.put(key, stats);
|
||||
}
|
||||
stats.startRequesting(intervalMs);
|
||||
stats.updateForeground(isForeground);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -45,9 +47,20 @@ public class LocationRequestStatistics {
|
||||
PackageStatistics stats = statistics.get(key);
|
||||
if (stats != null) {
|
||||
stats.stopRequesting();
|
||||
} else {
|
||||
// This shouldn't be a possible code path.
|
||||
Log.e(TAG, "Couldn't find package statistics when removing location request.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Signals that a package possibly switched background/foreground.
|
||||
*
|
||||
* @param packageName Name of package that has stopped requesting locations.
|
||||
* @param providerName Provider that is no longer being requested.
|
||||
*/
|
||||
public void updateForeground(String packageName, String providerName, boolean isForeground) {
|
||||
PackageProviderKey key = new PackageProviderKey(packageName, providerName);
|
||||
PackageStatistics stats = statistics.get(key);
|
||||
if (stats != null) {
|
||||
stats.updateForeground(isForeground);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -103,12 +116,21 @@ public class LocationRequestStatistics {
|
||||
// The total time this app has requested location (not including currently running requests).
|
||||
private long mTotalDurationMs;
|
||||
|
||||
// Time when this package most recently went to foreground, requesting location. 0 means
|
||||
// not currently in foreground.
|
||||
private long mLastForegroundElapsedTimeMs;
|
||||
// The time this app has requested location (not including currently running requests), while
|
||||
// in foreground.
|
||||
private long mForegroundDurationMs;
|
||||
|
||||
private PackageStatistics() {
|
||||
mInitialElapsedTimeMs = SystemClock.elapsedRealtime();
|
||||
mNumActiveRequests = 0;
|
||||
mTotalDurationMs = 0;
|
||||
mFastestIntervalMs = Long.MAX_VALUE;
|
||||
mSlowestIntervalMs = 0;
|
||||
mForegroundDurationMs = 0;
|
||||
mLastForegroundElapsedTimeMs = 0;
|
||||
}
|
||||
|
||||
private void startRequesting(long intervalMs) {
|
||||
@@ -127,6 +149,15 @@ public class LocationRequestStatistics {
|
||||
mNumActiveRequests++;
|
||||
}
|
||||
|
||||
private void updateForeground(boolean isForeground) {
|
||||
long nowElapsedTimeMs = SystemClock.elapsedRealtime();
|
||||
// if previous interval was foreground, accumulate before resetting start
|
||||
if (mLastForegroundElapsedTimeMs != 0) {
|
||||
mForegroundDurationMs += (nowElapsedTimeMs - mLastForegroundElapsedTimeMs);
|
||||
}
|
||||
mLastForegroundElapsedTimeMs = isForeground ? nowElapsedTimeMs : 0;
|
||||
}
|
||||
|
||||
private void stopRequesting() {
|
||||
if (mNumActiveRequests <= 0) {
|
||||
// Shouldn't be a possible code path
|
||||
@@ -139,6 +170,7 @@ public class LocationRequestStatistics {
|
||||
long lastDurationMs
|
||||
= SystemClock.elapsedRealtime() - mLastActivitationElapsedTimeMs;
|
||||
mTotalDurationMs += lastDurationMs;
|
||||
updateForeground(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,6 +186,18 @@ public class LocationRequestStatistics {
|
||||
return currentDurationMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the duration that this request has been active.
|
||||
*/
|
||||
public long getForegroundDurationMs() {
|
||||
long currentDurationMs = mForegroundDurationMs;
|
||||
if (mLastForegroundElapsedTimeMs != 0 ) {
|
||||
currentDurationMs
|
||||
+= SystemClock.elapsedRealtime() - mLastForegroundElapsedTimeMs;
|
||||
}
|
||||
return currentDurationMs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the time since the initial request in ms.
|
||||
*/
|
||||
@@ -193,7 +237,9 @@ public class LocationRequestStatistics {
|
||||
}
|
||||
s.append(": Duration requested ")
|
||||
.append((getDurationMs() / 1000) / 60)
|
||||
.append(" out of the last ")
|
||||
.append(" total, ")
|
||||
.append((getForegroundDurationMs() / 1000) / 60)
|
||||
.append(" foreground, out of the last ")
|
||||
.append((getTimeSinceFirstRequestMs() / 1000) / 60)
|
||||
.append(" minutes");
|
||||
if (isActive()) {
|
||||
|
||||
@@ -30,7 +30,7 @@ public class LocationRequestStatisticsTest extends AndroidTestCase {
|
||||
* Tests that adding a single package works correctly.
|
||||
*/
|
||||
public void testSinglePackage() {
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true);
|
||||
|
||||
assertEquals(1, mStatistics.statistics.size());
|
||||
PackageProviderKey key = mStatistics.statistics.keySet().iterator().next();
|
||||
@@ -47,9 +47,9 @@ public class LocationRequestStatisticsTest extends AndroidTestCase {
|
||||
* Tests that adding a single package works correctly when it is stopped and restarted.
|
||||
*/
|
||||
public void testSinglePackage_stopAndRestart() {
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true);
|
||||
mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true);
|
||||
|
||||
assertEquals(1, mStatistics.statistics.size());
|
||||
PackageProviderKey key = mStatistics.statistics.keySet().iterator().next();
|
||||
@@ -69,8 +69,8 @@ public class LocationRequestStatisticsTest extends AndroidTestCase {
|
||||
* Tests that adding a single package works correctly when multiple intervals are used.
|
||||
*/
|
||||
public void testSinglePackage_multipleIntervals() {
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL2);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL2, true);
|
||||
|
||||
assertEquals(1, mStatistics.statistics.size());
|
||||
PackageProviderKey key = mStatistics.statistics.keySet().iterator().next();
|
||||
@@ -91,8 +91,8 @@ public class LocationRequestStatisticsTest extends AndroidTestCase {
|
||||
* Tests that adding a single package works correctly when multiple providers are used.
|
||||
*/
|
||||
public void testSinglePackage_multipleProviders() {
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL2);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL2, true);
|
||||
|
||||
assertEquals(2, mStatistics.statistics.size());
|
||||
PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, PROVIDER1);
|
||||
@@ -120,10 +120,10 @@ public class LocationRequestStatisticsTest extends AndroidTestCase {
|
||||
* Tests that adding multiple packages works correctly.
|
||||
*/
|
||||
public void testMultiplePackages() {
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL1);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL2);
|
||||
mStatistics.startRequesting(PACKAGE2, PROVIDER1, INTERVAL1);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL1, true);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL2, true);
|
||||
mStatistics.startRequesting(PACKAGE2, PROVIDER1, INTERVAL1, true);
|
||||
|
||||
assertEquals(3, mStatistics.statistics.size());
|
||||
PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, PROVIDER1);
|
||||
@@ -165,11 +165,33 @@ public class LocationRequestStatisticsTest extends AndroidTestCase {
|
||||
assertFalse(stats3.isActive());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that switching foreground & background states accmulates time reasonably.
|
||||
*/
|
||||
public void testForegroundBackground() {
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true);
|
||||
mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL1, true);
|
||||
mStatistics.startRequesting(PACKAGE2, PROVIDER1, INTERVAL1, false);
|
||||
|
||||
mStatistics.updateForeground(PACKAGE1, PROVIDER2, false);
|
||||
mStatistics.updateForeground(PACKAGE2, PROVIDER1, true);
|
||||
|
||||
mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
|
||||
|
||||
for (PackageStatistics stats : mStatistics.statistics.values()) {
|
||||
verifyStatisticsTimes(stats);
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyStatisticsTimes(PackageStatistics stats) {
|
||||
long durationMs = stats.getDurationMs();
|
||||
long foregroundDurationMs = stats.getForegroundDurationMs();
|
||||
long timeSinceFirstRequestMs = stats.getTimeSinceFirstRequestMs();
|
||||
long maxDeltaMs = SystemClock.elapsedRealtime() - mStartElapsedRealtimeMs;
|
||||
assertTrue("Duration is too small", durationMs >= 0);
|
||||
assertTrue("Duration is too large", durationMs <= maxDeltaMs);
|
||||
assertTrue("Foreground Duration is too small", foregroundDurationMs >= 0);
|
||||
assertTrue("Foreground Duration is too large", foregroundDurationMs <= maxDeltaMs);
|
||||
assertTrue("Time since first request is too large", timeSinceFirstRequestMs <= maxDeltaMs);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user