diff options
| author | 2020-01-08 23:40:17 +0000 | |
|---|---|---|
| committer | 2020-01-08 23:40:17 +0000 | |
| commit | 165941bd0b18c21a9624e2af01d507ad533279cc (patch) | |
| tree | 9a3e71a44ca875a86389a6053ba3888de860d0d0 | |
| parent | 71b6aaf00190de037862bddbd1cc79f9f4e424b2 (diff) | |
| parent | fa1ef8d34dd7f032f0623a27d5b2a897f1c3da64 (diff) | |
Merge "Adding History of Location Requests to Dumpsys"
3 files changed, 200 insertions, 1 deletions
diff --git a/services/core/java/com/android/server/LocationManagerService.java b/services/core/java/com/android/server/LocationManagerService.java index c5f1923b0b98..0fc5340846f2 100644 --- a/services/core/java/com/android/server/LocationManagerService.java +++ b/services/core/java/com/android/server/LocationManagerService.java @@ -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()) { diff --git a/services/core/java/com/android/server/location/LocationRequestStatistics.java b/services/core/java/com/android/server/location/LocationRequestStatistics.java index b7ccb26da64b..45c833498ac7 100644 --- a/services/core/java/com/android/server/location/LocationRequestStatistics.java +++ b/services/core/java/com/android/server/location/LocationRequestStatistics.java @@ -1,8 +1,29 @@ +/* + * 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; } @@ -100,6 +125,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. */ public static class PackageStatistics { diff --git a/services/robotests/src/com/android/server/location/LocationRequestStatisticsTest.java b/services/robotests/src/com/android/server/location/LocationRequestStatisticsTest.java new file mode 100644 index 000000000000..4cbdbd178944 --- /dev/null +++ b/services/robotests/src/com/android/server/location/LocationRequestStatisticsTest.java @@ -0,0 +1,74 @@ +/* + * 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); + } +} |