Merge "Add more test coverage to ConnectivityManagerTest." into nyc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
25a61dcae9
@@ -38,9 +38,16 @@ import android.net.wifi.WifiManager;
|
|||||||
import android.test.AndroidTestCase;
|
import android.test.AndroidTestCase;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.os.SystemProperties;
|
import android.os.SystemProperties;
|
||||||
|
import android.system.Os;
|
||||||
|
import android.system.OsConstants;
|
||||||
|
|
||||||
import com.android.internal.telephony.PhoneConstants;
|
import com.android.internal.telephony.PhoneConstants;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.net.Socket;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
@@ -57,7 +64,15 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
|||||||
|
|
||||||
public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE;
|
public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE;
|
||||||
public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI;
|
public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI;
|
||||||
|
|
||||||
private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1
|
private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1
|
||||||
|
private static final String TEST_HOST = "connectivitycheck.gstatic.com";
|
||||||
|
private static final int SOCKET_TIMEOUT_MS = 2000;
|
||||||
|
private static final int HTTP_PORT = 80;
|
||||||
|
private static final String HTTP_REQUEST =
|
||||||
|
"GET /generate_204 HTTP/1.0\r\n" +
|
||||||
|
"Host: " + TEST_HOST + "\r\n" +
|
||||||
|
"Connection: keep-alive\r\n\r\n";
|
||||||
|
|
||||||
// Action sent to ConnectivityActionReceiver when a network callback is sent via PendingIntent.
|
// Action sent to ConnectivityActionReceiver when a network callback is sent via PendingIntent.
|
||||||
private static final String NETWORK_CALLBACK_ACTION =
|
private static final String NETWORK_CALLBACK_ACTION =
|
||||||
@@ -249,6 +264,12 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
|||||||
mCm.getBackgroundDataSetting();
|
mCm.getBackgroundDataSetting();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private NetworkRequest makeWifiNetworkRequest() {
|
||||||
|
return new NetworkRequest.Builder()
|
||||||
|
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exercises both registerNetworkCallback and unregisterNetworkCallback. This checks to
|
* Exercises both registerNetworkCallback and unregisterNetworkCallback. This checks to
|
||||||
* see if we get a callback for the TRANSPORT_WIFI transport type being available.
|
* see if we get a callback for the TRANSPORT_WIFI transport type being available.
|
||||||
@@ -265,16 +286,14 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We will register for a WIFI network being available or lost.
|
// We will register for a WIFI network being available or lost.
|
||||||
final NetworkRequest request = new NetworkRequest.Builder()
|
|
||||||
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
|
||||||
.build();
|
|
||||||
final TestNetworkCallback callback = new TestNetworkCallback();
|
final TestNetworkCallback callback = new TestNetworkCallback();
|
||||||
mCm.registerNetworkCallback(request, callback);
|
mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback);
|
||||||
|
|
||||||
final TestNetworkCallback defaultTrackingCallback = new TestNetworkCallback();
|
final TestNetworkCallback defaultTrackingCallback = new TestNetworkCallback();
|
||||||
mCm.registerDefaultNetworkCallback(defaultTrackingCallback);
|
mCm.registerDefaultNetworkCallback(defaultTrackingCallback);
|
||||||
|
|
||||||
final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
|
final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
|
||||||
|
Network wifiNetwork = null;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Make sure WiFi is connected to an access point to start with.
|
// Make sure WiFi is connected to an access point to start with.
|
||||||
@@ -285,10 +304,11 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
|||||||
// Now we should expect to get a network callback about availability of the wifi
|
// Now we should expect to get a network callback about availability of the wifi
|
||||||
// network even if it was already connected as a state-based action when the callback
|
// network even if it was already connected as a state-based action when the callback
|
||||||
// is registered.
|
// is registered.
|
||||||
assertTrue("Did not receive NetworkCallback.onAvailable for TRANSPORT_WIFI",
|
wifiNetwork = callback.waitForAvailable();
|
||||||
callback.waitForAvailable());
|
assertNotNull("Did not receive NetworkCallback.onAvailable for TRANSPORT_WIFI",
|
||||||
|
wifiNetwork);
|
||||||
|
|
||||||
assertTrue("Did not receive NetworkCallback.onAvailable for any default network",
|
assertNotNull("Did not receive NetworkCallback.onAvailable for any default network",
|
||||||
defaultTrackingCallback.waitForAvailable());
|
defaultTrackingCallback.waitForAvailable());
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
fail("Broadcast receiver or NetworkCallback wait was interrupted.");
|
fail("Broadcast receiver or NetworkCallback wait was interrupted.");
|
||||||
@@ -298,7 +318,7 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
|||||||
|
|
||||||
// Return WiFi to its original enabled/disabled state.
|
// Return WiFi to its original enabled/disabled state.
|
||||||
if (!previousWifiEnabledState) {
|
if (!previousWifiEnabledState) {
|
||||||
disconnectFromWifi();
|
disconnectFromWifi(wifiNetwork);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -329,10 +349,7 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
|||||||
mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
|
mContext, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
|
||||||
|
|
||||||
// We will register for a WIFI network being available or lost.
|
// We will register for a WIFI network being available or lost.
|
||||||
NetworkRequest request = new NetworkRequest.Builder()
|
mCm.registerNetworkCallback(makeWifiNetworkRequest(), pendingIntent);
|
||||||
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
|
|
||||||
.build();
|
|
||||||
mCm.registerNetworkCallback(request, pendingIntent);
|
|
||||||
|
|
||||||
final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
|
final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
|
||||||
|
|
||||||
@@ -356,7 +373,7 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
|||||||
|
|
||||||
// Return WiFi to its original enabled/disabled state.
|
// Return WiFi to its original enabled/disabled state.
|
||||||
if (!previousWifiEnabledState) {
|
if (!previousWifiEnabledState) {
|
||||||
disconnectFromWifi();
|
disconnectFromWifi(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -370,8 +387,10 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
|||||||
|
|
||||||
// We will toggle the state of wifi to generate a connectivity change.
|
// We will toggle the state of wifi to generate a connectivity change.
|
||||||
final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
|
final boolean previousWifiEnabledState = mWifiManager.isWifiEnabled();
|
||||||
|
|
||||||
if (previousWifiEnabledState) {
|
if (previousWifiEnabledState) {
|
||||||
disconnectFromWifi();
|
Network wifiNetwork = getWifiNetwork();
|
||||||
|
disconnectFromWifi(wifiNetwork);
|
||||||
} else {
|
} else {
|
||||||
connectToWifi();
|
connectToWifi();
|
||||||
}
|
}
|
||||||
@@ -387,12 +406,16 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
|||||||
if (previousWifiEnabledState) {
|
if (previousWifiEnabledState) {
|
||||||
connectToWifi();
|
connectToWifi();
|
||||||
} else {
|
} else {
|
||||||
disconnectFromWifi();
|
disconnectFromWifi(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Enable WiFi and wait for it to become connected to a network. */
|
/** Enable WiFi and wait for it to become connected to a network. */
|
||||||
private void connectToWifi() {
|
private Network connectToWifi() {
|
||||||
|
final TestNetworkCallback callback = new TestNetworkCallback();
|
||||||
|
mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback);
|
||||||
|
Network wifiNetwork = null;
|
||||||
|
|
||||||
ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
|
ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
|
||||||
ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED);
|
ConnectivityManager.TYPE_WIFI, NetworkInfo.State.CONNECTED);
|
||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
@@ -402,36 +425,94 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
|||||||
boolean connected = false;
|
boolean connected = false;
|
||||||
try {
|
try {
|
||||||
assertTrue(mWifiManager.setWifiEnabled(true));
|
assertTrue(mWifiManager.setWifiEnabled(true));
|
||||||
|
// Ensure we get both an onAvailable callback and a CONNECTIVITY_ACTION.
|
||||||
|
wifiNetwork = callback.waitForAvailable();
|
||||||
|
assertNotNull(wifiNetwork);
|
||||||
connected = receiver.waitForState();
|
connected = receiver.waitForState();
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
fail("connectToWifi was interrupted");
|
fail("connectToWifi was interrupted");
|
||||||
} finally {
|
} finally {
|
||||||
|
mCm.unregisterNetworkCallback(callback);
|
||||||
mContext.unregisterReceiver(receiver);
|
mContext.unregisterReceiver(receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue("Wifi must be configured to connect to an access point for this test.",
|
assertTrue("Wifi must be configured to connect to an access point for this test.",
|
||||||
connected);
|
connected);
|
||||||
|
return wifiNetwork;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Socket getBoundSocket(Network network, String host, int port) throws IOException {
|
||||||
|
InetSocketAddress addr = new InetSocketAddress(host, port);
|
||||||
|
Socket s = network.getSocketFactory().createSocket();
|
||||||
|
try {
|
||||||
|
s.setSoTimeout(SOCKET_TIMEOUT_MS);
|
||||||
|
s.connect(addr, SOCKET_TIMEOUT_MS);
|
||||||
|
} catch (IOException e) {
|
||||||
|
s.close();
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testHttpRequest(Socket s) throws IOException {
|
||||||
|
OutputStream out = s.getOutputStream();
|
||||||
|
InputStream in = s.getInputStream();
|
||||||
|
|
||||||
|
final byte[] requestBytes = HTTP_REQUEST.getBytes("UTF-8");
|
||||||
|
byte[] responseBytes = new byte[4096];
|
||||||
|
out.write(requestBytes);
|
||||||
|
in.read(responseBytes);
|
||||||
|
assertTrue(new String(responseBytes, "UTF-8").startsWith("HTTP/1.0 204 No Content\r\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Disable WiFi and wait for it to become disconnected from the network. */
|
/** Disable WiFi and wait for it to become disconnected from the network. */
|
||||||
private void disconnectFromWifi() {
|
private void disconnectFromWifi(Network wifiNetworkToCheck) {
|
||||||
|
final TestNetworkCallback callback = new TestNetworkCallback();
|
||||||
|
mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback);
|
||||||
|
Network lostWifiNetwork = null;
|
||||||
|
|
||||||
ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
|
ConnectivityActionReceiver receiver = new ConnectivityActionReceiver(
|
||||||
ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED);
|
ConnectivityManager.TYPE_WIFI, NetworkInfo.State.DISCONNECTED);
|
||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
|
||||||
mContext.registerReceiver(receiver, filter);
|
mContext.registerReceiver(receiver, filter);
|
||||||
|
|
||||||
|
// Assert that we can establish a TCP connection on wifi.
|
||||||
|
Socket wifiBoundSocket = null;
|
||||||
|
if (wifiNetworkToCheck != null) {
|
||||||
|
try {
|
||||||
|
wifiBoundSocket = getBoundSocket(wifiNetworkToCheck, TEST_HOST, HTTP_PORT);
|
||||||
|
testHttpRequest(wifiBoundSocket);
|
||||||
|
} catch (IOException e) {
|
||||||
|
fail("HTTP request before wifi disconnected failed with: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
boolean disconnected = false;
|
boolean disconnected = false;
|
||||||
try {
|
try {
|
||||||
assertTrue(mWifiManager.setWifiEnabled(false));
|
assertTrue(mWifiManager.setWifiEnabled(false));
|
||||||
|
// Ensure we get both an onLost callback and a CONNECTIVITY_ACTION.
|
||||||
|
lostWifiNetwork = callback.waitForLost();
|
||||||
|
assertNotNull(lostWifiNetwork);
|
||||||
disconnected = receiver.waitForState();
|
disconnected = receiver.waitForState();
|
||||||
} catch (InterruptedException ex) {
|
} catch (InterruptedException ex) {
|
||||||
fail("disconnectFromWifi was interrupted");
|
fail("disconnectFromWifi was interrupted");
|
||||||
} finally {
|
} finally {
|
||||||
|
mCm.unregisterNetworkCallback(callback);
|
||||||
mContext.unregisterReceiver(receiver);
|
mContext.unregisterReceiver(receiver);
|
||||||
}
|
}
|
||||||
|
|
||||||
assertTrue("Wifi failed to reach DISCONNECTED state.", disconnected);
|
assertTrue("Wifi failed to reach DISCONNECTED state.", disconnected);
|
||||||
|
|
||||||
|
// Check that the socket is closed when wifi disconnects.
|
||||||
|
if (wifiBoundSocket != null) {
|
||||||
|
try {
|
||||||
|
testHttpRequest(wifiBoundSocket);
|
||||||
|
fail("HTTP request should not succeed after wifi disconnects");
|
||||||
|
} catch (IOException expected) {
|
||||||
|
assertEquals(Os.strerror(OsConstants.ECONNABORTED), expected.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -498,15 +579,48 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
|||||||
*/
|
*/
|
||||||
private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback {
|
private static class TestNetworkCallback extends ConnectivityManager.NetworkCallback {
|
||||||
private final CountDownLatch mAvailableLatch = new CountDownLatch(1);
|
private final CountDownLatch mAvailableLatch = new CountDownLatch(1);
|
||||||
|
private final CountDownLatch mLostLatch = new CountDownLatch(1);
|
||||||
|
|
||||||
public boolean waitForAvailable() throws InterruptedException {
|
public Network currentNetwork;
|
||||||
return mAvailableLatch.await(30, TimeUnit.SECONDS);
|
public Network lastLostNetwork;
|
||||||
|
|
||||||
|
public Network waitForAvailable() throws InterruptedException {
|
||||||
|
return mAvailableLatch.await(30, TimeUnit.SECONDS) ? currentNetwork : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Network waitForLost() throws InterruptedException {
|
||||||
|
return mLostLatch.await(30, TimeUnit.SECONDS) ? lastLostNetwork : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAvailable(Network network) {
|
public void onAvailable(Network network) {
|
||||||
|
currentNetwork = network;
|
||||||
mAvailableLatch.countDown();
|
mAvailableLatch.countDown();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLost(Network network) {
|
||||||
|
lastLostNetwork = network;
|
||||||
|
if (network.equals(currentNetwork)) {
|
||||||
|
currentNetwork = null;
|
||||||
|
}
|
||||||
|
mLostLatch.countDown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Network getWifiNetwork() {
|
||||||
|
TestNetworkCallback callback = new TestNetworkCallback();
|
||||||
|
mCm.registerNetworkCallback(makeWifiNetworkRequest(), callback);
|
||||||
|
Network network = null;
|
||||||
|
try {
|
||||||
|
network = callback.waitForAvailable();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
fail("NetworkCallback wait was interrupted.");
|
||||||
|
} finally {
|
||||||
|
mCm.unregisterNetworkCallback(callback);
|
||||||
|
}
|
||||||
|
assertNotNull("Cannot find Network for wifi. Is wifi connected?", network);
|
||||||
|
return network;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Verify restricted networks cannot be requested. */
|
/** Verify restricted networks cannot be requested. */
|
||||||
@@ -523,8 +637,6 @@ public class ConnectivityManagerTest extends AndroidTestCase {
|
|||||||
try {
|
try {
|
||||||
mCm.requestNetwork(request, callback);
|
mCm.requestNetwork(request, callback);
|
||||||
fail("No exception thrown when restricted network requested.");
|
fail("No exception thrown when restricted network requested.");
|
||||||
} catch (SecurityException e) {
|
} catch (SecurityException expected) {}
|
||||||
// Expected.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user