Merge changes I5fffc137,Ifc076a8d into main

* changes:
  Add Log.wtf when keepalive metrics are unexpected.
  Add dump of KeepaliveStatsTracker
This commit is contained in:
Hansen Kurli
2023-11-01 08:50:39 +00:00
committed by Gerrit Code Review
4 changed files with 82 additions and 0 deletions

View File

@@ -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);
} }
/** /**

View File

@@ -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(

View File

@@ -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());
}
} }

View File

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