Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9e33ab41 authored by Wei Wang's avatar Wei Wang
Browse files

Add feature id to location dumpsys.

Sample dumpsys output:
 Reciever[961e275 listener UpdateRecord[passive android SensorNotification (1000 foreground) Request[POWER_NONE passive fastest=+30m0s0ms] null] monitoring location: true]
 At 2020-02-14 01:09:12: + passive request from android with feature SensorNotification at interval 1800 seconds

Bug: 129416976
Test: atest CtsLocationFineTestCases
Change-Id: I15dcc00aac61e47651e41fd95e08d7cdbc553b25
parent d7ecc623
Loading
Loading
Loading
Loading
+12 −6
Original line number Diff line number Diff line
@@ -1830,8 +1830,8 @@ public class LocationManagerService extends ILocationManager.Stub {

            // Update statistics for historical location requests by package/provider
            mRequestStatistics.startRequesting(
                    mReceiver.mCallerIdentity.mPackageName, provider, request.getInterval(),
                    mIsForegroundUid);
                    mReceiver.mCallerIdentity.mPackageName, mReceiver.mCallerIdentity.mFeatureId,
                    provider, request.getInterval(), mIsForegroundUid);
        }

        /**
@@ -1840,7 +1840,8 @@ public class LocationManagerService extends ILocationManager.Stub {
        private void updateForeground(boolean isForeground) {
            mIsForegroundUid = isForeground;
            mRequestStatistics.updateForeground(
                    mReceiver.mCallerIdentity.mPackageName, mProvider, isForeground);
                    mReceiver.mCallerIdentity.mPackageName, mReceiver.mCallerIdentity.mFeatureId,
                    mProvider, isForeground);
        }

        /**
@@ -1848,7 +1849,8 @@ public class LocationManagerService extends ILocationManager.Stub {
         */
        private void disposeLocked(boolean removeReceiver) {
            String packageName = mReceiver.mCallerIdentity.mPackageName;
            mRequestStatistics.stopRequesting(packageName, mProvider);
            mRequestStatistics.stopRequesting(packageName, mReceiver.mCallerIdentity.mFeatureId,
                    mProvider);

            mLocationUsageLogger.logLocationApiUsage(
                    LocationStatsEnums.USAGE_ENDED,
@@ -1883,6 +1885,10 @@ public class LocationManagerService extends ILocationManager.Stub {
            StringBuilder b = new StringBuilder("UpdateRecord[");
            b.append(mProvider).append(" ");
            b.append(mReceiver.mCallerIdentity.mPackageName);
            String featureId = mReceiver.mCallerIdentity.mFeatureId;
            if (featureId != null) {
                b.append(" ").append(featureId).append(" ");
            }
            b.append("(").append(mReceiver.mCallerIdentity.mUid);
            if (mIsForegroundUid) {
                b.append(" foreground");
@@ -2886,7 +2892,7 @@ public class LocationManagerService extends ILocationManager.Stub {
            for (Map.Entry<PackageProviderKey, PackageStatistics> entry
                    : sorted.entrySet()) {
                PackageProviderKey key = entry.getKey();
                ipw.println(key.providerName + ": " + key.packageName + ": " + entry.getValue());
                ipw.println(key.mPackageName + ": " + key.mProviderName + ": " + entry.getValue());
            }
            ipw.decreaseIndent();

+65 −33
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.location;

import android.annotation.Nullable;
import android.os.SystemClock;
import android.util.Log;
import android.util.TimeUtils;
@@ -25,6 +26,7 @@ import com.android.internal.util.IndentingPrintWriter;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Objects;

/**
 * Holds statistics for location requests (active requests by provider).
@@ -44,12 +46,13 @@ public class LocationRequestStatistics {
     * Signals that a package has started requesting 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 intervalMs   The interval that is requested in ms.
     */
    public void startRequesting(String packageName, String providerName, long intervalMs,
            boolean isForeground) {
        PackageProviderKey key = new PackageProviderKey(packageName, providerName);
    public void startRequesting(String packageName, @Nullable String featureId, String providerName,
            long intervalMs, boolean isForeground) {
        PackageProviderKey key = new PackageProviderKey(packageName, featureId, providerName);
        PackageStatistics stats = statistics.get(key);
        if (stats == null) {
            stats = new PackageStatistics();
@@ -57,32 +60,36 @@ public class LocationRequestStatistics {
        }
        stats.startRequesting(intervalMs);
        stats.updateForeground(isForeground);
        history.addRequest(packageName, providerName, intervalMs);
        history.addRequest(packageName, featureId, providerName, intervalMs);
    }

    /**
     * Signals that a package 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.
     */
    public void stopRequesting(String packageName, String providerName) {
        PackageProviderKey key = new PackageProviderKey(packageName, providerName);
    public void stopRequesting(String packageName, @Nullable String featureId,
            String providerName) {
        PackageProviderKey key = new PackageProviderKey(packageName, featureId, providerName);
        PackageStatistics stats = statistics.get(key);
        if (stats != null) {
            stats.stopRequesting();
        }
        history.removeRequest(packageName, providerName);
        history.removeRequest(packageName, featureId, providerName);
    }

    /**
     * Signals that a package possibly switched background/foreground.
     *
     * @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.
     */
    public void updateForeground(String packageName, String providerName, boolean isForeground) {
        PackageProviderKey key = new PackageProviderKey(packageName, providerName);
    public void updateForeground(String packageName, @Nullable String featureId,
            String providerName, boolean isForeground) {
        PackageProviderKey key = new PackageProviderKey(packageName, featureId, providerName);
        PackageStatistics stats = statistics.get(key);
        if (stats != null) {
            stats.updateForeground(isForeground);
@@ -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> {
        /**
         * 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").
         */
        public final String providerName;
        public final String mProviderName;

        PackageProviderKey(String packageName, String providerName) {
            this.packageName = packageName;
            this.providerName = providerName;
        PackageProviderKey(String packageName, @Nullable String featureId, String providerName) {
            this.mPackageName = packageName;
            this.mFeatureId = featureId;
            this.mProviderName = providerName;
        }

        @Override
        public int compareTo(PackageProviderKey other) {
            final int providerCompare = providerName.compareTo(other.providerName);
            final int providerCompare = mProviderName.compareTo(other.mProviderName);
            if (providerCompare != 0) {
                return providerCompare;
            } else {
                return packageName.compareTo(other.packageName);
                return mProviderName.compareTo(other.mProviderName);
            }
        }

@@ -124,13 +138,18 @@ public class LocationRequestStatistics {
            }

            PackageProviderKey otherKey = (PackageProviderKey) other;
            return packageName.equals(otherKey.packageName)
                    && providerName.equals(otherKey.providerName);
            return mPackageName.equals(otherKey.mPackageName)
                    && mProviderName.equals(otherKey.mProviderName)
                    && Objects.equals(mFeatureId, otherKey.mFeatureId);
        }

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

@@ -147,17 +166,18 @@ public class LocationRequestStatistics {
         * Append an added location request to the history
         */
        @VisibleForTesting
        void addRequest(String packageName, String providerName, long intervalMs) {
            addRequestSummary(new RequestSummary(packageName, providerName, intervalMs));
        void addRequest(String packageName, @Nullable String featureId, String providerName,
                long intervalMs) {
            addRequestSummary(new RequestSummary(packageName, featureId, providerName, intervalMs));
        }

        /**
         * Append a removed location request to the history
         */
        @VisibleForTesting
        void removeRequest(String packageName, String providerName) {
        void removeRequest(String packageName, @Nullable String featureId, String providerName) {
            addRequestSummary(new RequestSummary(
                    packageName, providerName, RequestSummary.REQUEST_ENDED_INTERVAL));
                    packageName, featureId, providerName, RequestSummary.REQUEST_ENDED_INTERVAL));
        }

        private void addRequestSummary(RequestSummary summary) {
@@ -193,6 +213,12 @@ public class LocationRequestStatistics {
         * Name of package requesting location.
         */
        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").
         */
@@ -211,8 +237,10 @@ public class LocationRequestStatistics {
         */
        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.mFeatureId = featureId;
            this.mProviderName = providerName;
            this.mIntervalMillis = intervalMillis;
            this.mElapsedRealtimeMillis = SystemClock.elapsedRealtime();
@@ -225,6 +253,9 @@ public class LocationRequestStatistics {
                    .append(mIntervalMillis == REQUEST_ENDED_INTERVAL ? "- " : "+ ")
                    .append(String.format("%7s", mProviderName)).append(" request from ")
                    .append(mPackageName);
            if (mFeatureId != null) {
                s.append(" with feature ").append(mFeatureId);
            }
            if (mIntervalMillis != REQUEST_ENDED_INTERVAL) {
                s.append(" at interval ").append(mIntervalMillis / 1000).append(" seconds");
            }
@@ -246,14 +277,15 @@ public class LocationRequestStatistics {
        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).
        // 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.
        // The time this app has requested location (not including currently running requests),
        // while in foreground.
        private long mForegroundDurationMs;

        // Time when package last went dormant (stopped requesting location)
+6 −4
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import java.io.StringWriter;
@RunWith(RobolectricTestRunner.class)
@Presubmit
public class LocationRequestStatisticsTest {
    private static final String FEATURE_ID = "featureId";

    /**
     * Check adding and removing requests & strings
@@ -43,17 +44,18 @@ public class LocationRequestStatisticsTest {
    public void testRequestSummary() {
        LocationRequestStatistics.RequestSummary summary =
                new LocationRequestStatistics.RequestSummary(
                "com.example", "gps", 1000);
                        "com.example", FEATURE_ID, "gps", 1000);
        StringWriter stringWriter = new StringWriter();
        summary.dump(new IndentingPrintWriter(new PrintWriter(stringWriter), "  "), 1234);
        assertThat(stringWriter.toString()).startsWith("At");

        StringWriter stringWriterRemove = new StringWriter();
        summary = new LocationRequestStatistics.RequestSummary(
                "com.example", "gps",
                "com.example", "gps", FEATURE_ID,
                LocationRequestStatistics.RequestSummary.REQUEST_ENDED_INTERVAL);
        summary.dump(new IndentingPrintWriter(new PrintWriter(stringWriterRemove), "  "), 2345);
        assertThat(stringWriterRemove.toString()).contains("-");
        assertThat(stringWriterRemove.toString()).contains(FEATURE_ID);
    }

    /**
@@ -62,11 +64,11 @@ public class LocationRequestStatisticsTest {
    @Test
    public void testSummaryList() {
        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);
        // Try (not) to overflow
        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(
                LocationRequestStatistics.RequestSummaryLimitedHistory.MAX_SIZE);
+45 −41
Original line number Diff line number Diff line
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;

import com.android.server.location.LocationRequestStatistics.PackageProviderKey;
import com.android.server.location.LocationRequestStatistics.PackageStatistics;

/**
 * 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 FEATURE_ID = "featureId";
    private static final String PROVIDER1 = "provider1";
    private static final String PROVIDER2 = "provider2";
    private static final long INTERVAL1 = 5000;
@@ -30,12 +31,13 @@ public class LocationRequestStatisticsTest extends AndroidTestCase {
     * Tests that adding a single package works correctly.
     */
    public void testSinglePackage() {
        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true);
        mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true);

        assertEquals(1, mStatistics.statistics.size());
        PackageProviderKey key = mStatistics.statistics.keySet().iterator().next();
        assertEquals(PACKAGE1, key.packageName);
        assertEquals(PROVIDER1, key.providerName);
        assertEquals(PACKAGE1, key.mPackageName);
        assertEquals(PROVIDER1, key.mProviderName);
        assertEquals(FEATURE_ID, key.mFeatureId);
        PackageStatistics stats = mStatistics.statistics.values().iterator().next();
        verifyStatisticsTimes(stats);
        assertEquals(INTERVAL1, stats.getFastestIntervalMs());
@@ -47,21 +49,22 @@ 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, true);
        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true);
        mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true);
        mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1);
        mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true);

        assertEquals(1, mStatistics.statistics.size());
        PackageProviderKey key = mStatistics.statistics.keySet().iterator().next();
        assertEquals(PACKAGE1, key.packageName);
        assertEquals(PROVIDER1, key.providerName);
        assertEquals(PACKAGE1, key.mPackageName);
        assertEquals(FEATURE_ID, key.mFeatureId);
        assertEquals(PROVIDER1, key.mProviderName);
        PackageStatistics stats = mStatistics.statistics.values().iterator().next();
        verifyStatisticsTimes(stats);
        assertEquals(INTERVAL1, stats.getFastestIntervalMs());
        assertEquals(INTERVAL1, stats.getSlowestIntervalMs());
        assertTrue(stats.isActive());

        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
        mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1);
        assertFalse(stats.isActive());
    }

@@ -69,21 +72,22 @@ 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, true);
        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL2, true);
        mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true);
        mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL2, true);

        assertEquals(1, mStatistics.statistics.size());
        PackageProviderKey key = mStatistics.statistics.keySet().iterator().next();
        assertEquals(PACKAGE1, key.packageName);
        assertEquals(PROVIDER1, key.providerName);
        assertEquals(PACKAGE1, key.mPackageName);
        assertEquals(PROVIDER1, key.mProviderName);
        assertEquals(FEATURE_ID, key.mFeatureId);
        PackageStatistics stats = mStatistics.statistics.values().iterator().next();
        verifyStatisticsTimes(stats);
        assertEquals(INTERVAL1, stats.getFastestIntervalMs());
        assertTrue(stats.isActive());

        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
        mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1);
        assertTrue(stats.isActive());
        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
        mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1);
        assertFalse(stats.isActive());
    }

@@ -91,27 +95,27 @@ 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, true);
        mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL2, true);
        mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true);
        mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER2, INTERVAL2, true);

        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);
        verifyStatisticsTimes(stats1);
        assertEquals(INTERVAL1, stats1.getSlowestIntervalMs());
        assertEquals(INTERVAL1, stats1.getFastestIntervalMs());
        assertTrue(stats1.isActive());
        PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, PROVIDER2);
        PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, FEATURE_ID, PROVIDER2);
        PackageStatistics stats2 = mStatistics.statistics.get(key2);
        verifyStatisticsTimes(stats2);
        assertEquals(INTERVAL2, stats2.getSlowestIntervalMs());
        assertEquals(INTERVAL2, stats2.getFastestIntervalMs());
        assertTrue(stats2.isActive());

        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
        mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1);
        assertFalse(stats1.isActive());
        assertTrue(stats2.isActive());
        mStatistics.stopRequesting(PACKAGE1, PROVIDER2);
        mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER2);
        assertFalse(stats1.isActive());
        assertFalse(stats2.isActive());
    }
