Merge changes I727849fa,If31ccbc7

* changes:
  Refactor buildKeepaliveMetrics to return DailyKeepaliveInfoReported
  Create KeepaliveStatsTracker for Duration metrics.
This commit is contained in:
Hansen Kurli 2023-04-24 04:03:09 +00:00 committed by Gerrit Code Review
commit 22a0120260
3 changed files with 700 additions and 0 deletions

View File

@ -177,6 +177,7 @@ public class AutomaticOnOffKeepaliveTracker {
private static final int MAX_EVENTS_LOGS = 40;
private final LocalLog mEventLog = new LocalLog(MAX_EVENTS_LOGS);
private final KeepaliveStatsTracker mKeepaliveStatsTracker = new KeepaliveStatsTracker();
/**
* Information about a managed keepalive.
*
@ -421,6 +422,7 @@ public class AutomaticOnOffKeepaliveTracker {
public void handleStartKeepalive(Message message) {
final AutomaticOnOffKeepalive autoKi = (AutomaticOnOffKeepalive) message.obj;
mEventLog.log("Start keepalive " + autoKi.mCallback + " on " + autoKi.getNetwork());
mKeepaliveStatsTracker.onStartKeepalive();
mKeepaliveTracker.handleStartKeepalive(autoKi.mKi);
// Add automatic on/off request into list to track its life cycle.
@ -438,12 +440,14 @@ public class AutomaticOnOffKeepaliveTracker {
}
private void handleResumeKeepalive(@NonNull final KeepaliveTracker.KeepaliveInfo ki) {
mKeepaliveStatsTracker.onResumeKeepalive();
mKeepaliveTracker.handleStartKeepalive(ki);
mEventLog.log("Resumed successfully keepalive " + ki.mCallback + " on " + ki.mNai);
}
private void handlePauseKeepalive(@NonNull final KeepaliveTracker.KeepaliveInfo ki) {
mEventLog.log("Suspend keepalive " + ki.mCallback + " on " + ki.mNai);
mKeepaliveStatsTracker.onPauseKeepalive();
// TODO : mKT.handleStopKeepalive should take a KeepaliveInfo instead
mKeepaliveTracker.handleStopKeepalive(ki.getNai(), ki.getSlot(), SUCCESS_PAUSED);
}
@ -467,6 +471,7 @@ public class AutomaticOnOffKeepaliveTracker {
private void cleanupAutoOnOffKeepalive(@NonNull final AutomaticOnOffKeepalive autoKi) {
ensureRunningOnHandlerThread();
mKeepaliveStatsTracker.onStopKeepalive(autoKi.mAutomaticOnOffState != STATE_SUSPENDED);
autoKi.close();
if (null != autoKi.mAlarmListener) mAlarmManager.cancel(autoKi.mAlarmListener);

View File

@ -0,0 +1,191 @@
/*
* Copyright (C) 2023 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.connectivity;
import android.os.SystemClock;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
import com.android.metrics.DailykeepaliveInfoReported;
import com.android.metrics.DurationForNumOfKeepalive;
import com.android.metrics.DurationPerNumOfKeepalive;
import java.util.ArrayList;
import java.util.List;
// TODO(b/273451360): Also track KeepaliveLifetimeForCarrier and DailykeepaliveInfoReported
/**
* Tracks carrier and duration metrics of automatic on/off keepalives.
*
* <p>This class follows AutomaticOnOffKeepaliveTracker closely and its on*Keepalive methods needs
* to be called in a timely manner to keep the metrics accurate. It is also not thread-safe and all
* public methods must be called by the same thread, namely the ConnectivityService handler thread.
*/
public class KeepaliveStatsTracker {
private static final String TAG = KeepaliveStatsTracker.class.getSimpleName();
private final Dependencies mDependencies;
// List of duration stats metric where the index is the number of concurrent keepalives.
// Each DurationForNumOfKeepalive message stores a registered duration and an active duration.
// Registered duration is the total time spent with mNumRegisteredKeepalive == index.
// Active duration is the total time spent with mNumActiveKeepalive == index.
private final List<DurationForNumOfKeepalive.Builder> mDurationPerNumOfKeepalive =
new ArrayList<>();
private int mNumRegisteredKeepalive = 0;
private int mNumActiveKeepalive = 0;
// A timestamp of the most recent time the duration metrics was updated.
private long mTimestampSinceLastUpdateDurations;
/** Dependency class */
@VisibleForTesting
public static class Dependencies {
// Returns a timestamp with the time base of SystemClock.uptimeMillis to keep durations
// relative to start time and avoid timezone change.
public long getUptimeMillis() {
return SystemClock.uptimeMillis();
}
}
public KeepaliveStatsTracker() {
this(new Dependencies());
}
@VisibleForTesting
public KeepaliveStatsTracker(Dependencies dependencies) {
mDependencies = dependencies;
mTimestampSinceLastUpdateDurations = mDependencies.getUptimeMillis();
}
/** Ensures the list of duration metrics is large enough for number of registered keepalives. */
private void ensureDurationPerNumOfKeepaliveSize() {
if (mNumActiveKeepalive < 0 || mNumRegisteredKeepalive < 0) {
throw new IllegalStateException(
"Number of active or registered keepalives is negative");
}
if (mNumActiveKeepalive > mNumRegisteredKeepalive) {
throw new IllegalStateException(
"Number of active keepalives greater than registered keepalives");
}
while (mDurationPerNumOfKeepalive.size() <= mNumRegisteredKeepalive) {
final DurationForNumOfKeepalive.Builder durationForNumOfKeepalive =
DurationForNumOfKeepalive.newBuilder();
durationForNumOfKeepalive.setNumOfKeepalive(mDurationPerNumOfKeepalive.size());
durationForNumOfKeepalive.setKeepaliveRegisteredDurationsMsec(0);
durationForNumOfKeepalive.setKeepaliveActiveDurationsMsec(0);
mDurationPerNumOfKeepalive.add(durationForNumOfKeepalive);
}
}
/**
* Updates the durations metrics to the given time. This should always be called before making a
* change to mNumRegisteredKeepalive or mNumActiveKeepalive to keep the duration metrics
* correct.
*
* @param timeNow a timestamp obtained using Dependencies.getUptimeMillis
*/
private void updateDurationsPerNumOfKeepalive(long timeNow) {
if (mDurationPerNumOfKeepalive.size() < mNumRegisteredKeepalive) {
Log.e(TAG, "Unexpected jump in number of registered keepalive");
}
ensureDurationPerNumOfKeepaliveSize();
final int durationIncrease = (int) (timeNow - mTimestampSinceLastUpdateDurations);
final DurationForNumOfKeepalive.Builder durationForNumOfRegisteredKeepalive =
mDurationPerNumOfKeepalive.get(mNumRegisteredKeepalive);
durationForNumOfRegisteredKeepalive.setKeepaliveRegisteredDurationsMsec(
durationForNumOfRegisteredKeepalive.getKeepaliveRegisteredDurationsMsec()
+ durationIncrease);
final DurationForNumOfKeepalive.Builder durationForNumOfActiveKeepalive =
mDurationPerNumOfKeepalive.get(mNumActiveKeepalive);
durationForNumOfActiveKeepalive.setKeepaliveActiveDurationsMsec(
durationForNumOfActiveKeepalive.getKeepaliveActiveDurationsMsec()
+ durationIncrease);
mTimestampSinceLastUpdateDurations = timeNow;
}
/** Inform the KeepaliveStatsTracker a keepalive has just started and is active. */
public void onStartKeepalive() {
final long timeNow = mDependencies.getUptimeMillis();
updateDurationsPerNumOfKeepalive(timeNow);
mNumRegisteredKeepalive++;
mNumActiveKeepalive++;
}
/** Inform the KeepaliveStatsTracker a keepalive has just been paused. */
public void onPauseKeepalive() {
final long timeNow = mDependencies.getUptimeMillis();
updateDurationsPerNumOfKeepalive(timeNow);
mNumActiveKeepalive--;
}
/** Inform the KeepaliveStatsTracker a keepalive has just been resumed. */
public void onResumeKeepalive() {
final long timeNow = mDependencies.getUptimeMillis();
updateDurationsPerNumOfKeepalive(timeNow);
mNumActiveKeepalive++;
}
/** Inform the KeepaliveStatsTracker a keepalive has just been stopped. */
public void onStopKeepalive(boolean wasActive) {
final long timeNow = mDependencies.getUptimeMillis();
updateDurationsPerNumOfKeepalive(timeNow);
mNumRegisteredKeepalive--;
if (wasActive) mNumActiveKeepalive--;
}
/**
* Builds and returns DailykeepaliveInfoReported proto.
*/
public DailykeepaliveInfoReported buildKeepaliveMetrics() {
final long timeNow = mDependencies.getUptimeMillis();
updateDurationsPerNumOfKeepalive(timeNow);
final DurationPerNumOfKeepalive.Builder durationPerNumOfKeepalive =
DurationPerNumOfKeepalive.newBuilder();
mDurationPerNumOfKeepalive.forEach(
durationForNumOfKeepalive ->
durationPerNumOfKeepalive.addDurationForNumOfKeepalive(
durationForNumOfKeepalive));
final DailykeepaliveInfoReported.Builder dailyKeepaliveInfoReported =
DailykeepaliveInfoReported.newBuilder();
// TODO(b/273451360): fill all the other values and write to ConnectivityStatsLog.
dailyKeepaliveInfoReported.setDurationPerNumOfKeepalive(durationPerNumOfKeepalive);
return dailyKeepaliveInfoReported.build();
}
/** Resets the stored metrics but maintains the state of keepalives */
public void resetMetrics() {
mDurationPerNumOfKeepalive.clear();
ensureDurationPerNumOfKeepaliveSize();
}
}

View File

@ -0,0 +1,504 @@
/*
* Copyright (C) 2022 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.connectivity;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.mockito.Mockito.doReturn;
import android.os.Build;
import androidx.test.filters.SmallTest;
import com.android.metrics.DailykeepaliveInfoReported;
import com.android.metrics.DurationForNumOfKeepalive;
import com.android.metrics.DurationPerNumOfKeepalive;
import com.android.testutils.DevSdkIgnoreRule;
import com.android.testutils.DevSdkIgnoreRunner;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@RunWith(DevSdkIgnoreRunner.class)
@SmallTest
@DevSdkIgnoreRule.IgnoreUpTo(Build.VERSION_CODES.TIRAMISU)
public class KeepaliveStatsTrackerTest {
private static final int TEST_UID = 1234;
private KeepaliveStatsTracker mKeepaliveStatsTracker;
@Mock KeepaliveStatsTracker.Dependencies mDependencies;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
setUptimeMillis(0);
mKeepaliveStatsTracker = new KeepaliveStatsTracker(mDependencies);
}
private void setUptimeMillis(long time) {
doReturn(time).when(mDependencies).getUptimeMillis();
}
/**
* Asserts that a DurationPerNumOfKeepalive contains expected values
*
* @param expectRegisteredDurations integer array where the index is the number of concurrent
* keepalives and the value is the expected duration of time that the tracker is in a state
* with the given number of keepalives registered.
* @param expectActiveDurations integer array where the index is the number of concurrent
* keepalives and the value is the expected duration of time that the tracker is in a state
* with the given number of keepalives active.
* @param resultDurationsPerNumOfKeepalive the DurationPerNumOfKeepalive message to assert.
*/
private void assertDurationMetrics(
int[] expectRegisteredDurations,
int[] expectActiveDurations,
DurationPerNumOfKeepalive resultDurationsPerNumOfKeepalive) {
final int maxNumOfKeepalive = expectRegisteredDurations.length;
assertEquals(maxNumOfKeepalive, expectActiveDurations.length);
assertEquals(
maxNumOfKeepalive,
resultDurationsPerNumOfKeepalive.getDurationForNumOfKeepaliveCount());
for (int numOfKeepalive = 0; numOfKeepalive < maxNumOfKeepalive; numOfKeepalive++) {
final DurationForNumOfKeepalive resultDurations =
resultDurationsPerNumOfKeepalive.getDurationForNumOfKeepalive(numOfKeepalive);
assertEquals(numOfKeepalive, resultDurations.getNumOfKeepalive());
assertEquals(
expectRegisteredDurations[numOfKeepalive],
resultDurations.getKeepaliveRegisteredDurationsMsec());
assertEquals(
expectActiveDurations[numOfKeepalive],
resultDurations.getKeepaliveActiveDurationsMsec());
}
}
private void assertDailyKeepaliveInfoReported(
DailykeepaliveInfoReported dailyKeepaliveInfoReported,
int[] expectRegisteredDurations,
int[] expectActiveDurations) {
// TODO(b/273451360) Assert these values when they are filled.
assertFalse(dailyKeepaliveInfoReported.hasKeepaliveLifetimePerCarrier());
assertFalse(dailyKeepaliveInfoReported.hasKeepaliveRequests());
assertFalse(dailyKeepaliveInfoReported.hasAutomaticKeepaliveRequests());
assertFalse(dailyKeepaliveInfoReported.hasDistinctUserCount());
assertTrue(dailyKeepaliveInfoReported.getUidList().isEmpty());
final DurationPerNumOfKeepalive resultDurations =
dailyKeepaliveInfoReported.getDurationPerNumOfKeepalive();
assertDurationMetrics(expectRegisteredDurations, expectActiveDurations, resultDurations);
}
@Test
public void testNoKeepalive() {
final int writeTime = 5000;
setUptimeMillis(writeTime);
final DailykeepaliveInfoReported dailyKeepaliveInfoReported =
mKeepaliveStatsTracker.buildKeepaliveMetrics();
// Expect that the durations are all in numOfKeepalive = 0.
final int[] expectRegisteredDurations = new int[] {writeTime};
final int[] expectActiveDurations = new int[] {writeTime};
assertDailyKeepaliveInfoReported(
dailyKeepaliveInfoReported,
expectRegisteredDurations,
expectActiveDurations);
}
/*
* Diagram of test (not to scale):
* Key: S - Start/Stop, P - Pause, R - Resume, W - Write
*
* Keepalive S W
* Timeline |------------------------------|
*/
@Test
public void testOneKeepalive_startOnly() {
final int startTime = 1000;
final int writeTime = 5000;
setUptimeMillis(startTime);
mKeepaliveStatsTracker.onStartKeepalive();
setUptimeMillis(writeTime);
final DailykeepaliveInfoReported dailyKeepaliveInfoReported =
mKeepaliveStatsTracker.buildKeepaliveMetrics();
// The keepalive is never stopped, expect the duration for numberOfKeepalive of 1 to range
// from startTime to writeTime.
final int[] expectRegisteredDurations = new int[] {startTime, writeTime - startTime};
final int[] expectActiveDurations = new int[] {startTime, writeTime - startTime};
assertDailyKeepaliveInfoReported(
dailyKeepaliveInfoReported,
expectRegisteredDurations,
expectActiveDurations);
}
/*
* Diagram of test (not to scale):
* Key: S - Start/Stop, P - Pause, R - Resume, W - Write
*
* Keepalive S P W
* Timeline |------------------------------|
*/
@Test
public void testOneKeepalive_paused() {
final int startTime = 1000;
final int pauseTime = 2030;
final int writeTime = 5000;
setUptimeMillis(startTime);
mKeepaliveStatsTracker.onStartKeepalive();
setUptimeMillis(pauseTime);
mKeepaliveStatsTracker.onPauseKeepalive();
setUptimeMillis(writeTime);
final DailykeepaliveInfoReported dailyKeepaliveInfoReported =
mKeepaliveStatsTracker.buildKeepaliveMetrics();
// The keepalive is paused but not stopped, expect the registered duration for
// numberOfKeepalive of 1 to still range from startTime to writeTime while the active
// duration stops at pauseTime.
final int[] expectRegisteredDurations = new int[] {startTime, writeTime - startTime};
final int[] expectActiveDurations =
new int[] {startTime + (writeTime - pauseTime), pauseTime - startTime};
assertDailyKeepaliveInfoReported(
dailyKeepaliveInfoReported,
expectRegisteredDurations,
expectActiveDurations);
}
/*
* Diagram of test (not to scale):
* Key: S - Start/Stop, P - Pause, R - Resume, W - Write
*
* Keepalive S P R W
* Timeline |------------------------------|
*/
@Test
public void testOneKeepalive_resumed() {
final int startTime = 1000;
final int pauseTime = 2030;
final int resumeTime = 3450;
final int writeTime = 5000;
setUptimeMillis(startTime);
mKeepaliveStatsTracker.onStartKeepalive();
setUptimeMillis(pauseTime);
mKeepaliveStatsTracker.onPauseKeepalive();
setUptimeMillis(resumeTime);
mKeepaliveStatsTracker.onResumeKeepalive();
setUptimeMillis(writeTime);
final DailykeepaliveInfoReported dailyKeepaliveInfoReported =
mKeepaliveStatsTracker.buildKeepaliveMetrics();
// The keepalive is paused and resumed but not stopped, expect the registered duration for
// numberOfKeepalive of 1 to still range from startTime to writeTime while the active
// duration stops at pauseTime but resumes at resumeTime and stops at writeTime.
final int[] expectRegisteredDurations = new int[] {startTime, writeTime - startTime};
final int[] expectActiveDurations =
new int[] {
startTime + (resumeTime - pauseTime),
(pauseTime - startTime) + (writeTime - resumeTime)
};
assertDailyKeepaliveInfoReported(
dailyKeepaliveInfoReported,
expectRegisteredDurations,
expectActiveDurations);
}
/*
* Diagram of test (not to scale):
* Key: S - Start/Stop, P - Pause, R - Resume, W - Write
*
* Keepalive S P R S W
* Timeline |------------------------------|
*/
@Test
public void testOneKeepalive_stopped() {
final int startTime = 1000;
final int pauseTime = 2930;
final int resumeTime = 3452;
final int stopTime = 4157;
final int writeTime = 5000;
setUptimeMillis(startTime);
mKeepaliveStatsTracker.onStartKeepalive();
setUptimeMillis(pauseTime);
mKeepaliveStatsTracker.onPauseKeepalive();
setUptimeMillis(resumeTime);
mKeepaliveStatsTracker.onResumeKeepalive();
setUptimeMillis(stopTime);
mKeepaliveStatsTracker.onStopKeepalive(/* wasActive= */ true);
setUptimeMillis(writeTime);
final DailykeepaliveInfoReported dailyKeepaliveInfoReported =
mKeepaliveStatsTracker.buildKeepaliveMetrics();
// The keepalive is now stopped, expect the registered duration for numberOfKeepalive of 1
// to now range from startTime to stopTime while the active duration stops at pauseTime but
// resumes at resumeTime and stops again at stopTime.
final int[] expectRegisteredDurations =
new int[] {startTime + (writeTime - stopTime), stopTime - startTime};
final int[] expectActiveDurations =
new int[] {
startTime + (resumeTime - pauseTime) + (writeTime - stopTime),
(pauseTime - startTime) + (stopTime - resumeTime)
};
assertDailyKeepaliveInfoReported(
dailyKeepaliveInfoReported,
expectRegisteredDurations,
expectActiveDurations);
}
/*
* Diagram of test (not to scale):
* Key: S - Start/Stop, P - Pause, R - Resume, W - Write
*
* Keepalive S P S W
* Timeline |------------------------------|
*/
@Test
public void testOneKeepalive_pausedStopped() {
final int startTime = 1000;
final int pauseTime = 2930;
final int stopTime = 4157;
final int writeTime = 5000;
setUptimeMillis(startTime);
mKeepaliveStatsTracker.onStartKeepalive();
setUptimeMillis(pauseTime);
mKeepaliveStatsTracker.onPauseKeepalive();
setUptimeMillis(stopTime);
mKeepaliveStatsTracker.onStopKeepalive(/* wasActive= */ false);
setUptimeMillis(writeTime);
final DailykeepaliveInfoReported dailyKeepaliveInfoReported =
mKeepaliveStatsTracker.buildKeepaliveMetrics();
// The keepalive is stopped while paused, expect the registered duration for
// numberOfKeepalive of 1 to range from startTime to stopTime while the active duration
// simply stops at pauseTime.
final int[] expectRegisteredDurations =
new int[] {startTime + (writeTime - stopTime), stopTime - startTime};
final int[] expectActiveDurations =
new int[] {startTime + (writeTime - pauseTime), (pauseTime - startTime)};
assertDailyKeepaliveInfoReported(
dailyKeepaliveInfoReported,
expectRegisteredDurations,
expectActiveDurations);
}
/*
* Diagram of test (not to scale):
* Key: S - Start/Stop, P - Pause, R - Resume, W - Write
*
* Keepalive S P R P R P R S W
* Timeline |------------------------------|
*/
@Test
public void testOneKeepalive_multiplePauses() {
final int startTime = 1000;
// Alternating timestamps of pause and resume
final int[] pauseResumeTimes = new int[] {1200, 1400, 1700, 2000, 2400, 2800};
final int stopTime = 4000;
final int writeTime = 5000;
setUptimeMillis(startTime);
mKeepaliveStatsTracker.onStartKeepalive();
for (int i = 0; i < pauseResumeTimes.length; i++) {
setUptimeMillis(pauseResumeTimes[i]);
if (i % 2 == 0) {
mKeepaliveStatsTracker.onPauseKeepalive();
} else {
mKeepaliveStatsTracker.onResumeKeepalive();
}
}
setUptimeMillis(stopTime);
mKeepaliveStatsTracker.onStopKeepalive(/* wasActive= */ true);
setUptimeMillis(writeTime);
final DailykeepaliveInfoReported dailyKeepaliveInfoReported =
mKeepaliveStatsTracker.buildKeepaliveMetrics();
final int[] expectRegisteredDurations =
new int[] {startTime + (writeTime - stopTime), stopTime - startTime};
final int[] expectActiveDurations =
new int[] {
startTime + /* sum of (Resume - Pause) */ (900) + (writeTime - stopTime),
(pauseResumeTimes[0] - startTime)
+ /* sum of (Pause - Resume) */ (700)
+ (stopTime - pauseResumeTimes[5])
};
assertDailyKeepaliveInfoReported(
dailyKeepaliveInfoReported,
expectRegisteredDurations,
expectActiveDurations);
}
/*
* Diagram of test (not to scale):
* Key: S - Start/Stop, P - Pause, R - Resume, W - Write
*
* Keepalive1 S1 P1 R1 S1 W
* Keepalive2 S2 P2 R2 W
* Timeline |------------------------------|
*/
@Test
public void testTwoKeepalives() {
// The suffix 1/2 indicates which keepalive it is referring to.
final int startTime1 = 1000;
final int pauseTime1 = 1500;
final int startTime2 = 2000;
final int resumeTime1 = 2500;
final int pauseTime2 = 3000;
final int resumeTime2 = 3500;
final int stopTime1 = 4157;
final int writeTime = 5000;
setUptimeMillis(startTime1);
mKeepaliveStatsTracker.onStartKeepalive();
setUptimeMillis(pauseTime1);
mKeepaliveStatsTracker.onPauseKeepalive();
setUptimeMillis(startTime2);
mKeepaliveStatsTracker.onStartKeepalive();
setUptimeMillis(resumeTime1);
mKeepaliveStatsTracker.onResumeKeepalive();
setUptimeMillis(pauseTime2);
mKeepaliveStatsTracker.onPauseKeepalive();
setUptimeMillis(resumeTime2);
mKeepaliveStatsTracker.onResumeKeepalive();
setUptimeMillis(stopTime1);
mKeepaliveStatsTracker.onStopKeepalive(/* wasActive= */ true);
setUptimeMillis(writeTime);
final DailykeepaliveInfoReported dailyKeepaliveInfoReported =
mKeepaliveStatsTracker.buildKeepaliveMetrics();
// With two keepalives, the number of concurrent keepalives can vary from 0-2 depending on
// both keepalive states.
final int[] expectRegisteredDurations =
new int[] {
startTime1,
// 1 registered keepalive before keepalive2 starts and after keepalive1 stops.
(startTime2 - startTime1) + (writeTime - stopTime1),
// 2 registered keepalives between keepalive2 start and keepalive1 stop.
stopTime1 - startTime2
};
final int[] expectActiveDurations =
new int[] {
// 0 active keepalives when keepalive1 is paused before keepalive2 starts.
startTime1 + (startTime2 - pauseTime1),
// 1 active keepalive before keepalive1 is paused.
(pauseTime1 - startTime1)
// before keepalive1 is resumed and after keepalive2 starts.
+ (resumeTime1 - startTime2)
// during keepalive2 is paused since keepalive1 has been resumed.
+ (resumeTime2 - pauseTime2)
// after keepalive1 stops since keepalive2 has been resumed.
+ (writeTime - stopTime1),
// 2 active keepalives before keepalive2 is paused and before keepalive1 stops.
(pauseTime2 - resumeTime1) + (stopTime1 - resumeTime2)
};
assertDailyKeepaliveInfoReported(
dailyKeepaliveInfoReported,
expectRegisteredDurations,
expectActiveDurations);
}
/*
* Diagram of test (not to scale):
* Key: S - Start/Stop, P - Pause, R - Resume, W - Write
*
* Keepalive S W(reset+W) S W
* Timeline |------------------------------|
*/
@Test
public void testResetMetrics() {
final int startTime = 1000;
final int writeTime = 5000;
final int stopTime = 7000;
final int writeTime2 = 10000;
setUptimeMillis(startTime);
mKeepaliveStatsTracker.onStartKeepalive();
setUptimeMillis(writeTime);
final DailykeepaliveInfoReported dailyKeepaliveInfoReported =
mKeepaliveStatsTracker.buildKeepaliveMetrics();
// Same expect as testOneKeepalive_startOnly
final int[] expectRegisteredDurations = new int[] {startTime, writeTime - startTime};
final int[] expectActiveDurations = new int[] {startTime, writeTime - startTime};
assertDailyKeepaliveInfoReported(
dailyKeepaliveInfoReported,
expectRegisteredDurations,
expectActiveDurations);
// Reset metrics
mKeepaliveStatsTracker.resetMetrics();
final DailykeepaliveInfoReported dailyKeepaliveInfoReported2 =
mKeepaliveStatsTracker.buildKeepaliveMetrics();
// Expect the stored durations to be 0 but still contain the number of keepalive = 1.
assertDailyKeepaliveInfoReported(
dailyKeepaliveInfoReported2,
/* expectRegisteredDurations= */ new int[] {0, 0},
/* expectActiveDurations= */ new int[] {0, 0});
// Expect that the keepalive is still registered after resetting so it can be stopped.
setUptimeMillis(stopTime);
mKeepaliveStatsTracker.onStopKeepalive(/* wasActive= */ true);
setUptimeMillis(writeTime2);
final DailykeepaliveInfoReported dailyKeepaliveInfoReported3 =
mKeepaliveStatsTracker.buildKeepaliveMetrics();
final int[] expectRegisteredDurations2 =
new int[] {writeTime2 - stopTime, stopTime - writeTime};
final int[] expectActiveDurations2 =
new int[] {writeTime2 - stopTime, stopTime - writeTime};
assertDailyKeepaliveInfoReported(
dailyKeepaliveInfoReported3,
expectRegisteredDurations2,
expectActiveDurations2);
}
}