blob: d79ecdddb4e2c2567c42fc25380c3a47aecde4cc [file] [log] [blame]
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.net.cts;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkConfig;
import android.net.NetworkInfo;
import android.net.NetworkInfo.DetailedState;
import android.net.NetworkInfo.State;
import android.net.wifi.WifiManager;
import android.test.AndroidTestCase;
import android.util.Log;
import com.android.internal.telephony.PhoneConstants;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
public class ConnectivityManagerTest extends AndroidTestCase {
private static final String TAG = ConnectivityManagerTest.class.getSimpleName();
private static final String FEATURE_ENABLE_HIPRI = "enableHIPRI";
public static final int TYPE_MOBILE = ConnectivityManager.TYPE_MOBILE;
public static final int TYPE_WIFI = ConnectivityManager.TYPE_WIFI;
private static final int HOST_ADDRESS = 0x7f000001;// represent ip 127.0.0.1
// device could have only one interface: data, wifi.
private static final int MIN_NUM_NETWORK_TYPES = 1;
private ConnectivityManager mCm;
private WifiManager mWifiManager;
private PackageManager mPackageManager;
private final HashMap<Integer, NetworkConfig> mNetworks =
new HashMap<Integer, NetworkConfig>();
private final List<Integer>mProtectedNetworks = new ArrayList<Integer>();
@Override
protected void setUp() throws Exception {
super.setUp();
mCm = (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);
mWifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
mPackageManager = getContext().getPackageManager();
// Get com.android.internal.R.array.networkAttributes
int resId = getContext().getResources().getIdentifier("networkAttributes", "array", "android");
String[] naStrings = getContext().getResources().getStringArray(resId);
for (String naString : naStrings) {
try {
NetworkConfig n = new NetworkConfig(naString);
mNetworks.put(n.type, n);
} catch (Exception e) {}
}
// Get com.android.internal.R.array.config_protectedNetworks
resId = getContext().getResources().getIdentifier("config_protectedNetworks", "array", "android");
int[] protectedNetworks = getContext().getResources().getIntArray(resId);
for (int p : protectedNetworks) {
mProtectedNetworks.add(p);
}
}
public void testIsNetworkTypeValid() {
assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE));
assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_WIFI));
assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_MMS));
assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_SUPL));
assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_DUN));
assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_HIPRI));
assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_WIMAX));
assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_BLUETOOTH));
assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_DUMMY));
assertTrue(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.TYPE_ETHERNET));
assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_FOTA));
assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_IMS));
assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_CBS));
assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_WIFI_P2P));
assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.TYPE_MOBILE_IA));
assertFalse(mCm.isNetworkTypeValid(-1));
assertTrue(mCm.isNetworkTypeValid(0));
assertTrue(mCm.isNetworkTypeValid(ConnectivityManager.MAX_NETWORK_TYPE));
assertFalse(ConnectivityManager.isNetworkTypeValid(ConnectivityManager.MAX_NETWORK_TYPE+1));
NetworkInfo[] ni = mCm.getAllNetworkInfo();
for (NetworkInfo n: ni) {
assertTrue(ConnectivityManager.isNetworkTypeValid(n.getType()));
}
}
public void testSetNetworkPreference() {
// getNetworkPreference() and setNetworkPreference() are both deprecated so they do
// not preform any action. Verify they are at least still callable.
mCm.setNetworkPreference(mCm.getNetworkPreference());
}
public void testGetActiveNetworkInfo() {
NetworkInfo ni = mCm.getActiveNetworkInfo();
assertTrue("You must have an active network connection to complete CTS", ni != null);
assertTrue(ConnectivityManager.isNetworkTypeValid(ni.getType()));
assertTrue(ni.getState() == State.CONNECTED);
}
public void testGetNetworkInfo() {
for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE+1; type++) {
if (isSupported(type)) {
NetworkInfo ni = mCm.getNetworkInfo(type);
assertTrue("Info shouldn't be null for " + type, ni != null);
State state = ni.getState();
assertTrue("Bad state for " + type, State.UNKNOWN.ordinal() >= state.ordinal()
&& state.ordinal() >= State.CONNECTING.ordinal());
DetailedState ds = ni.getDetailedState();
assertTrue("Bad detailed state for " + type,
DetailedState.FAILED.ordinal() >= ds.ordinal()
&& ds.ordinal() >= DetailedState.IDLE.ordinal());
} else {
assertNull("Info should be null for " + type, mCm.getNetworkInfo(type));
}
}
}
public void testGetAllNetworkInfo() {
NetworkInfo[] ni = mCm.getAllNetworkInfo();
assertTrue(ni.length >= MIN_NUM_NETWORK_TYPES);
for (int type = 0; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
int desiredFoundCount = (isSupported(type) ? 1 : 0);
int foundCount = 0;
for (NetworkInfo i : ni) {
if (i.getType() == type) foundCount++;
}
if (foundCount != desiredFoundCount) {
Log.e(TAG, "failure in testGetAllNetworkInfo. Dump of returned NetworkInfos:");
for (NetworkInfo networkInfo : ni) Log.e(TAG, " " + networkInfo);
}
assertTrue("Unexpected foundCount of " + foundCount + " for type " + type,
foundCount == desiredFoundCount);
}
}
public void testStartUsingNetworkFeature() {
final String invalidateFeature = "invalidateFeature";
final String mmsFeature = "enableMMS";
final int failureCode = -1;
final int wifiOnlyStartFailureCode = PhoneConstants.APN_REQUEST_FAILED;
final int wifiOnlyStopFailureCode = -1;
NetworkInfo ni = mCm.getNetworkInfo(TYPE_MOBILE);
if (ni != null) {
assertEquals(PhoneConstants.APN_REQUEST_FAILED,
mCm.startUsingNetworkFeature(TYPE_MOBILE, invalidateFeature));
assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE,
invalidateFeature));
} else {
assertEquals(wifiOnlyStartFailureCode, mCm.startUsingNetworkFeature(TYPE_MOBILE,
invalidateFeature));
assertEquals(wifiOnlyStopFailureCode, mCm.stopUsingNetworkFeature(TYPE_MOBILE,
invalidateFeature));
}
ni = mCm.getNetworkInfo(TYPE_WIFI);
if (ni != null) {
// Should return failure because MMS is not supported on WIFI.
assertEquals(PhoneConstants.APN_REQUEST_FAILED, mCm.startUsingNetworkFeature(TYPE_WIFI,
mmsFeature));
assertEquals(failureCode, mCm.stopUsingNetworkFeature(TYPE_WIFI,
mmsFeature));
}
}
private boolean isSupported(int networkType) {
return mNetworks.containsKey(networkType);
}
// true if only the system can turn it on
private boolean isNetworkProtected(int networkType) {
return mProtectedNetworks.contains(networkType);
}
public void testIsNetworkSupported() {
for (int type = -1; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
boolean supported = mCm.isNetworkSupported(type);
if (isSupported(type)) {
assertTrue(supported);
} else {
assertFalse(supported);
}
}
}
public void testRequestRouteToHost() {
for (int type = -1 ; type <= ConnectivityManager.MAX_NETWORK_TYPE; type++) {
NetworkInfo ni = mCm.getNetworkInfo(type);
boolean expectToWork = isSupported(type) && !isNetworkProtected(type) &&
ni != null && ni.isConnected();
try {
assertTrue("Network type " + type,
mCm.requestRouteToHost(type, HOST_ADDRESS) == expectToWork);
} catch (Exception e) {
Log.d(TAG, "got exception in requestRouteToHost for type " + type);
assertFalse("Exception received for type " + type, expectToWork);
}
//TODO verify route table
}
assertFalse(mCm.requestRouteToHost(-1, HOST_ADDRESS));
}
public void testTest() {
mCm.getBackgroundDataSetting();
}
/** Test that hipri can be brought up when Wifi is enabled. */
public void testStartUsingNetworkFeature_enableHipri() throws Exception {
if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)
|| !mPackageManager.hasSystemFeature(PackageManager.FEATURE_WIFI)) {
// This test requires a mobile data connection and WiFi.
return;
}
boolean isWifiEnabled = mWifiManager.isWifiEnabled();
boolean isWifiConnected = false;
NetworkInfo nwInfo = mCm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (nwInfo != null) {
isWifiConnected = nwInfo.isConnected();
}
try {
// Make sure WiFi is connected to an access point.
if (!isWifiConnected) {
connectToWifi();
}
// Register a receiver that will capture the connectivity change for hipri.
ConnectivityActionReceiver receiver =
new ConnectivityActionReceiver(ConnectivityManager.TYPE_MOBILE_HIPRI);
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
mContext.registerReceiver(receiver, filter);
// Try to start using the hipri feature...
int result = mCm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
FEATURE_ENABLE_HIPRI);
assertTrue("Couldn't start using the HIPRI feature.", result != -1);
// Check that the ConnectivityManager reported that it connected using hipri...
assertTrue("Couldn't connect using hipri...", receiver.waitForConnection());
assertTrue("Couldn't requestRouteToHost using HIPRI.",
mCm.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, HOST_ADDRESS));
// TODO check dns selection
// TODO check routes
} catch (InterruptedException e) {
fail("Broadcast receiver waiting for ConnectivityManager interrupted.");
} finally {
mCm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE,
FEATURE_ENABLE_HIPRI);
// TODO wait for HIPRI to go
// TODO check dns selection
// TODO check routes
if (!isWifiEnabled) {
mWifiManager.setWifiEnabled(false);
}
}
}
private void connectToWifi() throws InterruptedException {
ConnectivityActionReceiver receiver =
new ConnectivityActionReceiver(ConnectivityManager.TYPE_WIFI);
IntentFilter filter = new IntentFilter();
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
mContext.registerReceiver(receiver, filter);
assertTrue(mWifiManager.setWifiEnabled(true));
assertTrue("Wifi must be configured to connect to an access point for this test.",
receiver.waitForConnection());
mContext.unregisterReceiver(receiver);
}
/** Receiver that captures the last connectivity change's network type and state. */
private class ConnectivityActionReceiver extends BroadcastReceiver {
private final CountDownLatch mReceiveLatch = new CountDownLatch(1);
private final int mNetworkType;
ConnectivityActionReceiver(int networkType) {
mNetworkType = networkType;
}
public void onReceive(Context context, Intent intent) {
NetworkInfo networkInfo = intent.getExtras()
.getParcelable(ConnectivityManager.EXTRA_NETWORK_INFO);
int networkType = networkInfo.getType();
State networkState = networkInfo.getState();
Log.i(TAG, "Network type: " + networkType + " state: " + networkState);
if (networkType == mNetworkType && networkInfo.getState() == State.CONNECTED) {
mReceiveLatch.countDown();
}
}
public boolean waitForConnection() throws InterruptedException {
return mReceiveLatch.await(30, TimeUnit.SECONDS);
}
}
}