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