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