1/* 2 * Copyright (C) 2011, 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.bandwidthtest.util; 18 19import android.app.DownloadManager; 20import android.app.DownloadManager.Query; 21import android.app.DownloadManager.Request; 22import android.content.BroadcastReceiver; 23import android.content.Context; 24import android.content.Intent; 25import android.content.IntentFilter; 26import android.content.pm.ApplicationInfo; 27import android.content.pm.PackageManager; 28import android.content.pm.PackageManager.NameNotFoundException; 29import android.database.Cursor; 30import android.net.ConnectivityManager; 31import android.net.NetworkInfo; 32import android.net.NetworkInfo.State; 33import android.net.Uri; 34import android.net.wifi.ScanResult; 35import android.net.wifi.WifiConfiguration; 36import android.net.wifi.WifiConfiguration.KeyMgmt; 37import android.net.wifi.WifiManager; 38import android.os.Handler; 39import android.os.Message; 40import android.provider.Settings; 41import android.util.Log; 42 43import com.android.bandwidthtest.NetworkState; 44import com.android.bandwidthtest.NetworkState.StateTransitionDirection; 45import com.android.internal.util.AsyncChannel; 46 47import junit.framework.Assert; 48 49import java.io.IOException; 50import java.net.UnknownHostException; 51import java.util.List; 52 53/* 54 * Utility class used to set the connectivity of the device and to download files. 55 */ 56public class ConnectionUtil { 57 private static final String LOG_TAG = "ConnectionUtil"; 58 private static final String DOWNLOAD_MANAGER_PKG_NAME = "com.android.providers.downloads"; 59 private static final int WAIT_FOR_SCAN_RESULT = 10 * 1000; // 10 seconds 60 private static final int WIFI_SCAN_TIMEOUT = 50 * 1000; 61 public static final int SHORT_TIMEOUT = 5 * 1000; 62 public static final int LONG_TIMEOUT = 5 * 60 * 1000; // 5 minutes 63 private ConnectivityReceiver mConnectivityReceiver = null; 64 private WifiReceiver mWifiReceiver = null; 65 private DownloadReceiver mDownloadReceiver = null; 66 private DownloadManager mDownloadManager; 67 private NetworkInfo mNetworkInfo; 68 private NetworkInfo mOtherNetworkInfo; 69 private boolean mScanResultIsAvailable = false; 70 private ConnectivityManager mCM; 71 private Object mWifiMonitor = new Object(); 72 private Object mConnectivityMonitor = new Object(); 73 private Object mDownloadMonitor = new Object(); 74 private int mWifiState; 75 private NetworkInfo mWifiNetworkInfo; 76 private WifiManager mWifiManager; 77 private Context mContext; 78 // Verify connectivity state 79 private static final int NUM_NETWORK_TYPES = ConnectivityManager.MAX_NETWORK_TYPE + 1; 80 private NetworkState[] mConnectivityState = new NetworkState[NUM_NETWORK_TYPES]; 81 82 public ConnectionUtil(Context context) { 83 mContext = context; 84 } 85 86 /** 87 * Initialize the class. Needs to be called before any other methods in {@link ConnectionUtil} 88 * 89 * @throws Exception 90 */ 91 public void initialize() throws Exception { 92 // Register a connectivity receiver for CONNECTIVITY_ACTION 93 mConnectivityReceiver = new ConnectivityReceiver(); 94 mContext.registerReceiver(mConnectivityReceiver, 95 new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); 96 97 // Register a download receiver for ACTION_DOWNLOAD_COMPLETE 98 mDownloadReceiver = new DownloadReceiver(); 99 mContext.registerReceiver(mDownloadReceiver, 100 new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)); 101 102 // Register a wifi receiver 103 mWifiReceiver = new WifiReceiver(); 104 IntentFilter mIntentFilter = new IntentFilter(); 105 mIntentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); 106 mIntentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 107 mIntentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); 108 mIntentFilter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); 109 mIntentFilter.addAction(WifiManager.WIFI_AP_STATE_CHANGED_ACTION); 110 mContext.registerReceiver(mWifiReceiver, mIntentFilter); 111 112 // Get an instance of ConnectivityManager 113 mCM = (ConnectivityManager)mContext.getSystemService(Context.CONNECTIVITY_SERVICE); 114 115 // Get an instance of WifiManager 116 mWifiManager =(WifiManager)mContext.getSystemService(Context.WIFI_SERVICE); 117 mWifiManager.asyncConnect(mContext, new WifiServiceHandler()); 118 119 mDownloadManager = (DownloadManager)mContext.getSystemService(Context.DOWNLOAD_SERVICE); 120 121 initializeNetworkStates(); 122 123 124 } 125 126 /** 127 * Additional initialization needed for wifi related tests. 128 */ 129 public void wifiTestInit() { 130 mWifiManager.setWifiEnabled(true); 131 Log.v(LOG_TAG, "Clear Wifi before we start the test."); 132 sleep(SHORT_TIMEOUT); 133 removeConfiguredNetworksAndDisableWifi(); 134 } 135 136 137 /** 138 * A wrapper of a broadcast receiver which provides network connectivity information 139 * for all kinds of network: wifi, mobile, etc. 140 */ 141 private class ConnectivityReceiver extends BroadcastReceiver { 142 /** 143 * {@inheritDoc} 144 */ 145 @Override 146 public void onReceive(Context context, Intent intent) { 147 if (isInitialStickyBroadcast()) { 148 Log.d(LOG_TAG, "This is a sticky broadcast don't do anything."); 149 return; 150 } 151 Log.v(LOG_TAG, "ConnectivityReceiver: onReceive() is called with " + intent); 152 String action = intent.getAction(); 153 if (!action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { 154 Log.v("ConnectivityReceiver", "onReceive() called with " + intent); 155 return; 156 } 157 158 final ConnectivityManager connManager = (ConnectivityManager) context 159 .getSystemService(Context.CONNECTIVITY_SERVICE); 160 mNetworkInfo = connManager.getActiveNetworkInfo(); 161 162 if (intent.hasExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO)) { 163 mOtherNetworkInfo = (NetworkInfo) 164 intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO); 165 } 166 167 Log.v(LOG_TAG, "mNetworkInfo: " + mNetworkInfo.toString()); 168 recordNetworkState(mNetworkInfo.getType(), mNetworkInfo.getState()); 169 if (mOtherNetworkInfo != null) { 170 Log.v(LOG_TAG, "mOtherNetworkInfo: " + mOtherNetworkInfo.toString()); 171 recordNetworkState(mOtherNetworkInfo.getType(), mOtherNetworkInfo.getState()); 172 } 173 notifyNetworkConnectivityChange(); 174 } 175 } 176 177 /** 178 * A wrapper of a broadcast receiver which provides wifi information. 179 */ 180 private class WifiReceiver extends BroadcastReceiver { 181 /** 182 * {@inheritDoc} 183 */ 184 @Override 185 public void onReceive(Context context, Intent intent) { 186 String action = intent.getAction(); 187 Log.v("WifiReceiver", "onReceive() is calleld with " + intent); 188 if (action.equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) { 189 Log.v(LOG_TAG, "Scan results are available"); 190 notifyScanResult(); 191 } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { 192 mWifiNetworkInfo = 193 (NetworkInfo) intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); 194 Log.v(LOG_TAG, "mWifiNetworkInfo: " + mWifiNetworkInfo.toString()); 195 if (mWifiNetworkInfo.getState() == State.CONNECTED) { 196 intent.getStringExtra(WifiManager.EXTRA_BSSID); 197 } 198 notifyWifiState(); 199 } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { 200 mWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 201 WifiManager.WIFI_STATE_UNKNOWN); 202 notifyWifiState(); 203 } else if (action.equals(WifiManager.WIFI_AP_STATE_CHANGED_ACTION)) { 204 notifyWifiAPState(); 205 } else { 206 return; 207 } 208 } 209 } 210 211 /** 212 * A wrapper of a broadcast receiver which provides download manager information. 213 */ 214 private class DownloadReceiver extends BroadcastReceiver { 215 /** 216 * {@inheritDoc} 217 */ 218 @Override 219 public void onReceive(Context context, Intent intent) { 220 String action = intent.getAction(); 221 Log.v("DownloadReceiver", "onReceive() is called with " + intent); 222 // Download complete 223 if (action.equals(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) { 224 notifiyDownloadState(); 225 } 226 } 227 } 228 229 private class WifiServiceHandler extends Handler { 230 /** 231 * {@inheritDoc} 232 */ 233 @Override 234 public void handleMessage(Message msg) { 235 switch (msg.what) { 236 case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: 237 if (msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) { 238 // AsyncChannel in msg.obj 239 } else { 240 Log.v(LOG_TAG, "Failed to establish AsyncChannel connection"); 241 } 242 break; 243 default: 244 // Ignore 245 break; 246 } 247 } 248 } 249 250 /** 251 * Initialize all the network states. 252 */ 253 public void initializeNetworkStates() { 254 // For each network type, initialize network states to UNKNOWN, and no verification 255 // flag is set. 256 for (int networkType = NUM_NETWORK_TYPES - 1; networkType >= 0; networkType--) { 257 mConnectivityState[networkType] = new NetworkState(); 258 Log.v(LOG_TAG, "Initialize network state for " + networkType + ": " + 259 mConnectivityState[networkType].toString()); 260 } 261 } 262 263 public void recordNetworkState(int networkType, State networkState) { 264 // deposit a network state 265 Log.v(LOG_TAG, "record network state for network " + networkType + 266 ", state is " + networkState); 267 mConnectivityState[networkType].recordState(networkState); 268 } 269 270 /** 271 * Set the state transition criteria 272 * 273 * @param networkType 274 * @param initState 275 * @param transitionDir 276 * @param targetState 277 */ 278 public void setStateTransitionCriteria(int networkType, State initState, 279 StateTransitionDirection transitionDir, State targetState) { 280 mConnectivityState[networkType].setStateTransitionCriteria( 281 initState, transitionDir, targetState); 282 } 283 284 /** 285 * Validate the states recorded. 286 * @param networkType 287 * @return 288 */ 289 public boolean validateNetworkStates(int networkType) { 290 Log.v(LOG_TAG, "validate network state for " + networkType + ": "); 291 return mConnectivityState[networkType].validateStateTransition(); 292 } 293 294 /** 295 * Fetch the failure reason for the transition. 296 * @param networkType 297 * @return result from network state validation 298 */ 299 public String getTransitionFailureReason(int networkType) { 300 Log.v(LOG_TAG, "get network state transition failure reason for " + networkType + ": " + 301 mConnectivityState[networkType].toString()); 302 return mConnectivityState[networkType].getFailureReason(); 303 } 304 305 /** 306 * Send a notification via the mConnectivityMonitor when the network connectivity changes. 307 */ 308 private void notifyNetworkConnectivityChange() { 309 synchronized(mConnectivityMonitor) { 310 Log.v(LOG_TAG, "notify network connectivity changed"); 311 mConnectivityMonitor.notifyAll(); 312 } 313 } 314 315 /** 316 * Send a notification when a scan for the wifi network is done. 317 */ 318 private void notifyScanResult() { 319 synchronized (this) { 320 Log.v(LOG_TAG, "notify that scan results are available"); 321 this.notify(); 322 } 323 } 324 325 /** 326 * Send a notification via the mWifiMonitor when the wifi state changes. 327 */ 328 private void notifyWifiState() { 329 synchronized (mWifiMonitor) { 330 Log.v(LOG_TAG, "notify wifi state changed."); 331 mWifiMonitor.notify(); 332 } 333 } 334 335 /** 336 * Send a notification via the mDownloadMonitor when a download is complete. 337 */ 338 private void notifiyDownloadState() { 339 synchronized (mDownloadMonitor) { 340 Log.v(LOG_TAG, "notifiy download manager state changed."); 341 mDownloadMonitor.notify(); 342 } 343 } 344 345 /** 346 * Send a notification when the wifi ap state changes. 347 */ 348 private void notifyWifiAPState() { 349 synchronized (this) { 350 Log.v(LOG_TAG, "notify wifi AP state changed."); 351 this.notify(); 352 } 353 } 354 355 /** 356 * Start a download on a given url and wait for completion. 357 * 358 * @param targetUrl the target to download.x 359 * @param timeout to wait for download to finish 360 * @return true if we successfully downloaded the requestedUrl, false otherwise. 361 */ 362 public boolean startDownloadAndWait(String targetUrl, long timeout) { 363 if (targetUrl.length() == 0 || targetUrl == null) { 364 Log.v(LOG_TAG, "Empty or Null target url requested to DownloadManager"); 365 return true; 366 } 367 Request request = new Request(Uri.parse(targetUrl)); 368 long enqueue = mDownloadManager.enqueue(request); 369 Log.v(LOG_TAG, "Sending download request of " + targetUrl + " to DownloadManager"); 370 long startTime = System.currentTimeMillis(); 371 while (true) { 372 if ((System.currentTimeMillis() - startTime) > timeout) { 373 Log.v(LOG_TAG, "startDownloadAndWait timed out, failed to fetch " + targetUrl + 374 " within " + timeout); 375 return downloadSuccessful(enqueue); 376 } 377 Log.v(LOG_TAG, "Waiting for the download to finish " + targetUrl); 378 synchronized (mDownloadMonitor) { 379 try { 380 mDownloadMonitor.wait(SHORT_TIMEOUT); 381 } catch (InterruptedException e) { 382 e.printStackTrace(); 383 } 384 if (!downloadSuccessful(enqueue)) { 385 continue; 386 } 387 return true; 388 } 389 } 390 } 391 392 /** 393 * Fetch the Download Manager's UID. 394 * @return the Download Manager's UID 395 */ 396 public int downloadManagerUid() { 397 try { 398 PackageManager pm = mContext.getPackageManager(); 399 ApplicationInfo appInfo = pm.getApplicationInfo(DOWNLOAD_MANAGER_PKG_NAME, 400 PackageManager.GET_META_DATA); 401 return appInfo.uid; 402 } catch (NameNotFoundException e) { 403 Log.d(LOG_TAG, "Did not find the package for the download service."); 404 return -1; 405 } 406 } 407 408 /** 409 * Determines if a given download was successful by querying the DownloadManager. 410 * 411 * @param enqueue the id used to identify/query the DownloadManager with. 412 * @return true if download was successful, false otherwise. 413 */ 414 private boolean downloadSuccessful(long enqueue) { 415 Query query = new Query(); 416 query.setFilterById(enqueue); 417 Cursor c = mDownloadManager.query(query); 418 if (c.moveToFirst()) { 419 int columnIndex = c.getColumnIndex(DownloadManager.COLUMN_STATUS); 420 if (DownloadManager.STATUS_SUCCESSFUL == c.getInt(columnIndex)) { 421 Log.v(LOG_TAG, "Successfully downloaded file!"); 422 return true; 423 } 424 } 425 return false; 426 } 427 428 /** 429 * Wait for network connectivity state. 430 * @param networkType the network to check for 431 * @param expectedState the desired state 432 * @param timeout in milliseconds 433 * @return true if the network connectivity state matched what was expected 434 */ 435 public boolean waitForNetworkState(int networkType, State expectedState, long timeout) { 436 long startTime = System.currentTimeMillis(); 437 while (true) { 438 if ((System.currentTimeMillis() - startTime) > timeout) { 439 Log.v(LOG_TAG, "waitForNetworkState time out, the state of network type " + networkType + 440 " is: " + mCM.getNetworkInfo(networkType).getState()); 441 if (mCM.getNetworkInfo(networkType).getState() != expectedState) { 442 return false; 443 } else { 444 // the broadcast has been sent out. the state has been changed. 445 Log.v(LOG_TAG, "networktype: " + networkType + " state: " + 446 mCM.getNetworkInfo(networkType)); 447 return true; 448 } 449 } 450 Log.v(LOG_TAG, "Wait for the connectivity state for network: " + networkType + 451 " to be " + expectedState.toString()); 452 synchronized (mConnectivityMonitor) { 453 try { 454 mConnectivityMonitor.wait(SHORT_TIMEOUT); 455 } catch (InterruptedException e) { 456 e.printStackTrace(); 457 } 458 if (mNetworkInfo == null) { 459 Log.v(LOG_TAG, "Do not have networkInfo! Force fetch of network info."); 460 mNetworkInfo = mCM.getActiveNetworkInfo(); 461 } 462 // Still null after force fetch? Maybe the network did not have time to be brought 463 // up yet. 464 if (mNetworkInfo == null) { 465 Log.v(LOG_TAG, "Failed to force fetch networkInfo. " + 466 "The network is still not ready. Wait for the next broadcast"); 467 continue; 468 } 469 if ((mNetworkInfo.getType() != networkType) || 470 (mNetworkInfo.getState() != expectedState)) { 471 Log.v(LOG_TAG, "network state for " + mNetworkInfo.getType() + 472 "is: " + mNetworkInfo.getState()); 473 continue; 474 } 475 return true; 476 } 477 } 478 } 479 480 /** 481 * Wait for a given wifi state to occur within a given timeout. 482 * @param expectedState the expected wifi state. 483 * @param timeout for the state to be set in milliseconds. 484 * @return true if the state was achieved within the timeout, false otherwise. 485 */ 486 public boolean waitForWifiState(int expectedState, long timeout) { 487 // Wait for Wifi state: WIFI_STATE_DISABLED, WIFI_STATE_DISABLING, WIFI_STATE_ENABLED, 488 // WIFI_STATE_ENALBING, WIFI_STATE_UNKNOWN 489 long startTime = System.currentTimeMillis(); 490 while (true) { 491 if ((System.currentTimeMillis() - startTime) > timeout) { 492 if (mWifiState != expectedState) { 493 return false; 494 } else { 495 return true; 496 } 497 } 498 Log.v(LOG_TAG, "Wait for wifi state to be: " + expectedState); 499 synchronized (mWifiMonitor) { 500 try { 501 mWifiMonitor.wait(SHORT_TIMEOUT); 502 } catch (InterruptedException e) { 503 e.printStackTrace(); 504 } 505 if (mWifiState != expectedState) { 506 Log.v(LOG_TAG, "Wifi state is: " + mWifiState); 507 continue; 508 } 509 return true; 510 } 511 } 512 } 513 514 /** 515 * Convenience method to determine if we are connected to a mobile network. 516 * @return true if connected to a mobile network, false otherwise. 517 */ 518 public boolean isConnectedToMobile() { 519 NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); 520 return networkInfo.isConnected(); 521 } 522 523 /** 524 * Convenience method to determine if we are connected to wifi. 525 * @return true if connected to wifi, false otherwise. 526 */ 527 public boolean isConnectedToWifi() { 528 NetworkInfo networkInfo = mCM.getNetworkInfo(ConnectivityManager.TYPE_WIFI); 529 return networkInfo.isConnected(); 530 } 531 532 /** 533 * Associate the device to given SSID 534 * If the device is already associated with a WiFi, disconnect and forget it, 535 * We don't verify whether the connection is successful or not, leave this to the test 536 */ 537 public boolean connectToWifi(String knownSSID) { 538 WifiConfiguration config = new WifiConfiguration(); 539 config.SSID = knownSSID; 540 config.allowedKeyManagement.set(KeyMgmt.NONE); 541 return connectToWifiWithConfiguration(config); 542 } 543 544 /** 545 * Connect to Wi-Fi with the given configuration. 546 * @param config 547 * @return true if we are connected to a given AP. 548 */ 549 public boolean connectToWifiWithConfiguration(WifiConfiguration config) { 550 // The SSID in the configuration is a pure string, need to convert it to a quoted string. 551 String ssid = config.SSID; 552 config.SSID = convertToQuotedString(ssid); 553 554 // If wifi is not enabled, enable it 555 if (!mWifiManager.isWifiEnabled()) { 556 Log.v(LOG_TAG, "Wifi is not enabled, enable it"); 557 mWifiManager.setWifiEnabled(true); 558 // wait for the wifi state change before start scanning. 559 if (!waitForWifiState(WifiManager.WIFI_STATE_ENABLED, 2 * SHORT_TIMEOUT)) { 560 Log.v(LOG_TAG, "Wait for WIFI_STATE_ENABLED failed"); 561 return false; 562 } 563 } 564 565 boolean foundApInScanResults = false; 566 for (int retry = 0; retry < 5; retry++) { 567 List<ScanResult> netList = mWifiManager.getScanResults(); 568 if (netList != null) { 569 Log.v(LOG_TAG, "size of scan result list: " + netList.size()); 570 for (int i = 0; i < netList.size(); i++) { 571 ScanResult sr= netList.get(i); 572 if (sr.SSID.equals(ssid)) { 573 Log.v(LOG_TAG, "Found " + ssid + " in the scan result list."); 574 Log.v(LOG_TAG, "Retry: " + retry); 575 foundApInScanResults = true; 576 mWifiManager.connectNetwork(config); 577 break; 578 } 579 } 580 } 581 if (foundApInScanResults) { 582 return true; 583 } else { 584 // Start an active scan 585 mWifiManager.startScanActive(); 586 mScanResultIsAvailable = false; 587 long startTime = System.currentTimeMillis(); 588 while (!mScanResultIsAvailable) { 589 if ((System.currentTimeMillis() - startTime) > WIFI_SCAN_TIMEOUT) { 590 Log.v(LOG_TAG, "wait for scan results timeout"); 591 return false; 592 } 593 // wait for the scan results to be available 594 synchronized (this) { 595 // wait for the scan result to be available 596 try { 597 this.wait(WAIT_FOR_SCAN_RESULT); 598 } catch (InterruptedException e) { 599 e.printStackTrace(); 600 } 601 if ((mWifiManager.getScanResults() == null) || 602 (mWifiManager.getScanResults().size() <= 0)) { 603 continue; 604 } 605 mScanResultIsAvailable = true; 606 } 607 } 608 } 609 } 610 return false; 611 } 612 613 /* 614 * Disconnect from the current AP and remove configured networks. 615 */ 616 public boolean disconnectAP() { 617 // remove saved networks 618 List<WifiConfiguration> wifiConfigList = mWifiManager.getConfiguredNetworks(); 619 Log.v(LOG_TAG, "size of wifiConfigList: " + wifiConfigList.size()); 620 for (WifiConfiguration wifiConfig: wifiConfigList) { 621 Log.v(LOG_TAG, "Remove wifi configuration: " + wifiConfig.networkId); 622 int netId = wifiConfig.networkId; 623 mWifiManager.forgetNetwork(netId); 624 } 625 return true; 626 } 627 628 /** 629 * Enable Wifi 630 * @return true if Wifi is enabled successfully 631 */ 632 public boolean enableWifi() { 633 return mWifiManager.setWifiEnabled(true); 634 } 635 636 /** 637 * Disable Wifi 638 * @return true if Wifi is disabled successfully 639 */ 640 public boolean disableWifi() { 641 return mWifiManager.setWifiEnabled(false); 642 } 643 644 /** 645 * Remove configured networks and disable wifi 646 */ 647 public boolean removeConfiguredNetworksAndDisableWifi() { 648 if (!disconnectAP()) { 649 return false; 650 } 651 sleep(SHORT_TIMEOUT); 652 if (!mWifiManager.setWifiEnabled(false)) { 653 return false; 654 } 655 sleep(SHORT_TIMEOUT); 656 return true; 657 } 658 659 /** 660 * Make the current thread sleep. 661 * @param sleeptime the time to sleep in milliseconds 662 */ 663 private void sleep(long sleeptime) { 664 try { 665 Thread.sleep(sleeptime); 666 } catch (InterruptedException e) {} 667 } 668 669 /** 670 * Set airplane mode on device, caller is responsible to ensuring correct state. 671 * @param context {@link Context} 672 * @param enableAM to enable or disable airplane mode. 673 */ 674 public void setAirplaneMode(Context context, boolean enableAM) { 675 //set the airplane mode 676 Settings.System.putInt(context.getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 677 enableAM ? 1 : 0); 678 // Post the intent 679 Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); 680 intent.putExtra("state", enableAM); 681 context.sendBroadcast(intent); 682 } 683 684 /** 685 * Add quotes around the string. 686 * @param string to convert 687 * @return string with quotes around it 688 */ 689 protected static String convertToQuotedString(String string) { 690 return "\"" + string + "\""; 691 } 692 693 public void cleanUp() { 694 // Unregister receivers if defined. 695 if (mConnectivityReceiver != null) { 696 mContext.unregisterReceiver(mConnectivityReceiver); 697 } 698 if (mWifiReceiver != null) { 699 mContext.unregisterReceiver(mWifiReceiver); 700 } 701 if (mDownloadReceiver != null) { 702 mContext.unregisterReceiver(mDownloadReceiver); 703 } 704 Log.v(LOG_TAG, "onDestroy, inst=" + Integer.toHexString(hashCode())); 705 } 706 707 /** 708 * Helper method used to test data connectivity by pinging a series of popular sites. 709 * @return true if device has data connectivity, false otherwise. 710 */ 711 public boolean hasData() { 712 String[] hostList = {"www.google.com", "www.yahoo.com", 713 "www.bing.com", "www.facebook.com", "www.ask.com"}; 714 try { 715 for (int i = 0; i < hostList.length; ++i) { 716 String host = hostList[i]; 717 Process p = Runtime.getRuntime().exec("ping -c 10 -w 100 " + host); 718 int status = p.waitFor(); 719 if (status == 0) { 720 return true; 721 } 722 } 723 } catch (UnknownHostException e) { 724 Log.e(LOG_TAG, "Ping test Failed: Unknown Host"); 725 } catch (IOException e) { 726 Log.e(LOG_TAG, "Ping test Failed: IOException"); 727 } catch (InterruptedException e) { 728 Log.e(LOG_TAG, "Ping test Failed: InterruptedException"); 729 } 730 return false; 731 } 732}