Home | History | Annotate | Download | only in options
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "chrome/browser/chromeos/options/wifi_config_view.h"
      6 
      7 #include "base/command_line.h"  // TODO(jamescook): Remove.
      8 #include "base/string_util.h"
      9 #include "base/utf_string_conversions.h"
     10 #include "chrome/browser/chromeos/cros/cros_library.h"
     11 #include "chrome/browser/chromeos/login/user_manager.h"
     12 #include "chrome/browser/chromeos/options/wifi_config_model.h"
     13 #include "chrome/common/chrome_switches.h"  // TODO(jamescook): Remove.
     14 #include "grit/chromium_strings.h"
     15 #include "grit/generated_resources.h"
     16 #include "grit/locale_settings.h"
     17 #include "grit/theme_resources.h"
     18 #include "ui/base/l10n/l10n_util.h"
     19 #include "ui/base/resource/resource_bundle.h"
     20 #include "views/controls/button/checkbox.h"
     21 #include "views/controls/button/image_button.h"
     22 #include "views/controls/button/native_button.h"
     23 #include "views/controls/label.h"
     24 #include "views/controls/textfield/textfield.h"
     25 #include "views/layout/grid_layout.h"
     26 #include "views/layout/layout_constants.h"
     27 #include "views/window/window.h"
     28 
     29 namespace chromeos {
     30 
     31 namespace {
     32 
     33 enum SecurityComboboxIndex {
     34   SECURITY_INDEX_NONE  = 0,
     35   SECURITY_INDEX_WEP   = 1,
     36   SECURITY_INDEX_WPA   = 2,
     37   SECURITY_INDEX_RSN   = 3,
     38   SECURITY_INDEX_COUNT = 4
     39 };
     40 
     41 class SecurityComboboxModel : public ui::ComboboxModel {
     42  public:
     43   SecurityComboboxModel() {}
     44   virtual ~SecurityComboboxModel() {}
     45   virtual int GetItemCount() {
     46     return SECURITY_INDEX_COUNT;
     47   }
     48   virtual string16 GetItemAt(int index) {
     49     if (index == SECURITY_INDEX_NONE)
     50       return l10n_util::GetStringUTF16(
     51           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY_NONE);
     52     else if (index == SECURITY_INDEX_WEP)
     53       return l10n_util::GetStringUTF16(
     54           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY_WEP);
     55     else if (index == SECURITY_INDEX_WPA)
     56       return l10n_util::GetStringUTF16(
     57           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY_WPA);
     58     else if (index == SECURITY_INDEX_RSN)
     59       return l10n_util::GetStringUTF16(
     60           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY_RSN);
     61     NOTREACHED();
     62     return string16();
     63   }
     64  private:
     65   DISALLOW_COPY_AND_ASSIGN(SecurityComboboxModel);
     66 };
     67 
     68 // TODO(jamescook):  For M12 we only expose PEAP and EAP-TTLS.  Later, when
     69 // when we support all methods by default, order this list to be alphabetical.
     70 enum EAPMethodComboboxIndex {
     71   EAP_METHOD_INDEX_NONE  = 0,
     72   EAP_METHOD_INDEX_PEAP  = 1,
     73   EAP_METHOD_INDEX_TTLS  = 2,  // By default we support up to here.
     74   EAP_METHOD_INDEX_TLS   = 3,
     75   EAP_METHOD_INDEX_LEAP  = 4,  // Flag "--enable-all-eap" allows up to here.
     76   EAP_METHOD_INDEX_COUNT = 5
     77 };
     78 
     79 class EAPMethodComboboxModel : public ui::ComboboxModel {
     80  public:
     81   EAPMethodComboboxModel() {}
     82   virtual ~EAPMethodComboboxModel() {}
     83   virtual int GetItemCount() {
     84     // TODO(jamescook):  For M12 we only expose PEAP and EAP-TTLS by default.
     85     // Remove this switch when all methods are supported.
     86     if (!CommandLine::ForCurrentProcess()->HasSwitch(
     87         switches::kEnableExperimentalEap))
     88       return EAP_METHOD_INDEX_TTLS + 1;
     89     return EAP_METHOD_INDEX_COUNT;
     90   }
     91   virtual string16 GetItemAt(int index) {
     92     if (index == EAP_METHOD_INDEX_NONE)
     93       return l10n_util::GetStringUTF16(
     94           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_NONE);
     95     else if (index == EAP_METHOD_INDEX_PEAP)
     96       return l10n_util::GetStringUTF16(
     97           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_PEAP);
     98     else if (index == EAP_METHOD_INDEX_TLS)
     99       return l10n_util::GetStringUTF16(
    100           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_TLS);
    101     else if (index == EAP_METHOD_INDEX_TTLS)
    102       return l10n_util::GetStringUTF16(
    103           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_TTLS);
    104     else if (index == EAP_METHOD_INDEX_LEAP)
    105       return l10n_util::GetStringUTF16(
    106           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_LEAP);
    107     NOTREACHED();
    108     return string16();
    109   }
    110  private:
    111   DISALLOW_COPY_AND_ASSIGN(EAPMethodComboboxModel);
    112 };
    113 
    114 enum Phase2AuthComboboxIndex {
    115   PHASE_2_AUTH_INDEX_AUTO     = 0, // LEAP, EAP-TLS have only this auth.
    116   PHASE_2_AUTH_INDEX_MD5      = 1,
    117   PHASE_2_AUTH_INDEX_MSCHAPV2 = 2, // PEAP has up to this auth.
    118   PHASE_2_AUTH_INDEX_MSCHAP   = 3,
    119   PHASE_2_AUTH_INDEX_PAP      = 4,
    120   PHASE_2_AUTH_INDEX_CHAP     = 5, // EAP-TTLS has up to this auth.
    121   PHASE_2_AUTH_INDEX_COUNT    = 6
    122 };
    123 
    124 class Phase2AuthComboboxModel : public ui::ComboboxModel {
    125  public:
    126   explicit Phase2AuthComboboxModel(views::Combobox* eap_method_combobox)
    127       : eap_method_combobox_(eap_method_combobox) {}
    128   virtual ~Phase2AuthComboboxModel() {}
    129   virtual int GetItemCount() {
    130     switch (eap_method_combobox_->selected_item()) {
    131       case EAP_METHOD_INDEX_NONE:
    132       case EAP_METHOD_INDEX_TLS:
    133       case EAP_METHOD_INDEX_LEAP:
    134         return PHASE_2_AUTH_INDEX_AUTO + 1;
    135       case EAP_METHOD_INDEX_PEAP:
    136         return PHASE_2_AUTH_INDEX_MSCHAPV2 + 1;
    137       case EAP_METHOD_INDEX_TTLS:
    138         return PHASE_2_AUTH_INDEX_CHAP + 1;
    139     }
    140     NOTREACHED();
    141     return 0;
    142   }
    143   virtual string16 GetItemAt(int index) {
    144     if (index == PHASE_2_AUTH_INDEX_AUTO)
    145       return l10n_util::GetStringUTF16(
    146           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_AUTO);
    147     else if (index == PHASE_2_AUTH_INDEX_MD5)
    148       return l10n_util::GetStringUTF16(
    149           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_MD5);
    150     else if (index == PHASE_2_AUTH_INDEX_MSCHAPV2)
    151       return l10n_util::GetStringUTF16(
    152           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_MSCHAPV2);
    153     else if (index == PHASE_2_AUTH_INDEX_MSCHAP)
    154       return l10n_util::GetStringUTF16(
    155           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_MSCHAP);
    156     else if (index == PHASE_2_AUTH_INDEX_PAP)
    157       return l10n_util::GetStringUTF16(
    158           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_PAP);
    159     else if (index == PHASE_2_AUTH_INDEX_CHAP)
    160       return l10n_util::GetStringUTF16(
    161           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_CHAP);
    162     NOTREACHED();
    163     return string16();
    164   }
    165  private:
    166   views::Combobox* eap_method_combobox_;
    167   DISALLOW_COPY_AND_ASSIGN(Phase2AuthComboboxModel);
    168 };
    169 
    170 // Combobox that supports a preferred width.  Used by Server CA combobox
    171 // because the strings inside it are too wide.
    172 class ComboboxWithWidth : public views::Combobox {
    173  public:
    174   ComboboxWithWidth(ui::ComboboxModel* model, int width)
    175       : Combobox(model),
    176         width_(width) {
    177   }
    178   virtual ~ComboboxWithWidth() {}
    179   virtual gfx::Size GetPreferredSize() OVERRIDE {
    180     gfx::Size size = Combobox::GetPreferredSize();
    181     size.set_width(width_);
    182     return size;
    183   }
    184  private:
    185   int width_;
    186   DISALLOW_COPY_AND_ASSIGN(ComboboxWithWidth);
    187 };
    188 
    189 class ServerCACertComboboxModel : public ui::ComboboxModel {
    190  public:
    191   explicit ServerCACertComboboxModel(WifiConfigModel* wifi_config_model)
    192       : wifi_config_model_(wifi_config_model) {
    193   }
    194   virtual ~ServerCACertComboboxModel() {}
    195   virtual int GetItemCount() {
    196     // First "Default", then the certs, then "Do not check".
    197     return wifi_config_model_->GetServerCaCertCount() + 2;
    198   }
    199   virtual string16 GetItemAt(int combo_index) {
    200     if (combo_index == 0)
    201       return l10n_util::GetStringUTF16(
    202           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA_DEFAULT);
    203     if (combo_index == GetItemCount() - 1)
    204       return l10n_util::GetStringUTF16(
    205           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA_DO_NOT_CHECK);
    206     int cert_index = combo_index - 1;
    207     return wifi_config_model_->GetServerCaCertName(cert_index);
    208   }
    209  private:
    210   WifiConfigModel* wifi_config_model_;
    211   DISALLOW_COPY_AND_ASSIGN(ServerCACertComboboxModel);
    212 };
    213 
    214 class ClientCertComboboxModel : public ui::ComboboxModel {
    215  public:
    216   explicit ClientCertComboboxModel(WifiConfigModel* wifi_config_model)
    217       : wifi_config_model_(wifi_config_model) {
    218   }
    219   virtual ~ClientCertComboboxModel() {}
    220   virtual int GetItemCount() {
    221     // One initial item "None", then the certs.
    222     return 1 + wifi_config_model_->GetUserCertCount();
    223   }
    224   virtual string16 GetItemAt(int combo_index) {
    225     if (combo_index == 0)
    226       return l10n_util::GetStringUTF16(
    227           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_NONE);
    228     int cert_index = combo_index - 1;
    229     return wifi_config_model_->GetUserCertName(cert_index);
    230   }
    231  private:
    232   WifiConfigModel* wifi_config_model_;
    233   DISALLOW_COPY_AND_ASSIGN(ClientCertComboboxModel);
    234 };
    235 
    236 }  // namespace
    237 
    238 WifiConfigView::WifiConfigView(NetworkConfigView* parent, WifiNetwork* wifi)
    239     : ChildNetworkConfigView(parent, wifi),
    240       wifi_config_model_(new WifiConfigModel()),
    241       is_8021x_(false),
    242       ssid_textfield_(NULL),
    243       eap_method_combobox_(NULL),
    244       phase_2_auth_label_(NULL),
    245       phase_2_auth_combobox_(NULL),
    246       client_cert_label_(NULL),
    247       client_cert_combobox_(NULL),
    248       server_ca_cert_label_(NULL),
    249       server_ca_cert_combobox_(NULL),
    250       identity_label_(NULL),
    251       identity_textfield_(NULL),
    252       identity_anonymous_label_(NULL),
    253       identity_anonymous_textfield_(NULL),
    254       save_credentials_checkbox_(NULL),
    255       security_combobox_(NULL),
    256       passphrase_label_(NULL),
    257       passphrase_textfield_(NULL),
    258       passphrase_visible_button_(NULL),
    259       error_label_(NULL) {
    260   Init(wifi);
    261 }
    262 
    263 WifiConfigView::WifiConfigView(NetworkConfigView* parent)
    264     : ChildNetworkConfigView(parent),
    265       wifi_config_model_(new WifiConfigModel()),
    266       is_8021x_(false),
    267       ssid_textfield_(NULL),
    268       eap_method_combobox_(NULL),
    269       phase_2_auth_label_(NULL),
    270       phase_2_auth_combobox_(NULL),
    271       client_cert_label_(NULL),
    272       client_cert_combobox_(NULL),
    273       server_ca_cert_label_(NULL),
    274       server_ca_cert_combobox_(NULL),
    275       identity_label_(NULL),
    276       identity_textfield_(NULL),
    277       identity_anonymous_label_(NULL),
    278       identity_anonymous_textfield_(NULL),
    279       save_credentials_checkbox_(NULL),
    280       security_combobox_(NULL),
    281       passphrase_label_(NULL),
    282       passphrase_textfield_(NULL),
    283       passphrase_visible_button_(NULL),
    284       error_label_(NULL) {
    285   Init(NULL);
    286 }
    287 
    288 WifiConfigView::~WifiConfigView() {
    289 }
    290 
    291 string16 WifiConfigView::GetTitle() {
    292   return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_JOIN_WIFI_NETWORKS);
    293 }
    294 
    295 bool WifiConfigView::CanLogin() {
    296   static const size_t kMinWirelessPasswordLen = 5;
    297 
    298   if (service_path_.empty()) {
    299     // Enforce ssid is non empty.
    300     if (GetSSID().empty())
    301       return false;
    302 
    303     // If security is not none, also enforce passphrase is non empty.
    304     if (security_combobox_->selected_item() != SECURITY_INDEX_NONE &&
    305         passphrase_textfield_->text().length() < kMinWirelessPasswordLen)
    306       return false;
    307   } else {
    308     if (is_8021x_) {
    309       // Make sure the EAP method is set
    310       if (eap_method_combobox_->selected_item() == EAP_METHOD_INDEX_NONE)
    311         return false;
    312     } else {
    313       // if the network requires a passphrase, make sure it is the right length.
    314       if (passphrase_textfield_ != NULL &&
    315           passphrase_textfield_->text().length() < kMinWirelessPasswordLen)
    316         return false;
    317     }
    318   }
    319   return true;
    320 }
    321 
    322 void WifiConfigView::UpdateDialogButtons() {
    323   parent_->GetDialogClientView()->UpdateDialogButtons();
    324 }
    325 
    326 void WifiConfigView::RefreshEAPFields() {
    327   int selected = eap_method_combobox_->selected_item();
    328 
    329   // If EAP method changes, the phase 2 auth choices may have changed also.
    330   phase_2_auth_combobox_->ModelChanged();
    331   phase_2_auth_combobox_->SetSelectedItem(0);
    332   phase_2_auth_combobox_->SetEnabled(
    333       phase_2_auth_combobox_->model()->GetItemCount() > 1);
    334   phase_2_auth_label_->SetEnabled(phase_2_auth_combobox_->IsEnabled());
    335 
    336   // No password for EAP-TLS
    337   passphrase_textfield_->SetEnabled(selected != EAP_METHOD_INDEX_NONE &&
    338                                     selected != EAP_METHOD_INDEX_TLS);
    339   passphrase_label_->SetEnabled(passphrase_textfield_->IsEnabled());
    340   if (!passphrase_textfield_->IsEnabled())
    341     passphrase_textfield_->SetText(string16());
    342 
    343   // Client certs only for EAP-TLS
    344   if (client_cert_combobox_) {
    345     client_cert_combobox_->SetEnabled(selected == EAP_METHOD_INDEX_TLS);
    346     client_cert_label_->SetEnabled(client_cert_combobox_->IsEnabled());
    347   }
    348 
    349   // No server CA certs for LEAP
    350   server_ca_cert_combobox_->SetEnabled(selected != EAP_METHOD_INDEX_NONE &&
    351                                        selected != EAP_METHOD_INDEX_LEAP);
    352   server_ca_cert_label_->SetEnabled(server_ca_cert_combobox_->IsEnabled());
    353 
    354   // No anonymous identity if no phase 2 auth.
    355   identity_anonymous_textfield_->SetEnabled(
    356       phase_2_auth_combobox_->IsEnabled());
    357   identity_anonymous_label_->SetEnabled(
    358       identity_anonymous_textfield_->IsEnabled());
    359   if (!identity_anonymous_textfield_->IsEnabled())
    360     identity_anonymous_textfield_->SetText(string16());
    361 }
    362 
    363 void WifiConfigView::UpdateErrorLabel() {
    364   std::string error_msg;
    365   if (!service_path_.empty()) {
    366     NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
    367     const WifiNetwork* wifi = cros->FindWifiNetworkByPath(service_path_);
    368     if (wifi && wifi->failed()) {
    369       bool passphrase_empty = wifi->GetPassphrase().empty();
    370       switch (wifi->error()) {
    371         case ERROR_BAD_PASSPHRASE:
    372           if (!passphrase_empty) {
    373             error_msg = l10n_util::GetStringUTF8(
    374                 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_BAD_PASSPHRASE);
    375           }
    376           break;
    377         case ERROR_BAD_WEPKEY:
    378           if (!passphrase_empty) {
    379             error_msg = l10n_util::GetStringUTF8(
    380                 IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_BAD_WEPKEY);
    381           }
    382           break;
    383         default:
    384           error_msg = wifi->GetErrorString();
    385           break;
    386       }
    387     }
    388   }
    389   if (!error_msg.empty()) {
    390     error_label_->SetText(UTF8ToWide(error_msg));
    391     error_label_->SetVisible(true);
    392   } else {
    393     error_label_->SetVisible(false);
    394   }
    395 }
    396 
    397 void WifiConfigView::ContentsChanged(views::Textfield* sender,
    398                                      const string16& new_contents) {
    399   UpdateDialogButtons();
    400 }
    401 
    402 bool WifiConfigView::HandleKeyEvent(views::Textfield* sender,
    403                                     const views::KeyEvent& key_event) {
    404   if (sender == passphrase_textfield_ &&
    405       key_event.key_code() == ui::VKEY_RETURN) {
    406     parent_->GetDialogClientView()->AcceptWindow();
    407   }
    408   return false;
    409 }
    410 
    411 void WifiConfigView::ButtonPressed(views::Button* sender,
    412                                    const views::Event& event) {
    413   if (sender == passphrase_visible_button_) {
    414     if (passphrase_textfield_)
    415       passphrase_textfield_->SetPassword(!passphrase_textfield_->IsPassword());
    416   } else {
    417     NOTREACHED();
    418   }
    419 }
    420 
    421 void WifiConfigView::ItemChanged(views::Combobox* combo_box,
    422                                  int prev_index, int new_index) {
    423   if (new_index == prev_index)
    424     return;
    425   if (combo_box == security_combobox_) {
    426     // If changed to no security, then disable combobox and clear it.
    427     // Otherwise, enable it. Also, update can login.
    428     if (new_index == SECURITY_INDEX_NONE) {
    429       passphrase_label_->SetEnabled(false);
    430       passphrase_textfield_->SetEnabled(false);
    431       passphrase_textfield_->SetText(string16());
    432     } else {
    433       passphrase_label_->SetEnabled(true);
    434       passphrase_textfield_->SetEnabled(true);
    435     }
    436   } else if (combo_box == eap_method_combobox_) {
    437     RefreshEAPFields();
    438   }
    439   UpdateDialogButtons();
    440 }
    441 
    442 bool WifiConfigView::Login() {
    443   NetworkLibrary* cros = CrosLibrary::Get()->GetNetworkLibrary();
    444   if (service_path_.empty()) {
    445     ConnectionSecurity sec = SECURITY_UNKNOWN;
    446     switch (security_combobox_->selected_item()) {
    447       case SECURITY_INDEX_NONE:
    448         sec = SECURITY_NONE;
    449         break;
    450       case SECURITY_INDEX_WEP:
    451         sec = SECURITY_WEP;
    452         break;
    453       case SECURITY_INDEX_WPA:
    454         sec = SECURITY_WPA;
    455         break;
    456       case SECURITY_INDEX_RSN:
    457         sec = SECURITY_RSN;
    458         break;
    459     }
    460     cros->ConnectToWifiNetwork(
    461         sec, GetSSID(), GetPassphrase(), std::string(), std::string());
    462   } else {
    463     WifiNetwork* wifi = cros->FindWifiNetworkByPath(service_path_);
    464     if (!wifi) {
    465       // Flimflam no longer knows about this wifi network (edge case).
    466       // TODO(stevenjb): Add a notification (chromium-os13225).
    467       LOG(WARNING) << "Wifi network: " << service_path_ << " no longer exists.";
    468       return true;
    469     }
    470     if (is_8021x_) {
    471       // EAP method
    472       EAPMethod method = EAP_METHOD_UNKNOWN;
    473       switch (eap_method_combobox_->selected_item()) {
    474         case EAP_METHOD_INDEX_PEAP:
    475           method = EAP_METHOD_PEAP;
    476           break;
    477         case EAP_METHOD_INDEX_TLS:
    478           method = EAP_METHOD_TLS;
    479           break;
    480         case EAP_METHOD_INDEX_TTLS:
    481           method = EAP_METHOD_TTLS;
    482           break;
    483         case EAP_METHOD_INDEX_LEAP:
    484           method = EAP_METHOD_LEAP;
    485           break;
    486       }
    487       DCHECK(method != EAP_METHOD_UNKNOWN);
    488       wifi->SetEAPMethod(method);
    489 
    490       // Phase 2 authentication
    491       if (phase_2_auth_combobox_->IsEnabled()) {
    492         EAPPhase2Auth auth = EAP_PHASE_2_AUTH_AUTO;
    493         switch (phase_2_auth_combobox_->selected_item()) {
    494           case PHASE_2_AUTH_INDEX_MD5:
    495             auth = EAP_PHASE_2_AUTH_MD5;
    496             break;
    497           case PHASE_2_AUTH_INDEX_MSCHAPV2:
    498             auth = EAP_PHASE_2_AUTH_MSCHAPV2;
    499             break;
    500           case PHASE_2_AUTH_INDEX_MSCHAP:
    501             auth = EAP_PHASE_2_AUTH_MSCHAP;
    502             break;
    503           case PHASE_2_AUTH_INDEX_PAP:
    504             auth = EAP_PHASE_2_AUTH_PAP;
    505             break;
    506           case PHASE_2_AUTH_INDEX_CHAP:
    507             auth = EAP_PHASE_2_AUTH_CHAP;
    508             break;
    509         }
    510         wifi->SetEAPPhase2Auth(auth);
    511       }
    512 
    513       // Server CA certificate
    514       if (server_ca_cert_combobox_->IsEnabled()) {
    515         int selected = server_ca_cert_combobox_->selected_item();
    516         if (selected == 0) {
    517           // First item is "Default".
    518           wifi->SetEAPServerCaCertNssNickname(std::string());
    519           wifi->SetEAPUseSystemCAs(true);
    520         } else if (selected ==
    521             server_ca_cert_combobox_->model()->GetItemCount() - 1) {
    522           // Last item is "Do not check".
    523           wifi->SetEAPServerCaCertNssNickname(std::string());
    524           wifi->SetEAPUseSystemCAs(false);
    525         } else {
    526           int cert_index = selected - 1;
    527           std::string nss_nickname =
    528               wifi_config_model_->GetServerCaCertNssNickname(cert_index);
    529           wifi->SetEAPServerCaCertNssNickname(nss_nickname);
    530         }
    531       }
    532 
    533       // Client certificate
    534       if (client_cert_combobox_ && client_cert_combobox_->IsEnabled()) {
    535         int selected = client_cert_combobox_->selected_item();
    536         if (selected == 0) {
    537           // First item is "None".
    538           wifi->SetEAPClientCertPkcs11Id(std::string());
    539         } else {
    540           // Send cert ID to flimflam.
    541           int cert_index = selected - 1;
    542           std::string cert_pkcs11_id =
    543               wifi_config_model_->GetUserCertPkcs11Id(cert_index);
    544           wifi->SetEAPClientCertPkcs11Id(cert_pkcs11_id);
    545         }
    546       }
    547 
    548       // Identity
    549       if (identity_textfield_->IsEnabled()) {
    550         wifi->SetEAPIdentity(UTF16ToUTF8(identity_textfield_->text()));
    551       }
    552 
    553       // Anonymous identity
    554       if (identity_anonymous_textfield_->IsEnabled()) {
    555         wifi->SetEAPAnonymousIdentity(
    556             UTF16ToUTF8(identity_anonymous_textfield_->text()));
    557       }
    558 
    559       // Passphrase
    560       if (passphrase_textfield_->IsEnabled()) {
    561         wifi->SetEAPPassphrase(UTF16ToUTF8(passphrase_textfield_->text()));
    562       }
    563 
    564       // Save credentials
    565       wifi->SetSaveCredentials(save_credentials_checkbox_->checked());
    566     } else {
    567       const std::string passphrase = GetPassphrase();
    568       if (passphrase != wifi->passphrase())
    569         wifi->SetPassphrase(passphrase);
    570     }
    571 
    572     cros->ConnectToWifiNetwork(wifi);
    573     // Connection failures are responsible for updating the UI, including
    574     // reopening dialogs.
    575   }
    576   return true;  // dialog will be closed
    577 }
    578 
    579 void WifiConfigView::Cancel() {
    580 }
    581 
    582 std::string WifiConfigView::GetSSID() const {
    583   std::string result;
    584   if (ssid_textfield_ != NULL) {
    585     std::string untrimmed = UTF16ToUTF8(ssid_textfield_->text());
    586     TrimWhitespaceASCII(untrimmed, TRIM_ALL, &result);
    587   }
    588   return result;
    589 }
    590 
    591 std::string WifiConfigView::GetPassphrase() const {
    592   std::string result;
    593   if (passphrase_textfield_ != NULL)
    594     result = UTF16ToUTF8(passphrase_textfield_->text());
    595   return result;
    596 }
    597 
    598 // This will initialize the view depending on if we have a wifi network or not.
    599 // And if we are doing simple password encyption or the more complicated
    600 // 802.1x encryption.
    601 // If we are creating the "Join other network..." dialog, we will allow user
    602 // to enter the data. And if they select the 802.1x encryption, we will show
    603 // the 802.1x fields.
    604 void WifiConfigView::Init(WifiNetwork* wifi) {
    605   views::GridLayout* layout = views::GridLayout::CreatePanel(this);
    606   SetLayoutManager(layout);
    607 
    608   int column_view_set_id = 0;
    609   views::ColumnSet* column_set = layout->AddColumnSet(column_view_set_id);
    610   // Label
    611   column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
    612                         views::GridLayout::USE_PREF, 0, 0);
    613   // Textfield
    614   column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
    615                         views::GridLayout::USE_PREF, 0,
    616                         ChildNetworkConfigView::kPassphraseWidth);
    617   // Password visible button
    618   column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::FILL, 1,
    619                         views::GridLayout::USE_PREF, 0, 0);
    620 
    621   // SSID input
    622   layout->StartRow(0, column_view_set_id);
    623   layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
    624       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_ID))));
    625   if (!wifi) {
    626     ssid_textfield_ = new views::Textfield(views::Textfield::STYLE_DEFAULT);
    627     ssid_textfield_->SetController(this);
    628     ssid_textfield_->SetAccessibleName(l10n_util::GetStringUTF16(
    629         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_ID));
    630     layout->AddView(ssid_textfield_);
    631   } else {
    632     views::Label* label = new views::Label(UTF8ToWide(wifi->name()));
    633     label->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
    634     layout->AddView(label);
    635   }
    636   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    637 
    638   // Security select
    639   if (!wifi) {
    640     layout->StartRow(0, column_view_set_id);
    641     layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
    642           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY))));
    643     security_combobox_ = new views::Combobox(new SecurityComboboxModel());
    644     security_combobox_->set_listener(this);
    645     layout->AddView(security_combobox_);
    646     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    647   }
    648 
    649   is_8021x_ = wifi && wifi->encrypted() &&
    650       wifi->encryption() == SECURITY_8021X;
    651   if (is_8021x_) {
    652     // Only enumerate certificates in the data model for 802.1X networks.
    653     wifi_config_model_->UpdateCertificates();
    654 
    655     // EAP method
    656     layout->StartRow(0, column_view_set_id);
    657     layout->AddView(new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
    658         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD))));
    659     eap_method_combobox_ = new views::Combobox(new EAPMethodComboboxModel());
    660     eap_method_combobox_->set_listener(this);
    661     layout->AddView(eap_method_combobox_);
    662     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    663 
    664     // Phase 2 authentication
    665     layout->StartRow(0, column_view_set_id);
    666     phase_2_auth_label_ =
    667         new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
    668             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH)));
    669     layout->AddView(phase_2_auth_label_);
    670     phase_2_auth_combobox_ = new views::Combobox(
    671         new Phase2AuthComboboxModel(eap_method_combobox_));
    672     phase_2_auth_label_->SetEnabled(false);
    673     phase_2_auth_combobox_->SetEnabled(false);
    674     phase_2_auth_combobox_->set_listener(this);
    675     layout->AddView(phase_2_auth_combobox_);
    676     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    677 
    678     // Server CA certificate
    679     layout->StartRow(0, column_view_set_id);
    680     server_ca_cert_label_ =
    681         new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
    682             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA)));
    683     layout->AddView(server_ca_cert_label_);
    684     server_ca_cert_combobox_ = new ComboboxWithWidth(
    685         new ServerCACertComboboxModel(wifi_config_model_.get()),
    686         ChildNetworkConfigView::kPassphraseWidth);
    687     server_ca_cert_label_->SetEnabled(false);
    688     server_ca_cert_combobox_->SetEnabled(false);
    689     server_ca_cert_combobox_->set_listener(this);
    690     layout->AddView(server_ca_cert_combobox_);
    691     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    692 
    693     // TODO(jamescook): Add back client certificate combobox when we support
    694     // EAP-TLS by default.
    695     if (CommandLine::ForCurrentProcess()->HasSwitch(
    696         switches::kEnableExperimentalEap)) {
    697       // Client certificate
    698       layout->StartRow(0, column_view_set_id);
    699       client_cert_label_ = new views::Label(
    700           UTF16ToWide(l10n_util::GetStringUTF16(
    701               IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT)));
    702       layout->AddView(client_cert_label_);
    703       client_cert_combobox_ = new views::Combobox(
    704           new ClientCertComboboxModel(wifi_config_model_.get()));
    705       client_cert_label_->SetEnabled(false);
    706       client_cert_combobox_->SetEnabled(false);
    707       client_cert_combobox_->set_listener(this);
    708       layout->AddView(client_cert_combobox_);
    709       layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    710     }
    711 
    712     // Identity
    713     layout->StartRow(0, column_view_set_id);
    714     identity_label_ = new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
    715         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_IDENTITY)));
    716     layout->AddView(identity_label_);
    717     identity_textfield_ = new views::Textfield(
    718         views::Textfield::STYLE_DEFAULT);
    719     identity_textfield_->SetController(this);
    720     if (!wifi->identity().empty())
    721       identity_textfield_->SetText(UTF8ToUTF16(wifi->identity()));
    722     layout->AddView(identity_textfield_);
    723     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    724   }
    725 
    726   // Passphrase input
    727   layout->StartRow(0, column_view_set_id);
    728   int label_text_id = IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PASSPHRASE;
    729   passphrase_label_ = new views::Label(
    730       UTF16ToWide(l10n_util::GetStringUTF16(label_text_id)));
    731   layout->AddView(passphrase_label_);
    732   passphrase_textfield_ = new views::Textfield(
    733       views::Textfield::STYLE_PASSWORD);
    734   passphrase_textfield_->SetController(this);
    735   if (wifi && !wifi->GetPassphrase().empty())
    736     passphrase_textfield_->SetText(UTF8ToUTF16(wifi->GetPassphrase()));
    737   // Disable passphrase input initially for other network.
    738   if (!wifi) {
    739     passphrase_label_->SetEnabled(false);
    740     passphrase_textfield_->SetEnabled(false);
    741   }
    742   passphrase_textfield_->SetAccessibleName(l10n_util::GetStringUTF16(
    743       label_text_id));
    744   layout->AddView(passphrase_textfield_);
    745   // Password visible button.
    746   passphrase_visible_button_ = new views::ImageButton(this);
    747   passphrase_visible_button_->SetImage(
    748       views::ImageButton::BS_NORMAL,
    749       ResourceBundle::GetSharedInstance().
    750       GetBitmapNamed(IDR_STATUSBAR_NETWORK_SECURE));
    751   passphrase_visible_button_->SetImageAlignment(
    752       views::ImageButton::ALIGN_CENTER, views::ImageButton::ALIGN_MIDDLE);
    753   layout->AddView(passphrase_visible_button_);
    754   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    755 
    756   if (is_8021x_) {
    757     // Anonymous identity
    758     layout->StartRow(0, column_view_set_id);
    759     identity_anonymous_label_ =
    760         new views::Label(UTF16ToWide(l10n_util::GetStringUTF16(
    761             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_IDENTITY_ANONYMOUS)));
    762     layout->AddView(identity_anonymous_label_);
    763     identity_anonymous_textfield_ = new views::Textfield(
    764         views::Textfield::STYLE_DEFAULT);
    765     identity_anonymous_label_->SetEnabled(false);
    766     identity_anonymous_textfield_->SetEnabled(false);
    767     identity_anonymous_textfield_->SetController(this);
    768     layout->AddView(identity_anonymous_textfield_);
    769     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    770 
    771     // Save credentials
    772     layout->StartRow(0, column_view_set_id);
    773     save_credentials_checkbox_ = new views::Checkbox(
    774         UTF16ToWide(l10n_util::GetStringUTF16(
    775             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SAVE_CREDENTIALS)));
    776     layout->SkipColumns(1);
    777     layout->AddView(save_credentials_checkbox_);
    778     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    779   }
    780 
    781   // After creating the fields, we set the values. Fields need to be created
    782   // first because RefreshEAPFields() will enable/disable them as appropriate.
    783   if (is_8021x_) {
    784     // EAP Method
    785     switch (wifi->eap_method()) {
    786       case EAP_METHOD_PEAP:
    787         eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_PEAP);
    788         break;
    789       case EAP_METHOD_TTLS:
    790         eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_TTLS);
    791         break;
    792       case EAP_METHOD_TLS:
    793         if (CommandLine::ForCurrentProcess()->HasSwitch(
    794                 switches::kEnableExperimentalEap))
    795           eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_TLS);
    796         else // Clean up from previous run with the switch set.
    797           eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_NONE);
    798         break;
    799       case EAP_METHOD_LEAP:
    800         if (CommandLine::ForCurrentProcess()->HasSwitch(
    801                 switches::kEnableExperimentalEap))
    802           eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_LEAP);
    803         else // Clean up from previous run with the switch set.
    804           eap_method_combobox_->SetSelectedItem(EAP_METHOD_INDEX_NONE);
    805         break;
    806       default:
    807         break;
    808     }
    809     RefreshEAPFields();
    810 
    811     // Phase 2 authentication
    812     if (phase_2_auth_combobox_->IsEnabled()) {
    813       switch (wifi->eap_phase_2_auth()) {
    814         case EAP_PHASE_2_AUTH_MD5:
    815           phase_2_auth_combobox_->SetSelectedItem(PHASE_2_AUTH_INDEX_MD5);
    816           break;
    817         case EAP_PHASE_2_AUTH_MSCHAPV2:
    818           phase_2_auth_combobox_->SetSelectedItem(PHASE_2_AUTH_INDEX_MSCHAPV2);
    819           break;
    820         case EAP_PHASE_2_AUTH_MSCHAP:
    821           phase_2_auth_combobox_->SetSelectedItem(PHASE_2_AUTH_INDEX_MSCHAP);
    822           break;
    823         case EAP_PHASE_2_AUTH_PAP:
    824           phase_2_auth_combobox_->SetSelectedItem(PHASE_2_AUTH_INDEX_PAP);
    825           break;
    826         case EAP_PHASE_2_AUTH_CHAP:
    827           phase_2_auth_combobox_->SetSelectedItem(PHASE_2_AUTH_INDEX_CHAP);
    828           break;
    829         default:
    830           break;
    831       }
    832     }
    833 
    834     // Server CA certificate
    835     if (server_ca_cert_combobox_->IsEnabled()) {
    836       const std::string& nss_nickname = wifi->eap_server_ca_cert_nss_nickname();
    837       if (nss_nickname.empty()) {
    838         if (wifi->eap_use_system_cas()) {
    839           // "Default"
    840           server_ca_cert_combobox_->SetSelectedItem(0);
    841         } else {
    842           // "Do not check"
    843           server_ca_cert_combobox_->SetSelectedItem(
    844               server_ca_cert_combobox_->model()->GetItemCount() - 1);
    845         }
    846       } else {
    847         // select the certificate if available
    848         int cert_index = wifi_config_model_->GetServerCaCertIndex(nss_nickname);
    849         if (cert_index >= 0) {
    850           // Skip item for "Default"
    851           server_ca_cert_combobox_->SetSelectedItem(1 + cert_index);
    852         }
    853       }
    854     }
    855 
    856     // Client certificate
    857     if (client_cert_combobox_ && client_cert_combobox_->IsEnabled()) {
    858       const std::string& pkcs11_id = wifi->eap_client_cert_pkcs11_id();
    859       if (pkcs11_id.empty()) {
    860         // First item is "None".
    861         client_cert_combobox_->SetSelectedItem(0);
    862       } else {
    863         int cert_index = wifi_config_model_->GetUserCertIndex(pkcs11_id);
    864         if (cert_index >= 0) {
    865           // Skip item for "None"
    866           client_cert_combobox_->SetSelectedItem(1 + cert_index);
    867         }
    868       }
    869     }
    870 
    871     // Identity
    872     if (identity_textfield_->IsEnabled())
    873       identity_textfield_->SetText(UTF8ToUTF16(wifi->eap_identity()));
    874 
    875     // Anonymous identity
    876     if (identity_anonymous_textfield_->IsEnabled())
    877       identity_anonymous_textfield_->SetText(
    878           UTF8ToUTF16(wifi->eap_anonymous_identity()));
    879 
    880     // Passphrase
    881     if (passphrase_textfield_->IsEnabled())
    882       passphrase_textfield_->SetText(UTF8ToUTF16(wifi->eap_passphrase()));
    883 
    884     // Save credentials
    885     bool save_credentials = (wifi ? wifi->save_credentials() : false);
    886     save_credentials_checkbox_->SetChecked(save_credentials);
    887   }
    888 
    889   // Create an error label.
    890   layout->StartRow(0, column_view_set_id);
    891   layout->SkipColumns(1);
    892   error_label_ = new views::Label();
    893   error_label_->SetHorizontalAlignment(views::Label::ALIGN_LEFT);
    894   error_label_->SetColor(SK_ColorRED);
    895   layout->AddView(error_label_);
    896 
    897   // Set or hide the error text.
    898   UpdateErrorLabel();
    899 }
    900 
    901 void WifiConfigView::InitFocus() {
    902   // Set focus to a reasonable widget, depending on what we're showing.
    903   if (ssid_textfield_)
    904     ssid_textfield_->RequestFocus();
    905   else if (eap_method_combobox_)
    906     eap_method_combobox_->RequestFocus();
    907   else if (passphrase_textfield_ && passphrase_textfield_->IsEnabled())
    908     passphrase_textfield_->RequestFocus();
    909 }
    910 
    911 }  // namespace chromeos
    912