Loading services/core/java/com/android/server/LocationManagerService.java +12 −6 Original line number Original line Diff line number Diff line Loading @@ -1830,8 +1830,8 @@ public class LocationManagerService extends ILocationManager.Stub { // Update statistics for historical location requests by package/provider // Update statistics for historical location requests by package/provider mRequestStatistics.startRequesting( mRequestStatistics.startRequesting( mReceiver.mCallerIdentity.mPackageName, provider, request.getInterval(), mReceiver.mCallerIdentity.mPackageName, mReceiver.mCallerIdentity.mFeatureId, mIsForegroundUid); provider, request.getInterval(), mIsForegroundUid); } } /** /** Loading @@ -1840,7 +1840,8 @@ public class LocationManagerService extends ILocationManager.Stub { private void updateForeground(boolean isForeground) { private void updateForeground(boolean isForeground) { mIsForegroundUid = isForeground; mIsForegroundUid = isForeground; mRequestStatistics.updateForeground( mRequestStatistics.updateForeground( mReceiver.mCallerIdentity.mPackageName, mProvider, isForeground); mReceiver.mCallerIdentity.mPackageName, mReceiver.mCallerIdentity.mFeatureId, mProvider, isForeground); } } /** /** Loading @@ -1848,7 +1849,8 @@ public class LocationManagerService extends ILocationManager.Stub { */ */ private void disposeLocked(boolean removeReceiver) { private void disposeLocked(boolean removeReceiver) { String packageName = mReceiver.mCallerIdentity.mPackageName; String packageName = mReceiver.mCallerIdentity.mPackageName; mRequestStatistics.stopRequesting(packageName, mProvider); mRequestStatistics.stopRequesting(packageName, mReceiver.mCallerIdentity.mFeatureId, mProvider); mLocationUsageLogger.logLocationApiUsage( mLocationUsageLogger.logLocationApiUsage( LocationStatsEnums.USAGE_ENDED, LocationStatsEnums.USAGE_ENDED, Loading Loading @@ -1883,6 +1885,10 @@ public class LocationManagerService extends ILocationManager.Stub { StringBuilder b = new StringBuilder("UpdateRecord["); StringBuilder b = new StringBuilder("UpdateRecord["); b.append(mProvider).append(" "); b.append(mProvider).append(" "); b.append(mReceiver.mCallerIdentity.mPackageName); b.append(mReceiver.mCallerIdentity.mPackageName); String featureId = mReceiver.mCallerIdentity.mFeatureId; if (featureId != null) { b.append(" ").append(featureId).append(" "); } b.append("(").append(mReceiver.mCallerIdentity.mUid); b.append("(").append(mReceiver.mCallerIdentity.mUid); if (mIsForegroundUid) { if (mIsForegroundUid) { b.append(" foreground"); b.append(" foreground"); Loading Loading @@ -2886,7 +2892,7 @@ public class LocationManagerService extends ILocationManager.Stub { for (Map.Entry<PackageProviderKey, PackageStatistics> entry for (Map.Entry<PackageProviderKey, PackageStatistics> entry : sorted.entrySet()) { : sorted.entrySet()) { PackageProviderKey key = entry.getKey(); PackageProviderKey key = entry.getKey(); ipw.println(key.providerName + ": " + key.packageName + ": " + entry.getValue()); ipw.println(key.mPackageName + ": " + key.mProviderName + ": " + entry.getValue()); } } ipw.decreaseIndent(); ipw.decreaseIndent(); Loading services/core/java/com/android/server/location/LocationRequestStatistics.java +65 −33 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.location; package com.android.server.location; import android.annotation.Nullable; import android.os.SystemClock; import android.os.SystemClock; import android.util.Log; import android.util.Log; import android.util.TimeUtils; import android.util.TimeUtils; Loading @@ -25,6 +26,7 @@ import com.android.internal.util.IndentingPrintWriter; import java.util.ArrayList; import java.util.ArrayList; import java.util.HashMap; import java.util.HashMap; import java.util.Objects; /** /** * Holds statistics for location requests (active requests by provider). * Holds statistics for location requests (active requests by provider). Loading @@ -44,12 +46,13 @@ public class LocationRequestStatistics { * Signals that a package has started requesting locations. * Signals that a package has started requesting locations. * * * @param packageName Name of package that has requested locations. * @param packageName Name of package that has requested locations. * @param featureId Feature id associated with the request. * @param providerName Name of provider that is requested (e.g. "gps"). * @param providerName Name of provider that is requested (e.g. "gps"). * @param intervalMs The interval that is requested in ms. * @param intervalMs The interval that is requested in ms. */ */ public void startRequesting(String packageName, String providerName, long intervalMs, public void startRequesting(String packageName, @Nullable String featureId, String providerName, boolean isForeground) { long intervalMs, boolean isForeground) { PackageProviderKey key = new PackageProviderKey(packageName, providerName); PackageProviderKey key = new PackageProviderKey(packageName, featureId, providerName); PackageStatistics stats = statistics.get(key); PackageStatistics stats = statistics.get(key); if (stats == null) { if (stats == null) { stats = new PackageStatistics(); stats = new PackageStatistics(); Loading @@ -57,32 +60,36 @@ public class LocationRequestStatistics { } } stats.startRequesting(intervalMs); stats.startRequesting(intervalMs); stats.updateForeground(isForeground); stats.updateForeground(isForeground); history.addRequest(packageName, providerName, intervalMs); history.addRequest(packageName, featureId, providerName, intervalMs); } } /** /** * Signals that a package has stopped requesting locations. * Signals that a package has stopped requesting locations. * * * @param packageName Name of package that has stopped requesting locations. * @param packageName Name of package that has stopped requesting locations. * @param featureId Feature id associated with the request. * @param providerName Provider that is no longer being requested. * @param providerName Provider that is no longer being requested. */ */ public void stopRequesting(String packageName, String providerName) { public void stopRequesting(String packageName, @Nullable String featureId, PackageProviderKey key = new PackageProviderKey(packageName, providerName); String providerName) { PackageProviderKey key = new PackageProviderKey(packageName, featureId, providerName); PackageStatistics stats = statistics.get(key); PackageStatistics stats = statistics.get(key); if (stats != null) { if (stats != null) { stats.stopRequesting(); stats.stopRequesting(); } } history.removeRequest(packageName, providerName); history.removeRequest(packageName, featureId, providerName); } } /** /** * Signals that a package possibly switched background/foreground. * Signals that a package possibly switched background/foreground. * * * @param packageName Name of package that has stopped requesting locations. * @param packageName Name of package that has stopped requesting locations. * @param featureId Feature id associated with the request. * @param providerName Provider that is no longer being requested. * @param providerName Provider that is no longer being requested. */ */ public void updateForeground(String packageName, String providerName, boolean isForeground) { public void updateForeground(String packageName, @Nullable String featureId, PackageProviderKey key = new PackageProviderKey(packageName, providerName); String providerName, boolean isForeground) { PackageProviderKey key = new PackageProviderKey(packageName, featureId, providerName); PackageStatistics stats = statistics.get(key); PackageStatistics stats = statistics.get(key); if (stats != null) { if (stats != null) { stats.updateForeground(isForeground); stats.updateForeground(isForeground); Loading @@ -90,30 +97,37 @@ public class LocationRequestStatistics { } } /** /** * A key that holds both package and provider names. * A key that holds package, feature id, and provider names. */ */ public static class PackageProviderKey implements Comparable<PackageProviderKey> { public static class PackageProviderKey implements Comparable<PackageProviderKey> { /** /** * Name of package requesting location. * Name of package requesting location. */ */ public final String packageName; public final String mPackageName; /** * Feature id associated with the request, which can be used to attribute location access to * different parts of the application. */ @Nullable public final String mFeatureId; /** /** * Name of provider being requested (e.g. "gps"). * Name of provider being requested (e.g. "gps"). */ */ public final String providerName; public final String mProviderName; PackageProviderKey(String packageName, String providerName) { PackageProviderKey(String packageName, @Nullable String featureId, String providerName) { this.packageName = packageName; this.mPackageName = packageName; this.providerName = providerName; this.mFeatureId = featureId; this.mProviderName = providerName; } } @Override @Override public int compareTo(PackageProviderKey other) { public int compareTo(PackageProviderKey other) { final int providerCompare = providerName.compareTo(other.providerName); final int providerCompare = mProviderName.compareTo(other.mProviderName); if (providerCompare != 0) { if (providerCompare != 0) { return providerCompare; return providerCompare; } else { } else { return packageName.compareTo(other.packageName); return mProviderName.compareTo(other.mProviderName); } } } } Loading @@ -124,13 +138,18 @@ public class LocationRequestStatistics { } } PackageProviderKey otherKey = (PackageProviderKey) other; PackageProviderKey otherKey = (PackageProviderKey) other; return packageName.equals(otherKey.packageName) return mPackageName.equals(otherKey.mPackageName) && providerName.equals(otherKey.providerName); && mProviderName.equals(otherKey.mProviderName) && Objects.equals(mFeatureId, otherKey.mFeatureId); } } @Override @Override public int hashCode() { public int hashCode() { return packageName.hashCode() + 31 * providerName.hashCode(); int hash = mPackageName.hashCode() + 31 * mProviderName.hashCode(); if (mFeatureId != null) { hash += mFeatureId.hashCode() + 31 * hash; } return hash; } } } } Loading @@ -147,17 +166,18 @@ public class LocationRequestStatistics { * Append an added location request to the history * Append an added location request to the history */ */ @VisibleForTesting @VisibleForTesting void addRequest(String packageName, String providerName, long intervalMs) { void addRequest(String packageName, @Nullable String featureId, String providerName, addRequestSummary(new RequestSummary(packageName, providerName, intervalMs)); long intervalMs) { addRequestSummary(new RequestSummary(packageName, featureId, providerName, intervalMs)); } } /** /** * Append a removed location request to the history * Append a removed location request to the history */ */ @VisibleForTesting @VisibleForTesting void removeRequest(String packageName, String providerName) { void removeRequest(String packageName, @Nullable String featureId, String providerName) { addRequestSummary(new RequestSummary( addRequestSummary(new RequestSummary( packageName, providerName, RequestSummary.REQUEST_ENDED_INTERVAL)); packageName, featureId, providerName, RequestSummary.REQUEST_ENDED_INTERVAL)); } } private void addRequestSummary(RequestSummary summary) { private void addRequestSummary(RequestSummary summary) { Loading Loading @@ -193,6 +213,12 @@ public class LocationRequestStatistics { * Name of package requesting location. * Name of package requesting location. */ */ private final String mPackageName; private final String mPackageName; /** * Feature id associated with the request for identifying subsystem of an application. */ @Nullable private final String mFeatureId; /** /** * Name of provider being requested (e.g. "gps"). * Name of provider being requested (e.g. "gps"). */ */ Loading @@ -211,8 +237,10 @@ public class LocationRequestStatistics { */ */ static final long REQUEST_ENDED_INTERVAL = -1; static final long REQUEST_ENDED_INTERVAL = -1; RequestSummary(String packageName, String providerName, long intervalMillis) { RequestSummary(String packageName, @Nullable String featureId, String providerName, long intervalMillis) { this.mPackageName = packageName; this.mPackageName = packageName; this.mFeatureId = featureId; this.mProviderName = providerName; this.mProviderName = providerName; this.mIntervalMillis = intervalMillis; this.mIntervalMillis = intervalMillis; this.mElapsedRealtimeMillis = SystemClock.elapsedRealtime(); this.mElapsedRealtimeMillis = SystemClock.elapsedRealtime(); Loading @@ -225,6 +253,9 @@ public class LocationRequestStatistics { .append(mIntervalMillis == REQUEST_ENDED_INTERVAL ? "- " : "+ ") .append(mIntervalMillis == REQUEST_ENDED_INTERVAL ? "- " : "+ ") .append(String.format("%7s", mProviderName)).append(" request from ") .append(String.format("%7s", mProviderName)).append(" request from ") .append(mPackageName); .append(mPackageName); if (mFeatureId != null) { s.append(" with feature ").append(mFeatureId); } if (mIntervalMillis != REQUEST_ENDED_INTERVAL) { if (mIntervalMillis != REQUEST_ENDED_INTERVAL) { s.append(" at interval ").append(mIntervalMillis / 1000).append(" seconds"); s.append(" at interval ").append(mIntervalMillis / 1000).append(" seconds"); } } Loading @@ -246,14 +277,15 @@ public class LocationRequestStatistics { private long mFastestIntervalMs; private long mFastestIntervalMs; // The slowest interval this package has ever requested. // The slowest interval this package has ever requested. private long mSlowestIntervalMs; private long mSlowestIntervalMs; // The total time this app has requested location (not including currently running requests). // The total time this app has requested location (not including currently running // requests). private long mTotalDurationMs; private long mTotalDurationMs; // Time when this package most recently went to foreground, requesting location. 0 means // Time when this package most recently went to foreground, requesting location. 0 means // not currently in foreground. // not currently in foreground. private long mLastForegroundElapsedTimeMs; private long mLastForegroundElapsedTimeMs; // The time this app has requested location (not including currently running requests), while // The time this app has requested location (not including currently running requests), // in foreground. // while in foreground. private long mForegroundDurationMs; private long mForegroundDurationMs; // Time when package last went dormant (stopped requesting location) // Time when package last went dormant (stopped requesting location) Loading services/robotests/src/com/android/server/location/LocationRequestStatisticsTest.java +6 −4 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ import java.io.StringWriter; @RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class) @Presubmit @Presubmit public class LocationRequestStatisticsTest { public class LocationRequestStatisticsTest { private static final String FEATURE_ID = "featureId"; /** /** * Check adding and removing requests & strings * Check adding and removing requests & strings Loading @@ -43,17 +44,18 @@ public class LocationRequestStatisticsTest { public void testRequestSummary() { public void testRequestSummary() { LocationRequestStatistics.RequestSummary summary = LocationRequestStatistics.RequestSummary summary = new LocationRequestStatistics.RequestSummary( new LocationRequestStatistics.RequestSummary( "com.example", "gps", 1000); "com.example", FEATURE_ID, "gps", 1000); StringWriter stringWriter = new StringWriter(); StringWriter stringWriter = new StringWriter(); summary.dump(new IndentingPrintWriter(new PrintWriter(stringWriter), " "), 1234); summary.dump(new IndentingPrintWriter(new PrintWriter(stringWriter), " "), 1234); assertThat(stringWriter.toString()).startsWith("At"); assertThat(stringWriter.toString()).startsWith("At"); StringWriter stringWriterRemove = new StringWriter(); StringWriter stringWriterRemove = new StringWriter(); summary = new LocationRequestStatistics.RequestSummary( summary = new LocationRequestStatistics.RequestSummary( "com.example", "gps", "com.example", "gps", FEATURE_ID, LocationRequestStatistics.RequestSummary.REQUEST_ENDED_INTERVAL); LocationRequestStatistics.RequestSummary.REQUEST_ENDED_INTERVAL); summary.dump(new IndentingPrintWriter(new PrintWriter(stringWriterRemove), " "), 2345); summary.dump(new IndentingPrintWriter(new PrintWriter(stringWriterRemove), " "), 2345); assertThat(stringWriterRemove.toString()).contains("-"); assertThat(stringWriterRemove.toString()).contains("-"); assertThat(stringWriterRemove.toString()).contains(FEATURE_ID); } } /** /** Loading @@ -62,11 +64,11 @@ public class LocationRequestStatisticsTest { @Test @Test public void testSummaryList() { public void testSummaryList() { LocationRequestStatistics statistics = new LocationRequestStatistics(); LocationRequestStatistics statistics = new LocationRequestStatistics(); statistics.history.addRequest("com.example", "gps", 1000); statistics.history.addRequest("com.example", FEATURE_ID, "gps", 1000); assertThat(statistics.history.mList.size()).isEqualTo(1); assertThat(statistics.history.mList.size()).isEqualTo(1); // Try (not) to overflow // Try (not) to overflow for (int i = 0; i < LocationRequestStatistics.RequestSummaryLimitedHistory.MAX_SIZE; i++) { for (int i = 0; i < LocationRequestStatistics.RequestSummaryLimitedHistory.MAX_SIZE; i++) { statistics.history.addRequest("com.example", "gps", 1000); statistics.history.addRequest("com.example", FEATURE_ID, "gps", 1000); } } assertThat(statistics.history.mList.size()).isEqualTo( assertThat(statistics.history.mList.size()).isEqualTo( LocationRequestStatistics.RequestSummaryLimitedHistory.MAX_SIZE); LocationRequestStatistics.RequestSummaryLimitedHistory.MAX_SIZE); Loading services/tests/servicestests/src/com/android/server/location/LocationRequestStatisticsTest.java +45 −41 Original line number Original line Diff line number Diff line package com.android.server.location; 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.os.SystemClock; import android.test.AndroidTestCase; import android.test.AndroidTestCase; import com.android.server.location.LocationRequestStatistics.PackageProviderKey; import com.android.server.location.LocationRequestStatistics.PackageStatistics; /** /** * Unit tests for {@link LocationRequestStatistics}. * Unit tests for {@link LocationRequestStatistics}. */ */ public class LocationRequestStatisticsTest extends AndroidTestCase { public class LocationRequestStatisticsTest extends AndroidTestCase { private static final String PACKAGE1 = "package1"; private static final String PACKAGE1 = "package1"; private static final String PACKAGE2 = "package2"; private static final String PACKAGE2 = "package2"; private static final String FEATURE_ID = "featureId"; private static final String PROVIDER1 = "provider1"; private static final String PROVIDER1 = "provider1"; private static final String PROVIDER2 = "provider2"; private static final String PROVIDER2 = "provider2"; private static final long INTERVAL1 = 5000; private static final long INTERVAL1 = 5000; Loading @@ -30,12 +31,13 @@ public class LocationRequestStatisticsTest extends AndroidTestCase { * Tests that adding a single package works correctly. * Tests that adding a single package works correctly. */ */ public void testSinglePackage() { public void testSinglePackage() { mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true); assertEquals(1, mStatistics.statistics.size()); assertEquals(1, mStatistics.statistics.size()); PackageProviderKey key = mStatistics.statistics.keySet().iterator().next(); PackageProviderKey key = mStatistics.statistics.keySet().iterator().next(); assertEquals(PACKAGE1, key.packageName); assertEquals(PACKAGE1, key.mPackageName); assertEquals(PROVIDER1, key.providerName); assertEquals(PROVIDER1, key.mProviderName); assertEquals(FEATURE_ID, key.mFeatureId); PackageStatistics stats = mStatistics.statistics.values().iterator().next(); PackageStatistics stats = mStatistics.statistics.values().iterator().next(); verifyStatisticsTimes(stats); verifyStatisticsTimes(stats); assertEquals(INTERVAL1, stats.getFastestIntervalMs()); assertEquals(INTERVAL1, stats.getFastestIntervalMs()); Loading @@ -47,21 +49,22 @@ public class LocationRequestStatisticsTest extends AndroidTestCase { * Tests that adding a single package works correctly when it is stopped and restarted. * Tests that adding a single package works correctly when it is stopped and restarted. */ */ public void testSinglePackage_stopAndRestart() { public void testSinglePackage_stopAndRestart() { mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true); mStatistics.stopRequesting(PACKAGE1, PROVIDER1); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1); mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true); assertEquals(1, mStatistics.statistics.size()); assertEquals(1, mStatistics.statistics.size()); PackageProviderKey key = mStatistics.statistics.keySet().iterator().next(); PackageProviderKey key = mStatistics.statistics.keySet().iterator().next(); assertEquals(PACKAGE1, key.packageName); assertEquals(PACKAGE1, key.mPackageName); assertEquals(PROVIDER1, key.providerName); assertEquals(FEATURE_ID, key.mFeatureId); assertEquals(PROVIDER1, key.mProviderName); PackageStatistics stats = mStatistics.statistics.values().iterator().next(); PackageStatistics stats = mStatistics.statistics.values().iterator().next(); verifyStatisticsTimes(stats); verifyStatisticsTimes(stats); assertEquals(INTERVAL1, stats.getFastestIntervalMs()); assertEquals(INTERVAL1, stats.getFastestIntervalMs()); assertEquals(INTERVAL1, stats.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats.getSlowestIntervalMs()); assertTrue(stats.isActive()); assertTrue(stats.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER1); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1); assertFalse(stats.isActive()); assertFalse(stats.isActive()); } } Loading @@ -69,21 +72,22 @@ public class LocationRequestStatisticsTest extends AndroidTestCase { * Tests that adding a single package works correctly when multiple intervals are used. * Tests that adding a single package works correctly when multiple intervals are used. */ */ public void testSinglePackage_multipleIntervals() { public void testSinglePackage_multipleIntervals() { mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL2, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL2, true); assertEquals(1, mStatistics.statistics.size()); assertEquals(1, mStatistics.statistics.size()); PackageProviderKey key = mStatistics.statistics.keySet().iterator().next(); PackageProviderKey key = mStatistics.statistics.keySet().iterator().next(); assertEquals(PACKAGE1, key.packageName); assertEquals(PACKAGE1, key.mPackageName); assertEquals(PROVIDER1, key.providerName); assertEquals(PROVIDER1, key.mProviderName); assertEquals(FEATURE_ID, key.mFeatureId); PackageStatistics stats = mStatistics.statistics.values().iterator().next(); PackageStatistics stats = mStatistics.statistics.values().iterator().next(); verifyStatisticsTimes(stats); verifyStatisticsTimes(stats); assertEquals(INTERVAL1, stats.getFastestIntervalMs()); assertEquals(INTERVAL1, stats.getFastestIntervalMs()); assertTrue(stats.isActive()); assertTrue(stats.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER1); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1); assertTrue(stats.isActive()); assertTrue(stats.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER1); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1); assertFalse(stats.isActive()); assertFalse(stats.isActive()); } } Loading @@ -91,27 +95,27 @@ public class LocationRequestStatisticsTest extends AndroidTestCase { * Tests that adding a single package works correctly when multiple providers are used. * Tests that adding a single package works correctly when multiple providers are used. */ */ public void testSinglePackage_multipleProviders() { public void testSinglePackage_multipleProviders() { mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL2, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER2, INTERVAL2, true); assertEquals(2, mStatistics.statistics.size()); assertEquals(2, mStatistics.statistics.size()); PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, PROVIDER1); PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, FEATURE_ID, PROVIDER1); PackageStatistics stats1 = mStatistics.statistics.get(key1); PackageStatistics stats1 = mStatistics.statistics.get(key1); verifyStatisticsTimes(stats1); verifyStatisticsTimes(stats1); assertEquals(INTERVAL1, stats1.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats1.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats1.getFastestIntervalMs()); assertEquals(INTERVAL1, stats1.getFastestIntervalMs()); assertTrue(stats1.isActive()); assertTrue(stats1.isActive()); PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, PROVIDER2); PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, FEATURE_ID, PROVIDER2); PackageStatistics stats2 = mStatistics.statistics.get(key2); PackageStatistics stats2 = mStatistics.statistics.get(key2); verifyStatisticsTimes(stats2); verifyStatisticsTimes(stats2); assertEquals(INTERVAL2, stats2.getSlowestIntervalMs()); assertEquals(INTERVAL2, stats2.getSlowestIntervalMs()); assertEquals(INTERVAL2, stats2.getFastestIntervalMs()); assertEquals(INTERVAL2, stats2.getFastestIntervalMs()); assertTrue(stats2.isActive()); assertTrue(stats2.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER1); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1); assertFalse(stats1.isActive()); assertFalse(stats1.isActive()); assertTrue(stats2.isActive()); assertTrue(stats2.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER2); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER2); assertFalse(stats1.isActive()); assertFalse(stats1.isActive()); assertFalse(stats2.isActive()); assertFalse(stats2.isActive()); } } Loading @@ -120,46 +124,46 @@ public class LocationRequestStatisticsTest extends AndroidTestCase { * Tests that adding multiple packages works correctly. * Tests that adding multiple packages works correctly. */ */ public void testMultiplePackages() { public void testMultiplePackages() { mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER2, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL2, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER2, INTERVAL2, true); mStatistics.startRequesting(PACKAGE2, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE2, FEATURE_ID, PROVIDER1, INTERVAL1, true); assertEquals(3, mStatistics.statistics.size()); assertEquals(3, mStatistics.statistics.size()); PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, PROVIDER1); PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, FEATURE_ID, PROVIDER1); PackageStatistics stats1 = mStatistics.statistics.get(key1); PackageStatistics stats1 = mStatistics.statistics.get(key1); verifyStatisticsTimes(stats1); verifyStatisticsTimes(stats1); assertEquals(INTERVAL1, stats1.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats1.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats1.getFastestIntervalMs()); assertEquals(INTERVAL1, stats1.getFastestIntervalMs()); assertTrue(stats1.isActive()); assertTrue(stats1.isActive()); PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, PROVIDER2); PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, FEATURE_ID, PROVIDER2); PackageStatistics stats2 = mStatistics.statistics.get(key2); PackageStatistics stats2 = mStatistics.statistics.get(key2); verifyStatisticsTimes(stats2); verifyStatisticsTimes(stats2); assertEquals(INTERVAL2, stats2.getSlowestIntervalMs()); assertEquals(INTERVAL2, stats2.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats2.getFastestIntervalMs()); assertEquals(INTERVAL1, stats2.getFastestIntervalMs()); assertTrue(stats2.isActive()); assertTrue(stats2.isActive()); PackageProviderKey key3 = new PackageProviderKey(PACKAGE2, PROVIDER1); PackageProviderKey key3 = new PackageProviderKey(PACKAGE2, FEATURE_ID, PROVIDER1); PackageStatistics stats3 = mStatistics.statistics.get(key3); PackageStatistics stats3 = mStatistics.statistics.get(key3); verifyStatisticsTimes(stats3); verifyStatisticsTimes(stats3); assertEquals(INTERVAL1, stats3.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats3.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats3.getFastestIntervalMs()); assertEquals(INTERVAL1, stats3.getFastestIntervalMs()); assertTrue(stats3.isActive()); assertTrue(stats3.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER1); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1); assertFalse(stats1.isActive()); assertFalse(stats1.isActive()); assertTrue(stats2.isActive()); assertTrue(stats2.isActive()); assertTrue(stats3.isActive()); assertTrue(stats3.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER2); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER2); assertFalse(stats1.isActive()); assertFalse(stats1.isActive()); assertTrue(stats2.isActive()); assertTrue(stats2.isActive()); assertTrue(stats3.isActive()); assertTrue(stats3.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER2); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER2); assertFalse(stats2.isActive()); assertFalse(stats2.isActive()); mStatistics.stopRequesting(PACKAGE2, PROVIDER1); mStatistics.stopRequesting(PACKAGE2, FEATURE_ID, PROVIDER1); assertFalse(stats1.isActive()); assertFalse(stats1.isActive()); assertFalse(stats2.isActive()); assertFalse(stats2.isActive()); assertFalse(stats3.isActive()); assertFalse(stats3.isActive()); Loading @@ -169,14 +173,14 @@ public class LocationRequestStatisticsTest extends AndroidTestCase { * Tests that switching foreground & background states accmulates time reasonably. * Tests that switching foreground & background states accmulates time reasonably. */ */ public void testForegroundBackground() { public void testForegroundBackground() { mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER2, INTERVAL1, true); mStatistics.startRequesting(PACKAGE2, PROVIDER1, INTERVAL1, false); mStatistics.startRequesting(PACKAGE2, FEATURE_ID, PROVIDER1, INTERVAL1, false); mStatistics.updateForeground(PACKAGE1, PROVIDER2, false); mStatistics.updateForeground(PACKAGE1, FEATURE_ID, PROVIDER2, false); mStatistics.updateForeground(PACKAGE2, PROVIDER1, true); mStatistics.updateForeground(PACKAGE2, FEATURE_ID, PROVIDER1, true); mStatistics.stopRequesting(PACKAGE1, PROVIDER1); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1); for (PackageStatistics stats : mStatistics.statistics.values()) { for (PackageStatistics stats : mStatistics.statistics.values()) { verifyStatisticsTimes(stats); verifyStatisticsTimes(stats); Loading Loading
services/core/java/com/android/server/LocationManagerService.java +12 −6 Original line number Original line Diff line number Diff line Loading @@ -1830,8 +1830,8 @@ public class LocationManagerService extends ILocationManager.Stub { // Update statistics for historical location requests by package/provider // Update statistics for historical location requests by package/provider mRequestStatistics.startRequesting( mRequestStatistics.startRequesting( mReceiver.mCallerIdentity.mPackageName, provider, request.getInterval(), mReceiver.mCallerIdentity.mPackageName, mReceiver.mCallerIdentity.mFeatureId, mIsForegroundUid); provider, request.getInterval(), mIsForegroundUid); } } /** /** Loading @@ -1840,7 +1840,8 @@ public class LocationManagerService extends ILocationManager.Stub { private void updateForeground(boolean isForeground) { private void updateForeground(boolean isForeground) { mIsForegroundUid = isForeground; mIsForegroundUid = isForeground; mRequestStatistics.updateForeground( mRequestStatistics.updateForeground( mReceiver.mCallerIdentity.mPackageName, mProvider, isForeground); mReceiver.mCallerIdentity.mPackageName, mReceiver.mCallerIdentity.mFeatureId, mProvider, isForeground); } } /** /** Loading @@ -1848,7 +1849,8 @@ public class LocationManagerService extends ILocationManager.Stub { */ */ private void disposeLocked(boolean removeReceiver) { private void disposeLocked(boolean removeReceiver) { String packageName = mReceiver.mCallerIdentity.mPackageName; String packageName = mReceiver.mCallerIdentity.mPackageName; mRequestStatistics.stopRequesting(packageName, mProvider); mRequestStatistics.stopRequesting(packageName, mReceiver.mCallerIdentity.mFeatureId, mProvider); mLocationUsageLogger.logLocationApiUsage( mLocationUsageLogger.logLocationApiUsage( LocationStatsEnums.USAGE_ENDED, LocationStatsEnums.USAGE_ENDED, Loading Loading @@ -1883,6 +1885,10 @@ public class LocationManagerService extends ILocationManager.Stub { StringBuilder b = new StringBuilder("UpdateRecord["); StringBuilder b = new StringBuilder("UpdateRecord["); b.append(mProvider).append(" "); b.append(mProvider).append(" "); b.append(mReceiver.mCallerIdentity.mPackageName); b.append(mReceiver.mCallerIdentity.mPackageName); String featureId = mReceiver.mCallerIdentity.mFeatureId; if (featureId != null) { b.append(" ").append(featureId).append(" "); } b.append("(").append(mReceiver.mCallerIdentity.mUid); b.append("(").append(mReceiver.mCallerIdentity.mUid); if (mIsForegroundUid) { if (mIsForegroundUid) { b.append(" foreground"); b.append(" foreground"); Loading Loading @@ -2886,7 +2892,7 @@ public class LocationManagerService extends ILocationManager.Stub { for (Map.Entry<PackageProviderKey, PackageStatistics> entry for (Map.Entry<PackageProviderKey, PackageStatistics> entry : sorted.entrySet()) { : sorted.entrySet()) { PackageProviderKey key = entry.getKey(); PackageProviderKey key = entry.getKey(); ipw.println(key.providerName + ": " + key.packageName + ": " + entry.getValue()); ipw.println(key.mPackageName + ": " + key.mProviderName + ": " + entry.getValue()); } } ipw.decreaseIndent(); ipw.decreaseIndent(); Loading
services/core/java/com/android/server/location/LocationRequestStatistics.java +65 −33 Original line number Original line Diff line number Diff line Loading @@ -16,6 +16,7 @@ package com.android.server.location; package com.android.server.location; import android.annotation.Nullable; import android.os.SystemClock; import android.os.SystemClock; import android.util.Log; import android.util.Log; import android.util.TimeUtils; import android.util.TimeUtils; Loading @@ -25,6 +26,7 @@ import com.android.internal.util.IndentingPrintWriter; import java.util.ArrayList; import java.util.ArrayList; import java.util.HashMap; import java.util.HashMap; import java.util.Objects; /** /** * Holds statistics for location requests (active requests by provider). * Holds statistics for location requests (active requests by provider). Loading @@ -44,12 +46,13 @@ public class LocationRequestStatistics { * Signals that a package has started requesting locations. * Signals that a package has started requesting locations. * * * @param packageName Name of package that has requested locations. * @param packageName Name of package that has requested locations. * @param featureId Feature id associated with the request. * @param providerName Name of provider that is requested (e.g. "gps"). * @param providerName Name of provider that is requested (e.g. "gps"). * @param intervalMs The interval that is requested in ms. * @param intervalMs The interval that is requested in ms. */ */ public void startRequesting(String packageName, String providerName, long intervalMs, public void startRequesting(String packageName, @Nullable String featureId, String providerName, boolean isForeground) { long intervalMs, boolean isForeground) { PackageProviderKey key = new PackageProviderKey(packageName, providerName); PackageProviderKey key = new PackageProviderKey(packageName, featureId, providerName); PackageStatistics stats = statistics.get(key); PackageStatistics stats = statistics.get(key); if (stats == null) { if (stats == null) { stats = new PackageStatistics(); stats = new PackageStatistics(); Loading @@ -57,32 +60,36 @@ public class LocationRequestStatistics { } } stats.startRequesting(intervalMs); stats.startRequesting(intervalMs); stats.updateForeground(isForeground); stats.updateForeground(isForeground); history.addRequest(packageName, providerName, intervalMs); history.addRequest(packageName, featureId, providerName, intervalMs); } } /** /** * Signals that a package has stopped requesting locations. * Signals that a package has stopped requesting locations. * * * @param packageName Name of package that has stopped requesting locations. * @param packageName Name of package that has stopped requesting locations. * @param featureId Feature id associated with the request. * @param providerName Provider that is no longer being requested. * @param providerName Provider that is no longer being requested. */ */ public void stopRequesting(String packageName, String providerName) { public void stopRequesting(String packageName, @Nullable String featureId, PackageProviderKey key = new PackageProviderKey(packageName, providerName); String providerName) { PackageProviderKey key = new PackageProviderKey(packageName, featureId, providerName); PackageStatistics stats = statistics.get(key); PackageStatistics stats = statistics.get(key); if (stats != null) { if (stats != null) { stats.stopRequesting(); stats.stopRequesting(); } } history.removeRequest(packageName, providerName); history.removeRequest(packageName, featureId, providerName); } } /** /** * Signals that a package possibly switched background/foreground. * Signals that a package possibly switched background/foreground. * * * @param packageName Name of package that has stopped requesting locations. * @param packageName Name of package that has stopped requesting locations. * @param featureId Feature id associated with the request. * @param providerName Provider that is no longer being requested. * @param providerName Provider that is no longer being requested. */ */ public void updateForeground(String packageName, String providerName, boolean isForeground) { public void updateForeground(String packageName, @Nullable String featureId, PackageProviderKey key = new PackageProviderKey(packageName, providerName); String providerName, boolean isForeground) { PackageProviderKey key = new PackageProviderKey(packageName, featureId, providerName); PackageStatistics stats = statistics.get(key); PackageStatistics stats = statistics.get(key); if (stats != null) { if (stats != null) { stats.updateForeground(isForeground); stats.updateForeground(isForeground); Loading @@ -90,30 +97,37 @@ public class LocationRequestStatistics { } } /** /** * A key that holds both package and provider names. * A key that holds package, feature id, and provider names. */ */ public static class PackageProviderKey implements Comparable<PackageProviderKey> { public static class PackageProviderKey implements Comparable<PackageProviderKey> { /** /** * Name of package requesting location. * Name of package requesting location. */ */ public final String packageName; public final String mPackageName; /** * Feature id associated with the request, which can be used to attribute location access to * different parts of the application. */ @Nullable public final String mFeatureId; /** /** * Name of provider being requested (e.g. "gps"). * Name of provider being requested (e.g. "gps"). */ */ public final String providerName; public final String mProviderName; PackageProviderKey(String packageName, String providerName) { PackageProviderKey(String packageName, @Nullable String featureId, String providerName) { this.packageName = packageName; this.mPackageName = packageName; this.providerName = providerName; this.mFeatureId = featureId; this.mProviderName = providerName; } } @Override @Override public int compareTo(PackageProviderKey other) { public int compareTo(PackageProviderKey other) { final int providerCompare = providerName.compareTo(other.providerName); final int providerCompare = mProviderName.compareTo(other.mProviderName); if (providerCompare != 0) { if (providerCompare != 0) { return providerCompare; return providerCompare; } else { } else { return packageName.compareTo(other.packageName); return mProviderName.compareTo(other.mProviderName); } } } } Loading @@ -124,13 +138,18 @@ public class LocationRequestStatistics { } } PackageProviderKey otherKey = (PackageProviderKey) other; PackageProviderKey otherKey = (PackageProviderKey) other; return packageName.equals(otherKey.packageName) return mPackageName.equals(otherKey.mPackageName) && providerName.equals(otherKey.providerName); && mProviderName.equals(otherKey.mProviderName) && Objects.equals(mFeatureId, otherKey.mFeatureId); } } @Override @Override public int hashCode() { public int hashCode() { return packageName.hashCode() + 31 * providerName.hashCode(); int hash = mPackageName.hashCode() + 31 * mProviderName.hashCode(); if (mFeatureId != null) { hash += mFeatureId.hashCode() + 31 * hash; } return hash; } } } } Loading @@ -147,17 +166,18 @@ public class LocationRequestStatistics { * Append an added location request to the history * Append an added location request to the history */ */ @VisibleForTesting @VisibleForTesting void addRequest(String packageName, String providerName, long intervalMs) { void addRequest(String packageName, @Nullable String featureId, String providerName, addRequestSummary(new RequestSummary(packageName, providerName, intervalMs)); long intervalMs) { addRequestSummary(new RequestSummary(packageName, featureId, providerName, intervalMs)); } } /** /** * Append a removed location request to the history * Append a removed location request to the history */ */ @VisibleForTesting @VisibleForTesting void removeRequest(String packageName, String providerName) { void removeRequest(String packageName, @Nullable String featureId, String providerName) { addRequestSummary(new RequestSummary( addRequestSummary(new RequestSummary( packageName, providerName, RequestSummary.REQUEST_ENDED_INTERVAL)); packageName, featureId, providerName, RequestSummary.REQUEST_ENDED_INTERVAL)); } } private void addRequestSummary(RequestSummary summary) { private void addRequestSummary(RequestSummary summary) { Loading Loading @@ -193,6 +213,12 @@ public class LocationRequestStatistics { * Name of package requesting location. * Name of package requesting location. */ */ private final String mPackageName; private final String mPackageName; /** * Feature id associated with the request for identifying subsystem of an application. */ @Nullable private final String mFeatureId; /** /** * Name of provider being requested (e.g. "gps"). * Name of provider being requested (e.g. "gps"). */ */ Loading @@ -211,8 +237,10 @@ public class LocationRequestStatistics { */ */ static final long REQUEST_ENDED_INTERVAL = -1; static final long REQUEST_ENDED_INTERVAL = -1; RequestSummary(String packageName, String providerName, long intervalMillis) { RequestSummary(String packageName, @Nullable String featureId, String providerName, long intervalMillis) { this.mPackageName = packageName; this.mPackageName = packageName; this.mFeatureId = featureId; this.mProviderName = providerName; this.mProviderName = providerName; this.mIntervalMillis = intervalMillis; this.mIntervalMillis = intervalMillis; this.mElapsedRealtimeMillis = SystemClock.elapsedRealtime(); this.mElapsedRealtimeMillis = SystemClock.elapsedRealtime(); Loading @@ -225,6 +253,9 @@ public class LocationRequestStatistics { .append(mIntervalMillis == REQUEST_ENDED_INTERVAL ? "- " : "+ ") .append(mIntervalMillis == REQUEST_ENDED_INTERVAL ? "- " : "+ ") .append(String.format("%7s", mProviderName)).append(" request from ") .append(String.format("%7s", mProviderName)).append(" request from ") .append(mPackageName); .append(mPackageName); if (mFeatureId != null) { s.append(" with feature ").append(mFeatureId); } if (mIntervalMillis != REQUEST_ENDED_INTERVAL) { if (mIntervalMillis != REQUEST_ENDED_INTERVAL) { s.append(" at interval ").append(mIntervalMillis / 1000).append(" seconds"); s.append(" at interval ").append(mIntervalMillis / 1000).append(" seconds"); } } Loading @@ -246,14 +277,15 @@ public class LocationRequestStatistics { private long mFastestIntervalMs; private long mFastestIntervalMs; // The slowest interval this package has ever requested. // The slowest interval this package has ever requested. private long mSlowestIntervalMs; private long mSlowestIntervalMs; // The total time this app has requested location (not including currently running requests). // The total time this app has requested location (not including currently running // requests). private long mTotalDurationMs; private long mTotalDurationMs; // Time when this package most recently went to foreground, requesting location. 0 means // Time when this package most recently went to foreground, requesting location. 0 means // not currently in foreground. // not currently in foreground. private long mLastForegroundElapsedTimeMs; private long mLastForegroundElapsedTimeMs; // The time this app has requested location (not including currently running requests), while // The time this app has requested location (not including currently running requests), // in foreground. // while in foreground. private long mForegroundDurationMs; private long mForegroundDurationMs; // Time when package last went dormant (stopped requesting location) // Time when package last went dormant (stopped requesting location) Loading
services/robotests/src/com/android/server/location/LocationRequestStatisticsTest.java +6 −4 Original line number Original line Diff line number Diff line Loading @@ -35,6 +35,7 @@ import java.io.StringWriter; @RunWith(RobolectricTestRunner.class) @RunWith(RobolectricTestRunner.class) @Presubmit @Presubmit public class LocationRequestStatisticsTest { public class LocationRequestStatisticsTest { private static final String FEATURE_ID = "featureId"; /** /** * Check adding and removing requests & strings * Check adding and removing requests & strings Loading @@ -43,17 +44,18 @@ public class LocationRequestStatisticsTest { public void testRequestSummary() { public void testRequestSummary() { LocationRequestStatistics.RequestSummary summary = LocationRequestStatistics.RequestSummary summary = new LocationRequestStatistics.RequestSummary( new LocationRequestStatistics.RequestSummary( "com.example", "gps", 1000); "com.example", FEATURE_ID, "gps", 1000); StringWriter stringWriter = new StringWriter(); StringWriter stringWriter = new StringWriter(); summary.dump(new IndentingPrintWriter(new PrintWriter(stringWriter), " "), 1234); summary.dump(new IndentingPrintWriter(new PrintWriter(stringWriter), " "), 1234); assertThat(stringWriter.toString()).startsWith("At"); assertThat(stringWriter.toString()).startsWith("At"); StringWriter stringWriterRemove = new StringWriter(); StringWriter stringWriterRemove = new StringWriter(); summary = new LocationRequestStatistics.RequestSummary( summary = new LocationRequestStatistics.RequestSummary( "com.example", "gps", "com.example", "gps", FEATURE_ID, LocationRequestStatistics.RequestSummary.REQUEST_ENDED_INTERVAL); LocationRequestStatistics.RequestSummary.REQUEST_ENDED_INTERVAL); summary.dump(new IndentingPrintWriter(new PrintWriter(stringWriterRemove), " "), 2345); summary.dump(new IndentingPrintWriter(new PrintWriter(stringWriterRemove), " "), 2345); assertThat(stringWriterRemove.toString()).contains("-"); assertThat(stringWriterRemove.toString()).contains("-"); assertThat(stringWriterRemove.toString()).contains(FEATURE_ID); } } /** /** Loading @@ -62,11 +64,11 @@ public class LocationRequestStatisticsTest { @Test @Test public void testSummaryList() { public void testSummaryList() { LocationRequestStatistics statistics = new LocationRequestStatistics(); LocationRequestStatistics statistics = new LocationRequestStatistics(); statistics.history.addRequest("com.example", "gps", 1000); statistics.history.addRequest("com.example", FEATURE_ID, "gps", 1000); assertThat(statistics.history.mList.size()).isEqualTo(1); assertThat(statistics.history.mList.size()).isEqualTo(1); // Try (not) to overflow // Try (not) to overflow for (int i = 0; i < LocationRequestStatistics.RequestSummaryLimitedHistory.MAX_SIZE; i++) { for (int i = 0; i < LocationRequestStatistics.RequestSummaryLimitedHistory.MAX_SIZE; i++) { statistics.history.addRequest("com.example", "gps", 1000); statistics.history.addRequest("com.example", FEATURE_ID, "gps", 1000); } } assertThat(statistics.history.mList.size()).isEqualTo( assertThat(statistics.history.mList.size()).isEqualTo( LocationRequestStatistics.RequestSummaryLimitedHistory.MAX_SIZE); LocationRequestStatistics.RequestSummaryLimitedHistory.MAX_SIZE); Loading
services/tests/servicestests/src/com/android/server/location/LocationRequestStatisticsTest.java +45 −41 Original line number Original line Diff line number Diff line package com.android.server.location; 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.os.SystemClock; import android.test.AndroidTestCase; import android.test.AndroidTestCase; import com.android.server.location.LocationRequestStatistics.PackageProviderKey; import com.android.server.location.LocationRequestStatistics.PackageStatistics; /** /** * Unit tests for {@link LocationRequestStatistics}. * Unit tests for {@link LocationRequestStatistics}. */ */ public class LocationRequestStatisticsTest extends AndroidTestCase { public class LocationRequestStatisticsTest extends AndroidTestCase { private static final String PACKAGE1 = "package1"; private static final String PACKAGE1 = "package1"; private static final String PACKAGE2 = "package2"; private static final String PACKAGE2 = "package2"; private static final String FEATURE_ID = "featureId"; private static final String PROVIDER1 = "provider1"; private static final String PROVIDER1 = "provider1"; private static final String PROVIDER2 = "provider2"; private static final String PROVIDER2 = "provider2"; private static final long INTERVAL1 = 5000; private static final long INTERVAL1 = 5000; Loading @@ -30,12 +31,13 @@ public class LocationRequestStatisticsTest extends AndroidTestCase { * Tests that adding a single package works correctly. * Tests that adding a single package works correctly. */ */ public void testSinglePackage() { public void testSinglePackage() { mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true); assertEquals(1, mStatistics.statistics.size()); assertEquals(1, mStatistics.statistics.size()); PackageProviderKey key = mStatistics.statistics.keySet().iterator().next(); PackageProviderKey key = mStatistics.statistics.keySet().iterator().next(); assertEquals(PACKAGE1, key.packageName); assertEquals(PACKAGE1, key.mPackageName); assertEquals(PROVIDER1, key.providerName); assertEquals(PROVIDER1, key.mProviderName); assertEquals(FEATURE_ID, key.mFeatureId); PackageStatistics stats = mStatistics.statistics.values().iterator().next(); PackageStatistics stats = mStatistics.statistics.values().iterator().next(); verifyStatisticsTimes(stats); verifyStatisticsTimes(stats); assertEquals(INTERVAL1, stats.getFastestIntervalMs()); assertEquals(INTERVAL1, stats.getFastestIntervalMs()); Loading @@ -47,21 +49,22 @@ public class LocationRequestStatisticsTest extends AndroidTestCase { * Tests that adding a single package works correctly when it is stopped and restarted. * Tests that adding a single package works correctly when it is stopped and restarted. */ */ public void testSinglePackage_stopAndRestart() { public void testSinglePackage_stopAndRestart() { mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true); mStatistics.stopRequesting(PACKAGE1, PROVIDER1); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1); mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true); assertEquals(1, mStatistics.statistics.size()); assertEquals(1, mStatistics.statistics.size()); PackageProviderKey key = mStatistics.statistics.keySet().iterator().next(); PackageProviderKey key = mStatistics.statistics.keySet().iterator().next(); assertEquals(PACKAGE1, key.packageName); assertEquals(PACKAGE1, key.mPackageName); assertEquals(PROVIDER1, key.providerName); assertEquals(FEATURE_ID, key.mFeatureId); assertEquals(PROVIDER1, key.mProviderName); PackageStatistics stats = mStatistics.statistics.values().iterator().next(); PackageStatistics stats = mStatistics.statistics.values().iterator().next(); verifyStatisticsTimes(stats); verifyStatisticsTimes(stats); assertEquals(INTERVAL1, stats.getFastestIntervalMs()); assertEquals(INTERVAL1, stats.getFastestIntervalMs()); assertEquals(INTERVAL1, stats.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats.getSlowestIntervalMs()); assertTrue(stats.isActive()); assertTrue(stats.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER1); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1); assertFalse(stats.isActive()); assertFalse(stats.isActive()); } } Loading @@ -69,21 +72,22 @@ public class LocationRequestStatisticsTest extends AndroidTestCase { * Tests that adding a single package works correctly when multiple intervals are used. * Tests that adding a single package works correctly when multiple intervals are used. */ */ public void testSinglePackage_multipleIntervals() { public void testSinglePackage_multipleIntervals() { mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL2, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL2, true); assertEquals(1, mStatistics.statistics.size()); assertEquals(1, mStatistics.statistics.size()); PackageProviderKey key = mStatistics.statistics.keySet().iterator().next(); PackageProviderKey key = mStatistics.statistics.keySet().iterator().next(); assertEquals(PACKAGE1, key.packageName); assertEquals(PACKAGE1, key.mPackageName); assertEquals(PROVIDER1, key.providerName); assertEquals(PROVIDER1, key.mProviderName); assertEquals(FEATURE_ID, key.mFeatureId); PackageStatistics stats = mStatistics.statistics.values().iterator().next(); PackageStatistics stats = mStatistics.statistics.values().iterator().next(); verifyStatisticsTimes(stats); verifyStatisticsTimes(stats); assertEquals(INTERVAL1, stats.getFastestIntervalMs()); assertEquals(INTERVAL1, stats.getFastestIntervalMs()); assertTrue(stats.isActive()); assertTrue(stats.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER1); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1); assertTrue(stats.isActive()); assertTrue(stats.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER1); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1); assertFalse(stats.isActive()); assertFalse(stats.isActive()); } } Loading @@ -91,27 +95,27 @@ public class LocationRequestStatisticsTest extends AndroidTestCase { * Tests that adding a single package works correctly when multiple providers are used. * Tests that adding a single package works correctly when multiple providers are used. */ */ public void testSinglePackage_multipleProviders() { public void testSinglePackage_multipleProviders() { mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL2, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER2, INTERVAL2, true); assertEquals(2, mStatistics.statistics.size()); assertEquals(2, mStatistics.statistics.size()); PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, PROVIDER1); PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, FEATURE_ID, PROVIDER1); PackageStatistics stats1 = mStatistics.statistics.get(key1); PackageStatistics stats1 = mStatistics.statistics.get(key1); verifyStatisticsTimes(stats1); verifyStatisticsTimes(stats1); assertEquals(INTERVAL1, stats1.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats1.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats1.getFastestIntervalMs()); assertEquals(INTERVAL1, stats1.getFastestIntervalMs()); assertTrue(stats1.isActive()); assertTrue(stats1.isActive()); PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, PROVIDER2); PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, FEATURE_ID, PROVIDER2); PackageStatistics stats2 = mStatistics.statistics.get(key2); PackageStatistics stats2 = mStatistics.statistics.get(key2); verifyStatisticsTimes(stats2); verifyStatisticsTimes(stats2); assertEquals(INTERVAL2, stats2.getSlowestIntervalMs()); assertEquals(INTERVAL2, stats2.getSlowestIntervalMs()); assertEquals(INTERVAL2, stats2.getFastestIntervalMs()); assertEquals(INTERVAL2, stats2.getFastestIntervalMs()); assertTrue(stats2.isActive()); assertTrue(stats2.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER1); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1); assertFalse(stats1.isActive()); assertFalse(stats1.isActive()); assertTrue(stats2.isActive()); assertTrue(stats2.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER2); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER2); assertFalse(stats1.isActive()); assertFalse(stats1.isActive()); assertFalse(stats2.isActive()); assertFalse(stats2.isActive()); } } Loading @@ -120,46 +124,46 @@ public class LocationRequestStatisticsTest extends AndroidTestCase { * Tests that adding multiple packages works correctly. * Tests that adding multiple packages works correctly. */ */ public void testMultiplePackages() { public void testMultiplePackages() { mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER2, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL2, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER2, INTERVAL2, true); mStatistics.startRequesting(PACKAGE2, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE2, FEATURE_ID, PROVIDER1, INTERVAL1, true); assertEquals(3, mStatistics.statistics.size()); assertEquals(3, mStatistics.statistics.size()); PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, PROVIDER1); PackageProviderKey key1 = new PackageProviderKey(PACKAGE1, FEATURE_ID, PROVIDER1); PackageStatistics stats1 = mStatistics.statistics.get(key1); PackageStatistics stats1 = mStatistics.statistics.get(key1); verifyStatisticsTimes(stats1); verifyStatisticsTimes(stats1); assertEquals(INTERVAL1, stats1.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats1.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats1.getFastestIntervalMs()); assertEquals(INTERVAL1, stats1.getFastestIntervalMs()); assertTrue(stats1.isActive()); assertTrue(stats1.isActive()); PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, PROVIDER2); PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, FEATURE_ID, PROVIDER2); PackageStatistics stats2 = mStatistics.statistics.get(key2); PackageStatistics stats2 = mStatistics.statistics.get(key2); verifyStatisticsTimes(stats2); verifyStatisticsTimes(stats2); assertEquals(INTERVAL2, stats2.getSlowestIntervalMs()); assertEquals(INTERVAL2, stats2.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats2.getFastestIntervalMs()); assertEquals(INTERVAL1, stats2.getFastestIntervalMs()); assertTrue(stats2.isActive()); assertTrue(stats2.isActive()); PackageProviderKey key3 = new PackageProviderKey(PACKAGE2, PROVIDER1); PackageProviderKey key3 = new PackageProviderKey(PACKAGE2, FEATURE_ID, PROVIDER1); PackageStatistics stats3 = mStatistics.statistics.get(key3); PackageStatistics stats3 = mStatistics.statistics.get(key3); verifyStatisticsTimes(stats3); verifyStatisticsTimes(stats3); assertEquals(INTERVAL1, stats3.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats3.getSlowestIntervalMs()); assertEquals(INTERVAL1, stats3.getFastestIntervalMs()); assertEquals(INTERVAL1, stats3.getFastestIntervalMs()); assertTrue(stats3.isActive()); assertTrue(stats3.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER1); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1); assertFalse(stats1.isActive()); assertFalse(stats1.isActive()); assertTrue(stats2.isActive()); assertTrue(stats2.isActive()); assertTrue(stats3.isActive()); assertTrue(stats3.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER2); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER2); assertFalse(stats1.isActive()); assertFalse(stats1.isActive()); assertTrue(stats2.isActive()); assertTrue(stats2.isActive()); assertTrue(stats3.isActive()); assertTrue(stats3.isActive()); mStatistics.stopRequesting(PACKAGE1, PROVIDER2); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER2); assertFalse(stats2.isActive()); assertFalse(stats2.isActive()); mStatistics.stopRequesting(PACKAGE2, PROVIDER1); mStatistics.stopRequesting(PACKAGE2, FEATURE_ID, PROVIDER1); assertFalse(stats1.isActive()); assertFalse(stats1.isActive()); assertFalse(stats2.isActive()); assertFalse(stats2.isActive()); assertFalse(stats3.isActive()); assertFalse(stats3.isActive()); Loading @@ -169,14 +173,14 @@ public class LocationRequestStatisticsTest extends AndroidTestCase { * Tests that switching foreground & background states accmulates time reasonably. * Tests that switching foreground & background states accmulates time reasonably. */ */ public void testForegroundBackground() { public void testForegroundBackground() { mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL1, true); mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER2, INTERVAL1, true); mStatistics.startRequesting(PACKAGE2, PROVIDER1, INTERVAL1, false); mStatistics.startRequesting(PACKAGE2, FEATURE_ID, PROVIDER1, INTERVAL1, false); mStatistics.updateForeground(PACKAGE1, PROVIDER2, false); mStatistics.updateForeground(PACKAGE1, FEATURE_ID, PROVIDER2, false); mStatistics.updateForeground(PACKAGE2, PROVIDER1, true); mStatistics.updateForeground(PACKAGE2, FEATURE_ID, PROVIDER1, true); mStatistics.stopRequesting(PACKAGE1, PROVIDER1); mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1); for (PackageStatistics stats : mStatistics.statistics.values()) { for (PackageStatistics stats : mStatistics.statistics.values()) { verifyStatisticsTimes(stats); verifyStatisticsTimes(stats); Loading