Home | History | Annotate | Download | only in options
      1 // Copyright (c) 2012 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 "ash/system/chromeos/network/network_connect.h"
      8 #include "base/strings/string_util.h"
      9 #include "base/strings/stringprintf.h"
     10 #include "base/strings/utf_string_conversions.h"
     11 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
     12 #include "chrome/browser/chromeos/options/network_connect.h"
     13 #include "chrome/browser/profiles/profile_manager.h"
     14 #include "chromeos/login/login_state.h"
     15 #include "chromeos/network/network_configuration_handler.h"
     16 #include "chromeos/network/network_event_log.h"
     17 #include "chromeos/network/network_handler.h"
     18 #include "chromeos/network/network_state.h"
     19 #include "chromeos/network/network_state_handler.h"
     20 #include "chromeos/network/network_ui_data.h"
     21 #include "chromeos/network/onc/onc_constants.h"
     22 #include "grit/chromium_strings.h"
     23 #include "grit/generated_resources.h"
     24 #include "grit/locale_settings.h"
     25 #include "grit/theme_resources.h"
     26 #include "third_party/cros_system_api/dbus/service_constants.h"
     27 #include "ui/base/events/event.h"
     28 #include "ui/base/l10n/l10n_util.h"
     29 #include "ui/base/resource/resource_bundle.h"
     30 #include "ui/views/controls/button/checkbox.h"
     31 #include "ui/views/controls/button/image_button.h"
     32 #include "ui/views/controls/combobox/combobox.h"
     33 #include "ui/views/controls/label.h"
     34 #include "ui/views/controls/textfield/textfield.h"
     35 #include "ui/views/layout/grid_layout.h"
     36 #include "ui/views/layout/layout_constants.h"
     37 #include "ui/views/widget/widget.h"
     38 #include "ui/views/window/dialog_client_view.h"
     39 
     40 namespace chromeos {
     41 
     42 namespace {
     43 
     44 // Combobox that supports a preferred width.  Used by Server CA combobox
     45 // because the strings inside it are too wide.
     46 class ComboboxWithWidth : public views::Combobox {
     47  public:
     48   ComboboxWithWidth(ui::ComboboxModel* model, int width)
     49       : Combobox(model),
     50         width_(width) {
     51   }
     52   virtual ~ComboboxWithWidth() {}
     53   virtual gfx::Size GetPreferredSize() OVERRIDE {
     54     gfx::Size size = Combobox::GetPreferredSize();
     55     size.set_width(width_);
     56     return size;
     57   }
     58  private:
     59   int width_;
     60   DISALLOW_COPY_AND_ASSIGN(ComboboxWithWidth);
     61 };
     62 
     63 enum SecurityComboboxIndex {
     64   SECURITY_INDEX_NONE  = 0,
     65   SECURITY_INDEX_WEP   = 1,
     66   SECURITY_INDEX_PSK   = 2,
     67   SECURITY_INDEX_COUNT = 3
     68 };
     69 
     70 // Methods in alphabetical order.
     71 enum EAPMethodComboboxIndex {
     72   EAP_METHOD_INDEX_NONE  = 0,
     73   EAP_METHOD_INDEX_LEAP  = 1,
     74   EAP_METHOD_INDEX_PEAP  = 2,
     75   EAP_METHOD_INDEX_TLS   = 3,
     76   EAP_METHOD_INDEX_TTLS  = 4,
     77   EAP_METHOD_INDEX_COUNT = 5
     78 };
     79 
     80 enum Phase2AuthComboboxIndex {
     81   PHASE_2_AUTH_INDEX_AUTO     = 0,  // LEAP, EAP-TLS have only this auth.
     82   PHASE_2_AUTH_INDEX_MD5      = 1,
     83   PHASE_2_AUTH_INDEX_MSCHAPV2 = 2,  // PEAP has up to this auth.
     84   PHASE_2_AUTH_INDEX_MSCHAP   = 3,
     85   PHASE_2_AUTH_INDEX_PAP      = 4,
     86   PHASE_2_AUTH_INDEX_CHAP     = 5,  // EAP-TTLS has up to this auth.
     87   PHASE_2_AUTH_INDEX_COUNT    = 6
     88 };
     89 
     90 void ShillError(const std::string& function,
     91                 const std::string& error_name,
     92                 scoped_ptr<base::DictionaryValue> error_data) {
     93   NET_LOG_ERROR("Shill Error from WifiConfigView: " + error_name, function);
     94 }
     95 
     96 }  // namespace
     97 
     98 namespace internal {
     99 
    100 class SecurityComboboxModel : public ui::ComboboxModel {
    101  public:
    102   SecurityComboboxModel();
    103   virtual ~SecurityComboboxModel();
    104 
    105   // Overridden from ui::ComboboxModel:
    106   virtual int GetItemCount() const OVERRIDE;
    107   virtual string16 GetItemAt(int index) OVERRIDE;
    108 
    109  private:
    110   DISALLOW_COPY_AND_ASSIGN(SecurityComboboxModel);
    111 };
    112 
    113 class EAPMethodComboboxModel : public ui::ComboboxModel {
    114  public:
    115   EAPMethodComboboxModel();
    116   virtual ~EAPMethodComboboxModel();
    117 
    118   // Overridden from ui::ComboboxModel:
    119   virtual int GetItemCount() const OVERRIDE;
    120   virtual string16 GetItemAt(int index) OVERRIDE;
    121 
    122  private:
    123   DISALLOW_COPY_AND_ASSIGN(EAPMethodComboboxModel);
    124 };
    125 
    126 class Phase2AuthComboboxModel : public ui::ComboboxModel {
    127  public:
    128   explicit Phase2AuthComboboxModel(views::Combobox* eap_method_combobox);
    129   virtual ~Phase2AuthComboboxModel();
    130 
    131   // Overridden from ui::ComboboxModel:
    132   virtual int GetItemCount() const OVERRIDE;
    133   virtual string16 GetItemAt(int index) OVERRIDE;
    134 
    135  private:
    136   views::Combobox* eap_method_combobox_;
    137 
    138   DISALLOW_COPY_AND_ASSIGN(Phase2AuthComboboxModel);
    139 };
    140 
    141 class ServerCACertComboboxModel : public ui::ComboboxModel {
    142  public:
    143   ServerCACertComboboxModel();
    144   virtual ~ServerCACertComboboxModel();
    145 
    146   // Overridden from ui::ComboboxModel:
    147   virtual int GetItemCount() const OVERRIDE;
    148   virtual string16 GetItemAt(int index) OVERRIDE;
    149 
    150  private:
    151   DISALLOW_COPY_AND_ASSIGN(ServerCACertComboboxModel);
    152 };
    153 
    154 class UserCertComboboxModel : public ui::ComboboxModel {
    155  public:
    156   explicit UserCertComboboxModel(WifiConfigView* owner);
    157   virtual ~UserCertComboboxModel();
    158 
    159   // Overridden from ui::ComboboxModel:
    160   virtual int GetItemCount() const OVERRIDE;
    161   virtual string16 GetItemAt(int index) OVERRIDE;
    162 
    163  private:
    164   WifiConfigView* owner_;
    165 
    166   DISALLOW_COPY_AND_ASSIGN(UserCertComboboxModel);
    167 };
    168 
    169 // SecurityComboboxModel -------------------------------------------------------
    170 
    171 SecurityComboboxModel::SecurityComboboxModel() {
    172 }
    173 
    174 SecurityComboboxModel::~SecurityComboboxModel() {
    175 }
    176 
    177 int SecurityComboboxModel::GetItemCount() const {
    178     return SECURITY_INDEX_COUNT;
    179   }
    180 string16 SecurityComboboxModel::GetItemAt(int index) {
    181   if (index == SECURITY_INDEX_NONE)
    182     return l10n_util::GetStringUTF16(
    183         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY_NONE);
    184   else if (index == SECURITY_INDEX_WEP)
    185     return l10n_util::GetStringUTF16(
    186         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY_WEP);
    187   else if (index == SECURITY_INDEX_PSK)
    188     return l10n_util::GetStringUTF16(
    189         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY_PSK);
    190   NOTREACHED();
    191   return string16();
    192 }
    193 
    194 // EAPMethodComboboxModel ------------------------------------------------------
    195 
    196 EAPMethodComboboxModel::EAPMethodComboboxModel() {
    197 }
    198 
    199 EAPMethodComboboxModel::~EAPMethodComboboxModel() {
    200 }
    201 
    202 int EAPMethodComboboxModel::GetItemCount() const {
    203   return EAP_METHOD_INDEX_COUNT;
    204 }
    205 string16 EAPMethodComboboxModel::GetItemAt(int index) {
    206   if (index == EAP_METHOD_INDEX_NONE)
    207     return l10n_util::GetStringUTF16(
    208         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_NONE);
    209   else if (index == EAP_METHOD_INDEX_LEAP)
    210     return l10n_util::GetStringUTF16(
    211         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_LEAP);
    212   else if (index == EAP_METHOD_INDEX_PEAP)
    213     return l10n_util::GetStringUTF16(
    214         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_PEAP);
    215   else if (index == EAP_METHOD_INDEX_TLS)
    216     return l10n_util::GetStringUTF16(
    217         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_TLS);
    218   else if (index == EAP_METHOD_INDEX_TTLS)
    219     return l10n_util::GetStringUTF16(
    220         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD_TTLS);
    221   NOTREACHED();
    222   return string16();
    223 }
    224 
    225 // Phase2AuthComboboxModel -----------------------------------------------------
    226 
    227 Phase2AuthComboboxModel::Phase2AuthComboboxModel(
    228     views::Combobox* eap_method_combobox)
    229     : eap_method_combobox_(eap_method_combobox) {
    230 }
    231 
    232 Phase2AuthComboboxModel::~Phase2AuthComboboxModel() {
    233 }
    234 
    235 int Phase2AuthComboboxModel::GetItemCount() const {
    236   switch (eap_method_combobox_->selected_index()) {
    237     case EAP_METHOD_INDEX_NONE:
    238     case EAP_METHOD_INDEX_TLS:
    239     case EAP_METHOD_INDEX_LEAP:
    240       return PHASE_2_AUTH_INDEX_AUTO + 1;
    241     case EAP_METHOD_INDEX_PEAP:
    242       return PHASE_2_AUTH_INDEX_MSCHAPV2 + 1;
    243     case EAP_METHOD_INDEX_TTLS:
    244       return PHASE_2_AUTH_INDEX_CHAP + 1;
    245   }
    246   NOTREACHED();
    247   return 0;
    248 }
    249 
    250 string16 Phase2AuthComboboxModel::GetItemAt(int index) {
    251   if (index == PHASE_2_AUTH_INDEX_AUTO)
    252     return l10n_util::GetStringUTF16(
    253         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_AUTO);
    254   else if (index == PHASE_2_AUTH_INDEX_MD5)
    255     return l10n_util::GetStringUTF16(
    256         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_MD5);
    257   else if (index == PHASE_2_AUTH_INDEX_MSCHAPV2)
    258     return l10n_util::GetStringUTF16(
    259         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_MSCHAPV2);
    260   else if (index == PHASE_2_AUTH_INDEX_MSCHAP)
    261     return l10n_util::GetStringUTF16(
    262         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_MSCHAP);
    263   else if (index == PHASE_2_AUTH_INDEX_PAP)
    264     return l10n_util::GetStringUTF16(
    265         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_PAP);
    266   else if (index == PHASE_2_AUTH_INDEX_CHAP)
    267     return l10n_util::GetStringUTF16(
    268         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH_CHAP);
    269   NOTREACHED();
    270   return string16();
    271 }
    272 
    273 // ServerCACertComboboxModel ---------------------------------------------------
    274 
    275 ServerCACertComboboxModel::ServerCACertComboboxModel() {
    276 }
    277 
    278 ServerCACertComboboxModel::~ServerCACertComboboxModel() {
    279 }
    280 
    281 int ServerCACertComboboxModel::GetItemCount() const {
    282   if (CertLibrary::Get()->CertificatesLoading())
    283     return 1;  // "Loading"
    284   // First "Default", then the certs, then "Do not check".
    285   return CertLibrary::Get()->NumCertificates(
    286       CertLibrary::CERT_TYPE_SERVER_CA) + 2;
    287 }
    288 
    289 string16 ServerCACertComboboxModel::GetItemAt(int index) {
    290   if (CertLibrary::Get()->CertificatesLoading())
    291     return l10n_util::GetStringUTF16(
    292         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_LOADING);
    293   if (index == 0)
    294     return l10n_util::GetStringUTF16(
    295         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA_DEFAULT);
    296   if (index == GetItemCount() - 1)
    297     return l10n_util::GetStringUTF16(
    298         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA_DO_NOT_CHECK);
    299   int cert_index = index - 1;
    300   return CertLibrary::Get()->GetCertDisplayStringAt(
    301       CertLibrary::CERT_TYPE_SERVER_CA, cert_index);
    302 }
    303 
    304 // UserCertComboboxModel -------------------------------------------------------
    305 
    306 UserCertComboboxModel::UserCertComboboxModel(WifiConfigView* owner)
    307     : owner_(owner) {
    308 }
    309 
    310 UserCertComboboxModel::~UserCertComboboxModel() {
    311 }
    312 
    313 int UserCertComboboxModel::GetItemCount() const {
    314   if (!owner_->UserCertActive())
    315     return 0;
    316   if (CertLibrary::Get()->CertificatesLoading())
    317     return 1;  // "Loading"
    318   int num_certs =
    319       CertLibrary::Get()->NumCertificates(CertLibrary::CERT_TYPE_USER);
    320   if (num_certs == 0)
    321     return 1;  // "None installed"
    322   return num_certs;
    323 }
    324 
    325 string16 UserCertComboboxModel::GetItemAt(int index) {
    326   if (!owner_->UserCertActive())
    327     return string16();
    328   if (CertLibrary::Get()->CertificatesLoading())
    329     return l10n_util::GetStringUTF16(
    330         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_LOADING);
    331   if (CertLibrary::Get()->NumCertificates(CertLibrary::CERT_TYPE_USER) == 0)
    332     return l10n_util::GetStringUTF16(
    333         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_USER_CERT_NONE_INSTALLED);
    334   return CertLibrary::Get()->GetCertDisplayStringAt(
    335       CertLibrary::CERT_TYPE_USER, index);
    336 }
    337 
    338 }  // namespace internal
    339 
    340 WifiConfigView::WifiConfigView(NetworkConfigView* parent,
    341                                const std::string& service_path,
    342                                bool show_8021x)
    343     : ChildNetworkConfigView(parent, service_path),
    344       ssid_textfield_(NULL),
    345       eap_method_combobox_(NULL),
    346       phase_2_auth_label_(NULL),
    347       phase_2_auth_combobox_(NULL),
    348       user_cert_label_(NULL),
    349       user_cert_combobox_(NULL),
    350       server_ca_cert_label_(NULL),
    351       server_ca_cert_combobox_(NULL),
    352       identity_label_(NULL),
    353       identity_textfield_(NULL),
    354       identity_anonymous_label_(NULL),
    355       identity_anonymous_textfield_(NULL),
    356       save_credentials_checkbox_(NULL),
    357       share_network_checkbox_(NULL),
    358       shared_network_label_(NULL),
    359       security_combobox_(NULL),
    360       passphrase_label_(NULL),
    361       passphrase_textfield_(NULL),
    362       passphrase_visible_button_(NULL),
    363       error_label_(NULL),
    364       weak_ptr_factory_(this) {
    365   Init(show_8021x);
    366   NetworkHandler::Get()->network_state_handler()->AddObserver(this, FROM_HERE);
    367 }
    368 
    369 WifiConfigView::~WifiConfigView() {
    370   if (NetworkHandler::IsInitialized()) {
    371     NetworkHandler::Get()->network_state_handler()->RemoveObserver(
    372         this, FROM_HERE);
    373   }
    374   CertLibrary::Get()->RemoveObserver(this);
    375 }
    376 
    377 string16 WifiConfigView::GetTitle() const {
    378   return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_JOIN_WIFI_NETWORKS);
    379 }
    380 
    381 views::View* WifiConfigView::GetInitiallyFocusedView() {
    382   // Return a reasonable widget for initial focus,
    383   // depending on what we're showing.
    384   if (ssid_textfield_)
    385     return ssid_textfield_;
    386   else if (eap_method_combobox_)
    387     return eap_method_combobox_;
    388   else if (passphrase_textfield_ && passphrase_textfield_->enabled())
    389     return passphrase_textfield_;
    390   else
    391     return NULL;
    392 }
    393 
    394 bool WifiConfigView::CanLogin() {
    395   static const size_t kMinWirelessPasswordLen = 5;
    396 
    397   // We either have an existing wifi network or the user entered an SSID.
    398   if (service_path_.empty() && GetSsid().empty())
    399     return false;
    400 
    401   // If the network requires a passphrase, make sure it is the right length.
    402   if (passphrase_textfield_ != NULL
    403       && passphrase_textfield_->enabled()
    404       && passphrase_textfield_->text().length() < kMinWirelessPasswordLen)
    405     return false;
    406 
    407   // If we're using EAP, we must have a method.
    408   if (eap_method_combobox_ &&
    409       eap_method_combobox_->selected_index() == EAP_METHOD_INDEX_NONE)
    410     return false;
    411 
    412   // Block login if certs are required but user has none.
    413   if (UserCertRequired() && (!HaveUserCerts() || !IsUserCertValid()))
    414       return false;
    415 
    416   return true;
    417 }
    418 
    419 bool WifiConfigView::UserCertRequired() const {
    420   return UserCertActive();
    421 }
    422 
    423 bool WifiConfigView::HaveUserCerts() const {
    424   return CertLibrary::Get()->NumCertificates(CertLibrary::CERT_TYPE_USER) > 0;
    425 }
    426 
    427 bool WifiConfigView::IsUserCertValid() const {
    428   if (!UserCertActive())
    429     return false;
    430   int index = user_cert_combobox_->selected_index();
    431   if (index < 0)
    432     return false;
    433   // Currently only hardware-backed user certificates are valid.
    434   if (CertLibrary::Get()->IsHardwareBacked() &&
    435       !CertLibrary::Get()->IsCertHardwareBackedAt(
    436           CertLibrary::CERT_TYPE_USER, index))
    437     return false;
    438   return true;
    439 }
    440 
    441 bool WifiConfigView::Phase2AuthActive() const {
    442   if (phase_2_auth_combobox_)
    443     return phase_2_auth_combobox_->model()->GetItemCount() > 1;
    444   return false;
    445 }
    446 
    447 bool WifiConfigView::PassphraseActive() const {
    448   if (eap_method_combobox_) {
    449     // No password for EAP-TLS.
    450     int index = eap_method_combobox_->selected_index();
    451     return index != EAP_METHOD_INDEX_NONE && index != EAP_METHOD_INDEX_TLS;
    452   } else if (security_combobox_) {
    453     return security_combobox_->selected_index() != SECURITY_INDEX_NONE;
    454   }
    455   return false;
    456 }
    457 
    458 bool WifiConfigView::UserCertActive() const {
    459   // User certs only for EAP-TLS.
    460   if (eap_method_combobox_)
    461     return eap_method_combobox_->selected_index() == EAP_METHOD_INDEX_TLS;
    462 
    463   return false;
    464 }
    465 
    466 bool WifiConfigView::CaCertActive() const {
    467   // No server CA certs for LEAP.
    468   if (eap_method_combobox_) {
    469     int index = eap_method_combobox_->selected_index();
    470     return index != EAP_METHOD_INDEX_NONE && index != EAP_METHOD_INDEX_LEAP;
    471   }
    472   return false;
    473 }
    474 
    475 void WifiConfigView::UpdateDialogButtons() {
    476   parent_->GetDialogClientView()->UpdateDialogButtons();
    477 }
    478 
    479 void WifiConfigView::RefreshEapFields() {
    480   // If EAP method changes, the phase 2 auth choices may have changed also.
    481   phase_2_auth_combobox_->ModelChanged();
    482   phase_2_auth_combobox_->SetSelectedIndex(0);
    483   bool phase_2_auth_enabled = Phase2AuthActive();
    484   phase_2_auth_combobox_->SetEnabled(phase_2_auth_enabled &&
    485                                      phase_2_auth_ui_data_.IsEditable());
    486   phase_2_auth_label_->SetEnabled(phase_2_auth_enabled);
    487 
    488   // Passphrase.
    489   bool passphrase_enabled = PassphraseActive();
    490   passphrase_textfield_->SetEnabled(passphrase_enabled &&
    491                                     passphrase_ui_data_.IsEditable());
    492   passphrase_label_->SetEnabled(passphrase_enabled);
    493   if (!passphrase_enabled)
    494     passphrase_textfield_->SetText(string16());
    495 
    496   // User cert.
    497   bool certs_loading = CertLibrary::Get()->CertificatesLoading();
    498   bool user_cert_enabled = UserCertActive();
    499   user_cert_label_->SetEnabled(user_cert_enabled);
    500   bool have_user_certs = !certs_loading && HaveUserCerts();
    501   user_cert_combobox_->SetEnabled(user_cert_enabled &&
    502                                   have_user_certs &&
    503                                   user_cert_ui_data_.IsEditable());
    504   user_cert_combobox_->ModelChanged();
    505   user_cert_combobox_->SetSelectedIndex(0);
    506 
    507   // Server CA.
    508   bool ca_cert_enabled = CaCertActive();
    509   server_ca_cert_label_->SetEnabled(ca_cert_enabled);
    510   server_ca_cert_combobox_->SetEnabled(ca_cert_enabled &&
    511                                        !certs_loading &&
    512                                        server_ca_cert_ui_data_.IsEditable());
    513   server_ca_cert_combobox_->ModelChanged();
    514   server_ca_cert_combobox_->SetSelectedIndex(0);
    515 
    516   // No anonymous identity if no phase 2 auth.
    517   bool identity_anonymous_enabled = phase_2_auth_enabled;
    518   identity_anonymous_textfield_->SetEnabled(
    519       identity_anonymous_enabled && identity_anonymous_ui_data_.IsEditable());
    520   identity_anonymous_label_->SetEnabled(identity_anonymous_enabled);
    521   if (!identity_anonymous_enabled)
    522     identity_anonymous_textfield_->SetText(string16());
    523 
    524   RefreshShareCheckbox();
    525 }
    526 
    527 void WifiConfigView::RefreshShareCheckbox() {
    528   if (!share_network_checkbox_)
    529     return;
    530 
    531   if (security_combobox_ &&
    532       security_combobox_->selected_index() == SECURITY_INDEX_NONE) {
    533     share_network_checkbox_->SetEnabled(false);
    534     share_network_checkbox_->SetChecked(true);
    535   } else if (eap_method_combobox_ &&
    536              (eap_method_combobox_->selected_index() == EAP_METHOD_INDEX_TLS ||
    537               user_cert_combobox_->selected_index() != 0)) {
    538     // Can not share TLS network (requires certificate), or any network where
    539     // user certificates are enabled.
    540     share_network_checkbox_->SetEnabled(false);
    541     share_network_checkbox_->SetChecked(false);
    542   } else if (!LoginState::Get()->IsUserAuthenticated()) {
    543     // If not logged in as an authenticated user, networks must be shared.
    544     share_network_checkbox_->SetEnabled(false);
    545     share_network_checkbox_->SetChecked(true);
    546   } else {
    547     share_network_checkbox_->SetEnabled(true);
    548     share_network_checkbox_->SetChecked(false);  // Default to unshared.
    549   }
    550 }
    551 
    552 void WifiConfigView::UpdateErrorLabel() {
    553   base::string16 error_msg;
    554   if (UserCertRequired() && CertLibrary::Get()->CertificatesLoaded()) {
    555     if (!HaveUserCerts()) {
    556       if (!LoginState::Get()->IsUserAuthenticated()) {
    557         error_msg = l10n_util::GetStringUTF16(
    558             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_LOGIN_FOR_USER_CERT);
    559       } else {
    560         error_msg = l10n_util::GetStringUTF16(
    561             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PLEASE_INSTALL_USER_CERT);
    562       }
    563     } else if (!IsUserCertValid()) {
    564       error_msg = l10n_util::GetStringUTF16(
    565           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_REQUIRE_HARDWARE_BACKED);
    566     }
    567   }
    568   if (error_msg.empty() && !service_path_.empty()) {
    569     const NetworkState* wifi = NetworkHandler::Get()->network_state_handler()->
    570         GetNetworkState(service_path_);
    571     if (wifi && wifi->connection_state() == flimflam::kStateFailure)
    572       error_msg = ash::network_connect::ErrorString(wifi->error());
    573   }
    574   if (!error_msg.empty()) {
    575     error_label_->SetText(error_msg);
    576     error_label_->SetVisible(true);
    577   } else {
    578     error_label_->SetVisible(false);
    579   }
    580 }
    581 
    582 void WifiConfigView::ContentsChanged(views::Textfield* sender,
    583                                      const string16& new_contents) {
    584   UpdateDialogButtons();
    585 }
    586 
    587 bool WifiConfigView::HandleKeyEvent(views::Textfield* sender,
    588                                     const ui::KeyEvent& key_event) {
    589   if (sender == passphrase_textfield_ &&
    590       key_event.key_code() == ui::VKEY_RETURN) {
    591     parent_->GetDialogClientView()->AcceptWindow();
    592   }
    593   return false;
    594 }
    595 
    596 void WifiConfigView::ButtonPressed(views::Button* sender,
    597                                    const ui::Event& event) {
    598   if (sender == passphrase_visible_button_) {
    599     if (passphrase_textfield_) {
    600       passphrase_textfield_->SetObscured(!passphrase_textfield_->IsObscured());
    601       passphrase_visible_button_->SetToggled(
    602           !passphrase_textfield_->IsObscured());
    603     }
    604   } else {
    605     NOTREACHED();
    606   }
    607 }
    608 
    609 void WifiConfigView::OnSelectedIndexChanged(views::Combobox* combobox) {
    610   if (combobox == security_combobox_) {
    611     bool passphrase_enabled = PassphraseActive();
    612     passphrase_label_->SetEnabled(passphrase_enabled);
    613     passphrase_textfield_->SetEnabled(passphrase_enabled &&
    614                                       passphrase_ui_data_.IsEditable());
    615     if (!passphrase_enabled)
    616       passphrase_textfield_->SetText(string16());
    617     RefreshShareCheckbox();
    618   } else if (combobox == user_cert_combobox_) {
    619     RefreshShareCheckbox();
    620   } else if (combobox == eap_method_combobox_) {
    621     RefreshEapFields();
    622   }
    623   UpdateDialogButtons();
    624   UpdateErrorLabel();
    625 }
    626 
    627 void WifiConfigView::OnCertificatesLoaded(bool initial_load) {
    628   RefreshEapFields();
    629   UpdateDialogButtons();
    630   UpdateErrorLabel();
    631 }
    632 
    633 bool WifiConfigView::Login() {
    634   const bool share_default = true;
    635   if (service_path_.empty()) {
    636     // Set configuration properties.
    637     base::DictionaryValue properties;
    638     properties.SetStringWithoutPathExpansion(
    639         flimflam::kTypeProperty, flimflam::kTypeWifi);
    640     properties.SetStringWithoutPathExpansion(
    641         flimflam::kSSIDProperty, GetSsid());
    642     properties.SetStringWithoutPathExpansion(
    643         flimflam::kModeProperty, flimflam::kModeManaged);
    644     properties.SetBooleanWithoutPathExpansion(
    645         flimflam::kSaveCredentialsProperty, GetSaveCredentials());
    646     std::string security = flimflam::kSecurityNone;
    647     if (!eap_method_combobox_) {
    648       // Hidden ordinary Wi-Fi connection.
    649       switch (security_combobox_->selected_index()) {
    650         case SECURITY_INDEX_NONE:
    651           security = flimflam::kSecurityNone;
    652           break;
    653         case SECURITY_INDEX_WEP:
    654           security = flimflam::kSecurityWep;
    655           break;
    656         case SECURITY_INDEX_PSK:
    657           security = flimflam::kSecurityPsk;
    658           break;
    659       }
    660       std::string passphrase = GetPassphrase();
    661       if (!passphrase.empty()) {
    662         properties.SetStringWithoutPathExpansion(
    663             flimflam::kPassphraseProperty, GetPassphrase());
    664       }
    665     } else {
    666       // Hidden 802.1X EAP Wi-Fi connection.
    667       security = flimflam::kSecurity8021x;
    668       SetEapProperties(&properties);
    669     }
    670     properties.SetStringWithoutPathExpansion(
    671         flimflam::kSecurityProperty, security);
    672 
    673     // Configure and connect to network.
    674     bool shared = GetShareNetwork(share_default);
    675     ash::network_connect::CreateConfigurationAndConnect(&properties, shared);
    676   } else {
    677     const NetworkState* wifi = NetworkHandler::Get()->network_state_handler()->
    678         GetNetworkState(service_path_);
    679     if (!wifi) {
    680       // Shill no longer knows about this wifi network (edge case).
    681       // TODO(stevenjb): Add notification for this.
    682       NET_LOG_ERROR("Network not found", service_path_);
    683       return true;  // Close dialog
    684     }
    685     base::DictionaryValue properties;
    686     if (eap_method_combobox_) {
    687       // Visible 802.1X EAP Wi-Fi connection.
    688       SetEapProperties(&properties);
    689       properties.SetBooleanWithoutPathExpansion(
    690           flimflam::kSaveCredentialsProperty, GetSaveCredentials());
    691     } else {
    692       // Visible ordinary Wi-Fi connection.
    693       const std::string passphrase = GetPassphrase();
    694       if (!passphrase.empty()) {
    695         properties.SetStringWithoutPathExpansion(
    696             flimflam::kPassphraseProperty, passphrase);
    697       }
    698     }
    699     bool share_network = GetShareNetwork(share_default);
    700     ash::network_connect::ConfigureNetworkAndConnect(
    701         service_path_, properties, share_network);
    702   }
    703   return true;  // dialog will be closed
    704 }
    705 
    706 std::string WifiConfigView::GetSsid() const {
    707   std::string result;
    708   if (ssid_textfield_ != NULL) {
    709     std::string untrimmed = UTF16ToUTF8(ssid_textfield_->text());
    710     TrimWhitespaceASCII(untrimmed, TRIM_ALL, &result);
    711   }
    712   return result;
    713 }
    714 
    715 std::string WifiConfigView::GetPassphrase() const {
    716   std::string result;
    717   if (passphrase_textfield_ != NULL)
    718     result = UTF16ToUTF8(passphrase_textfield_->text());
    719   return result;
    720 }
    721 
    722 bool WifiConfigView::GetSaveCredentials() const {
    723   if (!save_credentials_checkbox_)
    724     return true;  // share networks by default (e.g. non 8021x).
    725   return save_credentials_checkbox_->checked();
    726 }
    727 
    728 bool WifiConfigView::GetShareNetwork(bool share_default) const {
    729   if (!share_network_checkbox_)
    730     return share_default;
    731   return share_network_checkbox_->checked();
    732 }
    733 
    734 std::string WifiConfigView::GetEapMethod() const {
    735   DCHECK(eap_method_combobox_);
    736   switch (eap_method_combobox_->selected_index()) {
    737     case EAP_METHOD_INDEX_PEAP:
    738       return flimflam::kEapMethodPEAP;
    739     case EAP_METHOD_INDEX_TLS:
    740       return flimflam::kEapMethodTLS;
    741     case EAP_METHOD_INDEX_TTLS:
    742       return flimflam::kEapMethodTTLS;
    743     case EAP_METHOD_INDEX_LEAP:
    744       return flimflam::kEapMethodLEAP;
    745     case EAP_METHOD_INDEX_NONE:
    746     default:
    747       return "";
    748   }
    749 }
    750 
    751 std::string WifiConfigView::GetEapPhase2Auth() const {
    752   DCHECK(phase_2_auth_combobox_);
    753   bool is_peap = (GetEapMethod() == flimflam::kEapMethodPEAP);
    754   switch (phase_2_auth_combobox_->selected_index()) {
    755     case PHASE_2_AUTH_INDEX_MD5:
    756       return is_peap ? flimflam::kEapPhase2AuthPEAPMD5
    757           : flimflam::kEapPhase2AuthTTLSMD5;
    758     case PHASE_2_AUTH_INDEX_MSCHAPV2:
    759       return is_peap ? flimflam::kEapPhase2AuthPEAPMSCHAPV2
    760           : flimflam::kEapPhase2AuthTTLSMSCHAPV2;
    761     case PHASE_2_AUTH_INDEX_MSCHAP:
    762       return flimflam::kEapPhase2AuthTTLSMSCHAP;
    763     case PHASE_2_AUTH_INDEX_PAP:
    764       return flimflam::kEapPhase2AuthTTLSPAP;
    765     case PHASE_2_AUTH_INDEX_CHAP:
    766       return flimflam::kEapPhase2AuthTTLSCHAP;
    767     case PHASE_2_AUTH_INDEX_AUTO:
    768     default:
    769       return "";
    770   }
    771 }
    772 
    773 std::string WifiConfigView::GetEapServerCaCertPEM() const {
    774   DCHECK(server_ca_cert_combobox_);
    775   int index = server_ca_cert_combobox_->selected_index();
    776   if (index == 0) {
    777     // First item is "Default".
    778     return std::string();
    779   } else if (index == server_ca_cert_combobox_->model()->GetItemCount() - 1) {
    780     // Last item is "Do not check".
    781     return std::string();
    782   } else {
    783     int cert_index = index - 1;
    784     return CertLibrary::Get()->GetCertPEMAt(
    785         CertLibrary::CERT_TYPE_SERVER_CA, cert_index);
    786   }
    787 }
    788 
    789 bool WifiConfigView::GetEapUseSystemCas() const {
    790   DCHECK(server_ca_cert_combobox_);
    791   // Only use system CAs if the first item ("Default") is selected.
    792   return server_ca_cert_combobox_->selected_index() == 0;
    793 }
    794 
    795 std::string WifiConfigView::GetEapClientCertPkcs11Id() const {
    796   DCHECK(user_cert_combobox_);
    797   if (!HaveUserCerts() || !UserCertActive()) {
    798     return std::string();  // No certificate selected or not required.
    799   } else {
    800     // Certificates are listed in the order they appear in the model.
    801     int index = user_cert_combobox_->selected_index();
    802     return CertLibrary::Get()->GetCertPkcs11IdAt(
    803         CertLibrary::CERT_TYPE_USER, index);
    804   }
    805 }
    806 
    807 std::string WifiConfigView::GetEapIdentity() const {
    808   DCHECK(identity_textfield_);
    809   return UTF16ToUTF8(identity_textfield_->text());
    810 }
    811 
    812 std::string WifiConfigView::GetEapAnonymousIdentity() const {
    813   DCHECK(identity_anonymous_textfield_);
    814   return UTF16ToUTF8(identity_anonymous_textfield_->text());
    815 }
    816 
    817 void WifiConfigView::SetEapProperties(base::DictionaryValue* properties) {
    818   properties->SetStringWithoutPathExpansion(
    819       flimflam::kEapIdentityProperty, GetEapIdentity());
    820   properties->SetStringWithoutPathExpansion(
    821       flimflam::kEapMethodProperty, GetEapMethod());
    822   properties->SetStringWithoutPathExpansion(
    823       flimflam::kEapPhase2AuthProperty, GetEapPhase2Auth());
    824   properties->SetStringWithoutPathExpansion(
    825       flimflam::kEapAnonymousIdentityProperty, GetEapAnonymousIdentity());
    826 
    827   // shill requires both CertID and KeyID for TLS connections, despite
    828   // the fact that by convention they are the same ID.
    829   properties->SetStringWithoutPathExpansion(
    830       flimflam::kEapCertIdProperty, GetEapClientCertPkcs11Id());
    831   properties->SetStringWithoutPathExpansion(
    832       flimflam::kEapKeyIdProperty, GetEapClientCertPkcs11Id());
    833 
    834   properties->SetBooleanWithoutPathExpansion(
    835       flimflam::kEapUseSystemCasProperty, GetEapUseSystemCas());
    836   properties->SetStringWithoutPathExpansion(
    837       flimflam::kEapPasswordProperty, GetPassphrase());
    838 
    839   base::ListValue* pem_list = new base::ListValue;
    840   pem_list->AppendString(GetEapServerCaCertPEM());
    841   properties->SetWithoutPathExpansion(
    842       shill::kEapCaCertPemProperty, pem_list);
    843 }
    844 
    845 void WifiConfigView::Cancel() {
    846 }
    847 
    848 // This will initialize the view depending on if we have a wifi network or not.
    849 // And if we are doing simple password encryption or the more complicated
    850 // 802.1x encryption.
    851 // If we are creating the "Join other network..." dialog, we will allow user
    852 // to enter the data. And if they select the 802.1x encryption, we will show
    853 // the 802.1x fields.
    854 void WifiConfigView::Init(bool show_8021x) {
    855   const NetworkState* wifi = NetworkHandler::Get()->network_state_handler()->
    856       GetNetworkState(service_path_);
    857   if (wifi) {
    858     DCHECK(wifi->type() == flimflam::kTypeWifi);
    859     if (wifi->security() == flimflam::kSecurity8021x)
    860       show_8021x = true;
    861     ParseWiFiEAPUIProperty(&eap_method_ui_data_, wifi, onc::eap::kOuter);
    862     ParseWiFiEAPUIProperty(&phase_2_auth_ui_data_, wifi, onc::eap::kInner);
    863     ParseWiFiEAPUIProperty(&user_cert_ui_data_, wifi, onc::eap::kClientCertRef);
    864     ParseWiFiEAPUIProperty(&server_ca_cert_ui_data_, wifi,
    865                            onc::eap::kServerCARef);
    866     if (server_ca_cert_ui_data_.IsManaged()) {
    867       ParseWiFiEAPUIProperty(&server_ca_cert_ui_data_, wifi,
    868                              onc::eap::kUseSystemCAs);
    869     }
    870     ParseWiFiEAPUIProperty(&identity_ui_data_, wifi, onc::eap::kIdentity);
    871     ParseWiFiEAPUIProperty(&identity_anonymous_ui_data_, wifi,
    872                            onc::eap::kAnonymousIdentity);
    873     ParseWiFiEAPUIProperty(&save_credentials_ui_data_, wifi,
    874                            onc::eap::kSaveCredentials);
    875     if (show_8021x)
    876       ParseWiFiEAPUIProperty(&passphrase_ui_data_, wifi, onc::eap::kPassword);
    877     else
    878       ParseWiFiUIProperty(&passphrase_ui_data_, wifi, onc::wifi::kPassphrase);
    879   }
    880 
    881   views::GridLayout* layout = views::GridLayout::CreatePanel(this);
    882   SetLayoutManager(layout);
    883 
    884   const int column_view_set_id = 0;
    885   views::ColumnSet* column_set = layout->AddColumnSet(column_view_set_id);
    886   const int kPasswordVisibleWidth = 20;
    887   // Label
    888   column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
    889                         views::GridLayout::USE_PREF, 0, 0);
    890   column_set->AddPaddingColumn(0, views::kRelatedControlSmallHorizontalSpacing);
    891   // Textfield, combobox.
    892   column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
    893                         views::GridLayout::USE_PREF, 0,
    894                         ChildNetworkConfigView::kInputFieldMinWidth);
    895   column_set->AddPaddingColumn(0, views::kRelatedControlSmallHorizontalSpacing);
    896   // Password visible button / policy indicator.
    897   column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::FILL, 1,
    898                         views::GridLayout::USE_PREF, 0, kPasswordVisibleWidth);
    899 
    900   // SSID input
    901   layout->StartRow(0, column_view_set_id);
    902   layout->AddView(new views::Label(l10n_util::GetStringUTF16(
    903       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_ID)));
    904   if (!wifi) {
    905     ssid_textfield_ = new views::Textfield(views::Textfield::STYLE_DEFAULT);
    906     ssid_textfield_->SetController(this);
    907     ssid_textfield_->SetAccessibleName(l10n_util::GetStringUTF16(
    908         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_ID));
    909     layout->AddView(ssid_textfield_);
    910   } else {
    911     views::Label* label = new views::Label(UTF8ToUTF16(wifi->name()));
    912     label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    913     layout->AddView(label);
    914   }
    915   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    916 
    917   // Security select
    918   if (!wifi && !show_8021x) {
    919     layout->StartRow(0, column_view_set_id);
    920     string16 label_text = l10n_util::GetStringUTF16(
    921         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY);
    922     layout->AddView(new views::Label(label_text));
    923     security_combobox_model_.reset(new internal::SecurityComboboxModel);
    924     security_combobox_ = new views::Combobox(security_combobox_model_.get());
    925     security_combobox_->SetAccessibleName(label_text);
    926     security_combobox_->set_listener(this);
    927     layout->AddView(security_combobox_);
    928     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    929   }
    930 
    931   // Only enumerate certificates in the data model for 802.1X networks.
    932   if (show_8021x) {
    933     // Observer any changes to the certificate list.
    934     CertLibrary::Get()->AddObserver(this);
    935 
    936     // EAP method
    937     layout->StartRow(0, column_view_set_id);
    938     string16 eap_label_text = l10n_util::GetStringUTF16(
    939         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD);
    940     layout->AddView(new views::Label(eap_label_text));
    941     eap_method_combobox_model_.reset(new internal::EAPMethodComboboxModel);
    942     eap_method_combobox_ = new views::Combobox(
    943         eap_method_combobox_model_.get());
    944     eap_method_combobox_->SetAccessibleName(eap_label_text);
    945     eap_method_combobox_->set_listener(this);
    946     eap_method_combobox_->SetEnabled(eap_method_ui_data_.IsEditable());
    947     layout->AddView(eap_method_combobox_);
    948     layout->AddView(new ControlledSettingIndicatorView(eap_method_ui_data_));
    949     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    950 
    951     // Phase 2 authentication
    952     layout->StartRow(0, column_view_set_id);
    953     string16 phase_2_label_text = l10n_util::GetStringUTF16(
    954         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH);
    955     phase_2_auth_label_ = new views::Label(phase_2_label_text);
    956     layout->AddView(phase_2_auth_label_);
    957     phase_2_auth_combobox_model_.reset(
    958         new internal::Phase2AuthComboboxModel(eap_method_combobox_));
    959     phase_2_auth_combobox_ = new views::Combobox(
    960         phase_2_auth_combobox_model_.get());
    961     phase_2_auth_combobox_->SetAccessibleName(phase_2_label_text);
    962     phase_2_auth_label_->SetEnabled(false);
    963     phase_2_auth_combobox_->SetEnabled(false);
    964     phase_2_auth_combobox_->set_listener(this);
    965     layout->AddView(phase_2_auth_combobox_);
    966     layout->AddView(new ControlledSettingIndicatorView(phase_2_auth_ui_data_));
    967     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    968 
    969     // Server CA certificate
    970     layout->StartRow(0, column_view_set_id);
    971     string16 server_ca_cert_label_text = l10n_util::GetStringUTF16(
    972         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA);
    973     server_ca_cert_label_ = new views::Label(server_ca_cert_label_text);
    974     layout->AddView(server_ca_cert_label_);
    975     server_ca_cert_combobox_model_.reset(
    976         new internal::ServerCACertComboboxModel());
    977     server_ca_cert_combobox_ = new ComboboxWithWidth(
    978         server_ca_cert_combobox_model_.get(),
    979         ChildNetworkConfigView::kInputFieldMinWidth);
    980     server_ca_cert_combobox_->SetAccessibleName(server_ca_cert_label_text);
    981     server_ca_cert_label_->SetEnabled(false);
    982     server_ca_cert_combobox_->SetEnabled(false);
    983     server_ca_cert_combobox_->set_listener(this);
    984     layout->AddView(server_ca_cert_combobox_);
    985     layout->AddView(
    986         new ControlledSettingIndicatorView(server_ca_cert_ui_data_));
    987     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    988 
    989     // User certificate
    990     layout->StartRow(0, column_view_set_id);
    991     string16 user_cert_label_text = l10n_util::GetStringUTF16(
    992         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT);
    993     user_cert_label_ = new views::Label(user_cert_label_text);
    994     layout->AddView(user_cert_label_);
    995     user_cert_combobox_model_.reset(new internal::UserCertComboboxModel(this));
    996     user_cert_combobox_ = new views::Combobox(user_cert_combobox_model_.get());
    997     user_cert_combobox_->SetAccessibleName(user_cert_label_text);
    998     user_cert_label_->SetEnabled(false);
    999     user_cert_combobox_->SetEnabled(false);
   1000     user_cert_combobox_->set_listener(this);
   1001     layout->AddView(user_cert_combobox_);
   1002     layout->AddView(new ControlledSettingIndicatorView(user_cert_ui_data_));
   1003     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
   1004 
   1005     // Identity
   1006     layout->StartRow(0, column_view_set_id);
   1007     string16 identity_label_text = l10n_util::GetStringUTF16(
   1008         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_IDENTITY);
   1009     identity_label_ = new views::Label(identity_label_text);
   1010     layout->AddView(identity_label_);
   1011     identity_textfield_ = new views::Textfield(
   1012         views::Textfield::STYLE_DEFAULT);
   1013     identity_textfield_->SetAccessibleName(identity_label_text);
   1014     identity_textfield_->SetController(this);
   1015     identity_textfield_->SetEnabled(identity_ui_data_.IsEditable());
   1016     layout->AddView(identity_textfield_);
   1017     layout->AddView(new ControlledSettingIndicatorView(identity_ui_data_));
   1018     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
   1019   }
   1020 
   1021   // Passphrase input
   1022   layout->StartRow(0, column_view_set_id);
   1023   int label_text_id = IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PASSPHRASE;
   1024   string16 passphrase_label_text = l10n_util::GetStringUTF16(label_text_id);
   1025   passphrase_label_ = new views::Label(passphrase_label_text);
   1026   layout->AddView(passphrase_label_);
   1027   passphrase_textfield_ = new views::Textfield(
   1028       views::Textfield::STYLE_OBSCURED);
   1029   passphrase_textfield_->SetController(this);
   1030   // Disable passphrase input initially for other network.
   1031   passphrase_label_->SetEnabled(wifi != NULL);
   1032   passphrase_textfield_->SetEnabled(wifi && passphrase_ui_data_.IsEditable());
   1033   passphrase_textfield_->SetAccessibleName(passphrase_label_text);
   1034   layout->AddView(passphrase_textfield_);
   1035 
   1036   if (passphrase_ui_data_.IsManaged()) {
   1037     layout->AddView(new ControlledSettingIndicatorView(passphrase_ui_data_));
   1038   } else {
   1039     // Password visible button.
   1040     passphrase_visible_button_ = new views::ToggleImageButton(this);
   1041     passphrase_visible_button_->set_focusable(true);
   1042     passphrase_visible_button_->SetTooltipText(
   1043         l10n_util::GetStringUTF16(
   1044             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PASSPHRASE_SHOW));
   1045     passphrase_visible_button_->SetToggledTooltipText(
   1046         l10n_util::GetStringUTF16(
   1047             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PASSPHRASE_HIDE));
   1048     passphrase_visible_button_->SetImage(
   1049         views::ImageButton::STATE_NORMAL,
   1050         ResourceBundle::GetSharedInstance().
   1051         GetImageSkiaNamed(IDR_NETWORK_SHOW_PASSWORD));
   1052     passphrase_visible_button_->SetImage(
   1053         views::ImageButton::STATE_HOVERED,
   1054         ResourceBundle::GetSharedInstance().
   1055         GetImageSkiaNamed(IDR_NETWORK_SHOW_PASSWORD_HOVER));
   1056     passphrase_visible_button_->SetToggledImage(
   1057         views::ImageButton::STATE_NORMAL,
   1058         ResourceBundle::GetSharedInstance().
   1059         GetImageSkiaNamed(IDR_NETWORK_HIDE_PASSWORD));
   1060     passphrase_visible_button_->SetToggledImage(
   1061         views::ImageButton::STATE_HOVERED,
   1062         ResourceBundle::GetSharedInstance().
   1063         GetImageSkiaNamed(IDR_NETWORK_HIDE_PASSWORD_HOVER));
   1064     passphrase_visible_button_->SetImageAlignment(
   1065         views::ImageButton::ALIGN_CENTER, views::ImageButton::ALIGN_MIDDLE);
   1066     layout->AddView(passphrase_visible_button_);
   1067   }
   1068 
   1069   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
   1070 
   1071   if (show_8021x) {
   1072     // Anonymous identity
   1073     layout->StartRow(0, column_view_set_id);
   1074     identity_anonymous_label_ =
   1075         new views::Label(l10n_util::GetStringUTF16(
   1076             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_IDENTITY_ANONYMOUS));
   1077     layout->AddView(identity_anonymous_label_);
   1078     identity_anonymous_textfield_ = new views::Textfield(
   1079         views::Textfield::STYLE_DEFAULT);
   1080     identity_anonymous_label_->SetEnabled(false);
   1081     identity_anonymous_textfield_->SetEnabled(false);
   1082     identity_anonymous_textfield_->SetController(this);
   1083     layout->AddView(identity_anonymous_textfield_);
   1084     layout->AddView(
   1085         new ControlledSettingIndicatorView(identity_anonymous_ui_data_));
   1086     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
   1087   }
   1088 
   1089   // Checkboxes.
   1090 
   1091   // Save credentials
   1092   if (show_8021x) {
   1093     layout->StartRow(0, column_view_set_id);
   1094     save_credentials_checkbox_ = new views::Checkbox(
   1095         l10n_util::GetStringUTF16(
   1096             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SAVE_CREDENTIALS));
   1097     save_credentials_checkbox_->SetEnabled(
   1098         save_credentials_ui_data_.IsEditable());
   1099     layout->SkipColumns(1);
   1100     layout->AddView(save_credentials_checkbox_);
   1101     layout->AddView(
   1102         new ControlledSettingIndicatorView(save_credentials_ui_data_));
   1103   }
   1104 
   1105   // Share network
   1106   if (!wifi || wifi->profile_path().empty()) {
   1107     layout->StartRow(0, column_view_set_id);
   1108     share_network_checkbox_ = new views::Checkbox(
   1109         l10n_util::GetStringUTF16(
   1110             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SHARE_NETWORK));
   1111     layout->SkipColumns(1);
   1112     layout->AddView(share_network_checkbox_);
   1113   }
   1114   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
   1115 
   1116   // Create an error label.
   1117   layout->StartRow(0, column_view_set_id);
   1118   layout->SkipColumns(1);
   1119   error_label_ = new views::Label();
   1120   error_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
   1121   error_label_->SetEnabledColor(SK_ColorRED);
   1122   layout->AddView(error_label_);
   1123 
   1124   // Initialize the field and checkbox values.
   1125 
   1126   if (!wifi && show_8021x)
   1127     RefreshEapFields();
   1128 
   1129   RefreshShareCheckbox();
   1130   UpdateErrorLabel();
   1131 
   1132   if (wifi) {
   1133     NetworkHandler::Get()->network_configuration_handler()->GetProperties(
   1134         service_path_,
   1135         base::Bind(&WifiConfigView::InitFromProperties,
   1136                    weak_ptr_factory_.GetWeakPtr(), show_8021x),
   1137         base::Bind(&ShillError, "GetProperties"));
   1138   }
   1139 }
   1140 
   1141 void WifiConfigView::InitFromProperties(
   1142     bool show_8021x,
   1143     const std::string& service_path,
   1144     const base::DictionaryValue& properties) {
   1145   std::string passphrase;
   1146   properties.GetStringWithoutPathExpansion(
   1147       flimflam::kPassphraseProperty, &passphrase);
   1148   passphrase_textfield_->SetText(UTF8ToUTF16(passphrase));
   1149 
   1150   if (!show_8021x)
   1151     return;
   1152 
   1153   // EAP Method
   1154   std::string eap_method;
   1155   properties.GetStringWithoutPathExpansion(
   1156       flimflam::kEapMethodProperty, &eap_method);
   1157   if (eap_method == flimflam::kEapMethodPEAP)
   1158     eap_method_combobox_->SetSelectedIndex(EAP_METHOD_INDEX_PEAP);
   1159   else if (eap_method == flimflam::kEapMethodTTLS)
   1160     eap_method_combobox_->SetSelectedIndex(EAP_METHOD_INDEX_TTLS);
   1161   else if (eap_method == flimflam::kEapMethodTLS)
   1162     eap_method_combobox_->SetSelectedIndex(EAP_METHOD_INDEX_TLS);
   1163   else if (eap_method == flimflam::kEapMethodLEAP)
   1164     eap_method_combobox_->SetSelectedIndex(EAP_METHOD_INDEX_LEAP);
   1165   RefreshEapFields();
   1166 
   1167   // Phase 2 authentication and anonymous identity.
   1168   if (Phase2AuthActive()) {
   1169     std::string eap_phase_2_auth;
   1170     properties.GetStringWithoutPathExpansion(
   1171         flimflam::kEapPhase2AuthProperty, &eap_phase_2_auth);
   1172     if (eap_phase_2_auth == flimflam::kEapPhase2AuthTTLSMD5)
   1173       phase_2_auth_combobox_->SetSelectedIndex(PHASE_2_AUTH_INDEX_MD5);
   1174     else if (eap_phase_2_auth == flimflam::kEapPhase2AuthTTLSMSCHAPV2)
   1175       phase_2_auth_combobox_->SetSelectedIndex(PHASE_2_AUTH_INDEX_MSCHAPV2);
   1176     else if (eap_phase_2_auth == flimflam::kEapPhase2AuthTTLSMSCHAP)
   1177       phase_2_auth_combobox_->SetSelectedIndex(PHASE_2_AUTH_INDEX_MSCHAP);
   1178     else if (eap_phase_2_auth == flimflam::kEapPhase2AuthTTLSPAP)
   1179       phase_2_auth_combobox_->SetSelectedIndex(PHASE_2_AUTH_INDEX_PAP);
   1180     else if (eap_phase_2_auth == flimflam::kEapPhase2AuthTTLSCHAP)
   1181       phase_2_auth_combobox_->SetSelectedIndex(PHASE_2_AUTH_INDEX_CHAP);
   1182 
   1183     std::string eap_anonymous_identity;
   1184     properties.GetStringWithoutPathExpansion(
   1185         flimflam::kEapAnonymousIdentityProperty, &eap_anonymous_identity);
   1186     identity_anonymous_textfield_->SetText(UTF8ToUTF16(eap_anonymous_identity));
   1187   }
   1188 
   1189   // Server CA certificate.
   1190   if (CaCertActive()) {
   1191     std::string eap_ca_cert_pem;
   1192     const base::ListValue* pems = NULL;
   1193     if (properties.GetListWithoutPathExpansion(
   1194             shill::kEapCaCertPemProperty, &pems))
   1195       pems->GetString(0, &eap_ca_cert_pem);
   1196     if (eap_ca_cert_pem.empty()) {
   1197       bool eap_use_system_cas = false;
   1198       properties.GetBooleanWithoutPathExpansion(
   1199           flimflam::kEapUseSystemCasProperty, &eap_use_system_cas);
   1200       if (eap_use_system_cas) {
   1201         // "Default"
   1202         server_ca_cert_combobox_->SetSelectedIndex(0);
   1203       } else {
   1204         // "Do not check".
   1205         server_ca_cert_combobox_->SetSelectedIndex(
   1206             server_ca_cert_combobox_->model()->GetItemCount() - 1);
   1207       }
   1208     } else {
   1209       // Select the certificate if available.
   1210       int cert_index = CertLibrary::Get()->GetCertIndexByPEM(
   1211           CertLibrary::CERT_TYPE_SERVER_CA, eap_ca_cert_pem);
   1212       if (cert_index >= 0) {
   1213         // Skip item for "Default".
   1214         server_ca_cert_combobox_->SetSelectedIndex(1 + cert_index);
   1215       }
   1216     }
   1217   }
   1218 
   1219   // User certificate.
   1220   if (UserCertActive()) {
   1221     std::string eap_cert_id;
   1222     properties.GetStringWithoutPathExpansion(
   1223         flimflam::kEapCertIdProperty, &eap_cert_id);
   1224     if (!eap_cert_id.empty()) {
   1225       int cert_index = CertLibrary::Get()->GetCertIndexByPkcs11Id(
   1226           CertLibrary::CERT_TYPE_USER, eap_cert_id);
   1227       if (cert_index >= 0)
   1228         user_cert_combobox_->SetSelectedIndex(cert_index);
   1229     }
   1230   }
   1231 
   1232   // Identity is always active.
   1233   std::string eap_identity;
   1234   properties.GetStringWithoutPathExpansion(
   1235       flimflam::kEapIdentityProperty, &eap_identity);
   1236   identity_textfield_->SetText(UTF8ToUTF16(eap_identity));
   1237 
   1238   // Passphrase
   1239   if (PassphraseActive()) {
   1240     std::string eap_password;
   1241     properties.GetStringWithoutPathExpansion(
   1242         flimflam::kEapPasswordProperty, &eap_password);
   1243     passphrase_textfield_->SetText(UTF8ToUTF16(eap_password));
   1244   }
   1245 
   1246   // Save credentials
   1247   bool save_credentials = false;
   1248   properties.GetBooleanWithoutPathExpansion(
   1249       flimflam::kSaveCredentialsProperty, &save_credentials);
   1250   save_credentials_checkbox_->SetChecked(save_credentials);
   1251 
   1252   RefreshShareCheckbox();
   1253   UpdateErrorLabel();
   1254 }
   1255 
   1256 void WifiConfigView::InitFocus() {
   1257   views::View* view_to_focus = GetInitiallyFocusedView();
   1258   if (view_to_focus)
   1259     view_to_focus->RequestFocus();
   1260 }
   1261 
   1262 void WifiConfigView::NetworkPropertiesUpdated(const NetworkState* network) {
   1263   if (network->path() != service_path_)
   1264     return;
   1265   UpdateErrorLabel();
   1266 }
   1267 
   1268 // static
   1269 void WifiConfigView::ParseWiFiUIProperty(
   1270     NetworkPropertyUIData* property_ui_data,
   1271     const NetworkState* network,
   1272     const std::string& key) {
   1273   onc::ONCSource onc_source = onc::ONC_SOURCE_NONE;
   1274   const base::DictionaryValue* onc =
   1275       network_connect::FindPolicyForActiveUser(network, &onc_source);
   1276 
   1277   property_ui_data->ParseOncProperty(
   1278       onc_source,
   1279       onc,
   1280       base::StringPrintf("%s.%s", onc::network_config::kWiFi, key.c_str()));
   1281 }
   1282 
   1283 // static
   1284 void WifiConfigView::ParseWiFiEAPUIProperty(
   1285     NetworkPropertyUIData* property_ui_data,
   1286     const NetworkState* network,
   1287     const std::string& key) {
   1288   ParseWiFiUIProperty(
   1289       property_ui_data, network,
   1290       base::StringPrintf("%s.%s", onc::wifi::kEAP, key.c_str()));
   1291 }
   1292 
   1293 }  // namespace chromeos
   1294