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