Merge "Adding Location Request History Foreground Tracking" into pi-dev

This commit is contained in:
TreeHugger Robot
2018-04-18 02:33:36 +00:00
committed by Android (Google) Code Review
3 changed files with 96 additions and 18 deletions

View File

@@ -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);
}
/**

View File

@@ -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()) {

View File

@@ -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);
}
}