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