Upstream version 10.39.225.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 "chrome/grit/generated_resources.h"
17 #include "chrome/grit/theme_resources.h"
18 #include "chromeos/login/login_state.h"
19 #include "chromeos/network/client_cert_util.h"
20 #include "chromeos/network/network_configuration_handler.h"
21 #include "chromeos/network/network_event_log.h"
22 #include "chromeos/network/network_handler.h"
23 #include "chromeos/network/network_state.h"
24 #include "chromeos/network/network_state_handler.h"
25 #include "chromeos/network/network_ui_data.h"
26 #include "chromeos/network/shill_property_util.h"
27 #include "components/onc/onc_constants.h"
28 #include "third_party/cros_system_api/dbus/service_constants.h"
29 #include "ui/base/l10n/l10n_util.h"
30 #include "ui/base/resource/resource_bundle.h"
31 #include "ui/events/event.h"
32 #include "ui/views/controls/button/checkbox.h"
33 #include "ui/views/controls/button/image_button.h"
34 #include "ui/views/controls/combobox/combobox.h"
35 #include "ui/views/controls/label.h"
36 #include "ui/views/controls/textfield/textfield.h"
37 #include "ui/views/layout/grid_layout.h"
38 #include "ui/views/layout/layout_constants.h"
39 #include "ui/views/widget/widget.h"
40 #include "ui/views/window/dialog_client_view.h"
41
42 namespace chromeos {
43
44 namespace {
45
46 // Combobox that supports a preferred width.  Used by Server CA combobox
47 // because the strings inside it are too wide.
48 class ComboboxWithWidth : public views::Combobox {
49  public:
50   ComboboxWithWidth(ui::ComboboxModel* model, int width)
51       : Combobox(model),
52         width_(width) {
53   }
54   virtual ~ComboboxWithWidth() {}
55   virtual gfx::Size GetPreferredSize() 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()->IsHardwareBacked() &&
445       !CertLibrary::Get()->IsCertHardwareBackedAt(
446           CertLibrary::CERT_TYPE_USER, index))
447     return false;
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 = ash::network_connect::ErrorString(
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);
703     }
704     properties.SetStringWithoutPathExpansion(
705         shill::kSecurityProperty, security);
706
707     // Configure and connect to network.
708     ash::network_connect::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);
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       ash::network_connect::CreateConfiguration(&properties, share_network);
736     } else {
737       ash::network_connect::ConfigureNetworkAndConnect(
738           service_path_, properties, share_network);
739     }
740   }
741   return true;  // dialog will be closed
742 }
743
744 std::string WifiConfigView::GetSsid() const {
745   std::string result;
746   if (ssid_textfield_ != NULL) {
747     std::string untrimmed = base::UTF16ToUTF8(ssid_textfield_->text());
748     base::TrimWhitespaceASCII(untrimmed, base::TRIM_ALL, &result);
749   }
750   return result;
751 }
752
753 std::string WifiConfigView::GetPassphrase() const {
754   std::string result;
755   if (passphrase_textfield_ != NULL)
756     result = base::UTF16ToUTF8(passphrase_textfield_->text());
757   return result;
758 }
759
760 bool WifiConfigView::GetSaveCredentials() const {
761   if (!save_credentials_checkbox_)
762     return true;  // share networks by default (e.g. non 8021x).
763   return save_credentials_checkbox_->checked();
764 }
765
766 bool WifiConfigView::GetShareNetwork(bool share_default) const {
767   if (!share_network_checkbox_)
768     return share_default;
769   return share_network_checkbox_->checked();
770 }
771
772 std::string WifiConfigView::GetEapMethod() const {
773   DCHECK(eap_method_combobox_);
774   switch (eap_method_combobox_->selected_index()) {
775     case EAP_METHOD_INDEX_PEAP:
776       return shill::kEapMethodPEAP;
777     case EAP_METHOD_INDEX_TLS:
778       return shill::kEapMethodTLS;
779     case EAP_METHOD_INDEX_TTLS:
780       return shill::kEapMethodTTLS;
781     case EAP_METHOD_INDEX_LEAP:
782       return shill::kEapMethodLEAP;
783     case EAP_METHOD_INDEX_NONE:
784     default:
785       return "";
786   }
787 }
788
789 std::string WifiConfigView::GetEapPhase2Auth() const {
790   DCHECK(phase_2_auth_combobox_);
791   bool is_peap = (GetEapMethod() == shill::kEapMethodPEAP);
792   switch (phase_2_auth_combobox_->selected_index()) {
793     case PHASE_2_AUTH_INDEX_MD5:
794       return is_peap ? shill::kEapPhase2AuthPEAPMD5
795           : shill::kEapPhase2AuthTTLSMD5;
796     case PHASE_2_AUTH_INDEX_MSCHAPV2:
797       return is_peap ? shill::kEapPhase2AuthPEAPMSCHAPV2
798           : shill::kEapPhase2AuthTTLSMSCHAPV2;
799     case PHASE_2_AUTH_INDEX_MSCHAP:
800       return shill::kEapPhase2AuthTTLSMSCHAP;
801     case PHASE_2_AUTH_INDEX_PAP:
802       return shill::kEapPhase2AuthTTLSPAP;
803     case PHASE_2_AUTH_INDEX_CHAP:
804       return shill::kEapPhase2AuthTTLSCHAP;
805     case PHASE_2_AUTH_INDEX_AUTO:
806     default:
807       return "";
808   }
809 }
810
811 std::string WifiConfigView::GetEapServerCaCertPEM() const {
812   DCHECK(server_ca_cert_combobox_);
813   int index = server_ca_cert_combobox_->selected_index();
814   if (index == 0) {
815     // First item is "Default".
816     return std::string();
817   } else if (index == server_ca_cert_combobox_->model()->GetItemCount() - 1) {
818     // Last item is "Do not check".
819     return std::string();
820   } else {
821     int cert_index = index - 1;
822     return CertLibrary::Get()->GetServerCACertPEMAt(cert_index);
823   }
824 }
825
826 bool WifiConfigView::GetEapUseSystemCas() const {
827   DCHECK(server_ca_cert_combobox_);
828   // Only use system CAs if the first item ("Default") is selected.
829   return server_ca_cert_combobox_->selected_index() == 0;
830 }
831
832 std::string WifiConfigView::GetEapSubjectMatch() const {
833   DCHECK(subject_match_textfield_);
834   return base::UTF16ToUTF8(subject_match_textfield_->text());
835 }
836
837 void WifiConfigView::SetEapClientCertProperties(
838     base::DictionaryValue* properties) const {
839   DCHECK(user_cert_combobox_);
840   if (!HaveUserCerts() || !UserCertActive()) {
841     // No certificate selected or not required.
842     client_cert::SetEmptyShillProperties(client_cert::CONFIG_TYPE_EAP,
843                                          properties);
844   } else {
845     // Certificates are listed in the order they appear in the model.
846     int index = user_cert_combobox_->selected_index();
847     int slot_id = -1;
848     const std::string pkcs11_id =
849         CertLibrary::Get()->GetUserCertPkcs11IdAt(index, &slot_id);
850     client_cert::SetShillProperties(
851         client_cert::CONFIG_TYPE_EAP, slot_id, pkcs11_id, properties);
852   }
853 }
854
855 std::string WifiConfigView::GetEapIdentity() const {
856   DCHECK(identity_textfield_);
857   return base::UTF16ToUTF8(identity_textfield_->text());
858 }
859
860 std::string WifiConfigView::GetEapAnonymousIdentity() const {
861   DCHECK(identity_anonymous_textfield_);
862   return base::UTF16ToUTF8(identity_anonymous_textfield_->text());
863 }
864
865 void WifiConfigView::SetEapProperties(base::DictionaryValue* properties) {
866   properties->SetStringWithoutPathExpansion(
867       shill::kEapIdentityProperty, GetEapIdentity());
868   properties->SetStringWithoutPathExpansion(
869       shill::kEapMethodProperty, GetEapMethod());
870   properties->SetStringWithoutPathExpansion(
871       shill::kEapPhase2AuthProperty, GetEapPhase2Auth());
872   properties->SetStringWithoutPathExpansion(
873       shill::kEapAnonymousIdentityProperty, GetEapAnonymousIdentity());
874   properties->SetStringWithoutPathExpansion(
875       shill::kEapSubjectMatchProperty, GetEapSubjectMatch());
876
877   SetEapClientCertProperties(properties);
878
879   properties->SetBooleanWithoutPathExpansion(
880       shill::kEapUseSystemCasProperty, GetEapUseSystemCas());
881   properties->SetStringWithoutPathExpansion(
882       shill::kEapPasswordProperty, GetPassphrase());
883
884   base::ListValue* pem_list = new base::ListValue;
885   std::string ca_cert_pem = GetEapServerCaCertPEM();
886   if (!ca_cert_pem.empty())
887     pem_list->AppendString(ca_cert_pem);
888   properties->SetWithoutPathExpansion(
889       shill::kEapCaCertPemProperty, pem_list);
890 }
891
892 void WifiConfigView::Cancel() {
893 }
894
895 void WifiConfigView::Init(bool show_8021x) {
896   const NetworkState* network = GetNetworkState();
897   if (network) {
898     if (network->type() == shill::kTypeWifi) {
899       if (network->security() == shill::kSecurity8021x)
900         show_8021x = true;
901     } else if (network->type() == shill::kTypeEthernet) {
902       show_8021x = true;
903     } else {
904       NOTREACHED() << "Unexpected network type for WifiConfigView: "
905                    << network->type() << " Path: " << service_path_;
906     }
907     ParseEAPUIProperty(&eap_method_ui_data_, network, ::onc::eap::kOuter);
908     ParseEAPUIProperty(&phase_2_auth_ui_data_, network, ::onc::eap::kInner);
909     ParseEAPUIProperty(
910         &user_cert_ui_data_, network, ::onc::client_cert::kClientCertRef);
911     ParseEAPUIProperty(
912         &server_ca_cert_ui_data_, network, ::onc::eap::kServerCARef);
913     if (server_ca_cert_ui_data_.IsManaged()) {
914       ParseEAPUIProperty(
915           &server_ca_cert_ui_data_, network, ::onc::eap::kUseSystemCAs);
916     }
917     ParseEAPUIProperty(&identity_ui_data_, network, ::onc::eap::kIdentity);
918     ParseEAPUIProperty(
919         &identity_anonymous_ui_data_, network, ::onc::eap::kAnonymousIdentity);
920     ParseEAPUIProperty(
921         &save_credentials_ui_data_, network, ::onc::eap::kSaveCredentials);
922     if (show_8021x)
923       ParseEAPUIProperty(&passphrase_ui_data_, network, ::onc::eap::kPassword);
924     else
925       ParseUIProperty(&passphrase_ui_data_, network, ::onc::wifi::kPassphrase);
926   }
927
928   views::GridLayout* layout = views::GridLayout::CreatePanel(this);
929   SetLayoutManager(layout);
930
931   const int column_view_set_id = 0;
932   views::ColumnSet* column_set = layout->AddColumnSet(column_view_set_id);
933   const int kPasswordVisibleWidth = 20;
934   // Label
935   column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
936                         views::GridLayout::USE_PREF, 0, 0);
937   column_set->AddPaddingColumn(0, views::kRelatedControlSmallHorizontalSpacing);
938   // Textfield, combobox.
939   column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
940                         views::GridLayout::USE_PREF, 0,
941                         ChildNetworkConfigView::kInputFieldMinWidth);
942   column_set->AddPaddingColumn(0, views::kRelatedControlSmallHorizontalSpacing);
943   // Password visible button / policy indicator.
944   column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::FILL, 1,
945                         views::GridLayout::USE_PREF, 0, kPasswordVisibleWidth);
946
947   // SSID input
948   if (!network || network->type() != shill::kTypeEthernet) {
949     layout->StartRow(0, column_view_set_id);
950     layout->AddView(new views::Label(l10n_util::GetStringUTF16(
951         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_ID)));
952     if (!network) {
953       ssid_textfield_ = new views::Textfield();
954       ssid_textfield_->set_controller(this);
955       ssid_textfield_->SetAccessibleName(l10n_util::GetStringUTF16(
956           IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_NETWORK_ID));
957       layout->AddView(ssid_textfield_);
958     } else {
959       views::Label* label =
960           new views::Label(base::UTF8ToUTF16(network->name()));
961       label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
962       layout->AddView(label);
963     }
964     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
965   }
966
967   // Security select
968   if (!network && !show_8021x) {
969     layout->StartRow(0, column_view_set_id);
970     base::string16 label_text = l10n_util::GetStringUTF16(
971         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SECURITY);
972     layout->AddView(new views::Label(label_text));
973     security_combobox_model_.reset(new internal::SecurityComboboxModel);
974     security_combobox_ = new views::Combobox(security_combobox_model_.get());
975     security_combobox_->SetAccessibleName(label_text);
976     security_combobox_->set_listener(this);
977     layout->AddView(security_combobox_);
978     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
979   }
980
981   // Only enumerate certificates in the data model for 802.1X networks.
982   if (show_8021x) {
983     // Observer any changes to the certificate list.
984     CertLibrary::Get()->AddObserver(this);
985
986     // EAP method
987     layout->StartRow(0, column_view_set_id);
988     base::string16 eap_label_text = l10n_util::GetStringUTF16(
989         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_METHOD);
990     layout->AddView(new views::Label(eap_label_text));
991     eap_method_combobox_model_.reset(new internal::EAPMethodComboboxModel);
992     eap_method_combobox_ = new views::Combobox(
993         eap_method_combobox_model_.get());
994     eap_method_combobox_->SetAccessibleName(eap_label_text);
995     eap_method_combobox_->set_listener(this);
996     eap_method_combobox_->SetEnabled(eap_method_ui_data_.IsEditable());
997     layout->AddView(eap_method_combobox_);
998     layout->AddView(new ControlledSettingIndicatorView(eap_method_ui_data_));
999     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
1000
1001     // Phase 2 authentication
1002     layout->StartRow(0, column_view_set_id);
1003     base::string16 phase_2_label_text = l10n_util::GetStringUTF16(
1004         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PHASE_2_AUTH);
1005     phase_2_auth_label_ = new views::Label(phase_2_label_text);
1006     layout->AddView(phase_2_auth_label_);
1007     phase_2_auth_combobox_model_.reset(
1008         new internal::Phase2AuthComboboxModel(eap_method_combobox_));
1009     phase_2_auth_combobox_ = new views::Combobox(
1010         phase_2_auth_combobox_model_.get());
1011     phase_2_auth_combobox_->SetAccessibleName(phase_2_label_text);
1012     phase_2_auth_label_->SetEnabled(false);
1013     phase_2_auth_combobox_->SetEnabled(false);
1014     phase_2_auth_combobox_->set_listener(this);
1015     layout->AddView(phase_2_auth_combobox_);
1016     layout->AddView(new ControlledSettingIndicatorView(phase_2_auth_ui_data_));
1017     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
1018
1019     // Server CA certificate
1020     layout->StartRow(0, column_view_set_id);
1021     base::string16 server_ca_cert_label_text = l10n_util::GetStringUTF16(
1022         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_SERVER_CA);
1023     server_ca_cert_label_ = new views::Label(server_ca_cert_label_text);
1024     layout->AddView(server_ca_cert_label_);
1025     server_ca_cert_combobox_model_.reset(
1026         new internal::ServerCACertComboboxModel());
1027     server_ca_cert_combobox_ = new ComboboxWithWidth(
1028         server_ca_cert_combobox_model_.get(),
1029         ChildNetworkConfigView::kInputFieldMinWidth);
1030     server_ca_cert_combobox_->SetAccessibleName(server_ca_cert_label_text);
1031     server_ca_cert_label_->SetEnabled(false);
1032     server_ca_cert_combobox_->SetEnabled(false);
1033     server_ca_cert_combobox_->set_listener(this);
1034     layout->AddView(server_ca_cert_combobox_);
1035     layout->AddView(
1036         new ControlledSettingIndicatorView(server_ca_cert_ui_data_));
1037     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
1038
1039     // Subject Match
1040     layout->StartRow(0, column_view_set_id);
1041     base::string16 subject_match_label_text = l10n_util::GetStringUTF16(
1042         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_EAP_SUBJECT_MATCH);
1043     subject_match_label_ = new views::Label(subject_match_label_text);
1044     layout->AddView(subject_match_label_);
1045     subject_match_textfield_ = new views::Textfield();
1046     subject_match_textfield_->SetAccessibleName(subject_match_label_text);
1047     subject_match_textfield_->set_controller(this);
1048     layout->AddView(subject_match_textfield_);
1049     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
1050
1051     // User certificate
1052     layout->StartRow(0, column_view_set_id);
1053     base::string16 user_cert_label_text = l10n_util::GetStringUTF16(
1054         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT);
1055     user_cert_label_ = new views::Label(user_cert_label_text);
1056     layout->AddView(user_cert_label_);
1057     user_cert_combobox_model_.reset(new internal::UserCertComboboxModel(this));
1058     user_cert_combobox_ = new views::Combobox(user_cert_combobox_model_.get());
1059     user_cert_combobox_->SetAccessibleName(user_cert_label_text);
1060     user_cert_label_->SetEnabled(false);
1061     user_cert_combobox_->SetEnabled(false);
1062     user_cert_combobox_->set_listener(this);
1063     layout->AddView(user_cert_combobox_);
1064     layout->AddView(new ControlledSettingIndicatorView(user_cert_ui_data_));
1065     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
1066
1067     // Identity
1068     layout->StartRow(0, column_view_set_id);
1069     base::string16 identity_label_text = l10n_util::GetStringUTF16(
1070         IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_IDENTITY);
1071     identity_label_ = new views::Label(identity_label_text);
1072     layout->AddView(identity_label_);
1073     identity_textfield_ = new views::Textfield();
1074     identity_textfield_->SetAccessibleName(identity_label_text);
1075     identity_textfield_->set_controller(this);
1076     identity_textfield_->SetEnabled(identity_ui_data_.IsEditable());
1077     layout->AddView(identity_textfield_);
1078     layout->AddView(new ControlledSettingIndicatorView(identity_ui_data_));
1079     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
1080   }
1081
1082   // Passphrase input
1083   layout->StartRow(0, column_view_set_id);
1084   int label_text_id = IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PASSPHRASE;
1085   base::string16 passphrase_label_text =
1086       l10n_util::GetStringUTF16(label_text_id);
1087   passphrase_label_ = new views::Label(passphrase_label_text);
1088   layout->AddView(passphrase_label_);
1089   passphrase_textfield_ = new PassphraseTextfield();
1090   passphrase_textfield_->set_controller(this);
1091   // Disable passphrase input initially for other network.
1092   passphrase_label_->SetEnabled(network);
1093   passphrase_textfield_->SetEnabled(network &&
1094                                     passphrase_ui_data_.IsEditable());
1095   passphrase_textfield_->SetAccessibleName(passphrase_label_text);
1096   layout->AddView(passphrase_textfield_);
1097
1098   if (passphrase_ui_data_.IsManaged()) {
1099     layout->AddView(new ControlledSettingIndicatorView(passphrase_ui_data_));
1100   } else {
1101     // Password visible button.
1102     passphrase_visible_button_ = new views::ToggleImageButton(this);
1103     passphrase_visible_button_->SetFocusable(true);
1104     passphrase_visible_button_->SetTooltipText(
1105         l10n_util::GetStringUTF16(
1106             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PASSPHRASE_SHOW));
1107     passphrase_visible_button_->SetToggledTooltipText(
1108         l10n_util::GetStringUTF16(
1109             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PASSPHRASE_HIDE));
1110     passphrase_visible_button_->SetImage(
1111         views::ImageButton::STATE_NORMAL,
1112         ResourceBundle::GetSharedInstance().
1113         GetImageSkiaNamed(IDR_NETWORK_SHOW_PASSWORD));
1114     passphrase_visible_button_->SetImage(
1115         views::ImageButton::STATE_HOVERED,
1116         ResourceBundle::GetSharedInstance().
1117         GetImageSkiaNamed(IDR_NETWORK_SHOW_PASSWORD_HOVER));
1118     passphrase_visible_button_->SetToggledImage(
1119         views::ImageButton::STATE_NORMAL,
1120         ResourceBundle::GetSharedInstance().
1121         GetImageSkiaNamed(IDR_NETWORK_HIDE_PASSWORD));
1122     passphrase_visible_button_->SetToggledImage(
1123         views::ImageButton::STATE_HOVERED,
1124         ResourceBundle::GetSharedInstance().
1125         GetImageSkiaNamed(IDR_NETWORK_HIDE_PASSWORD_HOVER));
1126     passphrase_visible_button_->SetImageAlignment(
1127         views::ImageButton::ALIGN_CENTER, views::ImageButton::ALIGN_MIDDLE);
1128     layout->AddView(passphrase_visible_button_);
1129   }
1130
1131   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
1132
1133   if (show_8021x) {
1134     // Anonymous identity
1135     layout->StartRow(0, column_view_set_id);
1136     identity_anonymous_label_ =
1137         new views::Label(l10n_util::GetStringUTF16(
1138             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_IDENTITY_ANONYMOUS));
1139     layout->AddView(identity_anonymous_label_);
1140     identity_anonymous_textfield_ = new views::Textfield();
1141     identity_anonymous_label_->SetEnabled(false);
1142     identity_anonymous_textfield_->SetEnabled(false);
1143     identity_anonymous_textfield_->set_controller(this);
1144     layout->AddView(identity_anonymous_textfield_);
1145     layout->AddView(
1146         new ControlledSettingIndicatorView(identity_anonymous_ui_data_));
1147     layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
1148   }
1149
1150   // Checkboxes.
1151
1152   // Save credentials
1153   if (show_8021x) {
1154     layout->StartRow(0, column_view_set_id);
1155     save_credentials_checkbox_ = new views::Checkbox(
1156         l10n_util::GetStringUTF16(
1157             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SAVE_CREDENTIALS));
1158     save_credentials_checkbox_->SetEnabled(
1159         save_credentials_ui_data_.IsEditable());
1160     layout->SkipColumns(1);
1161     layout->AddView(save_credentials_checkbox_);
1162     layout->AddView(
1163         new ControlledSettingIndicatorView(save_credentials_ui_data_));
1164   }
1165
1166   // Share network
1167   if (!network || network->profile_path().empty()) {
1168     layout->StartRow(0, column_view_set_id);
1169     share_network_checkbox_ = new views::Checkbox(
1170         l10n_util::GetStringUTF16(
1171             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SHARE_NETWORK));
1172     layout->SkipColumns(1);
1173     layout->AddView(share_network_checkbox_);
1174   }
1175   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
1176
1177   // Create an error label.
1178   layout->StartRow(0, column_view_set_id);
1179   layout->SkipColumns(1);
1180   error_label_ = new views::Label();
1181   error_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
1182   error_label_->SetEnabledColor(SK_ColorRED);
1183   layout->AddView(error_label_);
1184
1185   // Initialize the field and checkbox values.
1186
1187   if (!network && show_8021x)
1188     RefreshEapFields();
1189
1190   RefreshShareCheckbox();
1191   UpdateErrorLabel();
1192
1193   if (network) {
1194     NetworkHandler::Get()->network_configuration_handler()->GetProperties(
1195         service_path_,
1196         base::Bind(&WifiConfigView::InitFromProperties,
1197                    weak_ptr_factory_.GetWeakPtr(),
1198                    show_8021x),
1199         base::Bind(&ShillError, "GetProperties"));
1200   }
1201 }
1202
1203 void WifiConfigView::InitFromProperties(
1204     bool show_8021x,
1205     const std::string& service_path,
1206     const base::DictionaryValue& properties) {
1207   if (!show_8021x) {
1208     std::string passphrase;
1209     properties.GetStringWithoutPathExpansion(
1210         shill::kPassphraseProperty, &passphrase);
1211     passphrase_textfield_->SetText(base::UTF8ToUTF16(passphrase));
1212     return;
1213   }
1214
1215   // EAP Method
1216   std::string eap_method;
1217   properties.GetStringWithoutPathExpansion(
1218       shill::kEapMethodProperty, &eap_method);
1219   if (eap_method == shill::kEapMethodPEAP)
1220     eap_method_combobox_->SetSelectedIndex(EAP_METHOD_INDEX_PEAP);
1221   else if (eap_method == shill::kEapMethodTTLS)
1222     eap_method_combobox_->SetSelectedIndex(EAP_METHOD_INDEX_TTLS);
1223   else if (eap_method == shill::kEapMethodTLS)
1224     eap_method_combobox_->SetSelectedIndex(EAP_METHOD_INDEX_TLS);
1225   else if (eap_method == shill::kEapMethodLEAP)
1226     eap_method_combobox_->SetSelectedIndex(EAP_METHOD_INDEX_LEAP);
1227   RefreshEapFields();
1228
1229   // Phase 2 authentication and anonymous identity.
1230   if (Phase2AuthActive()) {
1231     std::string eap_phase_2_auth;
1232     properties.GetStringWithoutPathExpansion(
1233         shill::kEapPhase2AuthProperty, &eap_phase_2_auth);
1234     if (eap_phase_2_auth == shill::kEapPhase2AuthTTLSMD5)
1235       phase_2_auth_combobox_->SetSelectedIndex(PHASE_2_AUTH_INDEX_MD5);
1236     else if (eap_phase_2_auth == shill::kEapPhase2AuthTTLSMSCHAPV2)
1237       phase_2_auth_combobox_->SetSelectedIndex(PHASE_2_AUTH_INDEX_MSCHAPV2);
1238     else if (eap_phase_2_auth == shill::kEapPhase2AuthTTLSMSCHAP)
1239       phase_2_auth_combobox_->SetSelectedIndex(PHASE_2_AUTH_INDEX_MSCHAP);
1240     else if (eap_phase_2_auth == shill::kEapPhase2AuthTTLSPAP)
1241       phase_2_auth_combobox_->SetSelectedIndex(PHASE_2_AUTH_INDEX_PAP);
1242     else if (eap_phase_2_auth == shill::kEapPhase2AuthTTLSCHAP)
1243       phase_2_auth_combobox_->SetSelectedIndex(PHASE_2_AUTH_INDEX_CHAP);
1244
1245     std::string eap_anonymous_identity;
1246     properties.GetStringWithoutPathExpansion(
1247         shill::kEapAnonymousIdentityProperty, &eap_anonymous_identity);
1248     identity_anonymous_textfield_->SetText(
1249         base::UTF8ToUTF16(eap_anonymous_identity));
1250   }
1251
1252   // Subject match
1253   std::string subject_match;
1254   properties.GetStringWithoutPathExpansion(
1255       shill::kEapSubjectMatchProperty, &subject_match);
1256   subject_match_textfield_->SetText(base::UTF8ToUTF16(subject_match));
1257
1258   // Server CA certificate.
1259   if (CaCertActive()) {
1260     std::string eap_ca_cert_pem;
1261     const base::ListValue* pems = NULL;
1262     if (properties.GetListWithoutPathExpansion(
1263             shill::kEapCaCertPemProperty, &pems))
1264       pems->GetString(0, &eap_ca_cert_pem);
1265     if (eap_ca_cert_pem.empty()) {
1266       bool eap_use_system_cas = false;
1267       properties.GetBooleanWithoutPathExpansion(
1268           shill::kEapUseSystemCasProperty, &eap_use_system_cas);
1269       if (eap_use_system_cas) {
1270         // "Default"
1271         server_ca_cert_combobox_->SetSelectedIndex(0);
1272       } else {
1273         // "Do not check".
1274         server_ca_cert_combobox_->SetSelectedIndex(
1275             server_ca_cert_combobox_->model()->GetItemCount() - 1);
1276       }
1277     } else {
1278       // Select the certificate if available.
1279       int cert_index =
1280           CertLibrary::Get()->GetServerCACertIndexByPEM(eap_ca_cert_pem);
1281       if (cert_index >= 0) {
1282         // Skip item for "Default".
1283         server_ca_cert_combobox_->SetSelectedIndex(1 + cert_index);
1284       } else {
1285         // "Default"
1286         server_ca_cert_combobox_->SetSelectedIndex(0);
1287       }
1288     }
1289   }
1290
1291   // User certificate.
1292   if (UserCertActive()) {
1293     std::string eap_cert_id;
1294     properties.GetStringWithoutPathExpansion(
1295         shill::kEapCertIdProperty, &eap_cert_id);
1296     int unused_slot_id = 0;
1297     std::string pkcs11_id = client_cert::GetPkcs11AndSlotIdFromEapCertId(
1298         eap_cert_id, &unused_slot_id);
1299     if (!pkcs11_id.empty()) {
1300       int cert_index =
1301           CertLibrary::Get()->GetUserCertIndexByPkcs11Id(pkcs11_id);
1302       if (cert_index >= 0)
1303         user_cert_combobox_->SetSelectedIndex(cert_index);
1304     }
1305   }
1306
1307   // Identity is always active.
1308   std::string eap_identity;
1309   properties.GetStringWithoutPathExpansion(
1310       shill::kEapIdentityProperty, &eap_identity);
1311   identity_textfield_->SetText(base::UTF8ToUTF16(eap_identity));
1312
1313   // Passphrase
1314   if (PassphraseActive()) {
1315     std::string eap_password;
1316     properties.GetStringWithoutPathExpansion(
1317         shill::kEapPasswordProperty, &eap_password);
1318     passphrase_textfield_->SetText(base::UTF8ToUTF16(eap_password));
1319     // If 'Connectable' is True, show a fake passphrase to indicate that it
1320     // has already been set.
1321     bool connectable = false;
1322     properties.GetBooleanWithoutPathExpansion(
1323         shill::kConnectableProperty, &connectable);
1324     passphrase_textfield_->SetShowFake(connectable);
1325   }
1326
1327   // Save credentials
1328   bool save_credentials = false;
1329   properties.GetBooleanWithoutPathExpansion(
1330       shill::kSaveCredentialsProperty, &save_credentials);
1331   save_credentials_checkbox_->SetChecked(save_credentials);
1332
1333   UpdateDialogButtons();
1334   RefreshShareCheckbox();
1335   UpdateErrorLabel();
1336 }
1337
1338 void WifiConfigView::InitFocus() {
1339   views::View* view_to_focus = GetInitiallyFocusedView();
1340   if (view_to_focus)
1341     view_to_focus->RequestFocus();
1342 }
1343
1344 bool WifiConfigView::IsConfigureDialog() {
1345   const NetworkState* network = GetNetworkState();
1346   return network && network->type() == shill::kTypeEthernet;
1347 }
1348
1349 void WifiConfigView::NetworkPropertiesUpdated(const NetworkState* network) {
1350   if (network->path() != service_path_)
1351     return;
1352   UpdateErrorLabel();
1353 }
1354
1355 const NetworkState* WifiConfigView::GetNetworkState() const {
1356   if (service_path_.empty())
1357     return NULL;
1358   return NetworkHandler::Get()->network_state_handler()->GetNetworkState(
1359       service_path_);
1360 }
1361
1362 // static
1363 void WifiConfigView::ParseUIProperty(NetworkPropertyUIData* property_ui_data,
1364                                      const NetworkState* network,
1365                                      const std::string& key) {
1366   ::onc::ONCSource onc_source = ::onc::ONC_SOURCE_NONE;
1367   const base::DictionaryValue* onc =
1368       onc::FindPolicyForActiveUser(network->guid(), &onc_source);
1369   std::string onc_tag = network->type() == shill::kTypeEthernet
1370                             ? ::onc::network_config::kEthernet
1371                             : ::onc::network_config::kWiFi;
1372   property_ui_data->ParseOncProperty(onc_source, onc, onc_tag + '.' + key);
1373 }
1374
1375 // static
1376 void WifiConfigView::ParseEAPUIProperty(NetworkPropertyUIData* property_ui_data,
1377                                         const NetworkState* network,
1378                                         const std::string& key) {
1379   std::string onc_tag = network->type() == shill::kTypeEthernet
1380                             ? ::onc::ethernet::kEAP
1381                             : ::onc::wifi::kEAP;
1382   ParseUIProperty(property_ui_data, network, onc_tag + '.' + key);
1383 }
1384
1385 }  // namespace chromeos