Merge "Log history of location requests in LocationManager. -Assists with debugging power issues. Bug: 12824233"
This commit is contained in:
committed by
Android (Google) Code Review
commit
d63b4314b8
@@ -73,6 +73,9 @@ import com.android.server.location.LocationBlacklist;
|
|||||||
import com.android.server.location.LocationFudger;
|
import com.android.server.location.LocationFudger;
|
||||||
import com.android.server.location.LocationProviderInterface;
|
import com.android.server.location.LocationProviderInterface;
|
||||||
import com.android.server.location.LocationProviderProxy;
|
import com.android.server.location.LocationProviderProxy;
|
||||||
|
import com.android.server.location.LocationRequestStatistics;
|
||||||
|
import com.android.server.location.LocationRequestStatistics.PackageProviderKey;
|
||||||
|
import com.android.server.location.LocationRequestStatistics.PackageStatistics;
|
||||||
import com.android.server.location.MockProvider;
|
import com.android.server.location.MockProvider;
|
||||||
import com.android.server.location.PassiveProvider;
|
import com.android.server.location.PassiveProvider;
|
||||||
|
|
||||||
@@ -178,6 +181,8 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
private final HashMap<String, ArrayList<UpdateRecord>> mRecordsByProvider =
|
private final HashMap<String, ArrayList<UpdateRecord>> mRecordsByProvider =
|
||||||
new HashMap<String, ArrayList<UpdateRecord>>();
|
new HashMap<String, ArrayList<UpdateRecord>>();
|
||||||
|
|
||||||
|
private final LocationRequestStatistics mRequestStatistics = new LocationRequestStatistics();
|
||||||
|
|
||||||
// mapping from provider name to last known location
|
// mapping from provider name to last known location
|
||||||
private final HashMap<String, Location> mLastLocation = new HashMap<String, Location>();
|
private final HashMap<String, Location> mLastLocation = new HashMap<String, Location>();
|
||||||
|
|
||||||
@@ -568,7 +573,7 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
if (isAllowedByCurrentUserSettingsLocked(updateRecord.mProvider)) {
|
if (isAllowedByCurrentUserSettingsLocked(updateRecord.mProvider)) {
|
||||||
requestingLocation = true;
|
requestingLocation = true;
|
||||||
LocationProviderInterface locationProvider
|
LocationProviderInterface locationProvider
|
||||||
= mProvidersByName.get(updateRecord.mProvider);
|
= mProvidersByName.get(updateRecord.mProvider);
|
||||||
ProviderProperties properties = locationProvider != null
|
ProviderProperties properties = locationProvider != null
|
||||||
? locationProvider.getProperties() : null;
|
? locationProvider.getProperties() : null;
|
||||||
if (properties != null
|
if (properties != null
|
||||||
@@ -813,7 +818,7 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
long identity = Binder.clearCallingIdentity();
|
long identity = Binder.clearCallingIdentity();
|
||||||
receiver.decrementPendingBroadcastsLocked();
|
receiver.decrementPendingBroadcastsLocked();
|
||||||
Binder.restoreCallingIdentity(identity);
|
Binder.restoreCallingIdentity(identity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1288,13 +1293,18 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
if (!records.contains(this)) {
|
if (!records.contains(this)) {
|
||||||
records.add(this);
|
records.add(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Update statistics for historical location requests by package/provider
|
||||||
|
mRequestStatistics.startRequesting(
|
||||||
|
mReceiver.mPackageName, provider, request.getInterval());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method to be called when a record will no longer be used. Calling this multiple times
|
* Method to be called when a record will no longer be used.
|
||||||
* must have the same effect as calling it once.
|
|
||||||
*/
|
*/
|
||||||
void disposeLocked(boolean removeReceiver) {
|
void disposeLocked(boolean removeReceiver) {
|
||||||
|
mRequestStatistics.stopRequesting(mReceiver.mPackageName, mProvider);
|
||||||
|
|
||||||
// remove from mRecordsByProvider
|
// remove from mRecordsByProvider
|
||||||
ArrayList<UpdateRecord> globalRecords = mRecordsByProvider.get(this.mProvider);
|
ArrayList<UpdateRecord> globalRecords = mRecordsByProvider.get(this.mProvider);
|
||||||
if (globalRecords != null) {
|
if (globalRecords != null) {
|
||||||
@@ -1541,6 +1551,7 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
if (oldRecords != null) {
|
if (oldRecords != null) {
|
||||||
// Call dispose() on the obsolete update records.
|
// Call dispose() on the obsolete update records.
|
||||||
for (UpdateRecord record : oldRecords.values()) {
|
for (UpdateRecord record : oldRecords.values()) {
|
||||||
|
// Update statistics for historical location requests by package/provider
|
||||||
record.disposeLocked(false);
|
record.disposeLocked(false);
|
||||||
}
|
}
|
||||||
// Accumulate providers
|
// Accumulate providers
|
||||||
@@ -1762,7 +1773,7 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
@Override
|
@Override
|
||||||
public ProviderProperties getProviderProperties(String provider) {
|
public ProviderProperties getProviderProperties(String provider) {
|
||||||
if (mProvidersByName.get(provider) == null) {
|
if (mProvidersByName.get(provider) == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(),
|
checkResolutionLevelIsSufficientForProviderUse(getCallerAllowedResolutionLevel(),
|
||||||
@@ -1965,7 +1976,7 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
// Fetch latest status update time
|
// Fetch latest status update time
|
||||||
long newStatusUpdateTime = p.getStatusUpdateTime();
|
long newStatusUpdateTime = p.getStatusUpdateTime();
|
||||||
|
|
||||||
// Get latest status
|
// Get latest status
|
||||||
Bundle extras = new Bundle();
|
Bundle extras = new Bundle();
|
||||||
int status = p.getStatus(extras);
|
int status = p.getStatus(extras);
|
||||||
|
|
||||||
@@ -2179,7 +2190,7 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) !=
|
if (mContext.checkCallingPermission(ACCESS_MOCK_LOCATION) !=
|
||||||
PackageManager.PERMISSION_GRANTED) {
|
PackageManager.PERMISSION_GRANTED) {
|
||||||
throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission");
|
throw new SecurityException("Requires ACCESS_MOCK_LOCATION permission");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2351,13 +2362,20 @@ public class LocationManagerService extends ILocationManager.Stub {
|
|||||||
for (Receiver receiver : mReceivers.values()) {
|
for (Receiver receiver : mReceivers.values()) {
|
||||||
pw.println(" " + receiver);
|
pw.println(" " + receiver);
|
||||||
}
|
}
|
||||||
pw.println(" Records by Provider:");
|
pw.println(" Active Records by Provider:");
|
||||||
for (Map.Entry<String, ArrayList<UpdateRecord>> entry : mRecordsByProvider.entrySet()) {
|
for (Map.Entry<String, ArrayList<UpdateRecord>> entry : mRecordsByProvider.entrySet()) {
|
||||||
pw.println(" " + entry.getKey() + ":");
|
pw.println(" " + entry.getKey() + ":");
|
||||||
for (UpdateRecord record : entry.getValue()) {
|
for (UpdateRecord record : entry.getValue()) {
|
||||||
pw.println(" " + record);
|
pw.println(" " + record);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
pw.println(" Historical Records by Provider:");
|
||||||
|
for (Map.Entry<PackageProviderKey, PackageStatistics> entry
|
||||||
|
: mRequestStatistics.statistics.entrySet()) {
|
||||||
|
PackageProviderKey key = entry.getKey();
|
||||||
|
PackageStatistics stats = entry.getValue();
|
||||||
|
pw.println(" " + key.packageName + ": " + key.providerName + ": " + stats);
|
||||||
|
}
|
||||||
pw.println(" Last Known Locations:");
|
pw.println(" Last Known Locations:");
|
||||||
for (Map.Entry<String, Location> entry : mLastLocation.entrySet()) {
|
for (Map.Entry<String, Location> entry : mLastLocation.entrySet()) {
|
||||||
String provider = entry.getKey();
|
String provider = entry.getKey();
|
||||||
|
|||||||
@@ -0,0 +1,205 @@
|
|||||||
|
package com.android.server.location;
|
||||||
|
|
||||||
|
import android.os.SystemClock;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds statistics for location requests (active requests by provider).
|
||||||
|
*
|
||||||
|
* <p>Must be externally synchronized.
|
||||||
|
*/
|
||||||
|
public class LocationRequestStatistics {
|
||||||
|
private static final String TAG = "LocationStats";
|
||||||
|
|
||||||
|
// Maps package name nad provider to location request statistics.
|
||||||
|
public final HashMap<PackageProviderKey, PackageStatistics> statistics
|
||||||
|
= new HashMap<PackageProviderKey, PackageStatistics>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signals that a package has started requesting locations.
|
||||||
|
*
|
||||||
|
* @param packageName Name of package that has requested locations.
|
||||||
|
* @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) {
|
||||||
|
PackageProviderKey key = new PackageProviderKey(packageName, providerName);
|
||||||
|
PackageStatistics stats = statistics.get(key);
|
||||||
|
if (stats == null) {
|
||||||
|
stats = new PackageStatistics();
|
||||||
|
statistics.put(key, stats);
|
||||||
|
}
|
||||||
|
stats.startRequesting(intervalMs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signals that a package has stopped requesting locations.
|
||||||
|
*
|
||||||
|
* @param packageName Name of package that has stopped requesting locations.
|
||||||
|
* @param providerName Provider that is no longer being requested.
|
||||||
|
*/
|
||||||
|
public void stopRequesting(String packageName, String providerName) {
|
||||||
|
PackageProviderKey key = new PackageProviderKey(packageName, providerName);
|
||||||
|
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.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A key that holds both package and provider names.
|
||||||
|
*/
|
||||||
|
public static class PackageProviderKey {
|
||||||
|
/**
|
||||||
|
* Name of package requesting location.
|
||||||
|
*/
|
||||||
|
public final String packageName;
|
||||||
|
/**
|
||||||
|
* Name of provider being requested (e.g. "gps").
|
||||||
|
*/
|
||||||
|
public final String providerName;
|
||||||
|
|
||||||
|
public PackageProviderKey(String packageName, String providerName) {
|
||||||
|
this.packageName = packageName;
|
||||||
|
this.providerName = providerName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object other) {
|
||||||
|
if (!(other instanceof PackageProviderKey)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
PackageProviderKey otherKey = (PackageProviderKey) other;
|
||||||
|
return packageName.equals(otherKey.packageName)
|
||||||
|
&& providerName.equals(otherKey.providerName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return packageName.hashCode() + 31 * providerName.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Usage statistics for a package/provider pair.
|
||||||
|
*/
|
||||||
|
public static class PackageStatistics {
|
||||||
|
// Time when this package first requested location.
|
||||||
|
private final long mInitialElapsedTimeMs;
|
||||||
|
// Number of active location requests this package currently has.
|
||||||
|
private int mNumActiveRequests;
|
||||||
|
// Time when this package most recently went from not requesting location to requesting.
|
||||||
|
private long mLastActivitationElapsedTimeMs;
|
||||||
|
// The fastest interval this package has ever requested.
|
||||||
|
private long mFastestIntervalMs;
|
||||||
|
// The slowest interval this package has ever requested.
|
||||||
|
private long mSlowestIntervalMs;
|
||||||
|
// The total time this app has requested location (not including currently running requests).
|
||||||
|
private long mTotalDurationMs;
|
||||||
|
|
||||||
|
private PackageStatistics() {
|
||||||
|
mInitialElapsedTimeMs = SystemClock.elapsedRealtime();
|
||||||
|
mNumActiveRequests = 0;
|
||||||
|
mTotalDurationMs = 0;
|
||||||
|
mFastestIntervalMs = Long.MAX_VALUE;
|
||||||
|
mSlowestIntervalMs = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void startRequesting(long intervalMs) {
|
||||||
|
if (mNumActiveRequests == 0) {
|
||||||
|
mLastActivitationElapsedTimeMs = SystemClock.elapsedRealtime();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intervalMs < mFastestIntervalMs) {
|
||||||
|
mFastestIntervalMs = intervalMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (intervalMs > mSlowestIntervalMs) {
|
||||||
|
mSlowestIntervalMs = intervalMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
mNumActiveRequests++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopRequesting() {
|
||||||
|
if (mNumActiveRequests <= 0) {
|
||||||
|
// Shouldn't be a possible code path
|
||||||
|
Log.e(TAG, "Reference counting corrupted in usage statistics.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mNumActiveRequests--;
|
||||||
|
if (mNumActiveRequests == 0) {
|
||||||
|
long lastDurationMs
|
||||||
|
= SystemClock.elapsedRealtime() - mLastActivitationElapsedTimeMs;
|
||||||
|
mTotalDurationMs += lastDurationMs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the duration that this request has been active.
|
||||||
|
*/
|
||||||
|
public long getDurationMs() {
|
||||||
|
long currentDurationMs = mTotalDurationMs;
|
||||||
|
if (mNumActiveRequests > 0) {
|
||||||
|
currentDurationMs
|
||||||
|
+= SystemClock.elapsedRealtime() - mLastActivitationElapsedTimeMs;
|
||||||
|
}
|
||||||
|
return currentDurationMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the time since the initial request in ms.
|
||||||
|
*/
|
||||||
|
public long getTimeSinceFirstRequestMs() {
|
||||||
|
return SystemClock.elapsedRealtime() - mInitialElapsedTimeMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the fastest interval that has been tracked.
|
||||||
|
*/
|
||||||
|
public long getFastestIntervalMs() {
|
||||||
|
return mFastestIntervalMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the slowest interval that has been tracked.
|
||||||
|
*/
|
||||||
|
public long getSlowestIntervalMs() {
|
||||||
|
return mSlowestIntervalMs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if a request is active for these tracked statistics.
|
||||||
|
*/
|
||||||
|
public boolean isActive() {
|
||||||
|
return mNumActiveRequests > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder s = new StringBuilder();
|
||||||
|
if (mFastestIntervalMs == mSlowestIntervalMs) {
|
||||||
|
s.append("Interval ").append(mFastestIntervalMs / 1000).append(" seconds");
|
||||||
|
} else {
|
||||||
|
s.append("Min interval ").append(mFastestIntervalMs / 1000).append(" seconds");
|
||||||
|
s.append(": Max interval ").append(mSlowestIntervalMs / 1000).append(" seconds");
|
||||||
|
}
|
||||||
|
s.append(": Duration requested ")
|
||||||
|
.append((getDurationMs() / 1000) / 60)
|
||||||
|
.append(" out of the last ")
|
||||||
|
.append((getTimeSinceFirstRequestMs() / 1000) / 60)
|
||||||
|
.append(" minutes");
|
||||||
|
if (isActive()) {
|
||||||
|
s.append(": Currently active");
|
||||||
|
}
|
||||||
|
return s.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,175 @@
|
|||||||
|
package com.android.server.location;
|
||||||
|
|
||||||
|
import com.android.server.location.LocationRequestStatistics.PackageProviderKey;
|
||||||
|
import com.android.server.location.LocationRequestStatistics.PackageStatistics;
|
||||||
|
|
||||||
|
import android.os.SystemClock;
|
||||||
|
import android.test.AndroidTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unit tests for {@link LocationRequestStatistics}.
|
||||||
|
*/
|
||||||
|
public class LocationRequestStatisticsTest extends AndroidTestCase {
|
||||||
|
private static final String PACKAGE1 = "package1";
|
||||||
|
private static final String PACKAGE2 = "package2";
|
||||||
|
private static final String PROVIDER1 = "provider1";
|
||||||
|
private static final String PROVIDER2 = "provider2";
|
||||||
|
private static final long INTERVAL1 = 5000;
|
||||||
|
private static final long INTERVAL2 = 100000;
|
||||||
|
|
||||||
|
private LocationRequestStatistics mStatistics;
|
||||||
|
private long mStartElapsedRealtimeMs;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() {
|
||||||
|
mStatistics = new LocationRequestStatistics();
|
||||||
|
mStartElapsedRealtimeMs = SystemClock.elapsedRealtime();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that adding a single package works correctly.
|
||||||
|
*/
|
||||||
|
public void testSinglePackage() {
|
||||||
|
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
|
||||||
|
|
||||||
|
assertEquals(1, mStatistics.statistics.size());
|
||||||
|
PackageProviderKey key = mStatistics.statistics.keySet().iterator().next();
|
||||||
|
assertEquals(PACKAGE1, key.packageName);
|
||||||
|
assertEquals(PROVIDER1, key.providerName);
|
||||||
|
PackageStatistics stats = mStatistics.statistics.values().iterator().next();
|
||||||
|
verifyStatisticsTimes(stats);
|
||||||
|
assertEquals(INTERVAL1, stats.getFastestIntervalMs());
|
||||||
|
assertEquals(INTERVAL1, stats.getSlowestIntervalMs());
|
||||||
|
assertTrue(stats.isActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tests that adding a single package works correctly when it is stopped and restarted.
|
||||||
|
*/
|
||||||
|
public void testSinglePackage_stopAndRestart() {
|
||||||
|
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
|
||||||
|
mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
|
||||||
|
mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1);
|
||||||
|
|
||||||
|
assertEquals(1, mStatistics.statistics.size());
|
||||||
|
PackageProviderKey key = mStatistics.statistics.keySet().iterator().next();
|
||||||
|
assertEquals(PACKAGE1, key.packageName);
|
||||||
|
assertEquals(PROVIDER1, key.providerName);
|
||||||
|
PackageStatistics stats = mStatistics.statistics.values().iterator().next();
|
||||||
|
verifyStatisticsTimes(stats);
|
||||||
|
assertEquals(INTERVAL1, stats.getFastestIntervalMs());
|
||||||
|
assertEquals(INTERVAL1, stats.getSlowestIntervalMs());
|
||||||
|
assertTrue(stats.isActive());
|
||||||
|
|
||||||
|
mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
|
||||||
|
assertFalse(stats.isActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
assertEquals(1, mStatistics.statistics.size());
|
||||||
|
PackageProviderKey key = mStatistics.statistics.keySet().iterator().next();
|
||||||
|
assertEquals(PACKAGE1, key.packageName);
|
||||||
|
assertEquals(PROVIDER1, key.providerName);
|
||||||
|
PackageStatistics stats = mStatistics.statistics.values().iterator().next();
|
||||||
|
verifyStatisticsTimes(stats);
|
||||||
|
assertEquals(INTERVAL1, stats.getFastestIntervalMs());
|
||||||
|
assertTrue(stats.isActive());
|
||||||
|
|
||||||
|
mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
|
||||||
|
assertTrue(stats.isActive());
|
||||||
|
mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
|
||||||
|
assertFalse(stats.isActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
assertEquals(2, mStatistics.statistics.size());
|
||||||
|
PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, PROVIDER1);
|
||||||
|
PackageStatistics stats1 = mStatistics.statistics.get(key1);
|
||||||
|
verifyStatisticsTimes(stats1);
|
||||||
|
assertEquals(INTERVAL1, stats1.getSlowestIntervalMs());
|
||||||
|
assertEquals(INTERVAL1, stats1.getFastestIntervalMs());
|
||||||
|
assertTrue(stats1.isActive());
|
||||||
|
PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, PROVIDER2);
|
||||||
|
PackageStatistics stats2 = mStatistics.statistics.get(key2);
|
||||||
|
verifyStatisticsTimes(stats2);
|
||||||
|
assertEquals(INTERVAL2, stats2.getSlowestIntervalMs());
|
||||||
|
assertEquals(INTERVAL2, stats2.getFastestIntervalMs());
|
||||||
|
assertTrue(stats2.isActive());
|
||||||
|
|
||||||
|
mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
|
||||||
|
assertFalse(stats1.isActive());
|
||||||
|
assertTrue(stats2.isActive());
|
||||||
|
mStatistics.stopRequesting(PACKAGE1, PROVIDER2);
|
||||||
|
assertFalse(stats1.isActive());
|
||||||
|
assertFalse(stats2.isActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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);
|
||||||
|
|
||||||
|
assertEquals(3, mStatistics.statistics.size());
|
||||||
|
PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, PROVIDER1);
|
||||||
|
PackageStatistics stats1 = mStatistics.statistics.get(key1);
|
||||||
|
verifyStatisticsTimes(stats1);
|
||||||
|
assertEquals(INTERVAL1, stats1.getSlowestIntervalMs());
|
||||||
|
assertEquals(INTERVAL1, stats1.getFastestIntervalMs());
|
||||||
|
assertTrue(stats1.isActive());
|
||||||
|
|
||||||
|
PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, PROVIDER2);
|
||||||
|
PackageStatistics stats2 = mStatistics.statistics.get(key2);
|
||||||
|
verifyStatisticsTimes(stats2);
|
||||||
|
assertEquals(INTERVAL2, stats2.getSlowestIntervalMs());
|
||||||
|
assertEquals(INTERVAL1, stats2.getFastestIntervalMs());
|
||||||
|
assertTrue(stats2.isActive());
|
||||||
|
|
||||||
|
PackageProviderKey key3 = new PackageProviderKey(PACKAGE2, PROVIDER1);
|
||||||
|
PackageStatistics stats3 = mStatistics.statistics.get(key3);
|
||||||
|
verifyStatisticsTimes(stats3);
|
||||||
|
assertEquals(INTERVAL1, stats3.getSlowestIntervalMs());
|
||||||
|
assertEquals(INTERVAL1, stats3.getFastestIntervalMs());
|
||||||
|
assertTrue(stats3.isActive());
|
||||||
|
|
||||||
|
mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
|
||||||
|
assertFalse(stats1.isActive());
|
||||||
|
assertTrue(stats2.isActive());
|
||||||
|
assertTrue(stats3.isActive());
|
||||||
|
|
||||||
|
mStatistics.stopRequesting(PACKAGE1, PROVIDER2);
|
||||||
|
assertFalse(stats1.isActive());
|
||||||
|
assertTrue(stats2.isActive());
|
||||||
|
assertTrue(stats3.isActive());
|
||||||
|
mStatistics.stopRequesting(PACKAGE1, PROVIDER2);
|
||||||
|
assertFalse(stats2.isActive());
|
||||||
|
|
||||||
|
mStatistics.stopRequesting(PACKAGE2, PROVIDER1);
|
||||||
|
assertFalse(stats1.isActive());
|
||||||
|
assertFalse(stats2.isActive());
|
||||||
|
assertFalse(stats3.isActive());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void verifyStatisticsTimes(PackageStatistics stats) {
|
||||||
|
long durationMs = stats.getDurationMs();
|
||||||
|
long timeSinceFirstRequestMs = stats.getTimeSinceFirstRequestMs();
|
||||||
|
long maxDeltaMs = SystemClock.elapsedRealtime() - mStartElapsedRealtimeMs;
|
||||||
|
assertTrue("Duration is too large", durationMs <= maxDeltaMs);
|
||||||
|
assertTrue("Time since first request is too large", timeSinceFirstRequestMs <= maxDeltaMs);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user