Merge changes I5fffc137,Ifc076a8d into main
* changes: Add Log.wtf when keepalive metrics are unexpected. Add dump of KeepaliveStatsTracker
This commit is contained in:
@@ -692,8 +692,10 @@ public class AutomaticOnOffKeepaliveTracker {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Dump AutomaticOnOffKeepaliveTracker state.
|
* Dump AutomaticOnOffKeepaliveTracker state.
|
||||||
|
* This should be only be called in ConnectivityService handler thread.
|
||||||
*/
|
*/
|
||||||
public void dump(IndentingPrintWriter pw) {
|
public void dump(IndentingPrintWriter pw) {
|
||||||
|
ensureRunningOnHandlerThread();
|
||||||
mKeepaliveTracker.dump(pw);
|
mKeepaliveTracker.dump(pw);
|
||||||
// Reading DeviceConfig will check if the calling uid and calling package name are the same.
|
// Reading DeviceConfig will check if the calling uid and calling package name are the same.
|
||||||
// Clear calling identity to align the calling uid and package so that it won't fail if cts
|
// Clear calling identity to align the calling uid and package so that it won't fail if cts
|
||||||
@@ -712,6 +714,9 @@ public class AutomaticOnOffKeepaliveTracker {
|
|||||||
pw.increaseIndent();
|
pw.increaseIndent();
|
||||||
mEventLog.reverseDump(pw);
|
mEventLog.reverseDump(pw);
|
||||||
pw.decreaseIndent();
|
pw.decreaseIndent();
|
||||||
|
|
||||||
|
pw.println();
|
||||||
|
mKeepaliveStatsTracker.dump(pw);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ import android.os.SystemClock;
|
|||||||
import android.telephony.SubscriptionInfo;
|
import android.telephony.SubscriptionInfo;
|
||||||
import android.telephony.SubscriptionManager;
|
import android.telephony.SubscriptionManager;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
|
import android.util.IndentingPrintWriter;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.util.SparseArray;
|
import android.util.SparseArray;
|
||||||
import android.util.SparseIntArray;
|
import android.util.SparseIntArray;
|
||||||
@@ -73,6 +74,9 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
|||||||
public class KeepaliveStatsTracker {
|
public class KeepaliveStatsTracker {
|
||||||
private static final String TAG = KeepaliveStatsTracker.class.getSimpleName();
|
private static final String TAG = KeepaliveStatsTracker.class.getSimpleName();
|
||||||
private static final int INVALID_KEEPALIVE_ID = -1;
|
private static final int INVALID_KEEPALIVE_ID = -1;
|
||||||
|
// 1 hour acceptable deviation in metrics collection duration time.
|
||||||
|
private static final long MAX_EXPECTED_DURATION_MS =
|
||||||
|
AutomaticOnOffKeepaliveTracker.METRICS_COLLECTION_DURATION_MS + 1 * 60 * 60 * 1_000L;
|
||||||
|
|
||||||
@NonNull private final Handler mConnectivityServiceHandler;
|
@NonNull private final Handler mConnectivityServiceHandler;
|
||||||
@NonNull private final Dependencies mDependencies;
|
@NonNull private final Dependencies mDependencies;
|
||||||
@@ -709,6 +713,36 @@ public class KeepaliveStatsTracker {
|
|||||||
return mEnabled.get();
|
return mEnabled.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the DailykeepaliveInfoReported for the following:
|
||||||
|
* 1. total active durations/lifetimes <= total registered durations/lifetimes.
|
||||||
|
* 2. Total time in Durations == total time in Carrier lifetime stats
|
||||||
|
* 3. The total elapsed real time spent is within expectations.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
public boolean allMetricsExpected(DailykeepaliveInfoReported dailyKeepaliveInfoReported) {
|
||||||
|
int totalRegistered = 0;
|
||||||
|
int totalActiveDurations = 0;
|
||||||
|
int totalTimeSpent = 0;
|
||||||
|
for (DurationForNumOfKeepalive durationForNumOfKeepalive: dailyKeepaliveInfoReported
|
||||||
|
.getDurationPerNumOfKeepalive().getDurationForNumOfKeepaliveList()) {
|
||||||
|
final int n = durationForNumOfKeepalive.getNumOfKeepalive();
|
||||||
|
totalRegistered += durationForNumOfKeepalive.getKeepaliveRegisteredDurationsMsec() * n;
|
||||||
|
totalActiveDurations += durationForNumOfKeepalive.getKeepaliveActiveDurationsMsec() * n;
|
||||||
|
totalTimeSpent += durationForNumOfKeepalive.getKeepaliveRegisteredDurationsMsec();
|
||||||
|
}
|
||||||
|
int totalLifetimes = 0;
|
||||||
|
int totalActiveLifetimes = 0;
|
||||||
|
for (KeepaliveLifetimeForCarrier keepaliveLifetimeForCarrier: dailyKeepaliveInfoReported
|
||||||
|
.getKeepaliveLifetimePerCarrier().getKeepaliveLifetimeForCarrierList()) {
|
||||||
|
totalLifetimes += keepaliveLifetimeForCarrier.getLifetimeMsec();
|
||||||
|
totalActiveLifetimes += keepaliveLifetimeForCarrier.getActiveLifetimeMsec();
|
||||||
|
}
|
||||||
|
return totalActiveDurations <= totalRegistered && totalActiveLifetimes <= totalLifetimes
|
||||||
|
&& totalLifetimes == totalRegistered && totalActiveLifetimes == totalActiveDurations
|
||||||
|
&& totalTimeSpent <= MAX_EXPECTED_DURATION_MS;
|
||||||
|
}
|
||||||
|
|
||||||
/** Writes the stored metrics to ConnectivityStatsLog and resets. */
|
/** Writes the stored metrics to ConnectivityStatsLog and resets. */
|
||||||
public void writeAndResetMetrics() {
|
public void writeAndResetMetrics() {
|
||||||
ensureRunningOnHandlerThread();
|
ensureRunningOnHandlerThread();
|
||||||
@@ -724,9 +758,21 @@ public class KeepaliveStatsTracker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final DailykeepaliveInfoReported dailyKeepaliveInfoReported = buildAndResetMetrics();
|
final DailykeepaliveInfoReported dailyKeepaliveInfoReported = buildAndResetMetrics();
|
||||||
|
if (!allMetricsExpected(dailyKeepaliveInfoReported)) {
|
||||||
|
Log.wtf(TAG, "Unexpected metrics values: " + dailyKeepaliveInfoReported.toString());
|
||||||
|
}
|
||||||
mDependencies.writeStats(dailyKeepaliveInfoReported);
|
mDependencies.writeStats(dailyKeepaliveInfoReported);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Dump KeepaliveStatsTracker state. */
|
||||||
|
public void dump(IndentingPrintWriter pw) {
|
||||||
|
ensureRunningOnHandlerThread();
|
||||||
|
pw.println("KeepaliveStatsTracker enabled: " + isEnabled());
|
||||||
|
pw.increaseIndent();
|
||||||
|
pw.println(buildKeepaliveMetrics().toString());
|
||||||
|
pw.decreaseIndent();
|
||||||
|
}
|
||||||
|
|
||||||
private void ensureRunningOnHandlerThread() {
|
private void ensureRunningOnHandlerThread() {
|
||||||
if (mConnectivityServiceHandler.getLooper().getThread() != Thread.currentThread()) {
|
if (mConnectivityServiceHandler.getLooper().getThread() != Thread.currentThread()) {
|
||||||
throw new IllegalStateException(
|
throw new IllegalStateException(
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ import android.util.Log;
|
|||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.android.internal.util.IndentingPrintWriter;
|
||||||
import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker.AutomaticOnOffKeepalive;
|
import com.android.server.connectivity.AutomaticOnOffKeepaliveTracker.AutomaticOnOffKeepalive;
|
||||||
import com.android.server.connectivity.KeepaliveTracker.KeepaliveInfo;
|
import com.android.server.connectivity.KeepaliveTracker.KeepaliveInfo;
|
||||||
import com.android.testutils.DevSdkIgnoreRule;
|
import com.android.testutils.DevSdkIgnoreRule;
|
||||||
@@ -94,6 +95,7 @@ import org.mockito.Mock;
|
|||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
import java.io.FileDescriptor;
|
import java.io.FileDescriptor;
|
||||||
|
import java.io.StringWriter;
|
||||||
import java.net.Inet4Address;
|
import java.net.Inet4Address;
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
@@ -974,4 +976,19 @@ public class AutomaticOnOffKeepaliveTrackerTest {
|
|||||||
// The keepalive should be removed in AutomaticOnOffKeepaliveTracker.
|
// The keepalive should be removed in AutomaticOnOffKeepaliveTracker.
|
||||||
assertNull(getAutoKiForBinder(testInfo.binder));
|
assertNull(getAutoKiForBinder(testInfo.binder));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDumpDoesNotCrash() throws Exception {
|
||||||
|
final TestKeepaliveInfo testInfo1 = doStartNattKeepalive();
|
||||||
|
final TestKeepaliveInfo testInfo2 = doStartNattKeepalive();
|
||||||
|
checkAndProcessKeepaliveStart(TEST_SLOT, testInfo1.kpd);
|
||||||
|
checkAndProcessKeepaliveStart(TEST_SLOT + 1, testInfo2.kpd);
|
||||||
|
final AutomaticOnOffKeepalive autoKi1 = getAutoKiForBinder(testInfo1.binder);
|
||||||
|
doPauseKeepalive(autoKi1);
|
||||||
|
|
||||||
|
final StringWriter stringWriter = new StringWriter();
|
||||||
|
final IndentingPrintWriter pw = new IndentingPrintWriter(stringWriter, " ");
|
||||||
|
visibleOnHandlerThread(mTestHandler, () -> mAOOKeepaliveTracker.dump(pw));
|
||||||
|
assertFalse(stringWriter.toString().isEmpty());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ import static org.mockito.Mockito.doCallRealMethod;
|
|||||||
import static org.mockito.Mockito.doReturn;
|
import static org.mockito.Mockito.doReturn;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
import static org.mockito.Mockito.never;
|
import static org.mockito.Mockito.never;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
@@ -1293,5 +1294,18 @@ public class KeepaliveStatsTrackerTest {
|
|||||||
expectRegisteredDurations,
|
expectRegisteredDurations,
|
||||||
expectActiveDurations,
|
expectActiveDurations,
|
||||||
new KeepaliveCarrierStats[0]);
|
new KeepaliveCarrierStats[0]);
|
||||||
|
|
||||||
|
assertTrue(mKeepaliveStatsTracker.allMetricsExpected(dailyKeepaliveInfoReported));
|
||||||
|
|
||||||
|
// Write time after 26 hours.
|
||||||
|
final int writeTime2 = 26 * 60 * 60 * 1000;
|
||||||
|
setElapsedRealtime(writeTime2);
|
||||||
|
|
||||||
|
visibleOnHandlerThread(mTestHandler, () -> mKeepaliveStatsTracker.writeAndResetMetrics());
|
||||||
|
verify(mDependencies, times(2)).writeStats(dailyKeepaliveInfoReportedCaptor.capture());
|
||||||
|
final DailykeepaliveInfoReported dailyKeepaliveInfoReported2 =
|
||||||
|
dailyKeepaliveInfoReportedCaptor.getValue();
|
||||||
|
|
||||||
|
assertFalse(mKeepaliveStatsTracker.allMetricsExpected(dailyKeepaliveInfoReported2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user