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

Commit 165941bd authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Adding History of Location Requests to Dumpsys"

parents 71b6aaf0 fa1ef8d3
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -3192,6 +3192,8 @@ public class LocationManagerService extends ILocationManager.Stub {
            }
            ipw.decreaseIndent();

            mRequestStatistics.history.dump(ipw);

            ipw.println("Last Known Locations:");
            ipw.increaseIndent();
            for (Map.Entry<String, Location> entry : mLastLocation.entrySet()) {
+124 −1
Original line number Diff line number Diff line
/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.location;

import android.os.SystemClock;
import android.util.Log;
import android.util.TimeUtils;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.IndentingPrintWriter;

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

/**
@@ -17,6 +38,8 @@ public class LocationRequestStatistics {
    public final HashMap<PackageProviderKey, PackageStatistics> statistics
            = new HashMap<PackageProviderKey, PackageStatistics>();

    public final RequestSummaryLimitedHistory history = new RequestSummaryLimitedHistory();

    /**
     * Signals that a package has started requesting locations.
     *
@@ -34,6 +57,7 @@ public class LocationRequestStatistics {
        }
        stats.startRequesting(intervalMs);
        stats.updateForeground(isForeground);
        history.addRequest(packageName, providerName, intervalMs);
    }

    /**
@@ -48,6 +72,7 @@ public class LocationRequestStatistics {
        if (stats != null) {
            stats.stopRequesting();
        }
        history.removeRequest(packageName, providerName);
    }

    /**
@@ -77,7 +102,7 @@ public class LocationRequestStatistics {
         */
        public final String providerName;

        public PackageProviderKey(String packageName, String providerName) {
        PackageProviderKey(String packageName, String providerName) {
            this.packageName = packageName;
            this.providerName = providerName;
        }
@@ -99,6 +124,104 @@ public class LocationRequestStatistics {
        }
    }

    /**
     * A data structure to hold past requests
     */
    public static class RequestSummaryLimitedHistory {
        @VisibleForTesting
        static final int MAX_SIZE = 100;

        final ArrayList<RequestSummary> mList = new ArrayList<>(MAX_SIZE);

        /**
         * Append an added location request to the history
         */
        @VisibleForTesting
        void addRequest(String packageName, String providerName, long intervalMs) {
            addRequestSummary(new RequestSummary(packageName, providerName, intervalMs));
        }

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

        private void addRequestSummary(RequestSummary summary) {
            while (mList.size() >= MAX_SIZE) {
                mList.remove(0);
            }
            mList.add(summary);
        }

        /**
         * Dump history to a printwriter (for dumpsys location)
         */
        public void dump(IndentingPrintWriter ipw) {
            long systemElapsedOffsetMillis = System.currentTimeMillis()
                    - SystemClock.elapsedRealtime();

            ipw.println("Last Several Location Requests:");
            ipw.increaseIndent();

            for (RequestSummary requestSummary : mList) {
                requestSummary.dump(ipw, systemElapsedOffsetMillis);
            }

            ipw.decreaseIndent();
        }
    }

    /**
     * A data structure to hold a single request
     */
    static class RequestSummary {
        /**
         * Name of package requesting location.
         */
        private final String mPackageName;
        /**
         * Name of provider being requested (e.g. "gps").
         */
        private final String mProviderName;
        /**
         * Interval Requested, or REQUEST_ENDED_INTERVAL indicating request has ended
         */
        private final long mIntervalMillis;
        /**
         * Elapsed time of request
         */
        private final long mElapsedRealtimeMillis;

        /**
         * Placeholder for requested ending (other values indicate request started/changed)
         */
        static final long REQUEST_ENDED_INTERVAL = -1;

        RequestSummary(String packageName, String providerName, long intervalMillis) {
            this.mPackageName = packageName;
            this.mProviderName = providerName;
            this.mIntervalMillis = intervalMillis;
            this.mElapsedRealtimeMillis = SystemClock.elapsedRealtime();
        }

        void dump(IndentingPrintWriter ipw, long systemElapsedOffsetMillis) {
            StringBuilder s = new StringBuilder();
            long systemTimeMillis = systemElapsedOffsetMillis + mElapsedRealtimeMillis;
            s.append("At ").append(TimeUtils.formatForLogging(systemTimeMillis)).append(": ")
                    .append(mIntervalMillis == REQUEST_ENDED_INTERVAL ? "- " : "+ ")
                    .append(String.format("%7s", mProviderName)).append(" request from ")
                    .append(mPackageName);
            if (mIntervalMillis != REQUEST_ENDED_INTERVAL) {
                s.append(" at interval ").append(mIntervalMillis / 1000).append(" seconds");
            }
            ipw.println(s);
        }
    }

    /**
     * Usage statistics for a package/provider pair.
     */
+74 −0
Original line number Diff line number Diff line
/*
 * Copyright 2020 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.server.location;

import static com.google.common.truth.Truth.assertThat;

import android.platform.test.annotations.Presubmit;

import com.android.internal.util.IndentingPrintWriter;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;

import java.io.PrintWriter;
import java.io.StringWriter;

/**
 * Unit tests for {@link LocationRequestStatistics}.
 */
@RunWith(RobolectricTestRunner.class)
@Presubmit
public class LocationRequestStatisticsTest {

    /**
     * Check adding and removing requests & strings
     */
    @Test
    public void testRequestSummary() {
        LocationRequestStatistics.RequestSummary summary =
                new LocationRequestStatistics.RequestSummary(
                "com.example", "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",
                LocationRequestStatistics.RequestSummary.REQUEST_ENDED_INTERVAL);
        summary.dump(new IndentingPrintWriter(new PrintWriter(stringWriterRemove), "  "), 2345);
        assertThat(stringWriterRemove.toString()).contains("-");
    }

    /**
     * Check summary list size capping
     */
    @Test
    public void testSummaryList() {
        LocationRequestStatistics statistics = new LocationRequestStatistics();
        statistics.history.addRequest("com.example", "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);
        }
        assertThat(statistics.history.mList.size()).isEqualTo(
                LocationRequestStatistics.RequestSummaryLimitedHistory.MAX_SIZE);
    }
}