blob: 561e33e15d8871f493eb13a69d184538af7f03f0 [file] [log] [blame]
Xia Wangfc2dbd02010-03-23 12:17:06 -07001/*
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
Xia Wang7fb1f672010-03-04 11:54:39 -080017package com.android.connectivitymanagertest;
18
19import android.app.Activity;
20import android.content.Context;
21import android.content.BroadcastReceiver;
22import android.content.Intent;
23import android.content.IntentFilter;
Irfan Sheriffebe606f2011-02-24 11:39:15 -080024import android.net.ConnectivityManager;
25import android.net.NetworkInfo;
26import android.net.NetworkInfo.State;
27import android.net.wifi.WifiConfiguration;
28import android.net.wifi.WifiManager;
29import android.net.wifi.WifiInfo;
30import android.net.wifi.ScanResult;
31import android.net.wifi.WifiConfiguration.KeyMgmt;
Xia Wang7fb1f672010-03-04 11:54:39 -080032import android.os.Bundle;
Irfan Sheriffebe606f2011-02-24 11:39:15 -080033import android.os.Handler;
Xia Wang73055f12010-12-16 14:46:09 -080034import android.os.IPowerManager;
Irfan Sheriffebe606f2011-02-24 11:39:15 -080035import android.os.Message;
Xia Wang73055f12010-12-16 14:46:09 -080036import android.os.PowerManager;
37import android.os.ServiceManager;
38import android.os.SystemClock;
Christopher Tatec09cdce2012-09-10 16:50:14 -070039import android.os.UserHandle;
Xia Wang7fb1f672010-03-04 11:54:39 -080040import android.provider.Settings;
41import android.util.Log;
Yu Shan Emily Lauba1348e2010-07-16 11:55:43 -070042import android.view.KeyEvent;
Irfan Sheriffebe606f2011-02-24 11:39:15 -080043import android.widget.LinearLayout;
44
45import com.android.internal.util.AsyncChannel;
Xia Wangca1f2b12010-11-12 16:08:21 -080046
Xia Wang6bffe142011-02-17 15:32:37 -080047import java.io.IOException;
Xia Wangca1f2b12010-11-12 16:08:21 -080048import java.io.InputStream;
Xia Wang6bffe142011-02-17 15:32:37 -080049import java.net.UnknownHostException;
Xia Wangca1f2b12010-11-12 16:08:21 -080050import java.util.ArrayList;
Xia Wang7fb1f672010-03-04 11:54:39 -080051import java.util.List;
Xia Wang7fb1f672010-03-04 11:54:39 -080052
Xia Wang7fb1f672010-03-04 11:54:39 -080053
Xia Wang7fb1f672010-03-04 11:54:39 -080054/**
55 * An activity registered with connectivity manager broadcast
56 * provides network connectivity information and
57 * can be used to set device states: Cellular, Wifi, Airplane mode.
58 */
59public class ConnectivityManagerTestActivity extends Activity {
60
61 public static final String LOG_TAG = "ConnectivityManagerTestActivity";
Xia Wangca1f2b12010-11-12 16:08:21 -080062 public static final int WAIT_FOR_SCAN_RESULT = 10 * 1000; //10 seconds
Xia Wanga42a1e62010-11-22 16:59:48 -080063 public static final int WIFI_SCAN_TIMEOUT = 50 * 1000;
Xia Wangca1f2b12010-11-12 16:08:21 -080064 public static final int SHORT_TIMEOUT = 5 * 1000;
65 public static final long LONG_TIMEOUT = 50 * 1000;
Xia Wanga4c2caa2011-11-17 11:11:59 -080066 // 2 minutes timer between wifi stop and start
67 public static final long WIFI_STOP_START_INTERVAL = 2 * 60 * 1000;
Xia Wang6026d522010-11-16 11:35:47 -080068 public static final int SUCCESS = 0; // for Wifi tethering state change
69 public static final int FAILURE = 1;
70 public static final int INIT = -1;
Xia Wangca1f2b12010-11-12 16:08:21 -080071 private static final String ACCESS_POINT_FILE = "accesspoints.xml";
Xia Wang7fb1f672010-03-04 11:54:39 -080072 public ConnectivityReceiver mConnectivityReceiver = null;
73 public WifiReceiver mWifiReceiver = null;
Xia Wanga42a1e62010-11-22 16:59:48 -080074 private AccessPointParserHelper mParseHelper = null;
Xia Wang7fb1f672010-03-04 11:54:39 -080075 /*
76 * Track network connectivity information
77 */
78 public State mState;
79 public NetworkInfo mNetworkInfo;
80 public NetworkInfo mOtherNetworkInfo;
81 public boolean mIsFailOver;
82 public String mReason;
83 public boolean mScanResultIsAvailable = false;
84 public ConnectivityManager mCM;
Xia Wang2c159662010-03-27 18:25:14 -070085 public Object wifiObject = new Object();
86 public Object connectivityObject = new Object();
87 public int mWifiState;
88 public NetworkInfo mWifiNetworkInfo;
89 public String mBssid;
Yu Shan Emily Lau3d273da2011-01-20 21:24:29 -080090 public String mPowerSsid = "opennet"; //Default power SSID
Yu Shan Emily Lauba1348e2010-07-16 11:55:43 -070091 private Context mContext;
Xia Wang90e1c782010-12-03 14:51:17 -080092 public boolean scanResultAvailable = false;
Xia Wang7fb1f672010-03-04 11:54:39 -080093
94 /*
95 * Control Wifi States
96 */
97 public WifiManager mWifiManager;
98
99 /*
100 * Verify connectivity state
101 */
Xia Wang2c159662010-03-27 18:25:14 -0700102 public static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1;
Xia Wang7fb1f672010-03-04 11:54:39 -0800103 NetworkState[] connectivityState = new NetworkState[NUM_NETWORK_TYPES];
104
Xia Wang6026d522010-11-16 11:35:47 -0800105 // For wifi tethering tests
106 private String[] mWifiRegexs;
107 public int mWifiTetherResult = INIT; // -1 is initialization state
108
Xia Wang7fb1f672010-03-04 11:54:39 -0800109 /**
110 * A wrapper of a broadcast receiver which provides network connectivity information
111 * for all kinds of network: wifi, mobile, etc.
112 */
113 private class ConnectivityReceiver extends BroadcastReceiver {
114 @Override
115 public void onReceive(Context context, Intent intent) {
Xia Wanga42a1e62010-11-22 16:59:48 -0800116 log("ConnectivityReceiver: onReceive() is called with " + intent);
Xia Wang7fb1f672010-03-04 11:54:39 -0800117 String action = intent.getAction();
118 if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
119 Log.v("ConnectivityReceiver", "onReceive() called with " + intent);
120 return;
121 }
122
123 boolean noConnectivity =
124 intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
125
126 if (noConnectivity) {
127 mState = State.DISCONNECTED;
128 } else {
129 mState = State.CONNECTED;
130 }
131
132 mNetworkInfo = (NetworkInfo)
133 intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
134
135 mOtherNetworkInfo = (NetworkInfo)
136 intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
137
138 mReason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
139 mIsFailOver = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
Xia Wang2c159662010-03-27 18:25:14 -0700140
Xia Wanga42a1e62010-11-22 16:59:48 -0800141 log("mNetworkInfo: " + mNetworkInfo.toString());
Xia Wang2c159662010-03-27 18:25:14 -0700142 if (mOtherNetworkInfo != null) {
Xia Wanga42a1e62010-11-22 16:59:48 -0800143 log("mOtherNetworkInfo: " + mOtherNetworkInfo.toString());
Xia Wang2c159662010-03-27 18:25:14 -0700144 }
Xia Wang7fb1f672010-03-04 11:54:39 -0800145 recordNetworkState(mNetworkInfo.getType(), mNetworkInfo.getState());
146 if (mOtherNetworkInfo != null) {
147 recordNetworkState(mOtherNetworkInfo.getType(), mOtherNetworkInfo.getState());
148 }
Xia Wang2c159662010-03-27 18:25:14 -0700149 notifyNetworkConnectivityChange();
Xia Wang7fb1f672010-03-04 11:54:39 -0800150 }
151 }
152
153 private class WifiReceiver extends BroadcastReceiver {
154 @Override
155 public void onReceive(Context context, Intent intent) {
156 String action = intent.getAction();
Xia Wang2c159662010-03-27 18:25:14 -0700157 Log.v("WifiReceiver", "onReceive() is calleld with " + intent);
158 if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
Xia Wang90e1c782010-12-03 14:51:17 -0800159 log("scan results are available");
Xia Wang2c159662010-03-27 18:25:14 -0700160 notifyScanResult();
161 } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
162 mWifiNetworkInfo =
163 (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
Xia Wanga42a1e62010-11-22 16:59:48 -0800164 log("mWifiNetworkInfo: " + mWifiNetworkInfo.toString());
Xia Wang2c159662010-03-27 18:25:14 -0700165 if (mWifiNetworkInfo.getState() == State.CONNECTED) {
166 mBssid = intent.getStringExtra(WifiManager.EXTRA_BSSID);
167 }
168 notifyWifiState();
169 } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
170 mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
171 WifiManager.WIFI_STATE_UNKNOWN);
172 notifyWifiState();
Xia Wang6026d522010-11-16 11:35:47 -0800173 } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) {
174 notifyWifiAPState();
175 } else if (action.equals(ConnectivityManager.ACTION_TETHER_STATE_CHANGED)) {
176 ArrayList<String> available = intent.getStringArrayListExtra(
177 ConnectivityManager.EXTRA_AVAILABLE_TETHER);
178 ArrayList<String> active = intent.getStringArrayListExtra(
179 ConnectivityManager.EXTRA_ACTIVE_TETHER);
180 ArrayList<String> errored = intent.getStringArrayListExtra(
181 ConnectivityManager.EXTRA_ERRORED_TETHER);
182 updateTetherState(available.toArray(), active.toArray(), errored.toArray());
Xia Wang2c159662010-03-27 18:25:14 -0700183 }
184 else {
Xia Wang7fb1f672010-03-04 11:54:39 -0800185 return;
186 }
Xia Wang7fb1f672010-03-04 11:54:39 -0800187 }
188 }
189
Irfan Sheriffebe606f2011-02-24 11:39:15 -0800190 private class WifiServiceHandler extends Handler {
191 @Override
192 public void handleMessage(Message msg) {
193 switch (msg.what) {
194 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED:
195 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
196 //AsyncChannel in msg.obj
197 } else {
198 log("Failed to establish AsyncChannel connection");
199 }
200 break;
201 default:
202 //Ignore
203 break;
204 }
205 }
206 }
207
Xia Wang7fb1f672010-03-04 11:54:39 -0800208 public ConnectivityManagerTestActivity() {
209 mState = State.UNKNOWN;
Xia Wang90e1c782010-12-03 14:51:17 -0800210 scanResultAvailable = false;
Xia Wang7fb1f672010-03-04 11:54:39 -0800211 }
212
213 @Override
214 protected void onCreate(Bundle savedInstanceState) {
215 super.onCreate(savedInstanceState);
Xia Wanga42a1e62010-11-22 16:59:48 -0800216 log("onCreate, inst=" + Integer.toHexString(hashCode()));
Xia Wang7fb1f672010-03-04 11:54:39 -0800217
218 // Create a simple layout
219 LinearLayout contentView = new LinearLayout(this);
220 contentView.setOrientation(LinearLayout.VERTICAL);
221 setContentView(contentView);
222 setTitle("ConnectivityManagerTestActivity");
223
Xia Wang2c159662010-03-27 18:25:14 -0700224
Xia Wang7fb1f672010-03-04 11:54:39 -0800225 // register a connectivity receiver for CONNECTIVITY_ACTION;
Xia Wang2c159662010-03-27 18:25:14 -0700226 mConnectivityReceiver = new ConnectivityReceiver();
Xia Wang7fb1f672010-03-04 11:54:39 -0800227 registerReceiver(mConnectivityReceiver,
228 new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
229
230 mWifiReceiver = new WifiReceiver();
Xia Wang2c159662010-03-27 18:25:14 -0700231 IntentFilter mIntentFilter = new IntentFilter();
232 mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
233 mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
234 mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
Xia Wangca1f2b12010-11-12 16:08:21 -0800235 mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
Xia Wang6026d522010-11-16 11:35:47 -0800236 mIntentFilter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION);
237 mIntentFilter.addAction(ConnectivityManager.ACTION_TETHER_STATE_CHANGED);
Xia Wang2c159662010-03-27 18:25:14 -0700238 registerReceiver(mWifiReceiver, mIntentFilter);
239
Xia Wang7fb1f672010-03-04 11:54:39 -0800240 // Get an instance of ConnectivityManager
241 mCM = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
242 // Get an instance of WifiManager
243 mWifiManager =(WifiManager)getSystemService(Context.WIFI_SERVICE);
Xia Wang27284da2012-03-08 15:57:26 -0800244 mContext = this;
Irfan Sheriffebe606f2011-02-24 11:39:15 -0800245
Xia Wang2f19a312012-05-15 14:45:12 -0700246 if (mWifiManager.isWifiApEnabled()) {
247 // if soft AP is enabled, disable it
248 mWifiManager.setWifiApEnabled(null, false);
249 log("Disable soft ap");
250 }
Xia Wang7fb1f672010-03-04 11:54:39 -0800251
Xia Wang2f19a312012-05-15 14:45:12 -0700252 initializeNetworkStates();
Xia Wangdddfaa72011-04-08 16:31:01 -0700253 log("Clear Wifi before we start the test.");
Xia Wangdddfaa72011-04-08 16:31:01 -0700254 removeConfiguredNetworksAndDisableWifi();
Xia Wang6026d522010-11-16 11:35:47 -0800255 mWifiRegexs = mCM.getTetherableWifiRegexs();
Xia Wang7fb1f672010-03-04 11:54:39 -0800256 }
257
Xia Wangca1f2b12010-11-12 16:08:21 -0800258 public List<WifiConfiguration> loadNetworkConfigurations() throws Exception {
259 InputStream in = getAssets().open(ACCESS_POINT_FILE);
Xia Wanga42a1e62010-11-22 16:59:48 -0800260 mParseHelper = new AccessPointParserHelper(in);
261 return mParseHelper.getNetworkConfigurations();
Xia Wangca1f2b12010-11-12 16:08:21 -0800262 }
263
Xia Wang7fb1f672010-03-04 11:54:39 -0800264 // for each network type, initialize network states to UNKNOWN, and no verification flag is set
265 public void initializeNetworkStates() {
266 for (int networkType = NUM_NETWORK_TYPES - 1; networkType >=0; networkType--) {
267 connectivityState[networkType] = new NetworkState();
Xia Wanga42a1e62010-11-22 16:59:48 -0800268 log("Initialize network state for " + networkType + ": " +
Xia Wang7fb1f672010-03-04 11:54:39 -0800269 connectivityState[networkType].toString());
270 }
271 }
272
273 // deposit a network state
274 public void recordNetworkState(int networkType, State networkState) {
Xia Wanga42a1e62010-11-22 16:59:48 -0800275 log("record network state for network " + networkType +
Xia Wang2c159662010-03-27 18:25:14 -0700276 ", state is " + networkState);
Xia Wang7fb1f672010-03-04 11:54:39 -0800277 connectivityState[networkType].recordState(networkState);
278 }
279
280 // set the state transition criteria
281 public void setStateTransitionCriteria(int networkType, State initState,
282 int transitionDir, State targetState) {
283 connectivityState[networkType].setStateTransitionCriteria(
284 initState, transitionDir, targetState);
285 }
286
287 // Validate the states recorded
288 public boolean validateNetworkStates(int networkType) {
Xia Wanga42a1e62010-11-22 16:59:48 -0800289 log("validate network state for " + networkType + ": ");
Xia Wang7fb1f672010-03-04 11:54:39 -0800290 return connectivityState[networkType].validateStateTransition();
291 }
292
293 // return result from network state validation
294 public String getTransitionFailureReason(int networkType) {
Xia Wanga42a1e62010-11-22 16:59:48 -0800295 log("get network state transition failure reason for " + networkType + ": " +
Xia Wang7fb1f672010-03-04 11:54:39 -0800296 connectivityState[networkType].toString());
297 return connectivityState[networkType].getReason();
298 }
299
Xia Wang2c159662010-03-27 18:25:14 -0700300 private void notifyNetworkConnectivityChange() {
301 synchronized(connectivityObject) {
Xia Wanga42a1e62010-11-22 16:59:48 -0800302 log("notify network connectivity changed");
Xia Wang2c159662010-03-27 18:25:14 -0700303 connectivityObject.notifyAll();
304 }
305 }
Xia Wang7fb1f672010-03-04 11:54:39 -0800306 private void notifyScanResult() {
307 synchronized (this) {
Xia Wanga42a1e62010-11-22 16:59:48 -0800308 log("notify that scan results are available");
Xia Wang90e1c782010-12-03 14:51:17 -0800309 scanResultAvailable = true;
Xia Wang7fb1f672010-03-04 11:54:39 -0800310 this.notify();
311 }
312 }
313
Xia Wang6026d522010-11-16 11:35:47 -0800314 private void notifyWifiState() {
Xia Wang2c159662010-03-27 18:25:14 -0700315 synchronized (wifiObject) {
Xia Wanga42a1e62010-11-22 16:59:48 -0800316 log("notify wifi state changed");
Xia Wang2c159662010-03-27 18:25:14 -0700317 wifiObject.notify();
318 }
319 }
320
Xia Wang6026d522010-11-16 11:35:47 -0800321 private void notifyWifiAPState() {
322 synchronized (this) {
Xia Wanga42a1e62010-11-22 16:59:48 -0800323 log("notify wifi AP state changed");
Xia Wang6026d522010-11-16 11:35:47 -0800324 this.notify();
325 }
326 }
327
328 // Update wifi tethering state
329 private void updateTetherState(Object[] available, Object[] tethered, Object[] errored) {
330 boolean wifiTethered = false;
331 boolean wifiErrored = false;
332
333 synchronized (this) {
334 for (Object obj: tethered) {
335 String str = (String)obj;
336 for (String tethRex: mWifiRegexs) {
Xia Wanga42a1e62010-11-22 16:59:48 -0800337 log("str: " + str +"tethRex: " + tethRex);
Xia Wang6026d522010-11-16 11:35:47 -0800338 if (str.matches(tethRex)) {
339 wifiTethered = true;
340 }
341 }
342 }
343
344 for (Object obj: errored) {
345 String str = (String)obj;
346 for (String tethRex: mWifiRegexs) {
Xia Wanga42a1e62010-11-22 16:59:48 -0800347 log("error: str: " + str +"tethRex: " + tethRex);
Xia Wang6026d522010-11-16 11:35:47 -0800348 if (str.matches(tethRex)) {
349 wifiErrored = true;
350 }
351 }
352 }
353
354 if (wifiTethered) {
355 mWifiTetherResult = SUCCESS; // wifi tethering is successful
356 } else if (wifiErrored) {
357 mWifiTetherResult = FAILURE; // wifi tethering failed
358 }
Xia Wanga42a1e62010-11-22 16:59:48 -0800359 log("mWifiTetherResult: " + mWifiTetherResult);
Xia Wang6026d522010-11-16 11:35:47 -0800360 this.notify();
361 }
362 }
363
364
Xia Wangca1f2b12010-11-12 16:08:21 -0800365 // Wait for network connectivity state: CONNECTING, CONNECTED, SUSPENDED,
366 // DISCONNECTING, DISCONNECTED, UNKNOWN
367 public boolean waitForNetworkState(int networkType, State expectedState, long timeout) {
368 long startTime = System.currentTimeMillis();
369 while (true) {
370 if ((System.currentTimeMillis() - startTime) > timeout) {
Xia Wang90e1c782010-12-03 14:51:17 -0800371 log("waitForNetworkState time out, the state of network type " + networkType +
372 " is: " + mCM.getNetworkInfo(networkType).getState());
Xia Wangca1f2b12010-11-12 16:08:21 -0800373 if (mCM.getNetworkInfo(networkType).getState() != expectedState) {
374 return false;
375 } else {
376 // the broadcast has been sent out. the state has been changed.
Xia Wanga42a1e62010-11-22 16:59:48 -0800377 log("networktype: " + networkType + " state: " +
Xia Wangca1f2b12010-11-12 16:08:21 -0800378 mCM.getNetworkInfo(networkType));
379 return true;
380 }
381 }
Xia Wanga42a1e62010-11-22 16:59:48 -0800382 log("Wait for the connectivity state for network: " + networkType +
Xia Wangca1f2b12010-11-12 16:08:21 -0800383 " to be " + expectedState.toString());
384 synchronized (connectivityObject) {
385 try {
386 connectivityObject.wait(SHORT_TIMEOUT);
387 } catch (InterruptedException e) {
388 e.printStackTrace();
389 }
390 if ((mNetworkInfo.getType() != networkType) ||
391 (mNetworkInfo.getState() != expectedState)) {
Xia Wanga42a1e62010-11-22 16:59:48 -0800392 log("network state for " + mNetworkInfo.getType() +
Xia Wangca1f2b12010-11-12 16:08:21 -0800393 "is: " + mNetworkInfo.getState());
394 continue;
395 }
396 return true;
397 }
398 }
399 }
400
401 // Wait for Wifi state: WIFI_STATE_DISABLED, WIFI_STATE_DISABLING, WIFI_STATE_ENABLED,
402 // WIFI_STATE_ENALBING, WIFI_STATE_UNKNOWN
403 public boolean waitForWifiState(int expectedState, long timeout) {
404 long startTime = System.currentTimeMillis();
405 while (true) {
406 if ((System.currentTimeMillis() - startTime) > timeout) {
407 if (mWifiState != expectedState) {
408 return false;
409 } else {
410 return true;
411 }
412 }
Xia Wanga42a1e62010-11-22 16:59:48 -0800413 log("Wait for wifi state to be: " + expectedState);
Xia Wangca1f2b12010-11-12 16:08:21 -0800414 synchronized (wifiObject) {
415 try {
416 wifiObject.wait(SHORT_TIMEOUT);
417 } catch (InterruptedException e) {
418 e.printStackTrace();
419 }
420 if (mWifiState != expectedState) {
Xia Wanga42a1e62010-11-22 16:59:48 -0800421 log("Wifi state is: " + mWifiState);
Xia Wangca1f2b12010-11-12 16:08:21 -0800422 continue;
423 }
424 return true;
425 }
426 }
427 }
428
Xia Wang6026d522010-11-16 11:35:47 -0800429 // Wait for Wifi AP state: WIFI_AP_STATE_DISABLED, WIFI_AP_STATE_DISABLING,
430 // WIFI_AP_STATE_ENABLED, WIFI_STATE_ENALBING, WIFI_STATE_UNKNOWN
431 public boolean waitForWifiAPState(int expectedState, long timeout) {
432 long startTime = System.currentTimeMillis();
433 while (true) {
434 if ((System.currentTimeMillis() - startTime) > timeout) {
435 if (mWifiManager.getWifiApState() != expectedState) {
436 return false;
437 } else {
438 return true;
439 }
440 }
Xia Wanga42a1e62010-11-22 16:59:48 -0800441 log("Wait for wifi AP state to be: " + expectedState);
Xia Wang6026d522010-11-16 11:35:47 -0800442 synchronized (wifiObject) {
443 try {
444 wifiObject.wait(SHORT_TIMEOUT);
445 } catch (InterruptedException e) {
446 e.printStackTrace();
447 }
448 if (mWifiManager.getWifiApState() != expectedState) {
Xia Wanga42a1e62010-11-22 16:59:48 -0800449 log("Wifi state is: " + mWifiManager.getWifiApState());
Xia Wang6026d522010-11-16 11:35:47 -0800450 continue;
451 }
452 return true;
453 }
454 }
455 }
456
457 /**
458 * Wait for the wifi tethering result:
459 * @param timeout is the maximum waiting time
460 * @return SUCCESS if tethering result is successful
461 * FAILURE if tethering result returns error.
462 */
463 public int waitForTetherStateChange(long timeout) {
464 long startTime = System.currentTimeMillis();
465 while (true) {
466 if ((System.currentTimeMillis() - startTime) > timeout) {
467 return mWifiTetherResult;
468 }
Xia Wanga42a1e62010-11-22 16:59:48 -0800469 log("Wait for wifi tethering result.");
Xia Wang6026d522010-11-16 11:35:47 -0800470 synchronized (this) {
471 try {
472 this.wait(SHORT_TIMEOUT);
473 } catch (InterruptedException e) {
474 e.printStackTrace();
475 }
476 if (mWifiTetherResult == INIT ) {
477 continue;
478 } else {
479 return mWifiTetherResult;
480 }
481 }
482 }
483 }
484
Xia Wang7fb1f672010-03-04 11:54:39 -0800485 // Return true if device is currently connected to mobile network
486 public boolean isConnectedToMobile() {
487 return (mNetworkInfo.getType() == ConnectivityManager.TYPE_MOBILE);
488 }
489
490 // Return true if device is currently connected to Wifi
491 public boolean isConnectedToWifi() {
492 return (mNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI);
493 }
494
495 public boolean enableWifi() {
496 return mWifiManager.setWifiEnabled(true);
497 }
498
Xia Wang73055f12010-12-16 14:46:09 -0800499 // Turn screen off
500 public void turnScreenOff() {
501 log("Turn screen off");
502 PowerManager pm =
503 (PowerManager) getSystemService(Context.POWER_SERVICE);
Jeff Brown96307042012-07-27 15:51:34 -0700504 pm.goToSleep(SystemClock.uptimeMillis());
Xia Wang73055f12010-12-16 14:46:09 -0800505 }
506
507 // Turn screen on
508 public void turnScreenOn() {
509 log("Turn screen on");
Jeff Brown96307042012-07-27 15:51:34 -0700510 PowerManager pm =
511 (PowerManager) getSystemService(Context.POWER_SERVICE);
512 pm.wakeUp(SystemClock.uptimeMillis());
Xia Wang73055f12010-12-16 14:46:09 -0800513 }
514
Xia Wang7fb1f672010-03-04 11:54:39 -0800515 /**
Xia Wang6bffe142011-02-17 15:32:37 -0800516 * @param pingServerList a list of servers that can be used for ping test, can be null
517 * @return true if the ping test is successful, false otherwise.
518 */
519 public boolean pingTest(String[] pingServerList) {
520 boolean result = false;
521 String[] hostList = {"www.google.com", "www.yahoo.com",
522 "www.bing.com", "www.facebook.com", "www.ask.com"};
523 if (pingServerList != null) {
524 hostList = pingServerList;
525 }
526 try {
527 // assume the chance that all servers are down is very small
528 for (int i = 0; i < hostList.length; i++ ) {
529 String host = hostList[i];
530 log("Start ping test, ping " + host);
531 Process p = Runtime.getRuntime().exec("ping -c 10 -w 100 " + host);
532 int status = p.waitFor();
533 if (status == 0) {
534 // if any of the ping test is successful, return true
535 result = true;
536 break;
537 } else {
538 result = false;
539 log("ping " + host + " failed.");
540 }
541 }
542 } catch (UnknownHostException e) {
543 log("Ping test Fail: Unknown Host");
544 } catch (IOException e) {
545 log("Ping test Fail: IOException");
546 } catch (InterruptedException e) {
547 log("Ping test Fail: InterruptedException");
548 }
549 log("return");
550 return result;
551 }
552
553 /**
Xia Wang7fb1f672010-03-04 11:54:39 -0800554 * Associate the device to given SSID
555 * If the device is already associated with a WiFi, disconnect and forget it,
556 * We don't verify whether the connection is successful or not, leave this to the test
557 */
558 public boolean connectToWifi(String knownSSID) {
Xia Wangca1f2b12010-11-12 16:08:21 -0800559 WifiConfiguration config = new WifiConfiguration();
560 config.SSID = knownSSID;
561 config.allowedKeyManagement.set(KeyMgmt.NONE);
562 return connectToWifiWithConfiguration(config);
563 }
564
565 /**
566 * Connect to Wi-Fi with the given configuration. Note the SSID in the configuration
567 * is pure string, we need to convert it to quoted string.
568 * @param config
569 * @return
570 */
571 public boolean connectToWifiWithConfiguration(WifiConfiguration config) {
572 String ssid = config.SSID;
573 config.SSID = convertToQuotedString(ssid);
574
Xia Wang7fb1f672010-03-04 11:54:39 -0800575 //If Wifi is not enabled, enable it
576 if (!mWifiManager.isWifiEnabled()) {
Xia Wanga42a1e62010-11-22 16:59:48 -0800577 log("Wifi is not enabled, enable it");
Xia Wang7fb1f672010-03-04 11:54:39 -0800578 mWifiManager.setWifiEnabled(true);
Xia Wanga42a1e62010-11-22 16:59:48 -0800579 // wait for the wifi state change before start scanning.
580 if (!waitForWifiState(WifiManager.WIFI_STATE_ENABLED, 2*SHORT_TIMEOUT)) {
581 log("wait for WIFI_STATE_ENABLED failed");
582 return false;
Xia Wang7fb1f672010-03-04 11:54:39 -0800583 }
584 }
585
Xia Wanga42a1e62010-11-22 16:59:48 -0800586 boolean foundApInScanResults = false;
587 for (int retry = 0; retry < 5; retry++) {
588 List<ScanResult> netList = mWifiManager.getScanResults();
589 if (netList != null) {
590 log("size of scan result list: " + netList.size());
591 for (int i = 0; i < netList.size(); i++) {
592 ScanResult sr= netList.get(i);
593 if (sr.SSID.equals(ssid)) {
594 log("found " + ssid + " in the scan result list");
595 log("retry: " + retry);
596 foundApInScanResults = true;
Irfan Sheriff88759bb2012-07-02 15:58:28 -0700597 mWifiManager.connect(config,
Irfan Sheriffd3975a92012-02-24 10:54:13 -0800598 new WifiManager.ActionListener() {
599 public void onSuccess() {
600 }
601 public void onFailure(int reason) {
602 log("connect failure " + reason);
603 }
604 });
Xia Wanga42a1e62010-11-22 16:59:48 -0800605 break;
606 }
Xia Wangca1f2b12010-11-12 16:08:21 -0800607 }
Xia Wanga42a1e62010-11-22 16:59:48 -0800608 }
609 if (foundApInScanResults) {
610 return true;
611 } else {
612 // Start an active scan
613 mWifiManager.startScanActive();
614 mScanResultIsAvailable = false;
615 long startTime = System.currentTimeMillis();
616 while (!mScanResultIsAvailable) {
617 if ((System.currentTimeMillis() - startTime) > WIFI_SCAN_TIMEOUT) {
618 log("wait for scan results timeout");
619 return false;
620 }
621 // wait for the scan results to be available
622 synchronized (this) {
623 // wait for the scan result to be available
624 try {
625 this.wait(WAIT_FOR_SCAN_RESULT);
626 } catch (InterruptedException e) {
627 e.printStackTrace();
628 }
629 if ((mWifiManager.getScanResults() == null) ||
630 (mWifiManager.getScanResults().size() <= 0)) {
631 continue;
632 }
633 mScanResultIsAvailable = true;
634 }
635 }
636 }
Xia Wang7fb1f672010-03-04 11:54:39 -0800637 }
Xia Wanga42a1e62010-11-22 16:59:48 -0800638 return false;
Xia Wang7fb1f672010-03-04 11:54:39 -0800639 }
640
Xia Wang2c159662010-03-27 18:25:14 -0700641 /*
Xia Wangca1f2b12010-11-12 16:08:21 -0800642 * Disconnect from the current AP and remove configured networks.
Xia Wang7fb1f672010-03-04 11:54:39 -0800643 */
Xia Wang2c159662010-03-27 18:25:14 -0700644 public boolean disconnectAP() {
Xia Wangdddfaa72011-04-08 16:31:01 -0700645 // remove saved networks
Xia Wang81341fe2012-05-06 16:03:34 -0700646 if (!mWifiManager.isWifiEnabled()) {
647 log("Enabled wifi before remove configured networks");
648 mWifiManager.setWifiEnabled(true);
649 sleep(SHORT_TIMEOUT);
650 }
Xia Wangdddfaa72011-04-08 16:31:01 -0700651 List<WifiConfiguration> wifiConfigList = mWifiManager.getConfiguredNetworks();
652 log("size of wifiConfigList: " + wifiConfigList.size());
653 for (WifiConfiguration wifiConfig: wifiConfigList) {
654 log("remove wifi configuration: " + wifiConfig.networkId);
655 int netId = wifiConfig.networkId;
Irfan Sheriff88759bb2012-07-02 15:58:28 -0700656 mWifiManager.forget(netId, new WifiManager.ActionListener() {
Irfan Sheriffd3975a92012-02-24 10:54:13 -0800657 public void onSuccess() {
658 }
659 public void onFailure(int reason) {
660 log("Failed to forget " + reason);
661 }
662 });
Xia Wang2c159662010-03-27 18:25:14 -0700663 }
Xia Wang2c159662010-03-27 18:25:14 -0700664 return true;
665 }
666 /**
667 * Disable Wifi
668 * @return true if Wifi is disabled successfully
669 */
670 public boolean disableWifi() {
671 return mWifiManager.setWifiEnabled(false);
672 }
673
674 /**
Xia Wangca1f2b12010-11-12 16:08:21 -0800675 * Remove configured networks and disable wifi
Xia Wang2c159662010-03-27 18:25:14 -0700676 */
Xia Wangca1f2b12010-11-12 16:08:21 -0800677 public boolean removeConfiguredNetworksAndDisableWifi() {
Xia Wangdddfaa72011-04-08 16:31:01 -0700678 if (!disconnectAP()) {
679 return false;
680 }
681 sleep(SHORT_TIMEOUT);
682 if (!mWifiManager.setWifiEnabled(false)) {
683 return false;
684 }
685 sleep(SHORT_TIMEOUT);
Xia Wang7fb1f672010-03-04 11:54:39 -0800686 return true;
687 }
688
Xia Wangdddfaa72011-04-08 16:31:01 -0700689 private void sleep(long sleeptime) {
690 try {
691 Thread.sleep(sleeptime);
692 } catch (InterruptedException e) {}
693 }
694
Xia Wang7fb1f672010-03-04 11:54:39 -0800695 /**
696 * Set airplane mode
697 */
698 public void setAirplaneMode(Context context, boolean enableAM) {
699 //set the airplane mode
Christopher Tatec09cdce2012-09-10 16:50:14 -0700700 Settings.Global.putInt(context.getContentResolver(), Settings.Global.AIRPLANE_MODE_ON,
Xia Wang7fb1f672010-03-04 11:54:39 -0800701 enableAM ? 1 : 0);
702 // Post the intent
703 Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
704 intent.putExtra("state", enableAM);
Christopher Tatec09cdce2012-09-10 16:50:14 -0700705 context.sendBroadcastAsUser(intent, UserHandle.ALL);
Xia Wang7fb1f672010-03-04 11:54:39 -0800706 }
707
Xia Wang06906792010-05-20 10:22:59 -0700708 protected static String convertToQuotedString(String string) {
709 return "\"" + string + "\"";
710 }
711
Xia Wang7fb1f672010-03-04 11:54:39 -0800712 @Override
713 protected void onDestroy() {
714 super.onDestroy();
715
716 //Unregister receiver
717 if (mConnectivityReceiver != null) {
718 unregisterReceiver(mConnectivityReceiver);
719 }
720 if (mWifiReceiver != null) {
721 unregisterReceiver(mWifiReceiver);
722 }
Xia Wanga42a1e62010-11-22 16:59:48 -0800723 log("onDestroy, inst=" + Integer.toHexString(hashCode()));
Xia Wang7fb1f672010-03-04 11:54:39 -0800724 }
Yu Shan Emily Lauba1348e2010-07-16 11:55:43 -0700725
726 @Override
727 public void onStart() {
728 super.onStart();
729 mContext = this;
730 Bundle bundle = this.getIntent().getExtras();
731 if (bundle != null){
732 mPowerSsid = bundle.getString("power_ssid");
733 }
734 }
735 //A thread to set the device into airplane mode then turn on wifi.
736 Thread setDeviceWifiAndAirplaneThread = new Thread(new Runnable() {
737 public void run() {
738 setAirplaneMode(mContext, true);
739 connectToWifi(mPowerSsid);
740 }
741 });
742
743 //A thread to set the device into wifi
744 Thread setDeviceInWifiOnlyThread = new Thread(new Runnable() {
745 public void run() {
746 connectToWifi(mPowerSsid);
747 }
748 });
749
750 @Override
751 public boolean onKeyDown(int keyCode, KeyEvent event) {
752 switch (keyCode) {
753 //This is a tricky way for the scripted monkey to
754 //set the device in wifi and wifi in airplane mode.
755 case KeyEvent.KEYCODE_1:
756 setDeviceWifiAndAirplaneThread.start();
757 break;
758
759 case KeyEvent.KEYCODE_2:
760 setDeviceInWifiOnlyThread.start();
761 break;
762 }
763 return super.onKeyDown(keyCode, event);
764 }
Xia Wanga42a1e62010-11-22 16:59:48 -0800765
766 private void log(String message) {
767 Log.v(LOG_TAG, message);
768 }
Xia Wang7fb1f672010-03-04 11:54:39 -0800769}