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