1/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.connectivitymanagertest.functional;
18
19import android.net.ConnectivityManager;
20import android.net.NetworkInfo;
21import android.net.NetworkInfo.State;
22import android.net.wifi.WifiManager;
23import android.os.SystemClock;
24import android.provider.Settings;
25import android.test.suitebuilder.annotation.LargeTest;
26
27import com.android.connectivitymanagertest.ConnectivityManagerTestBase;
28import com.android.connectivitymanagertest.ConnectivityManagerTestRunner;
29
30public class ConnectivityManagerMobileTest extends  ConnectivityManagerTestBase {
31
32    public ConnectivityManagerMobileTest() {
33        super(ConnectivityManagerMobileTest.class.getSimpleName());
34    }
35
36    private String mSsid;
37    private String mPassword;
38    private boolean mWifiOnlyFlag;
39
40    @Override
41    public void setUp() throws Exception {
42        super.setUp();
43        ConnectivityManagerTestRunner mRunner =
44                (ConnectivityManagerTestRunner)getInstrumentation();
45        mSsid = mRunner.getWifiSsid();
46        mPassword = mRunner.getWifiPassword();
47        mWifiOnlyFlag = mRunner.isWifiOnly();
48
49        // Each test case will start with cellular connection
50        if (Settings.Global.getInt(getInstrumentation().getContext().getContentResolver(),
51                Settings.Global.AIRPLANE_MODE_ON) == 1) {
52            logv("airplane is not disabled, disable it.");
53            mCm.setAirplaneMode(false);
54        }
55
56        if (!mWifiOnlyFlag) {
57            if (!waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
58                    State.CONNECTED, LONG_TIMEOUT)) {
59                // Note: When the test fails in setUp(), tearDown is not called. In that case,
60                // the activity is destroyed which blocks the next test at "getActivity()".
61                // tearDown() is called here to avoid that situation.
62                tearDown();
63                fail("Device is not connected to Mobile, setUp failed");
64            }
65        }
66    }
67
68    @Override
69    public void tearDown() throws Exception {
70        removeConfiguredNetworksAndDisableWifi();
71        mCm.setAirplaneMode(false);
72        super.tearDown();
73    }
74
75    // Test case 1: Test enabling Wifi without associating with any AP, no broadcast on network
76    //              event should be expected.
77    @LargeTest
78    public void test3GToWifiNotification() {
79        if (mWifiOnlyFlag) {
80            logv(getName() + " is excluded for wifi-only test");
81            return;
82        }
83
84        // disable WiFi
85        assertTrue("failed to disable WiFi", disableWifi());
86
87        // wait for mobile
88        assertTrue("failed to wait for mobile connection", waitForNetworkState(
89                ConnectivityManager.TYPE_MOBILE, State.CONNECTED, LONG_TIMEOUT));
90
91        // assert that we are indeed using mobile
92        NetworkInfo ni = mCm.getActiveNetworkInfo();
93        assertEquals("active network is not mobile", ConnectivityManager.TYPE_MOBILE, ni.getType());
94
95        long timestamp = SystemClock.uptimeMillis();
96        // now enable WiFi
97        assertTrue("failed to enable WiFi", enableWifi());
98        // assert that WiFi state settles at disconnected since no AP should be configured
99        assertTrue("WiFi state is not DISCONNECTED after enabling", waitForWifiState(
100                WifiManager.WIFI_STATE_DISABLED, LONG_TIMEOUT));
101
102        // assert that no connectivity change broadcast was sent since we enable wifi
103        assertTrue("connectivity has changed since wifi enable",
104                timestamp > getLastConnectivityChangeTime());
105
106        // verify that the device is still connected to MOBILE
107        verifyCellularConnection();
108        // verify that connection actually works
109        assertTrue("no network connectivity at end of test", checkNetworkConnectivity());
110    }
111
112    // Test case 2: test connection to a given AP
113    @LargeTest
114    public void testConnectToWifi() {
115        assertNotNull("SSID is null", mSsid);
116
117        // assert that we are able to connect to the ap
118        assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
119        // assert that WifiManager reports correct state
120        assertTrue("wifi not enabled", waitForWifiState(
121                WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
122        // assert that ConnectivityManager reports correct state for Wifi
123        assertTrue("wifi not connected", waitForNetworkState(
124                ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
125        // below check disbabled since we have bug in what ConnectivityManager returns
126//        if (!mWifiOnlyFlag) {
127//            // assert that ConnectivityManager reports correct state for mobile
128//            assertTrue("mobile not disconnected", waitForNetworkState(
129//                    ConnectivityManager.TYPE_MOBILE, State.DISCONNECTED, LONG_TIMEOUT));
130//        }
131        // verify that connection actually works
132        assertTrue("no network connectivity at end of test", checkNetworkConnectivity());
133    }
134
135    // Test case 3: connect & reconnect to Wifi with known AP
136    @LargeTest
137    public void testConnectToWifWithKnownAP() {
138        assertNotNull("SSID is null", mSsid);
139        // enable WiFi
140        assertTrue("failed to enable wifi", enableWifi());
141        // wait for wifi enable
142        assertTrue("wifi not enabled", waitForWifiState(
143                WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
144        // Connect to AP
145        assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
146        // verify wifi connected as reported by ConnectivityManager
147        assertTrue("wifi not connected", waitForNetworkState(
148                ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
149
150        assertTrue("failed to disable wifi", disableWifi());
151
152        // Wait for the Wifi state to be DISABLED
153        assertTrue("wifi state not disabled", waitForWifiState(
154                WifiManager.WIFI_STATE_DISABLED, LONG_TIMEOUT));
155        // below check disbabled since we have bug in what ConnectivityManager returns
156//        assertTrue("wifi not disconnected", waitForNetworkState(ConnectivityManager.TYPE_WIFI,
157//                State.DISCONNECTED, LONG_TIMEOUT));
158        if (!mWifiOnlyFlag) {
159            assertTrue("mobile not connected after wifi disable", waitForNetworkState(
160                    ConnectivityManager.TYPE_MOBILE, State.CONNECTED, LONG_TIMEOUT));
161        }
162
163        // wait for 30s before restart wifi
164        SystemClock.sleep(LONG_TIMEOUT);
165        assertTrue("failed to enable wifi after disable", enableWifi());
166
167        // wait for wifi enable
168        assertTrue("wifi not enabled after toggle", waitForWifiState(
169                WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
170        // Wait for Wifi to be connected and mobile to be disconnected
171        assertTrue("wifi not connected after toggle", waitForNetworkState(
172                ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
173        // below check disbabled since we have bug in what ConnectivityManager returns
174//        if (!mWifiOnlyFlag) {
175//            assertTrue("mobile not disconnected after wifi toggle", waitForNetworkState(
176//                    ConnectivityManager.TYPE_MOBILE, State.DISCONNECTED, LONG_TIMEOUT));
177//        }
178        // verify that connection actually works
179        assertTrue("no network connectivity at end of test", checkNetworkConnectivity());
180    }
181
182    // Test case 4:  test disconnect and clear wifi settings
183    @LargeTest
184    public void testDisconnectWifi() {
185        assertNotNull("SSID is null", mSsid);
186
187        // enable WiFi
188        assertTrue("failed to enable wifi", enableWifi());
189        // wait for wifi enable
190        assertTrue("wifi not enabled", waitForWifiState(
191                WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
192        // connect to Wifi
193        assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
194
195        assertTrue("wifi not connected", waitForNetworkState(
196                ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
197
198        // clear Wifi
199        removeConfiguredNetworksAndDisableWifi();
200
201        // assert that wifi has been disabled
202        assertTrue("wifi state not disabled", waitForWifiState(
203                WifiManager.WIFI_STATE_DISABLED, LONG_TIMEOUT));
204        if (!mWifiOnlyFlag) {
205            // assert that mobile is now connected
206            assertTrue("mobile not enabled", waitForNetworkState(ConnectivityManager.TYPE_MOBILE,
207                    State.CONNECTED, LONG_TIMEOUT));
208            // verify that connection actually works
209            assertTrue("no network connectivity at end of test", checkNetworkConnectivity());
210        }
211    }
212
213    // Test case 5: test connectivity with mobile->airplane mode->mobile
214    @LargeTest
215    public void testDataConnectionWith3GToAmTo3G() {
216        if (mWifiOnlyFlag) {
217            logv(getName() + " is excluded for wifi-only test");
218            return;
219        }
220        // disable wifi
221        assertTrue("failed to disable wifi", disableWifi());
222        assertTrue("wifi state not disabled", waitForWifiState(
223                WifiManager.WIFI_STATE_DISABLED, LONG_TIMEOUT));
224        // assert that we have mobile connection
225        assertTrue("no mobile connection", waitForNetworkState(
226                ConnectivityManager.TYPE_MOBILE, State.CONNECTED, LONG_TIMEOUT));
227
228        // enable airplane mode
229        mCm.setAirplaneMode(true);
230        // assert no active network connection after airplane mode enabled
231        assertTrue("still has active network connection",
232                waitUntilNoActiveNetworkConnection(LONG_TIMEOUT));
233
234        // disable airplane mode
235        mCm.setAirplaneMode(false);
236        // assert there is active network connection after airplane mode disabled
237        assertTrue("no active network connection after airplane mode disable",
238                waitForActiveNetworkConnection(LONG_TIMEOUT));
239
240        // assert that we have mobile connection
241        assertTrue("no mobile connection", waitForNetworkState(
242                ConnectivityManager.TYPE_MOBILE, State.CONNECTED, LONG_TIMEOUT));
243        // verify that connection actually works
244        assertTrue("no network connectivity at end of test", checkNetworkConnectivity());
245    }
246
247    // Test case 6: test connectivity with airplane mode on but wifi enabled
248    @LargeTest
249    public void testDataConnectionOverAMWithWifi() {
250        assertNotNull("SSID is null", mSsid);
251        // enable airplane mode
252        mCm.setAirplaneMode(true);
253        // assert there is active network connection after airplane mode disabled
254        assertTrue("still has active network connection",
255                waitUntilNoActiveNetworkConnection(LONG_TIMEOUT));
256
257        // connect to Wifi
258        assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
259        assertTrue("wifi not connected", waitForNetworkState(
260                ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
261        // verify that connection actually works
262        assertTrue("no network connectivity after wifi enable", checkNetworkConnectivity());
263
264        // disable airplane mode
265        mCm.setAirplaneMode(false);
266    }
267
268    // Test case 7: test connectivity while transit from Wifi->AM->Wifi
269    @LargeTest
270    public void testDataConnectionWithWifiToAMToWifi () {
271        // connect to mTestAccessPoint
272        assertNotNull("SSID is null", mSsid);
273        // enable WiFi
274        assertTrue("failed to enable wifi", enableWifi());
275        // wait for wifi enable
276        assertTrue("wifi not enabled", waitForWifiState(
277                WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
278        // connect to Wifi
279        assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
280        assertTrue("wifi not connected", waitForNetworkState(
281                ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
282
283        // enable airplane mode without clearing Wifi
284        mCm.setAirplaneMode(true);
285        // assert there is active network connection after airplane mode disabled
286        assertTrue("still has active network connection",
287                waitUntilNoActiveNetworkConnection(LONG_TIMEOUT));
288
289        // disable airplane mode
290        mCm.setAirplaneMode(false);
291        // assert there is active network connection after airplane mode disabled
292        assertTrue("no active network connection after airplane mode disable",
293                waitForActiveNetworkConnection(LONG_TIMEOUT));
294        // assert that we have a Wifi connection
295        assertTrue("wifi not connected after airplane mode disable", waitForNetworkState(
296                ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
297        // verify that connection actually works
298        assertTrue("no network connectivity at end of test", checkNetworkConnectivity());
299    }
300
301    // Test case 8: test wifi state change while connecting/disconnecting to/from an AP
302    @LargeTest
303    public void testWifiStateChange () {
304        assertNotNull("SSID is null", mSsid);
305        // enable WiFi
306        assertTrue("failed to enable wifi", enableWifi());
307        // wait for wifi enable
308        assertTrue("wifi not enabled", waitForWifiState(
309                WifiManager.WIFI_STATE_ENABLED, LONG_TIMEOUT));
310        // connect to Wifi
311        assertTrue("failed to connect to " + mSsid, connectToWifi(mSsid, mPassword));
312        assertTrue("wifi not connected", waitForNetworkState(
313                ConnectivityManager.TYPE_WIFI, State.CONNECTED, WIFI_CONNECTION_TIMEOUT));
314        assertNotNull("not associated with any AP", mWifiManager.getConnectionInfo().getBSSID());
315
316        // disconnect from the current AP
317        assertTrue("failed to disconnect from AP", disconnectAP());
318
319        // below check disbabled since we have bug in what ConnectivityManager returns
320        // Verify the connectivity state for Wifi is DISCONNECTED
321//        assertTrue(waitForNetworkState(ConnectivityManager.TYPE_WIFI,
322//                State.DISCONNECTED, LONG_TIMEOUT));
323
324        // disable WiFi
325        assertTrue("failed to disable wifi", disableWifi());
326        assertTrue("wifi state not disabled", waitForWifiState(
327                WifiManager.WIFI_STATE_DISABLED, LONG_TIMEOUT));
328    }
329
330    // help function to verify 3G connection
331    private void verifyCellularConnection() {
332        NetworkInfo extraNetInfo = mCm.getActiveNetworkInfo();
333        assertEquals("network type is not MOBILE", ConnectivityManager.TYPE_MOBILE,
334                extraNetInfo.getType());
335        assertTrue("not connected to cellular network", extraNetInfo.isConnected());
336    }
337}
338