Loading core/java/android/net/metrics/ValidationProbeEvent.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading packages/NetworkStack/src/android/net/metrics/DataStallDetectionStats.java +28 −9 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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} * Loading Loading @@ -163,17 +181,18 @@ public final class DataStallDetectionStats { } private static int getWifiBand(@Nullable final WifiInfo info) { if (info != null) { 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; } } /** * Set the cellular data into Builder. Loading packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java +2 −1 Original line number Diff line number Diff line Loading @@ -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); Loading packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java +60 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -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()); } Loading @@ -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()); } Loading Loading @@ -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()); Loading @@ -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()); Loading Loading @@ -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 Loading @@ -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( Loading Loading @@ -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 */); } } } Loading
core/java/android/net/metrics/ValidationProbeEvent.java +1 −1 Original line number Diff line number Diff line Loading @@ -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; Loading
packages/NetworkStack/src/android/net/metrics/DataStallDetectionStats.java +28 −9 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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} * Loading Loading @@ -163,17 +181,18 @@ public final class DataStallDetectionStats { } private static int getWifiBand(@Nullable final WifiInfo info) { if (info != null) { 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; } } /** * Set the cellular data into Builder. Loading
packages/NetworkStack/src/com/android/server/connectivity/NetworkMonitor.java +2 −1 Original line number Diff line number Diff line Loading @@ -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); Loading
packages/NetworkStack/tests/src/com/android/server/connectivity/NetworkMonitorTest.java +60 −7 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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; Loading @@ -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; Loading Loading @@ -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() { Loading Loading @@ -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()); } Loading @@ -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()); } Loading Loading @@ -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()); Loading @@ -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()); Loading Loading @@ -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 Loading @@ -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( Loading Loading @@ -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 */); } } }