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