Loading src/com/android/server/connectivity/NetworkMonitor.java +35 −14 Original line number Original line Diff line number Diff line Loading @@ -377,6 +377,7 @@ public class NetworkMonitor extends StateMachine { private final int mDataStallMinEvaluateTime; private final int mDataStallMinEvaluateTime; private final int mDataStallValidDnsTimeThreshold; private final int mDataStallValidDnsTimeThreshold; private final int mDataStallEvaluationType; private final int mDataStallEvaluationType; @Nullable private final DnsStallDetector mDnsStallDetector; private final DnsStallDetector mDnsStallDetector; private long mLastProbeTime; private long mLastProbeTime; // Set to true if data stall is suspected and reset to false after metrics are sent to statsd. // Set to true if data stall is suspected and reset to false after metrics are sent to statsd. Loading Loading @@ -455,10 +456,11 @@ public class NetworkMonitor extends StateMachine { mRandom = deps.getRandom(); mRandom = deps.getRandom(); // TODO: Evaluate to move data stall configuration to a specific class. // TODO: Evaluate to move data stall configuration to a specific class. mConsecutiveDnsTimeoutThreshold = getConsecutiveDnsTimeoutThreshold(); mConsecutiveDnsTimeoutThreshold = getConsecutiveDnsTimeoutThreshold(); mDnsStallDetector = new DnsStallDetector(mConsecutiveDnsTimeoutThreshold); mDataStallMinEvaluateTime = getDataStallMinEvaluateTime(); mDataStallMinEvaluateTime = getDataStallMinEvaluateTime(); mDataStallValidDnsTimeThreshold = getDataStallValidDnsTimeThreshold(); mDataStallValidDnsTimeThreshold = getDataStallValidDnsTimeThreshold(); mDataStallEvaluationType = getDataStallEvaluationType(); mDataStallEvaluationType = getDataStallEvaluationType(); mDnsStallDetector = initDnsStallDetectorIfRequired(mDataStallEvaluationType, mConsecutiveDnsTimeoutThreshold); mTcpTracker = tst; mTcpTracker = tst; // Provide empty LinkProperties and NetworkCapabilities to make sure they are never null, // Provide empty LinkProperties and NetworkCapabilities to make sure they are never null, Loading Loading @@ -628,9 +630,12 @@ public class NetworkMonitor extends StateMachine { return HANDLED; return HANDLED; case CMD_FORCE_REEVALUATION: case CMD_FORCE_REEVALUATION: case CMD_CAPTIVE_PORTAL_RECHECK: case CMD_CAPTIVE_PORTAL_RECHECK: final int dnsCount = mDnsStallDetector.getConsecutiveTimeoutCount(); String msg = "Forcing reevaluation for UID " + message.arg1; validationLog("Forcing reevaluation for UID " + message.arg1 final DnsStallDetector dsd = getDnsStallDetector(); + ". Dns signal count: " + dnsCount); if (dsd != null) { msg += ". Dns signal count: " + dsd.getConsecutiveTimeoutCount(); } validationLog(msg); mUidResponsibleForReeval = message.arg1; mUidResponsibleForReeval = message.arg1; transitionTo(mEvaluatingState); transitionTo(mEvaluatingState); return HANDLED; return HANDLED; Loading Loading @@ -713,7 +718,10 @@ public class NetworkMonitor extends StateMachine { break; break; } } case EVENT_DNS_NOTIFICATION: case EVENT_DNS_NOTIFICATION: mDnsStallDetector.accumulateConsecutiveDnsTimeoutCount(message.arg1); final DnsStallDetector detector = getDnsStallDetector(); if (detector != null) { detector.accumulateConsecutiveDnsTimeoutCount(message.arg1); } break; break; // Set mAcceptPartialConnectivity to true and if network start evaluating or // Set mAcceptPartialConnectivity to true and if network start evaluating or // re-evaluating and get the result of partial connectivity, ProbingState will // re-evaluating and get the result of partial connectivity, ProbingState will Loading Loading @@ -777,7 +785,10 @@ public class NetworkMonitor extends StateMachine { transitionTo(mEvaluatingPrivateDnsState); transitionTo(mEvaluatingPrivateDnsState); break; break; case EVENT_DNS_NOTIFICATION: case EVENT_DNS_NOTIFICATION: mDnsStallDetector.accumulateConsecutiveDnsTimeoutCount(message.arg1); final DnsStallDetector dsd = getDnsStallDetector(); if (dsd == null) break; dsd.accumulateConsecutiveDnsTimeoutCount(message.arg1); if (evaluateDataStall()) { if (evaluateDataStall()) { transitionTo(mEvaluatingState); transitionTo(mEvaluatingState); } } Loading Loading @@ -873,11 +884,13 @@ public class NetworkMonitor extends StateMachine { @VisibleForTesting @VisibleForTesting protected void addDnsEvents(@NonNull final DataStallDetectionStats.Builder stats) { protected void addDnsEvents(@NonNull final DataStallDetectionStats.Builder stats) { final int size = mDnsStallDetector.mResultIndices.size(); final DnsStallDetector dsd = getDnsStallDetector(); if (dsd == null) return; final int size = dsd.mResultIndices.size(); for (int i = 1; i <= DEFAULT_DNS_LOG_SIZE && i <= size; i++) { for (int i = 1; i <= DEFAULT_DNS_LOG_SIZE && i <= size; i++) { final int index = mDnsStallDetector.mResultIndices.indexOf(size - i); final int index = dsd.mResultIndices.indexOf(size - i); stats.addDnsEvent(mDnsStallDetector.mDnsEvents[index].mReturnCode, stats.addDnsEvent(dsd.mDnsEvents[index].mReturnCode, dsd.mDnsEvents[index].mTimeStamp); mDnsStallDetector.mDnsEvents[index].mTimeStamp); } } } } Loading Loading @@ -2218,6 +2231,7 @@ public class NetworkMonitor extends StateMachine { } } @VisibleForTesting @VisibleForTesting @Nullable protected DnsStallDetector getDnsStallDetector() { protected DnsStallDetector getDnsStallDetector() { return mDnsStallDetector; return mDnsStallDetector; } } Loading Loading @@ -2267,15 +2281,16 @@ public class NetworkMonitor extends StateMachine { // Check dns signal. Suspect it may be a data stall if both : // Check dns signal. Suspect it may be a data stall if both : // 1. The number of consecutive DNS query timeouts >= mConsecutiveDnsTimeoutThreshold. // 1. The number of consecutive DNS query timeouts >= mConsecutiveDnsTimeoutThreshold. // 2. Those consecutive DNS queries happened in the last mValidDataStallDnsTimeThreshold ms. // 2. Those consecutive DNS queries happened in the last mValidDataStallDnsTimeThreshold ms. if ((result == null) && dataStallEvaluateTypeEnabled(DATA_STALL_EVALUATION_TYPE_DNS)) { final DnsStallDetector dsd = getDnsStallDetector(); if (mDnsStallDetector.isDataStallSuspected(mConsecutiveDnsTimeoutThreshold, if ((result == null) && (dsd != null) && dataStallEvaluateTypeEnabled(DATA_STALL_EVALUATION_TYPE_DNS)) { if (dsd.isDataStallSuspected(mConsecutiveDnsTimeoutThreshold, mDataStallValidDnsTimeThreshold)) { mDataStallValidDnsTimeThreshold)) { result = true; result = true; logNetworkEvent(NetworkEvent.NETWORK_CONSECUTIVE_DNS_TIMEOUT_FOUND); logNetworkEvent(NetworkEvent.NETWORK_CONSECUTIVE_DNS_TIMEOUT_FOUND); } } if (DBG || VDBG_STALL) { if (DBG || VDBG_STALL) { msg.add("consecutive dns timeout count=" msg.add("consecutive dns timeout count=" + dsd.getConsecutiveTimeoutCount()); + mDnsStallDetector.getConsecutiveTimeoutCount()); } } } } // log only data stall suspected. // log only data stall suspected. Loading Loading @@ -2426,4 +2441,10 @@ public class NetworkMonitor extends StateMachine { ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.Q)), network) ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.Q)), network) : null; : null; } } @Nullable private DnsStallDetector initDnsStallDetectorIfRequired(int type, int threshold) { return ((type & DATA_STALL_EVALUATION_TYPE_DNS) != 0) ? new DnsStallDetector(threshold) : null; } } } tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java +0 −3 Original line number Original line Diff line number Diff line Loading @@ -839,9 +839,6 @@ public class NetworkMonitorTest { // Evaluate TCP only. Expect ignoring DNS signal. // Evaluate TCP only. Expect ignoring DNS signal. setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_TCP); setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_TCP); WrappedNetworkMonitor wrappedMonitor = makeMonitor(METERED_CAPABILITIES); WrappedNetworkMonitor wrappedMonitor = makeMonitor(METERED_CAPABILITIES); // Condition met for DNS. wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000); makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD); assertFalse(wrappedMonitor.isDataStall()); assertFalse(wrappedMonitor.isDataStall()); // Packet received. // Packet received. when(mTstDependencies.isTcpInfoParsingSupported()).thenReturn(true); when(mTstDependencies.isTcpInfoParsingSupported()).thenReturn(true); Loading Loading
src/com/android/server/connectivity/NetworkMonitor.java +35 −14 Original line number Original line Diff line number Diff line Loading @@ -377,6 +377,7 @@ public class NetworkMonitor extends StateMachine { private final int mDataStallMinEvaluateTime; private final int mDataStallMinEvaluateTime; private final int mDataStallValidDnsTimeThreshold; private final int mDataStallValidDnsTimeThreshold; private final int mDataStallEvaluationType; private final int mDataStallEvaluationType; @Nullable private final DnsStallDetector mDnsStallDetector; private final DnsStallDetector mDnsStallDetector; private long mLastProbeTime; private long mLastProbeTime; // Set to true if data stall is suspected and reset to false after metrics are sent to statsd. // Set to true if data stall is suspected and reset to false after metrics are sent to statsd. Loading Loading @@ -455,10 +456,11 @@ public class NetworkMonitor extends StateMachine { mRandom = deps.getRandom(); mRandom = deps.getRandom(); // TODO: Evaluate to move data stall configuration to a specific class. // TODO: Evaluate to move data stall configuration to a specific class. mConsecutiveDnsTimeoutThreshold = getConsecutiveDnsTimeoutThreshold(); mConsecutiveDnsTimeoutThreshold = getConsecutiveDnsTimeoutThreshold(); mDnsStallDetector = new DnsStallDetector(mConsecutiveDnsTimeoutThreshold); mDataStallMinEvaluateTime = getDataStallMinEvaluateTime(); mDataStallMinEvaluateTime = getDataStallMinEvaluateTime(); mDataStallValidDnsTimeThreshold = getDataStallValidDnsTimeThreshold(); mDataStallValidDnsTimeThreshold = getDataStallValidDnsTimeThreshold(); mDataStallEvaluationType = getDataStallEvaluationType(); mDataStallEvaluationType = getDataStallEvaluationType(); mDnsStallDetector = initDnsStallDetectorIfRequired(mDataStallEvaluationType, mConsecutiveDnsTimeoutThreshold); mTcpTracker = tst; mTcpTracker = tst; // Provide empty LinkProperties and NetworkCapabilities to make sure they are never null, // Provide empty LinkProperties and NetworkCapabilities to make sure they are never null, Loading Loading @@ -628,9 +630,12 @@ public class NetworkMonitor extends StateMachine { return HANDLED; return HANDLED; case CMD_FORCE_REEVALUATION: case CMD_FORCE_REEVALUATION: case CMD_CAPTIVE_PORTAL_RECHECK: case CMD_CAPTIVE_PORTAL_RECHECK: final int dnsCount = mDnsStallDetector.getConsecutiveTimeoutCount(); String msg = "Forcing reevaluation for UID " + message.arg1; validationLog("Forcing reevaluation for UID " + message.arg1 final DnsStallDetector dsd = getDnsStallDetector(); + ". Dns signal count: " + dnsCount); if (dsd != null) { msg += ". Dns signal count: " + dsd.getConsecutiveTimeoutCount(); } validationLog(msg); mUidResponsibleForReeval = message.arg1; mUidResponsibleForReeval = message.arg1; transitionTo(mEvaluatingState); transitionTo(mEvaluatingState); return HANDLED; return HANDLED; Loading Loading @@ -713,7 +718,10 @@ public class NetworkMonitor extends StateMachine { break; break; } } case EVENT_DNS_NOTIFICATION: case EVENT_DNS_NOTIFICATION: mDnsStallDetector.accumulateConsecutiveDnsTimeoutCount(message.arg1); final DnsStallDetector detector = getDnsStallDetector(); if (detector != null) { detector.accumulateConsecutiveDnsTimeoutCount(message.arg1); } break; break; // Set mAcceptPartialConnectivity to true and if network start evaluating or // Set mAcceptPartialConnectivity to true and if network start evaluating or // re-evaluating and get the result of partial connectivity, ProbingState will // re-evaluating and get the result of partial connectivity, ProbingState will Loading Loading @@ -777,7 +785,10 @@ public class NetworkMonitor extends StateMachine { transitionTo(mEvaluatingPrivateDnsState); transitionTo(mEvaluatingPrivateDnsState); break; break; case EVENT_DNS_NOTIFICATION: case EVENT_DNS_NOTIFICATION: mDnsStallDetector.accumulateConsecutiveDnsTimeoutCount(message.arg1); final DnsStallDetector dsd = getDnsStallDetector(); if (dsd == null) break; dsd.accumulateConsecutiveDnsTimeoutCount(message.arg1); if (evaluateDataStall()) { if (evaluateDataStall()) { transitionTo(mEvaluatingState); transitionTo(mEvaluatingState); } } Loading Loading @@ -873,11 +884,13 @@ public class NetworkMonitor extends StateMachine { @VisibleForTesting @VisibleForTesting protected void addDnsEvents(@NonNull final DataStallDetectionStats.Builder stats) { protected void addDnsEvents(@NonNull final DataStallDetectionStats.Builder stats) { final int size = mDnsStallDetector.mResultIndices.size(); final DnsStallDetector dsd = getDnsStallDetector(); if (dsd == null) return; final int size = dsd.mResultIndices.size(); for (int i = 1; i <= DEFAULT_DNS_LOG_SIZE && i <= size; i++) { for (int i = 1; i <= DEFAULT_DNS_LOG_SIZE && i <= size; i++) { final int index = mDnsStallDetector.mResultIndices.indexOf(size - i); final int index = dsd.mResultIndices.indexOf(size - i); stats.addDnsEvent(mDnsStallDetector.mDnsEvents[index].mReturnCode, stats.addDnsEvent(dsd.mDnsEvents[index].mReturnCode, dsd.mDnsEvents[index].mTimeStamp); mDnsStallDetector.mDnsEvents[index].mTimeStamp); } } } } Loading Loading @@ -2218,6 +2231,7 @@ public class NetworkMonitor extends StateMachine { } } @VisibleForTesting @VisibleForTesting @Nullable protected DnsStallDetector getDnsStallDetector() { protected DnsStallDetector getDnsStallDetector() { return mDnsStallDetector; return mDnsStallDetector; } } Loading Loading @@ -2267,15 +2281,16 @@ public class NetworkMonitor extends StateMachine { // Check dns signal. Suspect it may be a data stall if both : // Check dns signal. Suspect it may be a data stall if both : // 1. The number of consecutive DNS query timeouts >= mConsecutiveDnsTimeoutThreshold. // 1. The number of consecutive DNS query timeouts >= mConsecutiveDnsTimeoutThreshold. // 2. Those consecutive DNS queries happened in the last mValidDataStallDnsTimeThreshold ms. // 2. Those consecutive DNS queries happened in the last mValidDataStallDnsTimeThreshold ms. if ((result == null) && dataStallEvaluateTypeEnabled(DATA_STALL_EVALUATION_TYPE_DNS)) { final DnsStallDetector dsd = getDnsStallDetector(); if (mDnsStallDetector.isDataStallSuspected(mConsecutiveDnsTimeoutThreshold, if ((result == null) && (dsd != null) && dataStallEvaluateTypeEnabled(DATA_STALL_EVALUATION_TYPE_DNS)) { if (dsd.isDataStallSuspected(mConsecutiveDnsTimeoutThreshold, mDataStallValidDnsTimeThreshold)) { mDataStallValidDnsTimeThreshold)) { result = true; result = true; logNetworkEvent(NetworkEvent.NETWORK_CONSECUTIVE_DNS_TIMEOUT_FOUND); logNetworkEvent(NetworkEvent.NETWORK_CONSECUTIVE_DNS_TIMEOUT_FOUND); } } if (DBG || VDBG_STALL) { if (DBG || VDBG_STALL) { msg.add("consecutive dns timeout count=" msg.add("consecutive dns timeout count=" + dsd.getConsecutiveTimeoutCount()); + mDnsStallDetector.getConsecutiveTimeoutCount()); } } } } // log only data stall suspected. // log only data stall suspected. Loading Loading @@ -2426,4 +2441,10 @@ public class NetworkMonitor extends StateMachine { ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.Q)), network) ShimUtils.isReleaseOrDevelopmentApiAbove(Build.VERSION_CODES.Q)), network) : null; : null; } } @Nullable private DnsStallDetector initDnsStallDetectorIfRequired(int type, int threshold) { return ((type & DATA_STALL_EVALUATION_TYPE_DNS) != 0) ? new DnsStallDetector(threshold) : null; } } }
tests/unit/src/com/android/server/connectivity/NetworkMonitorTest.java +0 −3 Original line number Original line Diff line number Diff line Loading @@ -839,9 +839,6 @@ public class NetworkMonitorTest { // Evaluate TCP only. Expect ignoring DNS signal. // Evaluate TCP only. Expect ignoring DNS signal. setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_TCP); setDataStallEvaluationType(DATA_STALL_EVALUATION_TYPE_TCP); WrappedNetworkMonitor wrappedMonitor = makeMonitor(METERED_CAPABILITIES); WrappedNetworkMonitor wrappedMonitor = makeMonitor(METERED_CAPABILITIES); // Condition met for DNS. wrappedMonitor.setLastProbeTime(SystemClock.elapsedRealtime() - 1000); makeDnsTimeoutEvent(wrappedMonitor, DEFAULT_DNS_TIMEOUT_THRESHOLD); assertFalse(wrappedMonitor.isDataStall()); assertFalse(wrappedMonitor.isDataStall()); // Packet received. // Packet received. when(mTstDependencies.isTcpInfoParsingSupported()).thenReturn(true); when(mTstDependencies.isTcpInfoParsingSupported()).thenReturn(true); Loading