@@ -120,46 +124,46 @@ public class LocationRequestStatisticsTest extends AndroidTestCase {
     * Tests that adding multiple packages works correctly.
     */
    public void testMultiplePackages() {
        mStatistics.startRequesting(PACKAGE1, PROVIDER1, INTERVAL1, true);
        mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL1, true);
        mStatistics.startRequesting(PACKAGE1, PROVIDER2, INTERVAL2, true);
        mStatistics.startRequesting(PACKAGE2, PROVIDER1, INTERVAL1, true);
        mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true);
        mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER2, INTERVAL1, true);
        mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER2, INTERVAL2, true);
        mStatistics.startRequesting(PACKAGE2, FEATURE_ID, PROVIDER1, INTERVAL1, true);

        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);
        verifyStatisticsTimes(stats1);
        assertEquals(INTERVAL1, stats1.getSlowestIntervalMs());
        assertEquals(INTERVAL1, stats1.getFastestIntervalMs());
        assertTrue(stats1.isActive());

        PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, PROVIDER2);
        PackageProviderKey key2 = new PackageProviderKey(PACKAGE1, FEATURE_ID, 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);
        PackageProviderKey key3 = new PackageProviderKey(PACKAGE2, FEATURE_ID, PROVIDER1);
        PackageStatistics stats3 = mStatistics.statistics.get(key3);
        verifyStatisticsTimes(stats3);
        assertEquals(INTERVAL1, stats3.getSlowestIntervalMs());
        assertEquals(INTERVAL1, stats3.getFastestIntervalMs());
        assertTrue(stats3.isActive());

        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
        mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1);
        assertFalse(stats1.isActive());
        assertTrue(stats2.isActive());
        assertTrue(stats3.isActive());

        mStatistics.stopRequesting(PACKAGE1, PROVIDER2);
        mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER2);
        assertFalse(stats1.isActive());
        assertTrue(stats2.isActive());
        assertTrue(stats3.isActive());
        mStatistics.stopRequesting(PACKAGE1, PROVIDER2);
        mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER2);
        assertFalse(stats2.isActive());

        mStatistics.stopRequesting(PACKAGE2, PROVIDER1);
        mStatistics.stopRequesting(PACKAGE2, FEATURE_ID, PROVIDER1);
        assertFalse(stats1.isActive());
        assertFalse(stats2.isActive());
        assertFalse(stats3.isActive());
@@ -169,14 +173,14 @@ public class LocationRequestStatisticsTest extends AndroidTestCase {
     * 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.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER1, INTERVAL1, true);
        mStatistics.startRequesting(PACKAGE1, FEATURE_ID, PROVIDER2, INTERVAL1, true);
        mStatistics.startRequesting(PACKAGE2, FEATURE_ID, PROVIDER1, INTERVAL1, false);

        mStatistics.updateForeground(PACKAGE1, PROVIDER2, false);
        mStatistics.updateForeground(PACKAGE2, PROVIDER1, true);
        mStatistics.updateForeground(PACKAGE1, FEATURE_ID, PROVIDER2, false);
        mStatistics.updateForeground(PACKAGE2, FEATURE_ID, PROVIDER1, true);

        mStatistics.stopRequesting(PACKAGE1, PROVIDER1);
        mStatistics.stopRequesting(PACKAGE1, FEATURE_ID, PROVIDER1);

        for (PackageStatistics stats : mStatistics.statistics.values()) {
            verifyStatisticsTimes(stats);