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