diff --git a/core/java/android/net/metrics/ValidationProbeEvent.java b/core/java/android/net/metrics/ValidationProbeEvent.java index 42e8aa6dc248d..a43dc60cec84e 100644 --- a/core/java/android/net/metrics/ValidationProbeEvent.java +++ b/core/java/android/net/metrics/ValidationProbeEvent.java @@ -79,7 +79,7 @@ public final class ValidationProbeEvent implements IpConnectivityLog.Event { } /** - * Utility to create an instance of {@link ApfProgramEvent}. + * Utility to create an instance of {@link ValidationProbeEvent}. */ public static class Builder { private long mDurationMs; diff --git a/packages/NetworkStack/src/android/net/metrics/DataStallDetectionStats.java b/packages/NetworkStack/src/android/net/metrics/DataStallDetectionStats.java index 6ea1e3d49dd41..225dc0f4bfdc4 100644 --- a/packages/NetworkStack/src/android/net/metrics/DataStallDetectionStats.java +++ b/packages/NetworkStack/src/android/net/metrics/DataStallDetectionStats.java @@ -30,7 +30,9 @@ import com.android.server.connectivity.nano.WifiData; import com.google.protobuf.nano.MessageNano; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; +import java.util.Objects; /** * Class to record the stats of detection level information for data stall. @@ -96,6 +98,22 @@ public final class DataStallDetectionStats { return sb.toString(); } + @Override + public boolean equals(@Nullable final Object o) { + if (!(o instanceof DataStallDetectionStats)) return false; + final DataStallDetectionStats other = (DataStallDetectionStats) o; + return (mNetworkType == other.mNetworkType) + && (mEvaluationType == other.mEvaluationType) + && Arrays.equals(mWifiInfo, other.mWifiInfo) + && Arrays.equals(mCellularInfo, other.mCellularInfo) + && Arrays.equals(mDns, other.mDns); + } + + @Override + public int hashCode() { + return Objects.hash(mNetworkType, mEvaluationType, mWifiInfo, mCellularInfo, mDns); + } + /** * Utility to create an instance of {@Link DataStallDetectionStats} * @@ -163,16 +181,17 @@ public final class DataStallDetectionStats { } private static int getWifiBand(@Nullable final WifiInfo info) { - if (info != null) { - int freq = info.getFrequency(); - // Refer to ScanResult.is5GHz() and ScanResult.is24GHz(). - if (freq > 4900 && freq < 5900) { - return DataStallEventProto.AP_BAND_5GHZ; - } else if (freq > 2400 && freq < 2500) { - return DataStallEventProto.AP_BAND_2GHZ; - } + if (info == null) return DataStallEventProto.AP_BAND_UNKNOWN; + + int freq = info.getFrequency(); + // Refer to ScanResult.is5GHz() and ScanResult.is24GHz(). + if (freq > 4900 && freq < 5900) { + return DataStallEventProto.AP_BAND_5GHZ; + } else if (freq > 2400 && freq < 2500) { + return DataStallEventProto.AP_BAND_2GHZ; + } else { + return DataStallEventProto.AP_BAND_UNKNOWN; } - return DataStallEventProto.AP_BAND_UNKNOWN; } /** diff --git a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java index 3c129ce81b653..e82a5d7b4881e 100644 --- a/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java +++ b/packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java @@ -729,7 +729,8 @@ public class NetworkMonitor extends StateMachine { return stats.build(); } - private void addDnsEvents(@NonNull final DataStallDetectionStats.Builder stats) { + @VisibleForTesting + protected void addDnsEvents(@NonNull final DataStallDetectionStats.Builder stats) { final int size = mDnsStallDetector.mResultIndices.size(); for (int i = 1; i <= DEFAULT_DNS_LOG_SIZE && i <= size; i++) { final int index = mDnsStallDetector.mResultIndices.indexOf(size - i); diff --git a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java index beb975d745c2a..ddb7030d314aa 100644 --- a/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java +++ b/packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java @@ -30,7 +30,6 @@ import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.any; import static org.mockito.Mockito.anyInt; -import static org.mockito.Mockito.anyObject; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.doThrow; @@ -40,6 +39,7 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import android.annotation.NonNull; import android.content.Context; import android.net.ConnectivityManager; import android.net.INetworkMonitorCallbacks; @@ -49,9 +49,11 @@ import android.net.Network; import android.net.NetworkCapabilities; import android.net.NetworkInfo; import android.net.captiveportal.CaptivePortalProbeResult; +import android.net.metrics.DataStallDetectionStats; import android.net.metrics.DataStallStatsUtils; import android.net.metrics.IpConnectivityLog; import android.net.util.SharedLog; +import android.net.wifi.WifiInfo; import android.net.wifi.WifiManager; import android.os.Bundle; import android.os.ConditionVariable; @@ -60,6 +62,7 @@ import android.os.SystemClock; import android.provider.Settings; import android.support.test.filters.SmallTest; import android.support.test.runner.AndroidJUnit4; +import android.telephony.CellSignalStrength; import android.telephony.TelephonyManager; import android.util.ArrayMap; @@ -101,6 +104,7 @@ public class NetworkMonitorTest { private @Mock INetworkMonitorCallbacks mCallbacks; private @Spy Network mNetwork = new Network(TEST_NETID); private @Mock DataStallStatsUtils mDataStallStatsUtils; + private @Mock WifiInfo mWifiInfo; private static final int TEST_NETID = 4242; @@ -108,10 +112,12 @@ public class NetworkMonitorTest { private static final String TEST_HTTPS_URL = "https://www.google.com/gen_204"; private static final String TEST_FALLBACK_URL = "http://fallback.google.com/gen_204"; private static final String TEST_OTHER_FALLBACK_URL = "http://otherfallback.google.com/gen_204"; + private static final String TEST_MCCMNC = "123456"; private static final int DATA_STALL_EVALUATION_TYPE_DNS = 1; private static final int RETURN_CODE_DNS_SUCCESS = 0; private static final int RETURN_CODE_DNS_TIMEOUT = 255; + private static final int DEFAULT_DNS_TIMEOUT_THRESHOLD = 5; private static final int HANDLER_TIMEOUT_MS = 1000; @@ -202,6 +208,11 @@ public class NetworkMonitorTest { protected void setLastProbeTime(long time) { mProbeTime = time; } + + @Override + protected void addDnsEvents(@NonNull final DataStallDetectionStats.Builder stats) { + generateTimeoutDnsEvent(stats, DEFAULT_DNS_TIMEOUT_THRESHOLD); + } } private WrappedNetworkMonitor makeMeteredWrappedNetworkMonitor() { @@ -387,7 +398,7 @@ public class NetworkMonitorTest { public void testIsDataStall_EvaluationDnsOnNotMeteredNetwork() { WrappedNetworkMonitor wrappedMonitor = makeNotMeteredWrappedNetworkMonitor(); wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100); - makeDnsTimeoutEvent(wrappedMonitor, 5); + makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD); assertTrue(wrappedMonitor.isDataStall()); } @@ -398,7 +409,7 @@ public class NetworkMonitorTest { assertFalse(wrappedMonitor.isDataStall()); wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000); - makeDnsTimeoutEvent(wrappedMonitor, 5); + makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD); assertTrue(wrappedMonitor.isDataStall()); } @@ -432,7 +443,7 @@ public class NetworkMonitorTest { // Test dns events happened in valid dns time threshold. WrappedNetworkMonitor wrappedMonitor = makeMeteredWrappedNetworkMonitor(); wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100); - makeDnsTimeoutEvent(wrappedMonitor, 5); + makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD); assertFalse(wrappedMonitor.isDataStall()); wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000); assertTrue(wrappedMonitor.isDataStall()); @@ -441,7 +452,7 @@ public class NetworkMonitorTest { setValidDataStallDnsTimeThreshold(0); wrappedMonitor = makeMeteredWrappedNetworkMonitor(); wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 100); - makeDnsTimeoutEvent(wrappedMonitor, 5); + makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD); assertFalse(wrappedMonitor.isDataStall()); wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000); assertFalse(wrappedMonitor.isDataStall()); @@ -514,7 +525,7 @@ public class NetworkMonitorTest { wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000); makeDnsTimeoutEvent(wrappedMonitor, 5); assertTrue(wrappedMonitor.isDataStall()); - verify(mDataStallStatsUtils, times(1)).write(eq(anyObject()), eq(anyObject())); + verify(mDataStallStatsUtils, times(1)).write(any(), any()); } @Test @@ -523,8 +534,44 @@ public class NetworkMonitorTest { wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000); makeDnsTimeoutEvent(wrappedMonitor, 3); assertFalse(wrappedMonitor.isDataStall()); - verify(mDataStallStatsUtils, times(0)).write(eq(anyObject()), eq(anyObject())); + verify(mDataStallStatsUtils, never()).write(any(), any()); } + + @Test + public void testCollectDataStallMetrics() { + WrappedNetworkMonitor wrappedMonitor = makeNotMeteredWrappedNetworkMonitor(); + + when(mTelephony.getDataNetworkType()).thenReturn(TelephonyManager.NETWORK_TYPE_LTE); + when(mTelephony.getNetworkOperator()).thenReturn(TEST_MCCMNC); + when(mTelephony.getSimOperator()).thenReturn(TEST_MCCMNC); + + DataStallDetectionStats.Builder stats = + new DataStallDetectionStats.Builder() + .setEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS) + .setNetworkType(NetworkCapabilities.TRANSPORT_CELLULAR) + .setCellData(TelephonyManager.NETWORK_TYPE_LTE /* radioType */, + true /* roaming */, + TEST_MCCMNC /* networkMccmnc */, + TEST_MCCMNC /* simMccmnc */, + CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN /* signalStrength */); + generateTimeoutDnsEvent(stats, DEFAULT_DNS_TIMEOUT_THRESHOLD); + + assertEquals(wrappedMonitor.buildDataStallDetectionStats( + NetworkCapabilities.TRANSPORT_CELLULAR), stats.build()); + + when(mWifi.getConnectionInfo()).thenReturn(mWifiInfo); + + stats = new DataStallDetectionStats.Builder() + .setEvaluationType(DATA_STALL_EVALUATION_TYPE_DNS) + .setNetworkType(NetworkCapabilities.TRANSPORT_WIFI) + .setWiFiData(mWifiInfo); + generateTimeoutDnsEvent(stats, DEFAULT_DNS_TIMEOUT_THRESHOLD); + + assertEquals( + wrappedMonitor.buildDataStallDetectionStats(NetworkCapabilities.TRANSPORT_WIFI), + stats.build()); + } + private void makeDnsTimeoutEvent(WrappedNetworkMonitor wrappedMonitor, int count) { for (int i = 0; i < count; i++) { wrappedMonitor.getDnsStallDetector().accumulateConsecutiveDnsTimeoutCount( @@ -614,5 +661,11 @@ public class NetworkMonitorTest { private void setStatus(HttpURLConnection connection, int status) throws IOException { doReturn(status).when(connection).getResponseCode(); } + + private void generateTimeoutDnsEvent(DataStallDetectionStats.Builder stats, int num) { + for (int i = 0; i < num; i++) { + stats.addDnsEvent(RETURN_CODE_DNS_TIMEOUT, 123456789 /* timeMs */); + } + } }