WifiSettings.java revision c1bad6bc68020590b7d6df50fdacaa28201b006f
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.settings.wifi; 18 19import static android.net.wifi.WifiConfiguration.INVALID_NETWORK_ID; 20 21import com.android.settings.ProgressCategoryBase; 22import com.android.settings.R; 23import com.android.settings.SettingsPreferenceFragment; 24 25import android.app.Activity; 26import android.app.AlertDialog; 27import android.content.BroadcastReceiver; 28import android.content.Context; 29import android.content.DialogInterface; 30import android.content.Intent; 31import android.content.IntentFilter; 32import android.net.ConnectivityManager; 33import android.net.NetworkInfo; 34import android.net.NetworkInfo.DetailedState; 35import android.net.wifi.ScanResult; 36import android.net.wifi.SupplicantState; 37import android.net.wifi.WifiConfiguration; 38import android.net.wifi.WifiConfiguration.KeyMgmt; 39import android.net.wifi.WifiInfo; 40import android.net.wifi.WifiManager; 41import android.os.Bundle; 42import android.os.Handler; 43import android.os.Message; 44import android.preference.CheckBoxPreference; 45import android.preference.Preference; 46import android.preference.PreferenceScreen; 47import android.provider.Settings.Secure; 48import android.security.Credentials; 49import android.security.KeyStore; 50import android.view.ContextMenu; 51import android.view.ContextMenu.ContextMenuInfo; 52import android.view.Menu; 53import android.view.MenuInflater; 54import android.view.MenuItem; 55import android.view.View; 56import android.widget.AdapterView.AdapterContextMenuInfo; 57import android.widget.Toast; 58 59import java.util.ArrayList; 60import java.util.Collection; 61import java.util.List; 62import java.util.concurrent.atomic.AtomicBoolean; 63 64/** 65 * This currently provides three types of UI. 66 * 67 * Two are for phones with relatively small screens: "for SetupWizard" and "for usual Settings". 68 * Users just need to launch WifiSettings Activity as usual. The request will be appropriately 69 * handled by ActivityManager, and they will have appropriate look-and-feel with this fragment. 70 * 71 * Third type is for Setup Wizard with X-Large, landscape UI. Users need to launch 72 * {@link WifiSettingsForSetupWizardXL} Activity, which contains this fragment but also has 73 * other decorations specific to that screen. 74 */ 75public class WifiSettings extends SettingsPreferenceFragment 76 implements DialogInterface.OnClickListener { 77 private static final int MENU_ID_SCAN = Menu.FIRST; 78 private static final int MENU_ID_ADVANCED = Menu.FIRST + 1; 79 private static final int MENU_ID_CONNECT = Menu.FIRST + 2; 80 private static final int MENU_ID_FORGET = Menu.FIRST + 3; 81 private static final int MENU_ID_MODIFY = Menu.FIRST + 4; 82 83 private final IntentFilter mFilter; 84 private final BroadcastReceiver mReceiver; 85 private final Scanner mScanner; 86 87 private WifiManager mWifiManager; 88 private WifiEnabler mWifiEnabler; 89 private CheckBoxPreference mNotifyOpenNetworks; 90 private ProgressCategoryBase mAccessPoints; 91 private Preference mAddNetwork; 92 // An access point being editted is stored here. 93 private AccessPoint mSelectedAccessPoint; 94 private boolean mEdit; 95 96 private DetailedState mLastState; 97 private WifiInfo mLastInfo; 98 99 private AtomicBoolean mConnected = new AtomicBoolean(false); 100 101 private int mKeyStoreNetworkId = INVALID_NETWORK_ID; 102 103 private WifiDialog mDialog; 104 105 /* Used in Wifi Setup context */ 106 107 // this boolean extra specifies whether to disable the Next button when not connected 108 private static final String EXTRA_ENABLE_NEXT_ON_CONNECT = "wifi_enable_next_on_connect"; 109 110 // Indicates that this fragment is used as a part of Setup Wizard with XL screen settings. 111 // This fragment should show information which has been shown as Dialog in combined UI 112 // inside this fragment. 113 /* package */ static final String IN_XL_SETUP_WIZARD = "in_setup_wizard"; 114 115 // should Next button only be enabled when we have a connection? 116 private boolean mEnableNextOnConnection; 117 private boolean mInXlSetupWizard; 118 119 /* End of "used in Wifi Setup context" */ 120 121 public WifiSettings() { 122 mFilter = new IntentFilter(); 123 mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); 124 mFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION); 125 mFilter.addAction(WifiManager.NETWORK_IDS_CHANGED_ACTION); 126 mFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); 127 mFilter.addAction(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION); 128 mFilter.addAction(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION); 129 mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); 130 mFilter.addAction(WifiManager.RSSI_CHANGED_ACTION); 131 132 mReceiver = new BroadcastReceiver() { 133 @Override 134 public void onReceive(Context context, Intent intent) { 135 handleEvent(intent); 136 } 137 }; 138 139 mScanner = new Scanner(); 140 } 141 142 @Override 143 public void onActivityCreated(Bundle savedInstanceState) { 144 // We don't call super.onActivityCreated() here, since it assumes we already set up 145 // Preference (probably in onCreate()), while WifiSettings exceptionally set it up in 146 // this method. 147 148 mWifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); 149 150 final Activity activity = getActivity(); 151 final Intent intent = activity.getIntent(); 152 153 154 // if we're supposed to enable/disable the Next button based on our current connection 155 // state, start it off in the right state 156 mEnableNextOnConnection = intent.getBooleanExtra(EXTRA_ENABLE_NEXT_ON_CONNECT, false); 157 mInXlSetupWizard = intent.getBooleanExtra(IN_XL_SETUP_WIZARD, false); 158 159 if (mEnableNextOnConnection) { 160 if (mEnableNextOnConnection && hasNextButton()) { 161 final ConnectivityManager connectivity = (ConnectivityManager) 162 getActivity().getSystemService(Context.CONNECTIVITY_SERVICE); 163 if (connectivity != null) { 164 NetworkInfo info = connectivity.getNetworkInfo(ConnectivityManager.TYPE_WIFI); 165 changeNextButtonState(info.isConnected()); 166 } 167 } 168 } 169 170 if (mInXlSetupWizard) { 171 addPreferencesFromResource(R.xml.wifi_access_points_for_wifi_setup_xl); 172 } else if (intent.getBooleanExtra("only_access_points", false)) { 173 addPreferencesFromResource(R.xml.wifi_access_points); 174 } else { 175 addPreferencesFromResource(R.xml.wifi_settings); 176 mWifiEnabler = new WifiEnabler(activity, 177 (CheckBoxPreference) findPreference("enable_wifi")); 178 mNotifyOpenNetworks = 179 (CheckBoxPreference) findPreference("notify_open_networks"); 180 mNotifyOpenNetworks.setChecked(Secure.getInt(getContentResolver(), 181 Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0) == 1); 182 } 183 184 // After confirming PreferenceScreen is available, we call super. 185 super.onActivityCreated(savedInstanceState); 186 187 // This may be either ProgressCategory or AccessPointCategoryForXL. 188 final ProgressCategoryBase preference = 189 (ProgressCategoryBase) findPreference("access_points"); 190 mAccessPoints = preference; 191 mAccessPoints.setOrderingAsAdded(false); 192 mAddNetwork = findPreference("add_network"); 193 194 registerForContextMenu(getListView()); 195 setHasOptionsMenu(true); 196 } 197 198 @Override 199 public void onResume() { 200 super.onResume(); 201 if (mWifiEnabler != null) { 202 mWifiEnabler.resume(); 203 } 204 getActivity().registerReceiver(mReceiver, mFilter); 205 if (mKeyStoreNetworkId != INVALID_NETWORK_ID && 206 KeyStore.getInstance().test() == KeyStore.NO_ERROR) { 207 mWifiManager.connectNetwork(mKeyStoreNetworkId); 208 } 209 mKeyStoreNetworkId = INVALID_NETWORK_ID; 210 updateAccessPoints(); 211 } 212 213 @Override 214 public void onPause() { 215 super.onPause(); 216 if (mWifiEnabler != null) { 217 mWifiEnabler.pause(); 218 } 219 getActivity().unregisterReceiver(mReceiver); 220 mScanner.pause(); 221 if (mDialog != null) { 222 mDialog.dismiss(); 223 mDialog = null; 224 } 225 } 226 227 @Override 228 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { 229 // We don't want menus in Setup Wizard XL. 230 if (!mInXlSetupWizard) { 231 menu.add(Menu.NONE, MENU_ID_SCAN, 0, R.string.wifi_menu_scan) 232 .setIcon(R.drawable.ic_menu_scan_network); 233 menu.add(Menu.NONE, MENU_ID_ADVANCED, 0, R.string.wifi_menu_advanced) 234 .setIcon(android.R.drawable.ic_menu_manage); 235 } 236 super.onCreateOptionsMenu(menu, inflater); 237 } 238 239 @Override 240 public boolean onOptionsItemSelected(MenuItem item) { 241 switch (item.getItemId()) { 242 case MENU_ID_SCAN: 243 if (mWifiManager.isWifiEnabled()) { 244 mScanner.forceScan(); 245 } 246 return true; 247 case MENU_ID_ADVANCED: 248 startFragment(this, AdvancedSettings.class.getCanonicalName(), -1, null); 249 return true; 250 } 251 return super.onOptionsItemSelected(item); 252 } 253 254 @Override 255 public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo info) { 256 if (info instanceof AdapterContextMenuInfo) { 257 Preference preference = (Preference) getListView().getItemAtPosition( 258 ((AdapterContextMenuInfo) info).position); 259 260 if (preference instanceof AccessPoint) { 261 mSelectedAccessPoint = (AccessPoint) preference; 262 menu.setHeaderTitle(mSelectedAccessPoint.ssid); 263 if (mSelectedAccessPoint.getLevel() != -1 264 && mSelectedAccessPoint.getState() == null) { 265 menu.add(Menu.NONE, MENU_ID_CONNECT, 0, R.string.wifi_menu_connect); 266 } 267 if (mSelectedAccessPoint.networkId != INVALID_NETWORK_ID) { 268 menu.add(Menu.NONE, MENU_ID_FORGET, 0, R.string.wifi_menu_forget); 269 menu.add(Menu.NONE, MENU_ID_MODIFY, 0, R.string.wifi_menu_modify); 270 } 271 } 272 } 273 } 274 275 @Override 276 public boolean onContextItemSelected(MenuItem item) { 277 if (mSelectedAccessPoint == null) { 278 return super.onContextItemSelected(item); 279 } 280 switch (item.getItemId()) { 281 case MENU_ID_CONNECT: { 282 if (mSelectedAccessPoint.networkId != INVALID_NETWORK_ID) { 283 if (!requireKeyStore(mSelectedAccessPoint.getConfig())) { 284 mWifiManager.connectNetwork(mSelectedAccessPoint.networkId); 285 } 286 } else if (mSelectedAccessPoint.security == AccessPoint.SECURITY_NONE) { 287 // Shortcut for open networks. 288 WifiConfiguration config = new WifiConfiguration(); 289 config.SSID = AccessPoint.convertToQuotedString(mSelectedAccessPoint.ssid); 290 config.allowedKeyManagement.set(KeyMgmt.NONE); 291 mWifiManager.connectNetwork(config); 292 } else { 293 showConfigUi(mSelectedAccessPoint, true); 294 } 295 return true; 296 } 297 case MENU_ID_FORGET: { 298 mWifiManager.forgetNetwork(mSelectedAccessPoint.networkId); 299 return true; 300 } 301 case MENU_ID_MODIFY: { 302 showConfigUi(mSelectedAccessPoint, true); 303 return true; 304 } 305 } 306 return super.onContextItemSelected(item); 307 } 308 309 @Override 310 public boolean onPreferenceTreeClick(PreferenceScreen screen, Preference preference) { 311 if (preference instanceof AccessPoint) { 312 mSelectedAccessPoint = (AccessPoint) preference; 313 showConfigUi(mSelectedAccessPoint, false); 314 } else if (preference == mAddNetwork) { 315 onAddNetworkPressed(); 316 } else if (preference == mNotifyOpenNetworks) { 317 Secure.putInt(getContentResolver(), 318 Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 319 mNotifyOpenNetworks.isChecked() ? 1 : 0); 320 } else { 321 return super.onPreferenceTreeClick(screen, preference); 322 } 323 return true; 324 } 325 326 /** 327 * Shows an appropriate Wifi configuration component. 328 * Called when a user clicks "Add network" preference or one of available networks is selected. 329 */ 330 private void showConfigUi(AccessPoint accessPoint, boolean edit) { 331 mEdit = edit; 332 if (mInXlSetupWizard) { 333 ((WifiSettingsForSetupWizardXL)getActivity()).showConfigUi(accessPoint, edit); 334 } else { 335 showDialog(accessPoint, edit); 336 } 337 } 338 339 private void showDialog(AccessPoint accessPoint, boolean edit) { 340 if (mDialog != null) { 341 mDialog.dismiss(); 342 } 343 mDialog = new WifiDialog(getActivity(), this, accessPoint, edit); 344 mDialog.show(); 345 } 346 347 /** 348 * Called from {@link WifiSettingsForSetupWizardXL} when the object wants to open 349 * {@link WifiDialog} anyway, though usually it prepares its own simplified UI for 350 * configuring a wifi network. 351 */ 352 /* package */ void showDialogForSelectedPreference() { 353 showDialog(mSelectedAccessPoint, mEdit); 354 } 355 356 private boolean requireKeyStore(WifiConfiguration config) { 357 if (WifiConfigController.requireKeyStore(config) && 358 KeyStore.getInstance().test() != KeyStore.NO_ERROR) { 359 mKeyStoreNetworkId = config.networkId; 360 Credentials.getInstance().unlock(getActivity()); 361 return true; 362 } 363 return false; 364 } 365 366 /** 367 * Shows the latest access points available with supplimental information like 368 * the strength of network and the security for it. 369 */ 370 private void updateAccessPoints() { 371 mAccessPoints.removeAll(); 372 373 // AccessPoints are automatically sorted with TreeSet. 374 final Collection<AccessPoint> accessPoints = constructAccessPoints(); 375 if (mInXlSetupWizard) { 376 ((WifiSettingsForSetupWizardXL)getActivity()).onAccessPointsUpdated( 377 mAccessPoints, accessPoints); 378 } else { 379 for (AccessPoint accessPoint : accessPoints) { 380 mAccessPoints.addPreference(accessPoint); 381 } 382 } 383 } 384 385 private Collection<AccessPoint> constructAccessPoints() { 386 Collection<AccessPoint> accessPoints = new ArrayList<AccessPoint>(); 387 388 final List<WifiConfiguration> configs = mWifiManager.getConfiguredNetworks(); 389 if (configs != null) { 390 for (WifiConfiguration config : configs) { 391 AccessPoint accessPoint = new AccessPoint(getActivity(), config); 392 accessPoint.update(mLastInfo, mLastState); 393 accessPoints.add(accessPoint); 394 } 395 } 396 397 final List<ScanResult> results = mWifiManager.getScanResults(); 398 if (results != null) { 399 for (ScanResult result : results) { 400 // Ignore hidden and ad-hoc networks. 401 if (result.SSID == null || result.SSID.length() == 0 || 402 result.capabilities.contains("[IBSS]")) { 403 continue; 404 } 405 406 boolean found = false; 407 for (AccessPoint accessPoint : accessPoints) { 408 if (accessPoint.update(result)) { 409 found = true; 410 } 411 } 412 if (!found) { 413 accessPoints.add(new AccessPoint(getActivity(), result)); 414 } 415 } 416 } 417 418 return accessPoints; 419 } 420 421 private void handleEvent(Intent intent) { 422 String action = intent.getAction(); 423 if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(action)) { 424 updateWifiState(intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 425 WifiManager.WIFI_STATE_UNKNOWN)); 426 } else if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(action) || 427 WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION.equals(action) || 428 WifiManager.LINK_CONFIGURATION_CHANGED_ACTION.equals(action)) { 429 updateAccessPoints(); 430 } else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(action)) { 431 //Ignore supplicant state changes when network is connected 432 //TODO: we should deprecate SUPPLICANT_STATE_CHANGED_ACTION and 433 //introduce a broadcast that combines the supplicant and network 434 //network state change events so the apps dont have to worry about 435 //ignoring supplicant state change when network is connected 436 //to get more fine grained information. 437 if (!mConnected.get()) { 438 updateConnectionState(WifiInfo.getDetailedStateOf((SupplicantState) 439 intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE))); 440 } 441 } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) { 442 NetworkInfo info = (NetworkInfo) intent.getParcelableExtra( 443 WifiManager.EXTRA_NETWORK_INFO); 444 mConnected.set(info.isConnected()); 445 changeNextButtonState(info.isConnected()); 446 updateConnectionState(info.getDetailedState()); 447 } else if (WifiManager.RSSI_CHANGED_ACTION.equals(action)) { 448 updateConnectionState(null); 449 } 450 } 451 452 private void updateConnectionState(DetailedState state) { 453 /* sticky broadcasts can call this when wifi is disabled */ 454 if (!mWifiManager.isWifiEnabled()) { 455 mScanner.pause(); 456 return; 457 } 458 459 if (state == DetailedState.OBTAINING_IPADDR) { 460 mScanner.pause(); 461 } else { 462 mScanner.resume(); 463 } 464 465 mLastInfo = mWifiManager.getConnectionInfo(); 466 if (state != null) { 467 mLastState = state; 468 } 469 470 for (int i = mAccessPoints.getPreferenceCount() - 1; i >= 0; --i) { 471 // Maybe there's a WifiConfigPreference 472 Preference preference = mAccessPoints.getPreference(i); 473 if (preference instanceof AccessPoint) { 474 final AccessPoint accessPoint = (AccessPoint) preference; 475 accessPoint.update(mLastInfo, mLastState); 476 } 477 } 478 479 if (mInXlSetupWizard) { 480 ((WifiSettingsForSetupWizardXL)getActivity()).updateConnectionState(mLastState); 481 } 482 } 483 484 private void updateWifiState(int state) { 485 if (state == WifiManager.WIFI_STATE_ENABLED) { 486 mScanner.resume(); 487 } else { 488 mScanner.pause(); 489 mAccessPoints.removeAll(); 490 } 491 } 492 493 private class Scanner extends Handler { 494 private int mRetry = 0; 495 496 void resume() { 497 if (!hasMessages(0)) { 498 sendEmptyMessage(0); 499 } 500 } 501 502 void forceScan() { 503 sendEmptyMessage(0); 504 } 505 506 void pause() { 507 mRetry = 0; 508 mAccessPoints.setProgress(false); 509 removeMessages(0); 510 } 511 512 @Override 513 public void handleMessage(Message message) { 514 if (mWifiManager.startScanActive()) { 515 mRetry = 0; 516 } else if (++mRetry >= 3) { 517 mRetry = 0; 518 Toast.makeText(getActivity(), R.string.wifi_fail_to_scan, 519 Toast.LENGTH_LONG).show(); 520 return; 521 } 522 mAccessPoints.setProgress(mRetry != 0); 523 // Combo scans can take 5-6s to complete. Increase interval to 10s. 524 sendEmptyMessageDelayed(0, 10000); 525 } 526 } 527 528 /** 529 * Renames/replaces "Next" button when appropriate. "Next" button usually exists in 530 * Wifi setup screens, not in usual wifi settings screen. 531 * 532 * @param connected true when the device is connected to a wifi network. 533 */ 534 private void changeNextButtonState(boolean connected) { 535 if (mInXlSetupWizard) { 536 ((WifiSettingsForSetupWizardXL)getActivity()).changeNextButtonState(connected); 537 } else if (mEnableNextOnConnection && hasNextButton()) { 538 getNextButton().setEnabled(connected); 539 } 540 } 541 542 public void onClick(DialogInterface dialogInterface, int button) { 543 if (mInXlSetupWizard) { 544 if (button == WifiDialog.BUTTON_FORGET && mSelectedAccessPoint != null) { 545 ((WifiSettingsForSetupWizardXL)getActivity()).onForgetButtonPressed(); 546 } else if (button == WifiDialog.BUTTON_SUBMIT) { 547 ((WifiSettingsForSetupWizardXL)getActivity()).onConnectButtonPressed(); 548 } 549 } else { 550 if (button == WifiDialog.BUTTON_FORGET && mSelectedAccessPoint != null) { 551 forget(); 552 } else if (button == WifiDialog.BUTTON_SUBMIT) { 553 submit(mDialog.getController()); 554 } 555 } 556 557 } 558 559 /* package */ void submit(WifiConfigController configController) { 560 switch(configController.chosenNetworkSetupMethod()) { 561 case WifiConfigController.WPS_PBC: 562 mWifiManager.startWpsPbc(mSelectedAccessPoint.bssid); 563 break; 564 case WifiConfigController.WPS_PIN_FROM_ACCESS_POINT: 565 int apPin = configController.getWpsPin(); 566 mWifiManager.startWpsWithPinFromAccessPoint(mSelectedAccessPoint.bssid, apPin); 567 break; 568 case WifiConfigController.WPS_PIN_FROM_DEVICE: 569 int pin = mWifiManager.startWpsWithPinFromDevice(mSelectedAccessPoint.bssid); 570 new AlertDialog.Builder(getActivity()) 571 .setTitle(R.string.wifi_wps_pin_method_configuration) 572 .setMessage(getResources().getString(R.string.wifi_wps_pin_output, pin)) 573 .setPositiveButton(android.R.string.ok, null) 574 .show(); 575 break; 576 case WifiConfigController.MANUAL: 577 final WifiConfiguration config = configController.getConfig(); 578 579 if (config == null) { 580 if (mSelectedAccessPoint != null 581 && !requireKeyStore(mSelectedAccessPoint.getConfig()) 582 && mSelectedAccessPoint.networkId != INVALID_NETWORK_ID) { 583 mWifiManager.connectNetwork(mSelectedAccessPoint.networkId); 584 } 585 } else if (config.networkId != INVALID_NETWORK_ID) { 586 if (mSelectedAccessPoint != null) { 587 mWifiManager.saveNetwork(config); 588 } 589 } else { 590 if (configController.isEdit() || requireKeyStore(config)) { 591 mWifiManager.saveNetwork(config); 592 } else { 593 mWifiManager.connectNetwork(config); 594 } 595 } 596 break; 597 } 598 599 if (mWifiManager.isWifiEnabled()) { 600 mScanner.resume(); 601 } 602 updateAccessPoints(); 603 } 604 605 /* package */ void forget() { 606 mWifiManager.forgetNetwork(mSelectedAccessPoint.networkId); 607 608 if (mWifiManager.isWifiEnabled()) { 609 mScanner.resume(); 610 } 611 updateAccessPoints(); 612 613 // We need to rename/replace "Next" button in wifi setup context. 614 changeNextButtonState(false); 615 } 616 617 /** 618 * Refreshes acccess points and ask Wifi module to scan networks again. 619 */ 620 /* package */ void refreshAccessPoints() { 621 if (mWifiManager.isWifiEnabled()) { 622 mScanner.resume(); 623 } 624 625 mAccessPoints.removeAll(); 626 } 627 628 /** 629 * Called when "add network" button is pressed. 630 */ 631 /* package */ void onAddNetworkPressed() { 632 // No exact access point is selected. 633 mSelectedAccessPoint = null; 634 showConfigUi(null, true); 635 } 636 637 /* package */ int getAccessPointsCount() { 638 if (mAccessPoints != null) { 639 return mAccessPoints.getPreferenceCount(); 640 } else { 641 return 0; 642 } 643 } 644 645 /** 646 * Requests wifi module to pause wifi scan. May be ignored when the module is disabled. 647 */ 648 /* package */ void pauseWifiScan() { 649 if (mWifiManager.isWifiEnabled()) { 650 mScanner.pause(); 651 } 652 } 653 654 /** 655 * Requests wifi module to resume wifi scan. May be ignored when the module is disabled. 656 */ 657 /* package */ void resumeWifiScan() { 658 if (mWifiManager.isWifiEnabled()) { 659 mScanner.resume(); 660 } 661 } 662} 663