Loading core/java/android/net/NetworkAgent.java +13 −3 Original line number Diff line number Diff line Loading @@ -120,12 +120,17 @@ public abstract class NetworkAgent extends Handler { * either a bad network configuration (no internet link) or captive portal. * * arg1 = either {@code VALID_NETWORK} or {@code INVALID_NETWORK} * obj = Bundle containing map from {@code REDIRECT_URL_KEY} to {@code String} * representing URL that Internet probe was redirect to, if it was redirected, * or mapping to {@code null} otherwise. */ public static final int CMD_REPORT_NETWORK_STATUS = BASE + 7; public static final int VALID_NETWORK = 1; public static final int INVALID_NETWORK = 2; public static String REDIRECT_URL_KEY = "redirect URL"; /** * Sent by the NetworkAgent to ConnectivityService to indicate this network was * explicitly selected. This should be sent before the NetworkInfo is marked Loading Loading @@ -283,11 +288,12 @@ public abstract class NetworkAgent extends Handler { break; } case CMD_REPORT_NETWORK_STATUS: { String redirectUrl = ((Bundle)msg.obj).getString(REDIRECT_URL_KEY); if (VDBG) { log("CMD_REPORT_NETWORK_STATUS(" + (msg.arg1 == VALID_NETWORK ? "VALID)" : "INVALID)")); (msg.arg1 == VALID_NETWORK ? "VALID, " : "INVALID, ") + redirectUrl); } networkStatus(msg.arg1); networkStatus(msg.arg1, redirectUrl); break; } case CMD_SAVE_ACCEPT_UNVALIDATED: { Loading Loading @@ -443,8 +449,12 @@ public abstract class NetworkAgent extends Handler { * * This may be called multiple times as the network status changes and may * generate false negatives if we lose ip connectivity before the link is torn down. * * @param status one of {@code VALID_NETWORK} or {@code INVALID_NETWORK}. * @param redirectUrl If the Internet probe was redirected, this is the destination it was * redirected to, otherwise {@code null}. */ protected void networkStatus(int status) { protected void networkStatus(int status, String redirectUrl) { } /** Loading services/core/java/com/android/server/ConnectivityService.java +11 −5 Original line number Diff line number Diff line Loading @@ -2025,11 +2025,15 @@ public class ConnectivityService extends IConnectivityManager.Stub default: return false; case NetworkMonitor.EVENT_NETWORK_TESTED: { NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj; if (isLiveNetworkAgent(nai, msg.what)) { final NetworkAgentInfo nai; synchronized (mNetworkForNetId) { nai = mNetworkForNetId.get(msg.arg2); } if (nai != null) { final boolean valid = (msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID); if (DBG) log(nai.name() + " validation " + (valid ? " passed" : "failed")); if (DBG) log(nai.name() + " validation " + (valid ? "passed" : "failed") + (msg.obj == null ? "" : " with redirect to " + (String)msg.obj)); if (valid != nai.lastValidated) { final int oldScore = nai.getCurrentScore(); nai.lastValidated = valid; Loading @@ -2040,10 +2044,12 @@ public class ConnectivityService extends IConnectivityManager.Stub } updateInetCondition(nai); // Let the NetworkAgent know the state of its network Bundle redirectUrlBundle = new Bundle(); redirectUrlBundle.putString(NetworkAgent.REDIRECT_URL_KEY, (String)msg.obj); nai.asyncChannel.sendMessage( android.net.NetworkAgent.CMD_REPORT_NETWORK_STATUS, NetworkAgent.CMD_REPORT_NETWORK_STATUS, (valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK), 0, null); 0, redirectUrlBundle); } break; } Loading services/core/java/com/android/server/connectivity/NetworkMonitor.java +35 −15 Original line number Diff line number Diff line Loading @@ -120,8 +120,9 @@ public class NetworkMonitor extends StateMachine { /** * Inform ConnectivityService that the network has been tested. * obj = NetworkAgentInfo * obj = String representing URL that Internet probe was redirect to, if it was redirected. * arg1 = One of the NETWORK_TESTED_RESULT_* constants. * arg2 = NetID. */ public static final int EVENT_NETWORK_TESTED = BASE + 2; Loading Loading @@ -334,8 +335,8 @@ public class NetworkMonitor extends StateMachine { mDontDisplaySigninNotification = true; mUserDoesNotWant = true; mConnectivityServiceHandler.sendMessage(obtainMessage( EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, 0, mNetworkAgentInfo)); EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, mNetworkAgentInfo.network.netId, null)); // TODO: Should teardown network. mUidResponsibleForReeval = 0; transitionTo(mEvaluatingState); Loading @@ -358,7 +359,7 @@ public class NetworkMonitor extends StateMachine { CaptivePortalStateChangeEvent.logEvent( CaptivePortalStateChangeEvent.NETWORK_MONITOR_VALIDATED); mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_VALID, 0, mNetworkAgentInfo)); NETWORK_TEST_RESULT_VALID, mNetworkAgentInfo.network.netId, null)); } @Override Loading Loading @@ -412,6 +413,21 @@ public class NetworkMonitor extends StateMachine { } } /** * Result of calling isCaptivePortal(). * @hide */ @VisibleForTesting public static final class CaptivePortalProbeResult { final int mHttpResponseCode; // HTTP response code returned from Internet probe. final String mRedirectUrl; // Redirect destination returned from Internet probe. public CaptivePortalProbeResult(int httpResponseCode, String redirectUrl) { mHttpResponseCode = httpResponseCode; mRedirectUrl = redirectUrl; } } // Being in the EvaluatingState State indicates the Network is being evaluated for internet // connectivity, or that the user has indicated that this network is unwanted. private class EvaluatingState extends State { Loading Loading @@ -464,19 +480,23 @@ public class NetworkMonitor extends StateMachine { // IPv6) could each take SOCKET_TIMEOUT_MS. During this time this StateMachine // will be unresponsive. isCaptivePortal() could be executed on another Thread // if this is found to cause problems. int httpResponseCode = isCaptivePortal(); CaptivePortalProbeResult probeResult = isCaptivePortal(); CaptivePortalCheckResultEvent.logEvent(mNetworkAgentInfo.network.netId, httpResponseCode); if (httpResponseCode == 204) { probeResult.mHttpResponseCode); if (probeResult.mHttpResponseCode == 204) { transitionTo(mValidatedState); } else if (httpResponseCode >= 200 && httpResponseCode <= 399) { } else if (probeResult.mHttpResponseCode >= 200 && probeResult.mHttpResponseCode <= 399) { mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, mNetworkAgentInfo.network.netId, probeResult.mRedirectUrl)); transitionTo(mCaptivePortalState); } else { final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0); sendMessageDelayed(msg, mReevaluateDelayMs); mConnectivityServiceHandler.sendMessage(obtainMessage( EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, 0, mNetworkAgentInfo)); EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, mNetworkAgentInfo.network.netId, probeResult.mRedirectUrl)); if (mAttempts >= BLAME_FOR_EVALUATION_ATTEMPTS) { // Don't continue to blame UID forever. TrafficStats.clearThreadStatsUid(); Loading Loading @@ -533,8 +553,6 @@ public class NetworkMonitor extends StateMachine { @Override public void enter() { mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, 0, mNetworkAgentInfo)); // Don't annoy user with sign-in notifications. if (mDontDisplaySigninNotification) return; // Create a CustomIntentReceiver that sends us a Loading Loading @@ -639,11 +657,12 @@ public class NetworkMonitor extends StateMachine { * Returns HTTP response code. */ @VisibleForTesting protected int isCaptivePortal() { if (!mIsCaptivePortalCheckEnabled) return 204; protected CaptivePortalProbeResult isCaptivePortal() { if (!mIsCaptivePortalCheckEnabled) return new CaptivePortalProbeResult(204, null); HttpURLConnection urlConnection = null; int httpResponseCode = 599; String redirectUrl = null; try { URL url = new URL(getCaptivePortalServerUrl(mContext)); // On networks with a PAC instead of fetching a URL that should result in a 204 Loading Loading @@ -699,6 +718,7 @@ public class NetworkMonitor extends StateMachine { long requestTimestamp = SystemClock.elapsedRealtime(); httpResponseCode = urlConnection.getResponseCode(); redirectUrl = urlConnection.getHeaderField("location"); // Time how long it takes to get a response to our request long responseTimestamp = SystemClock.elapsedRealtime(); Loading Loading @@ -739,7 +759,7 @@ public class NetworkMonitor extends StateMachine { urlConnection.disconnect(); } } return httpResponseCode; return new CaptivePortalProbeResult(httpResponseCode, redirectUrl); } /** Loading services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java +28 −5 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ import android.util.LogPrinter; import com.android.internal.util.WakeupMessage; import com.android.server.connectivity.NetworkAgentInfo; import com.android.server.connectivity.NetworkMonitor; import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult; import com.android.server.net.NetworkPinner; import java.net.InetAddress; Loading Loading @@ -223,11 +224,15 @@ public class ConnectivityServiceTest extends AndroidTestCase { private final NetworkCapabilities mNetworkCapabilities; private final IdleableHandlerThread mHandlerThread; private final ConditionVariable mDisconnected = new ConditionVariable(); private final ConditionVariable mNetworkStatusReceived = new ConditionVariable(); private int mScore; private NetworkAgent mNetworkAgent; private int mStartKeepaliveError = PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED; private int mStopKeepaliveError = PacketKeepalive.NO_KEEPALIVE; private Integer mExpectedKeepaliveSlot = null; // Contains the redirectUrl from networkStatus(). Before reading, wait for // mNetworkStatusReceived. private String mRedirectUrl; MockNetworkAgent(int transport) { final int type = transportToLegacyType(transport); Loading Loading @@ -266,6 +271,12 @@ public class ConnectivityServiceTest extends AndroidTestCase { public void stopPacketKeepalive(Message msg) { onPacketKeepaliveEvent(msg.arg1, mStopKeepaliveError); } @Override public void networkStatus(int status, String redirectUrl) { mRedirectUrl = redirectUrl; mNetworkStatusReceived.open(); } }; // Waits for the NetworkAgent to be registered, which includes the creation of the // NetworkMonitor. Loading Loading @@ -340,13 +351,15 @@ public class ConnectivityServiceTest extends AndroidTestCase { if (callback != null) mCm.unregisterNetworkCallback(callback); } public void connectWithCaptivePortal() { public void connectWithCaptivePortal(String redirectUrl) { mWrappedNetworkMonitor.gen204ProbeResult = 200; mWrappedNetworkMonitor.gen204ProbeRedirectUrl = redirectUrl; connect(false); waitFor(new Criteria() { public boolean get() { NetworkCapabilities caps = mCm.getNetworkCapabilities(getNetwork()); return caps != null && caps.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL);} }); mWrappedNetworkMonitor.gen204ProbeResult = 500; mWrappedNetworkMonitor.gen204ProbeRedirectUrl = null; } public void disconnect() { Loading Loading @@ -381,6 +394,11 @@ public class ConnectivityServiceTest extends AndroidTestCase { public void setExpectedKeepaliveSlot(Integer slot) { mExpectedKeepaliveSlot = slot; } public String waitForRedirectUrl() { assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS)); return mRedirectUrl; } } /** Loading Loading @@ -543,6 +561,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { private class WrappedNetworkMonitor extends NetworkMonitor { // HTTP response code fed back to NetworkMonitor for Internet connectivity probe. public int gen204ProbeResult = 500; public String gen204ProbeRedirectUrl = null; public WrappedNetworkMonitor(Context context, Handler handler, NetworkAgentInfo networkAgentInfo, NetworkRequest defaultRequest) { Loading @@ -550,8 +569,8 @@ public class ConnectivityServiceTest extends AndroidTestCase { } @Override protected int isCaptivePortal() { return gen204ProbeResult; protected CaptivePortalProbeResult isCaptivePortal() { return new CaptivePortalProbeResult(gen204ProbeResult, gen204ProbeRedirectUrl); } @Override Loading Loading @@ -1344,8 +1363,10 @@ public class ConnectivityServiceTest extends AndroidTestCase { // Bring up a network with a captive portal. // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); mWiFiNetworkAgent.connectWithCaptivePortal(); String firstRedirectUrl = "http://example.com/firstPath"; mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl); captivePortalCallback.expectCallback(CallbackState.AVAILABLE); assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl); // Take down network. // Expect onLost callback. Loading @@ -1355,8 +1376,10 @@ public class ConnectivityServiceTest extends AndroidTestCase { // Bring up a network with a captive portal. // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); mWiFiNetworkAgent.connectWithCaptivePortal(); String secondRedirectUrl = "http://example.com/secondPath"; mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl); captivePortalCallback.expectCallback(CallbackState.AVAILABLE); assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), secondRedirectUrl); // Make captive portal disappear then revalidate. // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL. Loading Loading
core/java/android/net/NetworkAgent.java +13 −3 Original line number Diff line number Diff line Loading @@ -120,12 +120,17 @@ public abstract class NetworkAgent extends Handler { * either a bad network configuration (no internet link) or captive portal. * * arg1 = either {@code VALID_NETWORK} or {@code INVALID_NETWORK} * obj = Bundle containing map from {@code REDIRECT_URL_KEY} to {@code String} * representing URL that Internet probe was redirect to, if it was redirected, * or mapping to {@code null} otherwise. */ public static final int CMD_REPORT_NETWORK_STATUS = BASE + 7; public static final int VALID_NETWORK = 1; public static final int INVALID_NETWORK = 2; public static String REDIRECT_URL_KEY = "redirect URL"; /** * Sent by the NetworkAgent to ConnectivityService to indicate this network was * explicitly selected. This should be sent before the NetworkInfo is marked Loading Loading @@ -283,11 +288,12 @@ public abstract class NetworkAgent extends Handler { break; } case CMD_REPORT_NETWORK_STATUS: { String redirectUrl = ((Bundle)msg.obj).getString(REDIRECT_URL_KEY); if (VDBG) { log("CMD_REPORT_NETWORK_STATUS(" + (msg.arg1 == VALID_NETWORK ? "VALID)" : "INVALID)")); (msg.arg1 == VALID_NETWORK ? "VALID, " : "INVALID, ") + redirectUrl); } networkStatus(msg.arg1); networkStatus(msg.arg1, redirectUrl); break; } case CMD_SAVE_ACCEPT_UNVALIDATED: { Loading Loading @@ -443,8 +449,12 @@ public abstract class NetworkAgent extends Handler { * * This may be called multiple times as the network status changes and may * generate false negatives if we lose ip connectivity before the link is torn down. * * @param status one of {@code VALID_NETWORK} or {@code INVALID_NETWORK}. * @param redirectUrl If the Internet probe was redirected, this is the destination it was * redirected to, otherwise {@code null}. */ protected void networkStatus(int status) { protected void networkStatus(int status, String redirectUrl) { } /** Loading
services/core/java/com/android/server/ConnectivityService.java +11 −5 Original line number Diff line number Diff line Loading @@ -2025,11 +2025,15 @@ public class ConnectivityService extends IConnectivityManager.Stub default: return false; case NetworkMonitor.EVENT_NETWORK_TESTED: { NetworkAgentInfo nai = (NetworkAgentInfo)msg.obj; if (isLiveNetworkAgent(nai, msg.what)) { final NetworkAgentInfo nai; synchronized (mNetworkForNetId) { nai = mNetworkForNetId.get(msg.arg2); } if (nai != null) { final boolean valid = (msg.arg1 == NetworkMonitor.NETWORK_TEST_RESULT_VALID); if (DBG) log(nai.name() + " validation " + (valid ? " passed" : "failed")); if (DBG) log(nai.name() + " validation " + (valid ? "passed" : "failed") + (msg.obj == null ? "" : " with redirect to " + (String)msg.obj)); if (valid != nai.lastValidated) { final int oldScore = nai.getCurrentScore(); nai.lastValidated = valid; Loading @@ -2040,10 +2044,12 @@ public class ConnectivityService extends IConnectivityManager.Stub } updateInetCondition(nai); // Let the NetworkAgent know the state of its network Bundle redirectUrlBundle = new Bundle(); redirectUrlBundle.putString(NetworkAgent.REDIRECT_URL_KEY, (String)msg.obj); nai.asyncChannel.sendMessage( android.net.NetworkAgent.CMD_REPORT_NETWORK_STATUS, NetworkAgent.CMD_REPORT_NETWORK_STATUS, (valid ? NetworkAgent.VALID_NETWORK : NetworkAgent.INVALID_NETWORK), 0, null); 0, redirectUrlBundle); } break; } Loading
services/core/java/com/android/server/connectivity/NetworkMonitor.java +35 −15 Original line number Diff line number Diff line Loading @@ -120,8 +120,9 @@ public class NetworkMonitor extends StateMachine { /** * Inform ConnectivityService that the network has been tested. * obj = NetworkAgentInfo * obj = String representing URL that Internet probe was redirect to, if it was redirected. * arg1 = One of the NETWORK_TESTED_RESULT_* constants. * arg2 = NetID. */ public static final int EVENT_NETWORK_TESTED = BASE + 2; Loading Loading @@ -334,8 +335,8 @@ public class NetworkMonitor extends StateMachine { mDontDisplaySigninNotification = true; mUserDoesNotWant = true; mConnectivityServiceHandler.sendMessage(obtainMessage( EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, 0, mNetworkAgentInfo)); EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, mNetworkAgentInfo.network.netId, null)); // TODO: Should teardown network. mUidResponsibleForReeval = 0; transitionTo(mEvaluatingState); Loading @@ -358,7 +359,7 @@ public class NetworkMonitor extends StateMachine { CaptivePortalStateChangeEvent.logEvent( CaptivePortalStateChangeEvent.NETWORK_MONITOR_VALIDATED); mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_VALID, 0, mNetworkAgentInfo)); NETWORK_TEST_RESULT_VALID, mNetworkAgentInfo.network.netId, null)); } @Override Loading Loading @@ -412,6 +413,21 @@ public class NetworkMonitor extends StateMachine { } } /** * Result of calling isCaptivePortal(). * @hide */ @VisibleForTesting public static final class CaptivePortalProbeResult { final int mHttpResponseCode; // HTTP response code returned from Internet probe. final String mRedirectUrl; // Redirect destination returned from Internet probe. public CaptivePortalProbeResult(int httpResponseCode, String redirectUrl) { mHttpResponseCode = httpResponseCode; mRedirectUrl = redirectUrl; } } // Being in the EvaluatingState State indicates the Network is being evaluated for internet // connectivity, or that the user has indicated that this network is unwanted. private class EvaluatingState extends State { Loading Loading @@ -464,19 +480,23 @@ public class NetworkMonitor extends StateMachine { // IPv6) could each take SOCKET_TIMEOUT_MS. During this time this StateMachine // will be unresponsive. isCaptivePortal() could be executed on another Thread // if this is found to cause problems. int httpResponseCode = isCaptivePortal(); CaptivePortalProbeResult probeResult = isCaptivePortal(); CaptivePortalCheckResultEvent.logEvent(mNetworkAgentInfo.network.netId, httpResponseCode); if (httpResponseCode == 204) { probeResult.mHttpResponseCode); if (probeResult.mHttpResponseCode == 204) { transitionTo(mValidatedState); } else if (httpResponseCode >= 200 && httpResponseCode <= 399) { } else if (probeResult.mHttpResponseCode >= 200 && probeResult.mHttpResponseCode <= 399) { mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, mNetworkAgentInfo.network.netId, probeResult.mRedirectUrl)); transitionTo(mCaptivePortalState); } else { final Message msg = obtainMessage(CMD_REEVALUATE, ++mReevaluateToken, 0); sendMessageDelayed(msg, mReevaluateDelayMs); mConnectivityServiceHandler.sendMessage(obtainMessage( EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, 0, mNetworkAgentInfo)); EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, mNetworkAgentInfo.network.netId, probeResult.mRedirectUrl)); if (mAttempts >= BLAME_FOR_EVALUATION_ATTEMPTS) { // Don't continue to blame UID forever. TrafficStats.clearThreadStatsUid(); Loading Loading @@ -533,8 +553,6 @@ public class NetworkMonitor extends StateMachine { @Override public void enter() { mConnectivityServiceHandler.sendMessage(obtainMessage(EVENT_NETWORK_TESTED, NETWORK_TEST_RESULT_INVALID, 0, mNetworkAgentInfo)); // Don't annoy user with sign-in notifications. if (mDontDisplaySigninNotification) return; // Create a CustomIntentReceiver that sends us a Loading Loading @@ -639,11 +657,12 @@ public class NetworkMonitor extends StateMachine { * Returns HTTP response code. */ @VisibleForTesting protected int isCaptivePortal() { if (!mIsCaptivePortalCheckEnabled) return 204; protected CaptivePortalProbeResult isCaptivePortal() { if (!mIsCaptivePortalCheckEnabled) return new CaptivePortalProbeResult(204, null); HttpURLConnection urlConnection = null; int httpResponseCode = 599; String redirectUrl = null; try { URL url = new URL(getCaptivePortalServerUrl(mContext)); // On networks with a PAC instead of fetching a URL that should result in a 204 Loading Loading @@ -699,6 +718,7 @@ public class NetworkMonitor extends StateMachine { long requestTimestamp = SystemClock.elapsedRealtime(); httpResponseCode = urlConnection.getResponseCode(); redirectUrl = urlConnection.getHeaderField("location"); // Time how long it takes to get a response to our request long responseTimestamp = SystemClock.elapsedRealtime(); Loading Loading @@ -739,7 +759,7 @@ public class NetworkMonitor extends StateMachine { urlConnection.disconnect(); } } return httpResponseCode; return new CaptivePortalProbeResult(httpResponseCode, redirectUrl); } /** Loading
services/tests/servicestests/src/com/android/server/ConnectivityServiceTest.java +28 −5 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ import android.util.LogPrinter; import com.android.internal.util.WakeupMessage; import com.android.server.connectivity.NetworkAgentInfo; import com.android.server.connectivity.NetworkMonitor; import com.android.server.connectivity.NetworkMonitor.CaptivePortalProbeResult; import com.android.server.net.NetworkPinner; import java.net.InetAddress; Loading Loading @@ -223,11 +224,15 @@ public class ConnectivityServiceTest extends AndroidTestCase { private final NetworkCapabilities mNetworkCapabilities; private final IdleableHandlerThread mHandlerThread; private final ConditionVariable mDisconnected = new ConditionVariable(); private final ConditionVariable mNetworkStatusReceived = new ConditionVariable(); private int mScore; private NetworkAgent mNetworkAgent; private int mStartKeepaliveError = PacketKeepalive.ERROR_HARDWARE_UNSUPPORTED; private int mStopKeepaliveError = PacketKeepalive.NO_KEEPALIVE; private Integer mExpectedKeepaliveSlot = null; // Contains the redirectUrl from networkStatus(). Before reading, wait for // mNetworkStatusReceived. private String mRedirectUrl; MockNetworkAgent(int transport) { final int type = transportToLegacyType(transport); Loading Loading @@ -266,6 +271,12 @@ public class ConnectivityServiceTest extends AndroidTestCase { public void stopPacketKeepalive(Message msg) { onPacketKeepaliveEvent(msg.arg1, mStopKeepaliveError); } @Override public void networkStatus(int status, String redirectUrl) { mRedirectUrl = redirectUrl; mNetworkStatusReceived.open(); } }; // Waits for the NetworkAgent to be registered, which includes the creation of the // NetworkMonitor. Loading Loading @@ -340,13 +351,15 @@ public class ConnectivityServiceTest extends AndroidTestCase { if (callback != null) mCm.unregisterNetworkCallback(callback); } public void connectWithCaptivePortal() { public void connectWithCaptivePortal(String redirectUrl) { mWrappedNetworkMonitor.gen204ProbeResult = 200; mWrappedNetworkMonitor.gen204ProbeRedirectUrl = redirectUrl; connect(false); waitFor(new Criteria() { public boolean get() { NetworkCapabilities caps = mCm.getNetworkCapabilities(getNetwork()); return caps != null && caps.hasCapability(NET_CAPABILITY_CAPTIVE_PORTAL);} }); mWrappedNetworkMonitor.gen204ProbeResult = 500; mWrappedNetworkMonitor.gen204ProbeRedirectUrl = null; } public void disconnect() { Loading Loading @@ -381,6 +394,11 @@ public class ConnectivityServiceTest extends AndroidTestCase { public void setExpectedKeepaliveSlot(Integer slot) { mExpectedKeepaliveSlot = slot; } public String waitForRedirectUrl() { assertTrue(mNetworkStatusReceived.block(TIMEOUT_MS)); return mRedirectUrl; } } /** Loading Loading @@ -543,6 +561,7 @@ public class ConnectivityServiceTest extends AndroidTestCase { private class WrappedNetworkMonitor extends NetworkMonitor { // HTTP response code fed back to NetworkMonitor for Internet connectivity probe. public int gen204ProbeResult = 500; public String gen204ProbeRedirectUrl = null; public WrappedNetworkMonitor(Context context, Handler handler, NetworkAgentInfo networkAgentInfo, NetworkRequest defaultRequest) { Loading @@ -550,8 +569,8 @@ public class ConnectivityServiceTest extends AndroidTestCase { } @Override protected int isCaptivePortal() { return gen204ProbeResult; protected CaptivePortalProbeResult isCaptivePortal() { return new CaptivePortalProbeResult(gen204ProbeResult, gen204ProbeRedirectUrl); } @Override Loading Loading @@ -1344,8 +1363,10 @@ public class ConnectivityServiceTest extends AndroidTestCase { // Bring up a network with a captive portal. // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); mWiFiNetworkAgent.connectWithCaptivePortal(); String firstRedirectUrl = "http://example.com/firstPath"; mWiFiNetworkAgent.connectWithCaptivePortal(firstRedirectUrl); captivePortalCallback.expectCallback(CallbackState.AVAILABLE); assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), firstRedirectUrl); // Take down network. // Expect onLost callback. Loading @@ -1355,8 +1376,10 @@ public class ConnectivityServiceTest extends AndroidTestCase { // Bring up a network with a captive portal. // Expect onAvailable callback of listen for NET_CAPABILITY_CAPTIVE_PORTAL. mWiFiNetworkAgent = new MockNetworkAgent(TRANSPORT_WIFI); mWiFiNetworkAgent.connectWithCaptivePortal(); String secondRedirectUrl = "http://example.com/secondPath"; mWiFiNetworkAgent.connectWithCaptivePortal(secondRedirectUrl); captivePortalCallback.expectCallback(CallbackState.AVAILABLE); assertEquals(mWiFiNetworkAgent.waitForRedirectUrl(), secondRedirectUrl); // Make captive portal disappear then revalidate. // Expect onLost callback because network no longer provides NET_CAPABILITY_CAPTIVE_PORTAL. Loading