Merge "Update multiple validation result to ConnectivityService" into qt-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
399b7500af
@@ -24,8 +24,13 @@ import static android.net.ConnectivityManager.EXTRA_CAPTIVE_PORTAL_URL;
|
|||||||
import static android.net.ConnectivityManager.TYPE_MOBILE;
|
import static android.net.ConnectivityManager.TYPE_MOBILE;
|
||||||
import static android.net.ConnectivityManager.TYPE_WIFI;
|
import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||||
import static android.net.DnsResolver.FLAG_EMPTY;
|
import static android.net.DnsResolver.FLAG_EMPTY;
|
||||||
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_INVALID;
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS;
|
||||||
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY;
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK;
|
||||||
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP;
|
||||||
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS;
|
||||||
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS;
|
||||||
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
|
||||||
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
import static android.net.NetworkCapabilities.TRANSPORT_CELLULAR;
|
||||||
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
import static android.net.NetworkCapabilities.TRANSPORT_WIFI;
|
||||||
@@ -69,7 +74,6 @@ import android.content.IntentFilter;
|
|||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.net.ConnectivityManager;
|
import android.net.ConnectivityManager;
|
||||||
import android.net.DnsResolver;
|
import android.net.DnsResolver;
|
||||||
import android.net.INetworkMonitor;
|
|
||||||
import android.net.INetworkMonitorCallbacks;
|
import android.net.INetworkMonitorCallbacks;
|
||||||
import android.net.LinkProperties;
|
import android.net.LinkProperties;
|
||||||
import android.net.Network;
|
import android.net.Network;
|
||||||
@@ -277,7 +281,7 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
private static final int BLAME_FOR_EVALUATION_ATTEMPTS = 5;
|
private static final int BLAME_FOR_EVALUATION_ATTEMPTS = 5;
|
||||||
// Delay between reevaluations once a captive portal has been found.
|
// Delay between reevaluations once a captive portal has been found.
|
||||||
private static final int CAPTIVE_PORTAL_REEVALUATE_DELAY_MS = 10 * 60 * 1000;
|
private static final int CAPTIVE_PORTAL_REEVALUATE_DELAY_MS = 10 * 60 * 1000;
|
||||||
|
private static final int NETWORK_VALIDATION_RESULT_INVALID = 0;
|
||||||
private String mPrivateDnsProviderHostname = "";
|
private String mPrivateDnsProviderHostname = "";
|
||||||
|
|
||||||
private final Context mContext;
|
private final Context mContext;
|
||||||
@@ -348,7 +352,8 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
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.
|
||||||
private boolean mCollectDataStallMetrics;
|
private boolean mCollectDataStallMetrics;
|
||||||
private boolean mAcceptPartialConnectivity;
|
private boolean mAcceptPartialConnectivity = false;
|
||||||
|
private final EvaluationState mEvaluationState = new EvaluationState();
|
||||||
|
|
||||||
public NetworkMonitor(Context context, INetworkMonitorCallbacks cb, Network network,
|
public NetworkMonitor(Context context, INetworkMonitorCallbacks cb, Network network,
|
||||||
SharedLog validationLog) {
|
SharedLog validationLog) {
|
||||||
@@ -601,7 +606,8 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
case APP_RETURN_UNWANTED:
|
case APP_RETURN_UNWANTED:
|
||||||
mDontDisplaySigninNotification = true;
|
mDontDisplaySigninNotification = true;
|
||||||
mUserDoesNotWant = true;
|
mUserDoesNotWant = true;
|
||||||
notifyNetworkTested(NETWORK_TEST_RESULT_INVALID, null);
|
mEvaluationState.reportEvaluationResult(
|
||||||
|
NETWORK_VALIDATION_RESULT_INVALID, null);
|
||||||
// TODO: Should teardown network.
|
// TODO: Should teardown network.
|
||||||
mUidResponsibleForReeval = 0;
|
mUidResponsibleForReeval = 0;
|
||||||
transitionTo(mEvaluatingState);
|
transitionTo(mEvaluatingState);
|
||||||
@@ -653,7 +659,7 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
// re-evaluating and get the result of partial connectivity, ProbingState will
|
// re-evaluating and get the result of partial connectivity, ProbingState will
|
||||||
// disable HTTPS probe and transition to EvaluatingPrivateDnsState.
|
// disable HTTPS probe and transition to EvaluatingPrivateDnsState.
|
||||||
case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
|
case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
|
||||||
mAcceptPartialConnectivity = true;
|
maybeDisableHttpsProbing(true /* acceptPartial */);
|
||||||
break;
|
break;
|
||||||
case EVENT_LINK_PROPERTIES_CHANGED:
|
case EVENT_LINK_PROPERTIES_CHANGED:
|
||||||
mLinkProperties = (LinkProperties) message.obj;
|
mLinkProperties = (LinkProperties) message.obj;
|
||||||
@@ -677,7 +683,14 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
public void enter() {
|
public void enter() {
|
||||||
maybeLogEvaluationResult(
|
maybeLogEvaluationResult(
|
||||||
networkEventType(validationStage(), EvaluationResult.VALIDATED));
|
networkEventType(validationStage(), EvaluationResult.VALIDATED));
|
||||||
notifyNetworkTested(INetworkMonitor.NETWORK_TEST_RESULT_VALID, null);
|
// If the user has accepted that and HTTPS probing is disabled, then mark the network
|
||||||
|
// as validated and partial so that settings can keep informing the user that the
|
||||||
|
// connection is limited.
|
||||||
|
int result = NETWORK_VALIDATION_RESULT_VALID;
|
||||||
|
if (!mUseHttps && mAcceptPartialConnectivity) {
|
||||||
|
result |= NETWORK_VALIDATION_RESULT_PARTIAL;
|
||||||
|
}
|
||||||
|
mEvaluationState.reportEvaluationResult(result, null /* redirectUrl */);
|
||||||
mValidations++;
|
mValidations++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -820,6 +833,9 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
}
|
}
|
||||||
mReevaluateDelayMs = INITIAL_REEVALUATE_DELAY_MS;
|
mReevaluateDelayMs = INITIAL_REEVALUATE_DELAY_MS;
|
||||||
mEvaluateAttempts = 0;
|
mEvaluateAttempts = 0;
|
||||||
|
// Reset all current probe results to zero, but retain current validation state until
|
||||||
|
// validation succeeds or fails.
|
||||||
|
mEvaluationState.clearProbeResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -875,8 +891,7 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
// 1. Network is connected and finish the network validation.
|
// 1. Network is connected and finish the network validation.
|
||||||
// 2. NetworkMonitor detects network is partial connectivity and user accepts it.
|
// 2. NetworkMonitor detects network is partial connectivity and user accepts it.
|
||||||
case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
|
case EVENT_ACCEPT_PARTIAL_CONNECTIVITY:
|
||||||
mAcceptPartialConnectivity = true;
|
maybeDisableHttpsProbing(true /* acceptPartial */);
|
||||||
mUseHttps = false;
|
|
||||||
transitionTo(mEvaluatingPrivateDnsState);
|
transitionTo(mEvaluatingPrivateDnsState);
|
||||||
return HANDLED;
|
return HANDLED;
|
||||||
default:
|
default:
|
||||||
@@ -1019,6 +1034,8 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
mPrivateDnsConfig = null;
|
mPrivateDnsConfig = null;
|
||||||
validationLog("Strict mode hostname resolution failed: " + uhe.getMessage());
|
validationLog("Strict mode hostname resolution failed: " + uhe.getMessage());
|
||||||
}
|
}
|
||||||
|
mEvaluationState.reportProbeResult(NETWORK_VALIDATION_PROBE_PRIVDNS,
|
||||||
|
(mPrivateDnsConfig != null) /* succeeded */);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifyPrivateDnsConfigResolved() {
|
private void notifyPrivateDnsConfigResolved() {
|
||||||
@@ -1030,8 +1047,8 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void handlePrivateDnsEvaluationFailure() {
|
private void handlePrivateDnsEvaluationFailure() {
|
||||||
notifyNetworkTested(NETWORK_TEST_RESULT_INVALID, null);
|
mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_INVALID,
|
||||||
|
null /* redirectUrl */);
|
||||||
// Queue up a re-evaluation with backoff.
|
// Queue up a re-evaluation with backoff.
|
||||||
//
|
//
|
||||||
// TODO: Consider abandoning this state after a few attempts and
|
// TODO: Consider abandoning this state after a few attempts and
|
||||||
@@ -1050,21 +1067,22 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
final String host = UUID.randomUUID().toString().substring(0, 8)
|
final String host = UUID.randomUUID().toString().substring(0, 8)
|
||||||
+ oneTimeHostnameSuffix;
|
+ oneTimeHostnameSuffix;
|
||||||
final Stopwatch watch = new Stopwatch().start();
|
final Stopwatch watch = new Stopwatch().start();
|
||||||
|
boolean success = false;
|
||||||
|
long time;
|
||||||
try {
|
try {
|
||||||
final InetAddress[] ips = mNetwork.getAllByName(host);
|
final InetAddress[] ips = mNetwork.getAllByName(host);
|
||||||
final long time = watch.stop();
|
time = watch.stop();
|
||||||
final String strIps = Arrays.toString(ips);
|
final String strIps = Arrays.toString(ips);
|
||||||
final boolean success = (ips != null && ips.length > 0);
|
success = (ips != null && ips.length > 0);
|
||||||
validationLog(PROBE_PRIVDNS, host, String.format("%dms: %s", time, strIps));
|
validationLog(PROBE_PRIVDNS, host, String.format("%dms: %s", time, strIps));
|
||||||
logValidationProbe(time, PROBE_PRIVDNS, success ? DNS_SUCCESS : DNS_FAILURE);
|
|
||||||
return success;
|
|
||||||
} catch (UnknownHostException uhe) {
|
} catch (UnknownHostException uhe) {
|
||||||
final long time = watch.stop();
|
time = watch.stop();
|
||||||
validationLog(PROBE_PRIVDNS, host,
|
validationLog(PROBE_PRIVDNS, host,
|
||||||
String.format("%dms - Error: %s", time, uhe.getMessage()));
|
String.format("%dms - Error: %s", time, uhe.getMessage()));
|
||||||
logValidationProbe(time, PROBE_PRIVDNS, DNS_FAILURE);
|
|
||||||
}
|
}
|
||||||
return false;
|
logValidationProbe(time, PROBE_PRIVDNS, success ? DNS_SUCCESS : DNS_FAILURE);
|
||||||
|
mEvaluationState.reportProbeResult(NETWORK_VALIDATION_PROBE_PRIVDNS, success);
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1106,22 +1124,24 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
// state (even if no Private DNS validation required).
|
// state (even if no Private DNS validation required).
|
||||||
transitionTo(mEvaluatingPrivateDnsState);
|
transitionTo(mEvaluatingPrivateDnsState);
|
||||||
} else if (probeResult.isPortal()) {
|
} else if (probeResult.isPortal()) {
|
||||||
notifyNetworkTested(NETWORK_TEST_RESULT_INVALID, probeResult.redirectUrl);
|
mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_INVALID,
|
||||||
|
probeResult.redirectUrl);
|
||||||
mLastPortalProbeResult = probeResult;
|
mLastPortalProbeResult = probeResult;
|
||||||
transitionTo(mCaptivePortalState);
|
transitionTo(mCaptivePortalState);
|
||||||
} else if (probeResult.isPartialConnectivity()) {
|
} else if (probeResult.isPartialConnectivity()) {
|
||||||
logNetworkEvent(NetworkEvent.NETWORK_PARTIAL_CONNECTIVITY);
|
mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_PARTIAL,
|
||||||
notifyNetworkTested(NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY,
|
null /* redirectUrl */);
|
||||||
probeResult.redirectUrl);
|
// Check if disable https probing needed.
|
||||||
|
maybeDisableHttpsProbing(mAcceptPartialConnectivity);
|
||||||
if (mAcceptPartialConnectivity) {
|
if (mAcceptPartialConnectivity) {
|
||||||
mUseHttps = false;
|
|
||||||
transitionTo(mEvaluatingPrivateDnsState);
|
transitionTo(mEvaluatingPrivateDnsState);
|
||||||
} else {
|
} else {
|
||||||
transitionTo(mWaitingForNextProbeState);
|
transitionTo(mWaitingForNextProbeState);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
logNetworkEvent(NetworkEvent.NETWORK_VALIDATION_FAILED);
|
logNetworkEvent(NetworkEvent.NETWORK_VALIDATION_FAILED);
|
||||||
notifyNetworkTested(NETWORK_TEST_RESULT_INVALID, probeResult.redirectUrl);
|
mEvaluationState.reportEvaluationResult(NETWORK_VALIDATION_RESULT_INVALID,
|
||||||
|
null /* redirectUrl */);
|
||||||
transitionTo(mWaitingForNextProbeState);
|
transitionTo(mWaitingForNextProbeState);
|
||||||
}
|
}
|
||||||
return HANDLED;
|
return HANDLED;
|
||||||
@@ -1469,10 +1489,13 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
final CaptivePortalProbeResult result;
|
final CaptivePortalProbeResult result;
|
||||||
if (pacUrl != null) {
|
if (pacUrl != null) {
|
||||||
result = sendDnsAndHttpProbes(null, pacUrl, ValidationProbeEvent.PROBE_PAC);
|
result = sendDnsAndHttpProbes(null, pacUrl, ValidationProbeEvent.PROBE_PAC);
|
||||||
|
reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, result);
|
||||||
} else if (mUseHttps) {
|
} else if (mUseHttps) {
|
||||||
|
// Probe results are reported inside sendParallelHttpProbes.
|
||||||
result = sendParallelHttpProbes(proxyInfo, httpsUrl, httpUrl);
|
result = sendParallelHttpProbes(proxyInfo, httpsUrl, httpUrl);
|
||||||
} else {
|
} else {
|
||||||
result = sendDnsAndHttpProbes(proxyInfo, httpUrl, ValidationProbeEvent.PROBE_HTTP);
|
result = sendDnsAndHttpProbes(proxyInfo, httpUrl, ValidationProbeEvent.PROBE_HTTP);
|
||||||
|
reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
long endTime = SystemClock.elapsedRealtime();
|
long endTime = SystemClock.elapsedRealtime();
|
||||||
@@ -1484,6 +1507,7 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
log("isCaptivePortal: isSuccessful()=" + result.isSuccessful()
|
log("isCaptivePortal: isSuccessful()=" + result.isSuccessful()
|
||||||
+ " isPortal()=" + result.isPortal()
|
+ " isPortal()=" + result.isPortal()
|
||||||
+ " RedirectUrl=" + result.redirectUrl
|
+ " RedirectUrl=" + result.redirectUrl
|
||||||
|
+ " isPartialConnectivity()=" + result.isPartialConnectivity()
|
||||||
+ " Time=" + (endTime - startTime) + "ms");
|
+ " Time=" + (endTime - startTime) + "ms");
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -1498,6 +1522,10 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
// Only do this if HttpURLConnection is about to, to avoid any potentially
|
// Only do this if HttpURLConnection is about to, to avoid any potentially
|
||||||
// unnecessary resolution.
|
// unnecessary resolution.
|
||||||
final String host = (proxy != null) ? proxy.getHost() : url.getHost();
|
final String host = (proxy != null) ? proxy.getHost() : url.getHost();
|
||||||
|
// This method cannot safely report probe results because it might not be running on the
|
||||||
|
// state machine thread. Reporting results here would cause races and potentially send
|
||||||
|
// information to callers that does not make sense because the state machine has already
|
||||||
|
// changed state.
|
||||||
sendDnsProbe(host);
|
sendDnsProbe(host);
|
||||||
return sendHttpProbe(url, probeType, null);
|
return sendHttpProbe(url, probeType, null);
|
||||||
}
|
}
|
||||||
@@ -1682,10 +1710,12 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
|
|
||||||
// Look for a conclusive probe result first.
|
// Look for a conclusive probe result first.
|
||||||
if (httpResult.isPortal()) {
|
if (httpResult.isPortal()) {
|
||||||
|
reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, httpResult);
|
||||||
return httpResult;
|
return httpResult;
|
||||||
}
|
}
|
||||||
// httpsResult.isPortal() is not expected, but check it nonetheless.
|
// httpsResult.isPortal() is not expected, but check it nonetheless.
|
||||||
if (httpsResult.isPortal() || httpsResult.isSuccessful()) {
|
if (httpsResult.isPortal() || httpsResult.isSuccessful()) {
|
||||||
|
reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTPS, httpsResult);
|
||||||
return httpsResult;
|
return httpsResult;
|
||||||
}
|
}
|
||||||
// If a fallback method exists, use it to retry portal detection.
|
// If a fallback method exists, use it to retry portal detection.
|
||||||
@@ -1695,6 +1725,7 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
CaptivePortalProbeResult fallbackProbeResult = null;
|
CaptivePortalProbeResult fallbackProbeResult = null;
|
||||||
if (fallbackUrl != null) {
|
if (fallbackUrl != null) {
|
||||||
fallbackProbeResult = sendHttpProbe(fallbackUrl, PROBE_FALLBACK, probeSpec);
|
fallbackProbeResult = sendHttpProbe(fallbackUrl, PROBE_FALLBACK, probeSpec);
|
||||||
|
reportHttpProbeResult(NETWORK_VALIDATION_PROBE_FALLBACK, fallbackProbeResult);
|
||||||
if (fallbackProbeResult.isPortal()) {
|
if (fallbackProbeResult.isPortal()) {
|
||||||
return fallbackProbeResult;
|
return fallbackProbeResult;
|
||||||
}
|
}
|
||||||
@@ -1702,10 +1733,15 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
// Otherwise wait until http and https probes completes and use their results.
|
// Otherwise wait until http and https probes completes and use their results.
|
||||||
try {
|
try {
|
||||||
httpProbe.join();
|
httpProbe.join();
|
||||||
|
reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, httpProbe.result());
|
||||||
|
|
||||||
if (httpProbe.result().isPortal()) {
|
if (httpProbe.result().isPortal()) {
|
||||||
return httpProbe.result();
|
return httpProbe.result();
|
||||||
}
|
}
|
||||||
|
|
||||||
httpsProbe.join();
|
httpsProbe.join();
|
||||||
|
reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTPS, httpsProbe.result());
|
||||||
|
|
||||||
final boolean isHttpSuccessful =
|
final boolean isHttpSuccessful =
|
||||||
(httpProbe.result().isSuccessful()
|
(httpProbe.result().isSuccessful()
|
||||||
|| (fallbackProbeResult != null && fallbackProbeResult.isSuccessful()));
|
|| (fallbackProbeResult != null && fallbackProbeResult.isSuccessful()));
|
||||||
@@ -2024,4 +2060,79 @@ public class NetworkMonitor extends StateMachine {
|
|||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Class to keep state of evaluation results and probe results.
|
||||||
|
// The main purpose is to ensure NetworkMonitor can notify ConnectivityService of probe results
|
||||||
|
// as soon as they happen, without triggering any other changes. This requires keeping state on
|
||||||
|
// the most recent evaluation result. Calling reportProbeResult will ensure that the results
|
||||||
|
// reported to ConnectivityService contain the previous evaluation result, and thus won't
|
||||||
|
// trigger a validation or partial connectivity state change.
|
||||||
|
@VisibleForTesting
|
||||||
|
protected class EvaluationState {
|
||||||
|
// The latest validation result for this network. This is a bitmask of
|
||||||
|
// INetworkMonitor.NETWORK_VALIDATION_RESULT_* constants.
|
||||||
|
private int mEvaluationResult = NETWORK_VALIDATION_RESULT_INVALID;
|
||||||
|
// Indicates which probes have completed since clearProbeResults was called.
|
||||||
|
// This is a bitmask of INetworkMonitor.NETWORK_VALIDATION_PROBE_* constants.
|
||||||
|
private int mProbeResults = 0;
|
||||||
|
// The latest redirect URL.
|
||||||
|
private String mRedirectUrl;
|
||||||
|
|
||||||
|
protected void clearProbeResults() {
|
||||||
|
mProbeResults = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Probe result for http probe should be updated from reportHttpProbeResult().
|
||||||
|
protected void reportProbeResult(int probeResult, boolean succeeded) {
|
||||||
|
if (succeeded) {
|
||||||
|
mProbeResults |= probeResult;
|
||||||
|
} else {
|
||||||
|
mProbeResults &= ~probeResult;
|
||||||
|
}
|
||||||
|
notifyNetworkTested(getNetworkTestResult(), mRedirectUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void reportEvaluationResult(int result, @Nullable String redirectUrl) {
|
||||||
|
mEvaluationResult = result;
|
||||||
|
mRedirectUrl = redirectUrl;
|
||||||
|
notifyNetworkTested(getNetworkTestResult(), mRedirectUrl);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getNetworkTestResult() {
|
||||||
|
return mEvaluationResult | mProbeResults;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
protected EvaluationState getEvaluationState() {
|
||||||
|
return mEvaluationState;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void maybeDisableHttpsProbing(boolean acceptPartial) {
|
||||||
|
mAcceptPartialConnectivity = acceptPartial;
|
||||||
|
// Ignore https probe in next validation if user accept partial connectivity on a partial
|
||||||
|
// connectivity network.
|
||||||
|
if (((mEvaluationState.getNetworkTestResult() & NETWORK_VALIDATION_RESULT_PARTIAL) != 0)
|
||||||
|
&& mAcceptPartialConnectivity) {
|
||||||
|
mUseHttps = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Report HTTP, HTTP or FALLBACK probe result.
|
||||||
|
@VisibleForTesting
|
||||||
|
protected void reportHttpProbeResult(int probeResult,
|
||||||
|
@NonNull final CaptivePortalProbeResult result) {
|
||||||
|
boolean succeeded = result.isSuccessful();
|
||||||
|
// The success of a HTTP probe does not tell us whether the DNS probe succeeded.
|
||||||
|
// The DNS and HTTP probes run one after the other in sendDnsAndHttpProbes, and that
|
||||||
|
// method cannot report the result of the DNS probe because that it could be running
|
||||||
|
// on a different thread which is racing with the main state machine thread. So, if
|
||||||
|
// an HTTP or HTTPS probe succeeded, assume that the DNS probe succeeded. But if an
|
||||||
|
// HTTP or HTTPS probe failed, don't assume that DNS is not working.
|
||||||
|
// TODO: fix this.
|
||||||
|
if (succeeded) {
|
||||||
|
probeResult |= NETWORK_VALIDATION_PROBE_DNS;
|
||||||
|
}
|
||||||
|
mEvaluationState.reportProbeResult(probeResult, succeeded);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,13 @@
|
|||||||
package com.android.server.connectivity;
|
package com.android.server.connectivity;
|
||||||
|
|
||||||
import static android.net.CaptivePortal.APP_RETURN_DISMISSED;
|
import static android.net.CaptivePortal.APP_RETURN_DISMISSED;
|
||||||
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_INVALID;
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS;
|
||||||
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY;
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK;
|
||||||
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_VALID;
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP;
|
||||||
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS;
|
||||||
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_PRIVDNS;
|
||||||
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
|
||||||
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
||||||
import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD;
|
import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_CONSECUTIVE_DNS_TIMEOUT_THRESHOLD;
|
||||||
import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_EVALUATION_TYPE;
|
import static android.net.util.DataStallUtils.CONFIG_DATA_STALL_EVALUATION_TYPE;
|
||||||
@@ -98,6 +102,7 @@ import org.mockito.Captor;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
import org.mockito.Spy;
|
import org.mockito.Spy;
|
||||||
|
import org.mockito.verification.VerificationWithTimeout;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
@@ -149,6 +154,19 @@ public class NetworkMonitorTest {
|
|||||||
private static final String TEST_OTHER_FALLBACK_URL = "http://otherfallback.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 String TEST_MCCMNC = "123456";
|
||||||
|
|
||||||
|
private static final int VALIDATION_RESULT_INVALID = 0;
|
||||||
|
private static final int VALIDATION_RESULT_PORTAL = 0;
|
||||||
|
private static final String TEST_REDIRECT_URL = "android.com";
|
||||||
|
private static final int VALIDATION_RESULT_PARTIAL = NETWORK_VALIDATION_PROBE_DNS
|
||||||
|
| NETWORK_VALIDATION_PROBE_HTTP
|
||||||
|
| NETWORK_VALIDATION_RESULT_PARTIAL;
|
||||||
|
private static final int VALIDATION_RESULT_FALLBACK_PARTIAL = NETWORK_VALIDATION_PROBE_DNS
|
||||||
|
| NETWORK_VALIDATION_PROBE_FALLBACK
|
||||||
|
| NETWORK_VALIDATION_RESULT_PARTIAL;
|
||||||
|
private static final int VALIDATION_RESULT_VALID = NETWORK_VALIDATION_PROBE_DNS
|
||||||
|
| NETWORK_VALIDATION_PROBE_HTTPS
|
||||||
|
| NETWORK_VALIDATION_RESULT_VALID;
|
||||||
|
|
||||||
private static final int RETURN_CODE_DNS_SUCCESS = 0;
|
private static final int RETURN_CODE_DNS_SUCCESS = 0;
|
||||||
private static final int RETURN_CODE_DNS_TIMEOUT = 255;
|
private static final int RETURN_CODE_DNS_TIMEOUT = 255;
|
||||||
private static final int DEFAULT_DNS_TIMEOUT_THRESHOLD = 5;
|
private static final int DEFAULT_DNS_TIMEOUT_THRESHOLD = 5;
|
||||||
@@ -472,8 +490,7 @@ public class NetworkMonitorTest {
|
|||||||
public void testIsCaptivePortal_HttpProbeIsPortal() throws IOException {
|
public void testIsCaptivePortal_HttpProbeIsPortal() throws IOException {
|
||||||
setSslException(mHttpsConnection);
|
setSslException(mHttpsConnection);
|
||||||
setPortal302(mHttpConnection);
|
setPortal302(mHttpConnection);
|
||||||
|
runPortalNetworkTest(VALIDATION_RESULT_PORTAL);
|
||||||
runPortalNetworkTest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -489,8 +506,7 @@ public class NetworkMonitorTest {
|
|||||||
setSslException(mHttpsConnection);
|
setSslException(mHttpsConnection);
|
||||||
setStatus(mHttpConnection, 500);
|
setStatus(mHttpConnection, 500);
|
||||||
setPortal302(mFallbackConnection);
|
setPortal302(mFallbackConnection);
|
||||||
|
runPortalNetworkTest(VALIDATION_RESULT_INVALID);
|
||||||
runPortalNetworkTest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -518,7 +534,7 @@ public class NetworkMonitorTest {
|
|||||||
when(mRandom.nextInt()).thenReturn(2);
|
when(mRandom.nextInt()).thenReturn(2);
|
||||||
|
|
||||||
// First check always uses the first fallback URL: inconclusive
|
// First check always uses the first fallback URL: inconclusive
|
||||||
final NetworkMonitor monitor = runNetworkTest(NETWORK_TEST_RESULT_INVALID);
|
final NetworkMonitor monitor = runNetworkTest(VALIDATION_RESULT_INVALID);
|
||||||
assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
|
assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
|
||||||
verify(mFallbackConnection, times(1)).getResponseCode();
|
verify(mFallbackConnection, times(1)).getResponseCode();
|
||||||
verify(mOtherFallbackConnection, never()).getResponseCode();
|
verify(mOtherFallbackConnection, never()).getResponseCode();
|
||||||
@@ -548,8 +564,7 @@ public class NetworkMonitorTest {
|
|||||||
setSslException(mHttpsConnection);
|
setSslException(mHttpsConnection);
|
||||||
setStatus(mHttpConnection, 500);
|
setStatus(mHttpConnection, 500);
|
||||||
setPortal302(mOtherFallbackConnection);
|
setPortal302(mOtherFallbackConnection);
|
||||||
|
runPortalNetworkTest(VALIDATION_RESULT_INVALID);
|
||||||
runPortalNetworkTest();
|
|
||||||
verify(mOtherFallbackConnection, times(1)).getResponseCode();
|
verify(mOtherFallbackConnection, times(1)).getResponseCode();
|
||||||
verify(mFallbackConnection, never()).getResponseCode();
|
verify(mFallbackConnection, never()).getResponseCode();
|
||||||
}
|
}
|
||||||
@@ -572,7 +587,7 @@ public class NetworkMonitorTest {
|
|||||||
set302(mOtherFallbackConnection, "https://www.google.com/test?q=3");
|
set302(mOtherFallbackConnection, "https://www.google.com/test?q=3");
|
||||||
|
|
||||||
// HTTPS failed, fallback spec went through -> partial connectivity
|
// HTTPS failed, fallback spec went through -> partial connectivity
|
||||||
runPartialConnectivityNetworkTest();
|
runPartialConnectivityNetworkTest(VALIDATION_RESULT_FALLBACK_PARTIAL);
|
||||||
verify(mOtherFallbackConnection, times(1)).getResponseCode();
|
verify(mOtherFallbackConnection, times(1)).getResponseCode();
|
||||||
verify(mFallbackConnection, never()).getResponseCode();
|
verify(mFallbackConnection, never()).getResponseCode();
|
||||||
}
|
}
|
||||||
@@ -581,8 +596,7 @@ public class NetworkMonitorTest {
|
|||||||
public void testIsCaptivePortal_FallbackSpecIsPortal() throws IOException {
|
public void testIsCaptivePortal_FallbackSpecIsPortal() throws IOException {
|
||||||
setupFallbackSpec();
|
setupFallbackSpec();
|
||||||
set302(mOtherFallbackConnection, "http://login.portal.example.com");
|
set302(mOtherFallbackConnection, "http://login.portal.example.com");
|
||||||
|
runPortalNetworkTest(VALIDATION_RESULT_INVALID);
|
||||||
runPortalNetworkTest();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -591,7 +605,7 @@ public class NetworkMonitorTest {
|
|||||||
setSslException(mHttpsConnection);
|
setSslException(mHttpsConnection);
|
||||||
setPortal302(mHttpConnection);
|
setPortal302(mHttpConnection);
|
||||||
|
|
||||||
runNotPortalNetworkTest();
|
runNoValidationNetworkTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -677,7 +691,8 @@ public class NetworkMonitorTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoInternetCapabilityValidated() throws Exception {
|
public void testNoInternetCapabilityValidated() throws Exception {
|
||||||
runNetworkTest(NO_INTERNET_CAPABILITIES, NETWORK_TEST_RESULT_VALID);
|
runNetworkTest(NO_INTERNET_CAPABILITIES, NETWORK_VALIDATION_RESULT_VALID,
|
||||||
|
getGeneralVerification());
|
||||||
verify(mCleartextDnsNetwork, never()).openConnection(any());
|
verify(mCleartextDnsNetwork, never()).openConnection(any());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -713,10 +728,11 @@ public class NetworkMonitorTest {
|
|||||||
setStatus(mHttpsConnection, 204);
|
setStatus(mHttpsConnection, 204);
|
||||||
setStatus(mHttpConnection, 204);
|
setStatus(mHttpConnection, 204);
|
||||||
|
|
||||||
|
reset(mCallbacks);
|
||||||
nm.notifyCaptivePortalAppFinished(APP_RETURN_DISMISSED);
|
nm.notifyCaptivePortalAppFinished(APP_RETURN_DISMISSED);
|
||||||
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
|
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
|
||||||
.notifyNetworkTested(NETWORK_TEST_RESULT_VALID, null);
|
.notifyNetworkTested(eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTP
|
||||||
|
| NETWORK_VALIDATION_RESULT_VALID), any());
|
||||||
assertEquals(0, mRegisteredReceivers.size());
|
assertEquals(0, mRegisteredReceivers.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -730,7 +746,8 @@ public class NetworkMonitorTest {
|
|||||||
wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
|
wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
|
||||||
wnm.notifyNetworkConnected(TEST_LINK_PROPERTIES, NOT_METERED_CAPABILITIES);
|
wnm.notifyNetworkConnected(TEST_LINK_PROPERTIES, NOT_METERED_CAPABILITIES);
|
||||||
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
|
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
|
||||||
.notifyNetworkTested(eq(NETWORK_TEST_RESULT_VALID), eq(null));
|
.notifyNetworkTested(eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS),
|
||||||
|
eq(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -743,38 +760,47 @@ public class NetworkMonitorTest {
|
|||||||
WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
|
WrappedNetworkMonitor wnm = makeNotMeteredNetworkMonitor();
|
||||||
wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
|
wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
|
||||||
wnm.notifyNetworkConnected(TEST_LINK_PROPERTIES, NOT_METERED_CAPABILITIES);
|
wnm.notifyNetworkConnected(TEST_LINK_PROPERTIES, NOT_METERED_CAPABILITIES);
|
||||||
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
|
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
|
||||||
.notifyNetworkTested(eq(NETWORK_TEST_RESULT_INVALID), eq(null));
|
.notifyNetworkTested(
|
||||||
|
eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS),
|
||||||
|
eq(null));
|
||||||
|
|
||||||
// Fix DNS and retry, expect validation to succeed.
|
// Fix DNS and retry, expect validation to succeed.
|
||||||
reset(mCallbacks);
|
reset(mCallbacks);
|
||||||
mFakeDns.setAnswer("dns.google", new String[]{"2001:db8::1"});
|
mFakeDns.setAnswer("dns.google", new String[]{"2001:db8::1"});
|
||||||
|
|
||||||
wnm.forceReevaluation(Process.myUid());
|
wnm.forceReevaluation(Process.myUid());
|
||||||
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
|
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
|
||||||
.notifyNetworkTested(eq(NETWORK_TEST_RESULT_VALID), eq(null));
|
.notifyNetworkTested(eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS),
|
||||||
|
eq(null));
|
||||||
|
|
||||||
// Change configuration to an invalid DNS name, expect validation to fail.
|
// Change configuration to an invalid DNS name, expect validation to fail.
|
||||||
reset(mCallbacks);
|
reset(mCallbacks);
|
||||||
mFakeDns.setAnswer("dns.bad", new String[0]);
|
mFakeDns.setAnswer("dns.bad", new String[0]);
|
||||||
wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.bad", new InetAddress[0]));
|
wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.bad", new InetAddress[0]));
|
||||||
|
// Strict mode hostname resolve fail. Expect only notification for evaluation fail. No probe
|
||||||
|
// notification.
|
||||||
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
|
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
|
||||||
.notifyNetworkTested(eq(NETWORK_TEST_RESULT_INVALID), eq(null));
|
.notifyNetworkTested(eq(VALIDATION_RESULT_VALID), eq(null));
|
||||||
|
|
||||||
// Change configuration back to working again, but make private DNS not work.
|
// Change configuration back to working again, but make private DNS not work.
|
||||||
// Expect validation to fail.
|
// Expect validation to fail.
|
||||||
reset(mCallbacks);
|
reset(mCallbacks);
|
||||||
mFakeDns.setNonBypassPrivateDnsWorking(false);
|
mFakeDns.setNonBypassPrivateDnsWorking(false);
|
||||||
wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google", new InetAddress[0]));
|
wnm.notifyPrivateDnsSettingsChanged(new PrivateDnsConfig("dns.google",
|
||||||
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
|
new InetAddress[0]));
|
||||||
.notifyNetworkTested(eq(NETWORK_TEST_RESULT_INVALID), eq(null));
|
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
|
||||||
|
.notifyNetworkTested(
|
||||||
|
eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS),
|
||||||
|
eq(null));
|
||||||
|
|
||||||
// Make private DNS work again. Expect validation to succeed.
|
// Make private DNS work again. Expect validation to succeed.
|
||||||
reset(mCallbacks);
|
reset(mCallbacks);
|
||||||
mFakeDns.setNonBypassPrivateDnsWorking(true);
|
mFakeDns.setNonBypassPrivateDnsWorking(true);
|
||||||
wnm.forceReevaluation(Process.myUid());
|
wnm.forceReevaluation(Process.myUid());
|
||||||
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
|
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).atLeastOnce())
|
||||||
.notifyNetworkTested(eq(NETWORK_TEST_RESULT_VALID), eq(null));
|
.notifyNetworkTested(
|
||||||
|
eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_PRIVDNS), eq(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -834,12 +860,14 @@ public class NetworkMonitorTest {
|
|||||||
public void testIgnoreHttpsProbe() throws Exception {
|
public void testIgnoreHttpsProbe() throws Exception {
|
||||||
setSslException(mHttpsConnection);
|
setSslException(mHttpsConnection);
|
||||||
setStatus(mHttpConnection, 204);
|
setStatus(mHttpConnection, 204);
|
||||||
|
// Expect to send HTTP, HTTPS, FALLBACK probe and evaluation result notifications to CS.
|
||||||
|
final NetworkMonitor nm = runNetworkTest(VALIDATION_RESULT_PARTIAL);
|
||||||
|
|
||||||
final NetworkMonitor nm = runNetworkTest(NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY);
|
reset(mCallbacks);
|
||||||
|
|
||||||
nm.setAcceptPartialConnectivity();
|
nm.setAcceptPartialConnectivity();
|
||||||
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
|
// Expect to update evaluation result notifications to CS.
|
||||||
.notifyNetworkTested(eq(NETWORK_TEST_RESULT_VALID), any());
|
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
|
||||||
|
eq(VALIDATION_RESULT_PARTIAL | NETWORK_VALIDATION_RESULT_VALID), eq(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -847,12 +875,13 @@ public class NetworkMonitorTest {
|
|||||||
setStatus(mHttpsConnection, 500);
|
setStatus(mHttpsConnection, 500);
|
||||||
setStatus(mHttpConnection, 204);
|
setStatus(mHttpConnection, 204);
|
||||||
setStatus(mFallbackConnection, 500);
|
setStatus(mFallbackConnection, 500);
|
||||||
runPartialConnectivityNetworkTest();
|
runPartialConnectivityNetworkTest(VALIDATION_RESULT_PARTIAL);
|
||||||
|
|
||||||
|
reset(mCallbacks);
|
||||||
setStatus(mHttpsConnection, 500);
|
setStatus(mHttpsConnection, 500);
|
||||||
setStatus(mHttpConnection, 500);
|
setStatus(mHttpConnection, 500);
|
||||||
setStatus(mFallbackConnection, 204);
|
setStatus(mFallbackConnection, 204);
|
||||||
runPartialConnectivityNetworkTest();
|
runPartialConnectivityNetworkTest(VALIDATION_RESULT_FALLBACK_PARTIAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertIpAddressArrayEquals(String[] expected, InetAddress[] actual) {
|
private void assertIpAddressArrayEquals(String[] expected, InetAddress[] actual) {
|
||||||
@@ -896,6 +925,82 @@ public class NetworkMonitorTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testNotifyNetwork_WithforceReevaluation() throws Exception {
|
||||||
|
final NetworkMonitor nm = runValidatedNetworkTest();
|
||||||
|
// Verify forceReevalution will not reset the validation result but only probe result until
|
||||||
|
// getting the validation result.
|
||||||
|
reset(mCallbacks);
|
||||||
|
setSslException(mHttpsConnection);
|
||||||
|
setStatus(mHttpConnection, 500);
|
||||||
|
setStatus(mFallbackConnection, 204);
|
||||||
|
nm.forceReevaluation(Process.myUid());
|
||||||
|
final ArgumentCaptor<Integer> intCaptor = ArgumentCaptor.forClass(Integer.class);
|
||||||
|
// Expect to send HTTP, HTTPs, FALLBACK and evaluation results.
|
||||||
|
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(4))
|
||||||
|
.notifyNetworkTested(intCaptor.capture(), any());
|
||||||
|
List<Integer> intArgs = intCaptor.getAllValues();
|
||||||
|
|
||||||
|
assertEquals(Integer.valueOf(NETWORK_VALIDATION_PROBE_DNS
|
||||||
|
| NETWORK_VALIDATION_PROBE_FALLBACK | NETWORK_VALIDATION_RESULT_VALID),
|
||||||
|
intArgs.get(0));
|
||||||
|
assertTrue((intArgs.get(1) & NETWORK_VALIDATION_RESULT_VALID) != 0);
|
||||||
|
assertTrue((intArgs.get(2) & NETWORK_VALIDATION_RESULT_VALID) != 0);
|
||||||
|
assertTrue((intArgs.get(3) & NETWORK_VALIDATION_RESULT_PARTIAL) != 0);
|
||||||
|
assertTrue((intArgs.get(3) & NETWORK_VALIDATION_RESULT_VALID) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEvaluationState_clearProbeResults() throws Exception {
|
||||||
|
final NetworkMonitor nm = runValidatedNetworkTest();
|
||||||
|
nm.getEvaluationState().clearProbeResults();
|
||||||
|
// Verify probe results are all reset and only evaluation result left.
|
||||||
|
assertEquals(NETWORK_VALIDATION_RESULT_VALID,
|
||||||
|
nm.getEvaluationState().getNetworkTestResult());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEvaluationState_reportProbeResult() throws Exception {
|
||||||
|
final NetworkMonitor nm = runValidatedNetworkTest();
|
||||||
|
|
||||||
|
reset(mCallbacks);
|
||||||
|
|
||||||
|
nm.reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, CaptivePortalProbeResult.SUCCESS);
|
||||||
|
// Verify result should be appended and notifyNetworkTested callback is triggered once.
|
||||||
|
assertEquals(nm.getEvaluationState().getNetworkTestResult(),
|
||||||
|
VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_HTTP);
|
||||||
|
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
|
||||||
|
eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_PROBE_HTTP), any());
|
||||||
|
|
||||||
|
nm.reportHttpProbeResult(NETWORK_VALIDATION_PROBE_HTTP, CaptivePortalProbeResult.FAILED);
|
||||||
|
// Verify DNS probe result should not be cleared.
|
||||||
|
assertTrue((nm.getEvaluationState().getNetworkTestResult() & NETWORK_VALIDATION_PROBE_DNS)
|
||||||
|
== NETWORK_VALIDATION_PROBE_DNS);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEvaluationState_reportEvaluationResult() throws Exception {
|
||||||
|
final NetworkMonitor nm = runValidatedNetworkTest();
|
||||||
|
|
||||||
|
nm.getEvaluationState().reportEvaluationResult(NETWORK_VALIDATION_RESULT_PARTIAL,
|
||||||
|
null /* redirectUrl */);
|
||||||
|
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
|
||||||
|
eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS
|
||||||
|
| NETWORK_VALIDATION_RESULT_PARTIAL), eq(null));
|
||||||
|
|
||||||
|
nm.getEvaluationState().reportEvaluationResult(
|
||||||
|
NETWORK_VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_PARTIAL,
|
||||||
|
null /* redirectUrl */);
|
||||||
|
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
|
||||||
|
eq(VALIDATION_RESULT_VALID | NETWORK_VALIDATION_RESULT_PARTIAL), eq(null));
|
||||||
|
|
||||||
|
nm.getEvaluationState().reportEvaluationResult(VALIDATION_RESULT_INVALID,
|
||||||
|
TEST_REDIRECT_URL);
|
||||||
|
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1)).notifyNetworkTested(
|
||||||
|
eq(NETWORK_VALIDATION_PROBE_DNS | NETWORK_VALIDATION_PROBE_HTTPS),
|
||||||
|
eq(TEST_REDIRECT_URL));
|
||||||
|
}
|
||||||
|
|
||||||
private void makeDnsTimeoutEvent(WrappedNetworkMonitor wrappedMonitor, int count) {
|
private void makeDnsTimeoutEvent(WrappedNetworkMonitor wrappedMonitor, int count) {
|
||||||
for (int i = 0; i < count; i++) {
|
for (int i = 0; i < count; i++) {
|
||||||
wrappedMonitor.getDnsStallDetector().accumulateConsecutiveDnsTimeoutCount(
|
wrappedMonitor.getDnsStallDetector().accumulateConsecutiveDnsTimeoutCount(
|
||||||
@@ -954,39 +1059,64 @@ public class NetworkMonitorTest {
|
|||||||
eq(Settings.Global.CAPTIVE_PORTAL_MODE), anyInt())).thenReturn(mode);
|
eq(Settings.Global.CAPTIVE_PORTAL_MODE), anyInt())).thenReturn(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runPortalNetworkTest() {
|
private void runPortalNetworkTest(int result) {
|
||||||
runNetworkTest(NETWORK_TEST_RESULT_INVALID);
|
// The network test event will be triggered twice with the same result. Expect to capture
|
||||||
|
// the second one with direct url.
|
||||||
|
runPortalNetworkTest(result,
|
||||||
|
(VerificationWithTimeout) timeout(HANDLER_TIMEOUT_MS).times(2));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runPortalNetworkTest(int result, VerificationWithTimeout mode) {
|
||||||
|
runNetworkTest(result, mode);
|
||||||
assertEquals(1, mRegisteredReceivers.size());
|
assertEquals(1, mRegisteredReceivers.size());
|
||||||
assertNotNull(mNetworkTestedRedirectUrlCaptor.getValue());
|
assertNotNull(mNetworkTestedRedirectUrlCaptor.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runNotPortalNetworkTest() {
|
private void runNotPortalNetworkTest() {
|
||||||
runNetworkTest(NETWORK_TEST_RESULT_VALID);
|
runNetworkTest(VALIDATION_RESULT_VALID);
|
||||||
|
assertEquals(0, mRegisteredReceivers.size());
|
||||||
|
assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runNoValidationNetworkTest() {
|
||||||
|
runNetworkTest(NETWORK_VALIDATION_RESULT_VALID);
|
||||||
assertEquals(0, mRegisteredReceivers.size());
|
assertEquals(0, mRegisteredReceivers.size());
|
||||||
assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
|
assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runFailedNetworkTest() {
|
private void runFailedNetworkTest() {
|
||||||
runNetworkTest(NETWORK_TEST_RESULT_INVALID);
|
runNetworkTest(VALIDATION_RESULT_INVALID);
|
||||||
assertEquals(0, mRegisteredReceivers.size());
|
assertEquals(0, mRegisteredReceivers.size());
|
||||||
assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
|
assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runPartialConnectivityNetworkTest() {
|
private void runPartialConnectivityNetworkTest(int result) {
|
||||||
runNetworkTest(NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY);
|
runNetworkTest(result);
|
||||||
assertEquals(0, mRegisteredReceivers.size());
|
assertEquals(0, mRegisteredReceivers.size());
|
||||||
assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
|
assertNull(mNetworkTestedRedirectUrlCaptor.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NetworkMonitor runValidatedNetworkTest() throws Exception {
|
||||||
|
setStatus(mHttpsConnection, 204);
|
||||||
|
setStatus(mHttpConnection, 204);
|
||||||
|
// Expect to send HTTPs and evaluation results.
|
||||||
|
return runNetworkTest(VALIDATION_RESULT_VALID);
|
||||||
|
}
|
||||||
|
|
||||||
private NetworkMonitor runNetworkTest(int testResult) {
|
private NetworkMonitor runNetworkTest(int testResult) {
|
||||||
return runNetworkTest(METERED_CAPABILITIES, testResult);
|
return runNetworkTest(METERED_CAPABILITIES, testResult, getGeneralVerification());
|
||||||
}
|
}
|
||||||
|
|
||||||
private NetworkMonitor runNetworkTest(NetworkCapabilities nc, int testResult) {
|
private NetworkMonitor runNetworkTest(int testResult, VerificationWithTimeout mode) {
|
||||||
|
return runNetworkTest(METERED_CAPABILITIES, testResult, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
private NetworkMonitor runNetworkTest(NetworkCapabilities nc, int testResult,
|
||||||
|
VerificationWithTimeout mode) {
|
||||||
final NetworkMonitor monitor = makeMonitor(nc);
|
final NetworkMonitor monitor = makeMonitor(nc);
|
||||||
monitor.notifyNetworkConnected(TEST_LINK_PROPERTIES, nc);
|
monitor.notifyNetworkConnected(TEST_LINK_PROPERTIES, nc);
|
||||||
try {
|
try {
|
||||||
verify(mCallbacks, timeout(HANDLER_TIMEOUT_MS).times(1))
|
verify(mCallbacks, mode)
|
||||||
.notifyNetworkTested(eq(testResult), mNetworkTestedRedirectUrlCaptor.capture());
|
.notifyNetworkTested(eq(testResult), mNetworkTestedRedirectUrlCaptor.capture());
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
fail("Unexpected exception: " + e);
|
fail("Unexpected exception: " + e);
|
||||||
@@ -1018,5 +1148,10 @@ public class NetworkMonitorTest {
|
|||||||
stats.addDnsEvent(RETURN_CODE_DNS_TIMEOUT, 123456789 /* timeMs */);
|
stats.addDnsEvent(RETURN_CODE_DNS_TIMEOUT, 123456789 /* timeMs */);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private VerificationWithTimeout getGeneralVerification() {
|
||||||
|
return (VerificationWithTimeout) timeout(HANDLER_TIMEOUT_MS).atLeastOnce();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ import static android.net.ConnectivityManager.TYPE_NONE;
|
|||||||
import static android.net.ConnectivityManager.TYPE_VPN;
|
import static android.net.ConnectivityManager.TYPE_VPN;
|
||||||
import static android.net.ConnectivityManager.getNetworkTypeName;
|
import static android.net.ConnectivityManager.getNetworkTypeName;
|
||||||
import static android.net.ConnectivityManager.isNetworkTypeValid;
|
import static android.net.ConnectivityManager.isNetworkTypeValid;
|
||||||
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY;
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
|
||||||
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_VALID;
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_FOREGROUND;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_INTERNET;
|
||||||
@@ -2605,21 +2605,12 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
|
final NetworkAgentInfo nai = getNetworkAgentInfoForNetId(msg.arg2);
|
||||||
if (nai == null) break;
|
if (nai == null) break;
|
||||||
|
|
||||||
final boolean partialConnectivity =
|
final boolean wasPartial = nai.partialConnectivity;
|
||||||
(msg.arg1 == NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY)
|
nai.partialConnectivity = ((msg.arg1 & NETWORK_VALIDATION_RESULT_PARTIAL) != 0);
|
||||||
|| (nai.networkMisc.acceptPartialConnectivity
|
|
||||||
&& nai.partialConnectivity);
|
|
||||||
// Once a network is determined to have partial connectivity, it cannot
|
|
||||||
// go back to full connectivity without a disconnect. This is because
|
|
||||||
// NetworkMonitor can only communicate either PARTIAL_CONNECTIVITY or VALID,
|
|
||||||
// but not both.
|
|
||||||
// TODO: Provide multi-testResult to improve the communication between
|
|
||||||
// ConnectivityService and NetworkMonitor, so that ConnectivityService could
|
|
||||||
// know the real status of network.
|
|
||||||
final boolean partialConnectivityChanged =
|
final boolean partialConnectivityChanged =
|
||||||
(partialConnectivity && !nai.partialConnectivity);
|
(wasPartial != nai.partialConnectivity);
|
||||||
|
|
||||||
final boolean valid = (msg.arg1 == NETWORK_TEST_RESULT_VALID);
|
final boolean valid = ((msg.arg1 & NETWORK_VALIDATION_RESULT_VALID) != 0);
|
||||||
final boolean wasValidated = nai.lastValidated;
|
final boolean wasValidated = nai.lastValidated;
|
||||||
final boolean wasDefault = isDefaultNetwork(nai);
|
final boolean wasDefault = isDefaultNetwork(nai);
|
||||||
if (nai.everCaptivePortalDetected && !nai.captivePortalLoginNotified
|
if (nai.everCaptivePortalDetected && !nai.captivePortalLoginNotified
|
||||||
@@ -2649,21 +2640,23 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai);
|
if (oldScore != nai.getCurrentScore()) sendUpdatedScoreToFactories(nai);
|
||||||
if (valid) {
|
if (valid) {
|
||||||
handleFreshlyValidatedNetwork(nai);
|
handleFreshlyValidatedNetwork(nai);
|
||||||
// Clear NO_INTERNET and LOST_INTERNET notifications if network becomes
|
// Clear NO_INTERNET, PARTIAL_CONNECTIVITY and LOST_INTERNET
|
||||||
// valid.
|
// notifications if network becomes valid.
|
||||||
mNotifier.clearNotification(nai.network.netId,
|
mNotifier.clearNotification(nai.network.netId,
|
||||||
NotificationType.NO_INTERNET);
|
NotificationType.NO_INTERNET);
|
||||||
mNotifier.clearNotification(nai.network.netId,
|
mNotifier.clearNotification(nai.network.netId,
|
||||||
NotificationType.LOST_INTERNET);
|
NotificationType.LOST_INTERNET);
|
||||||
|
mNotifier.clearNotification(nai.network.netId,
|
||||||
|
NotificationType.PARTIAL_CONNECTIVITY);
|
||||||
}
|
}
|
||||||
} else if (partialConnectivityChanged) {
|
} else if (partialConnectivityChanged) {
|
||||||
nai.partialConnectivity = partialConnectivity;
|
|
||||||
updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
|
updateCapabilities(nai.getCurrentScore(), nai, nai.networkCapabilities);
|
||||||
}
|
}
|
||||||
updateInetCondition(nai);
|
updateInetCondition(nai);
|
||||||
// Let the NetworkAgent know the state of its network
|
// Let the NetworkAgent know the state of its network
|
||||||
Bundle redirectUrlBundle = new Bundle();
|
Bundle redirectUrlBundle = new Bundle();
|
||||||
redirectUrlBundle.putString(NetworkAgent.REDIRECT_URL_KEY, redirectUrl);
|
redirectUrlBundle.putString(NetworkAgent.REDIRECT_URL_KEY, redirectUrl);
|
||||||
|
// TODO: Evaluate to update partial connectivity to status to NetworkAgent.
|
||||||
nai.asyncChannel.sendMessage(
|
nai.asyncChannel.sendMessage(
|
||||||
NetworkAgent.CMD_REPORT_NETWORK_STATUS,
|
NetworkAgent.CMD_REPORT_NETWORK_STATUS,
|
||||||
(valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK),
|
(valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK),
|
||||||
@@ -3443,6 +3436,9 @@ public class ConnectivityService extends IConnectivityManager.Stub
|
|||||||
// Inform NetworkMonitor that partial connectivity is acceptable. This will likely
|
// Inform NetworkMonitor that partial connectivity is acceptable. This will likely
|
||||||
// result in a partial connectivity result which will be processed by
|
// result in a partial connectivity result which will be processed by
|
||||||
// maybeHandleNetworkMonitorMessage.
|
// maybeHandleNetworkMonitorMessage.
|
||||||
|
//
|
||||||
|
// TODO: NetworkMonitor does not refer to the "never ask again" bit. The bit is stored
|
||||||
|
// per network. Therefore, NetworkMonitor may still do https probe.
|
||||||
try {
|
try {
|
||||||
nai.networkMonitor().setAcceptPartialConnectivity();
|
nai.networkMonitor().setAcceptPartialConnectivity();
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
|
|||||||
@@ -30,9 +30,12 @@ import static android.net.ConnectivityManager.TYPE_MOBILE_MMS;
|
|||||||
import static android.net.ConnectivityManager.TYPE_NONE;
|
import static android.net.ConnectivityManager.TYPE_NONE;
|
||||||
import static android.net.ConnectivityManager.TYPE_VPN;
|
import static android.net.ConnectivityManager.TYPE_VPN;
|
||||||
import static android.net.ConnectivityManager.TYPE_WIFI;
|
import static android.net.ConnectivityManager.TYPE_WIFI;
|
||||||
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_INVALID;
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_DNS;
|
||||||
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY;
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_FALLBACK;
|
||||||
import static android.net.INetworkMonitor.NETWORK_TEST_RESULT_VALID;
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTP;
|
||||||
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_PROBE_HTTPS;
|
||||||
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_PARTIAL;
|
||||||
|
import static android.net.INetworkMonitor.NETWORK_VALIDATION_RESULT_VALID;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_CBS;
|
||||||
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
|
import static android.net.NetworkCapabilities.NET_CAPABILITY_DUN;
|
||||||
@@ -443,6 +446,16 @@ public class ConnectivityServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class MockNetworkAgent {
|
private class MockNetworkAgent {
|
||||||
|
private static final int VALIDATION_RESULT_BASE = NETWORK_VALIDATION_PROBE_DNS
|
||||||
|
| NETWORK_VALIDATION_PROBE_HTTP
|
||||||
|
| NETWORK_VALIDATION_PROBE_HTTPS;
|
||||||
|
private static final int VALIDATION_RESULT_VALID = VALIDATION_RESULT_BASE
|
||||||
|
| NETWORK_VALIDATION_RESULT_VALID;
|
||||||
|
private static final int VALIDATION_RESULT_PARTIAL = VALIDATION_RESULT_BASE
|
||||||
|
| NETWORK_VALIDATION_PROBE_FALLBACK
|
||||||
|
| NETWORK_VALIDATION_RESULT_PARTIAL;
|
||||||
|
private static final int VALIDATION_RESULT_INVALID = 0;
|
||||||
|
|
||||||
private final INetworkMonitor mNetworkMonitor;
|
private final INetworkMonitor mNetworkMonitor;
|
||||||
private final NetworkInfo mNetworkInfo;
|
private final NetworkInfo mNetworkInfo;
|
||||||
private final NetworkCapabilities mNetworkCapabilities;
|
private final NetworkCapabilities mNetworkCapabilities;
|
||||||
@@ -460,17 +473,17 @@ public class ConnectivityServiceTest {
|
|||||||
private String mRedirectUrl;
|
private String mRedirectUrl;
|
||||||
|
|
||||||
private INetworkMonitorCallbacks mNmCallbacks;
|
private INetworkMonitorCallbacks mNmCallbacks;
|
||||||
private int mNmValidationResult = NETWORK_TEST_RESULT_INVALID;
|
private int mNmValidationResult = VALIDATION_RESULT_BASE;
|
||||||
private String mNmValidationRedirectUrl = null;
|
private String mNmValidationRedirectUrl = null;
|
||||||
private boolean mNmProvNotificationRequested = false;
|
private boolean mNmProvNotificationRequested = false;
|
||||||
|
|
||||||
void setNetworkValid() {
|
void setNetworkValid() {
|
||||||
mNmValidationResult = NETWORK_TEST_RESULT_VALID;
|
mNmValidationResult = VALIDATION_RESULT_VALID;
|
||||||
mNmValidationRedirectUrl = null;
|
mNmValidationRedirectUrl = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setNetworkInvalid() {
|
void setNetworkInvalid() {
|
||||||
mNmValidationResult = NETWORK_TEST_RESULT_INVALID;
|
mNmValidationResult = VALIDATION_RESULT_INVALID;
|
||||||
mNmValidationRedirectUrl = null;
|
mNmValidationRedirectUrl = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -480,7 +493,12 @@ public class ConnectivityServiceTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setNetworkPartial() {
|
void setNetworkPartial() {
|
||||||
mNmValidationResult = NETWORK_TEST_RESULT_PARTIAL_CONNECTIVITY;
|
mNmValidationResult = VALIDATION_RESULT_PARTIAL;
|
||||||
|
mNmValidationRedirectUrl = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setNetworkPartialValid() {
|
||||||
|
mNmValidationResult = VALIDATION_RESULT_PARTIAL | VALIDATION_RESULT_VALID;
|
||||||
mNmValidationRedirectUrl = null;
|
mNmValidationRedirectUrl = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,7 +615,7 @@ public class ConnectivityServiceTest {
|
|||||||
private void onValidationRequested() {
|
private void onValidationRequested() {
|
||||||
try {
|
try {
|
||||||
if (mNmProvNotificationRequested
|
if (mNmProvNotificationRequested
|
||||||
&& mNmValidationResult == NETWORK_TEST_RESULT_VALID) {
|
&& mNmValidationResult == VALIDATION_RESULT_VALID) {
|
||||||
mNmCallbacks.hideProvisioningNotification();
|
mNmCallbacks.hideProvisioningNotification();
|
||||||
mNmProvNotificationRequested = false;
|
mNmProvNotificationRequested = false;
|
||||||
}
|
}
|
||||||
@@ -2651,7 +2669,7 @@ public class ConnectivityServiceTest {
|
|||||||
|
|
||||||
// With HTTPS probe disabled, NetworkMonitor should pass the network validation with http
|
// With HTTPS probe disabled, NetworkMonitor should pass the network validation with http
|
||||||
// probe.
|
// probe.
|
||||||
mWiFiNetworkAgent.setNetworkValid();
|
mWiFiNetworkAgent.setNetworkPartialValid();
|
||||||
// If the user chooses yes to use this partial connectivity wifi, switch the default
|
// If the user chooses yes to use this partial connectivity wifi, switch the default
|
||||||
// network to wifi and check if wifi becomes valid or not.
|
// network to wifi and check if wifi becomes valid or not.
|
||||||
mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */,
|
mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */,
|
||||||
@@ -2748,6 +2766,54 @@ public class ConnectivityServiceTest {
|
|||||||
callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
|
callback.expectCallback(CallbackState.LOST, mWiFiNetworkAgent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCaptivePortalOnPartialConnectivity() throws RemoteException {
|
||||||
|
final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
|
||||||
|
final NetworkRequest captivePortalRequest = new NetworkRequest.Builder()
|
||||||
|
.addCapability(NET_CAPABILITY_CAPTIVE_PORTAL).build();
|
||||||
|
mCm.registerNetworkCallback(captivePortalRequest, captivePortalCallback);
|
||||||
|
|
||||||
|
final TestNetworkCallback validatedCallback = new TestNetworkCallback();
|
||||||
|
final NetworkRequest validatedRequest = new NetworkRequest.Builder()
|
||||||
|
.addCapability(NET_CAPABILITY_VALIDATED).build();
|
||||||
|
mCm.registerNetworkCallback(validatedRequest, validatedCallback);
|
||||||
|
|
||||||
|
// Bring up a network with a captive portal.
|
||||||
|
// Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL.
|
||||||
|
mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI);
|
||||||
|
String firstRedirectUrl = "http://example.com/firstPath";
|
||||||
|
mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl);
|
||||||
|
captivePortalCallback.expectAvailableCallbacksUnvalidated(mWiFiNetworkAgent);
|
||||||
|
assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl);
|
||||||
|
|
||||||
|
// Check that startCaptivePortalApp sends the expected command to NetworkMonitor.
|
||||||
|
mCm.startCaptivePortalApp(mWiFiNetworkAgent.getNetwork());
|
||||||
|
verify(mWiFiNetworkAgent.mNetworkMonitor, timeout(TIMEOUT_MS).times(1))
|
||||||
|
.launchCaptivePortalApp();
|
||||||
|
|
||||||
|
// Report that the captive portal is dismissed with partial connectivity, and check that
|
||||||
|
// callbacks are fired.
|
||||||
|
mWiFiNetworkAgent.setNetworkPartial();
|
||||||
|
mWiFiNetworkAgent.mNetworkMonitor.forceReevaluation(Process.myUid());
|
||||||
|
waitForIdle();
|
||||||
|
captivePortalCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY,
|
||||||
|
mWiFiNetworkAgent);
|
||||||
|
|
||||||
|
// Report partial connectivity is accepted.
|
||||||
|
mWiFiNetworkAgent.setNetworkPartialValid();
|
||||||
|
mCm.setAcceptPartialConnectivity(mWiFiNetworkAgent.getNetwork(), true /* accept */,
|
||||||
|
false /* always */);
|
||||||
|
waitForIdle();
|
||||||
|
mCm.reportNetworkConnectivity(mWiFiNetworkAgent.getNetwork(), true);
|
||||||
|
validatedCallback.expectAvailableCallbacksValidated(mWiFiNetworkAgent);
|
||||||
|
NetworkCapabilities nc =
|
||||||
|
validatedCallback.expectCapabilitiesWith(NET_CAPABILITY_PARTIAL_CONNECTIVITY,
|
||||||
|
mWiFiNetworkAgent);
|
||||||
|
|
||||||
|
mCm.unregisterNetworkCallback(captivePortalCallback);
|
||||||
|
mCm.unregisterNetworkCallback(validatedCallback);
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testCaptivePortal() {
|
public void testCaptivePortal() {
|
||||||
final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
|
final TestNetworkCallback captivePortalCallback = new TestNetworkCallback();
|
||||||
|
|||||||
Reference in New Issue
Block a user