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