Home | History | Annotate | Download | only in options
      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/wimax_config_view.h"
      6 
      7 #include "ash/system/chromeos/network/network_connect.h"
      8 #include "base/strings/string_util.h"
      9 #include "base/strings/stringprintf.h"
     10 #include "base/strings/utf_string_conversions.h"
     11 #include "chrome/browser/chromeos/enrollment_dialog_view.h"
     12 #include "chrome/browser/chromeos/login/startup_utils.h"
     13 #include "chrome/browser/chromeos/options/network_connect.h"
     14 #include "chrome/browser/profiles/profile_manager.h"
     15 #include "chromeos/login/login_state.h"
     16 #include "chromeos/network/network_configuration_handler.h"
     17 #include "chromeos/network/network_event_log.h"
     18 #include "chromeos/network/network_profile.h"
     19 #include "chromeos/network/network_profile_handler.h"
     20 #include "chromeos/network/network_state.h"
     21 #include "chromeos/network/network_state_handler.h"
     22 #include "chromeos/network/onc/onc_constants.h"
     23 #include "grit/chromium_strings.h"
     24 #include "grit/generated_resources.h"
     25 #include "grit/locale_settings.h"
     26 #include "grit/theme_resources.h"
     27 #include "third_party/cros_system_api/dbus/service_constants.h"
     28 #include "ui/base/events/event.h"
     29 #include "ui/base/l10n/l10n_util.h"
     30 #include "ui/base/resource/resource_bundle.h"
     31 #include "ui/views/controls/button/checkbox.h"
     32 #include "ui/views/controls/button/image_button.h"
     33 #include "ui/views/controls/label.h"
     34 #include "ui/views/controls/textfield/textfield.h"
     35 #include "ui/views/layout/grid_layout.h"
     36 #include "ui/views/layout/layout_constants.h"
     37 #include "ui/views/widget/widget.h"
     38 #include "ui/views/window/dialog_client_view.h"
     39 
     40 namespace chromeos {
     41 
     42 namespace {
     43 
     44 void ShillError(const std::string& function,
     45                 const std::string& error_name,
     46                 scoped_ptr<base::DictionaryValue> error_data) {
     47   NET_LOG_ERROR("Shill Error from WimaxConfigView: " + error_name, function);
     48 }
     49 
     50 }  // namespace
     51 
     52 WimaxConfigView::WimaxConfigView(NetworkConfigView* parent,
     53                                  const std::string& service_path)
     54     : ChildNetworkConfigView(parent, service_path),
     55       identity_label_(NULL),
     56       identity_textfield_(NULL),
     57       save_credentials_checkbox_(NULL),
     58       share_network_checkbox_(NULL),
     59       shared_network_label_(NULL),
     60       passphrase_label_(NULL),
     61       passphrase_textfield_(NULL),
     62       passphrase_visible_button_(NULL),
     63       error_label_(NULL),
     64       weak_ptr_factory_(this) {
     65   Init();
     66 }
     67 
     68 WimaxConfigView::~WimaxConfigView() {
     69 }
     70 
     71 string16 WimaxConfigView::GetTitle() const {
     72   return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_JOIN_WIMAX_NETWORKS);
     73 }
     74 
     75 views::View* WimaxConfigView::GetInitiallyFocusedView() {
     76   if (identity_textfield_ && identity_textfield_->enabled())
     77     return identity_textfield_;
     78   if (passphrase_textfield_ && passphrase_textfield_->enabled())
     79     return passphrase_textfield_;
     80   return NULL;
     81 }
     82 
     83 bool WimaxConfigView::CanLogin() {
     84   // In OOBE it may be valid to log in with no credentials (crbug.com/137776).
     85   if (!chromeos::StartupUtils::IsOobeCompleted())
     86     return true;
     87 
     88   // TODO(benchan): Update this with the correct minimum length (don't just
     89   // check if empty).
     90   // If the network requires a passphrase, make sure it is the right length.
     91   return passphrase_textfield_ && !passphrase_textfield_->text().empty();
     92 }
     93 
     94 void WimaxConfigView::UpdateDialogButtons() {
     95   parent_->GetDialogClientView()->UpdateDialogButtons();
     96 }
     97 
     98 void WimaxConfigView::UpdateErrorLabel() {
     99   base::string16 error_msg;
    100   if (!service_path_.empty()) {
    101     const NetworkState* wimax = NetworkHandler::Get()->network_state_handler()->
    102         GetNetworkState(service_path_);
    103     if (wimax && wimax->connection_state() == flimflam::kStateFailure)
    104       error_msg = ash::network_connect::ErrorString(wimax->error());
    105   }
    106   if (!error_msg.empty()) {
    107     error_label_->SetText(error_msg);
    108     error_label_->SetVisible(true);
    109   } else {
    110     error_label_->SetVisible(false);
    111   }
    112 }
    113 
    114 void WimaxConfigView::ContentsChanged(views::Textfield* sender,
    115                                       const string16& new_contents) {
    116   UpdateDialogButtons();
    117 }
    118 
    119 bool WimaxConfigView::HandleKeyEvent(views::Textfield* sender,
    120                                      const ui::KeyEvent& key_event) {
    121   if (sender == passphrase_textfield_ &&
    122       key_event.key_code() == ui::VKEY_RETURN) {
    123     parent_->GetDialogClientView()->AcceptWindow();
    124   }
    125   return false;
    126 }
    127 
    128 void WimaxConfigView::ButtonPressed(views::Button* sender,
    129                                    const ui::Event& event) {
    130   if (sender == passphrase_visible_button_) {
    131     if (passphrase_textfield_) {
    132       passphrase_textfield_->SetObscured(!passphrase_textfield_->IsObscured());
    133       passphrase_visible_button_->SetToggled(
    134           !passphrase_textfield_->IsObscured());
    135     }
    136   } else {
    137     NOTREACHED();
    138   }
    139 }
    140 
    141 bool WimaxConfigView::Login() {
    142   const NetworkState* wimax = NetworkHandler::Get()->network_state_handler()->
    143       GetNetworkState(service_path_);
    144   if (!wimax) {
    145     // Shill no longer knows about this network (edge case).
    146     // TODO(stevenjb): Add notification for this.
    147     NET_LOG_ERROR("Network not found", service_path_);
    148     return true;  // Close dialog
    149   }
    150   base::DictionaryValue properties;
    151   properties.SetStringWithoutPathExpansion(
    152       flimflam::kEapIdentityProperty, GetEapIdentity());
    153   properties.SetStringWithoutPathExpansion(
    154       flimflam::kEapPasswordProperty, GetEapPassphrase());
    155   properties.SetBooleanWithoutPathExpansion(
    156       flimflam::kSaveCredentialsProperty, GetSaveCredentials());
    157 
    158   const bool share_default = true;
    159   bool share_network = GetShareNetwork(share_default);
    160   ash::network_connect::ConfigureNetworkAndConnect(
    161       service_path_, properties, share_network);
    162   return true;  // dialog will be closed
    163 }
    164 
    165 std::string WimaxConfigView::GetEapIdentity() const {
    166   DCHECK(identity_textfield_);
    167   return UTF16ToUTF8(identity_textfield_->text());
    168 }
    169 
    170 std::string WimaxConfigView::GetEapPassphrase() const {
    171   return passphrase_textfield_ ? UTF16ToUTF8(passphrase_textfield_->text()) :
    172                                  std::string();
    173 }
    174 
    175 bool WimaxConfigView::GetSaveCredentials() const {
    176   return save_credentials_checkbox_ ? save_credentials_checkbox_->checked() :
    177                                       false;
    178 }
    179 
    180 bool WimaxConfigView::GetShareNetwork(bool share_default) const {
    181   return share_network_checkbox_ ? share_network_checkbox_->checked() :
    182                                    share_default;
    183 }
    184 
    185 void WimaxConfigView::Cancel() {
    186 }
    187 
    188 void WimaxConfigView::Init() {
    189   const NetworkState* wimax = NetworkHandler::Get()->network_state_handler()->
    190       GetNetworkState(service_path_);
    191   DCHECK(wimax && wimax->type() == flimflam::kTypeWimax);
    192 
    193   WifiConfigView::ParseWiFiEAPUIProperty(
    194       &save_credentials_ui_data_, wimax, onc::eap::kSaveCredentials);
    195   WifiConfigView::ParseWiFiEAPUIProperty(
    196       &identity_ui_data_, wimax, onc::eap::kIdentity);
    197   WifiConfigView::ParseWiFiUIProperty(
    198       &passphrase_ui_data_, wimax, onc::wifi::kPassphrase);
    199 
    200   views::GridLayout* layout = views::GridLayout::CreatePanel(this);
    201   SetLayoutManager(layout);
    202 
    203   const int column_view_set_id = 0;
    204   views::ColumnSet* column_set = layout->AddColumnSet(column_view_set_id);
    205   const int kPasswordVisibleWidth = 20;
    206   // Label
    207   column_set->AddColumn(views::GridLayout::LEADING, views::GridLayout::FILL, 1,
    208                         views::GridLayout::USE_PREF, 0, 0);
    209   column_set->AddPaddingColumn(0, views::kRelatedControlSmallHorizontalSpacing);
    210   // Textfield, combobox.
    211   column_set->AddColumn(views::GridLayout::FILL, views::GridLayout::FILL, 1,
    212                         views::GridLayout::USE_PREF, 0,
    213                         ChildNetworkConfigView::kInputFieldMinWidth);
    214   column_set->AddPaddingColumn(0, views::kRelatedControlSmallHorizontalSpacing);
    215   // Password visible button / policy indicator.
    216   column_set->AddColumn(views::GridLayout::CENTER, views::GridLayout::FILL, 1,
    217                         views::GridLayout::USE_PREF, 0, kPasswordVisibleWidth);
    218 
    219   // Network name
    220   layout->StartRow(0, column_view_set_id);
    221   layout->AddView(new views::Label(l10n_util::GetStringUTF16(
    222       IDS_OPTIONS_SETTINGS_INTERNET_TAB_NETWORK)));
    223   views::Label* label = new views::Label(UTF8ToUTF16(wimax->name()));
    224   label->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    225   layout->AddView(label);
    226   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    227 
    228   // Identity
    229   layout->StartRow(0, column_view_set_id);
    230   string16 identity_label_text = l10n_util::GetStringUTF16(
    231       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_CERT_IDENTITY);
    232   identity_label_ = new views::Label(identity_label_text);
    233   layout->AddView(identity_label_);
    234   identity_textfield_ = new views::Textfield(
    235       views::Textfield::STYLE_DEFAULT);
    236   identity_textfield_->SetAccessibleName(identity_label_text);
    237   identity_textfield_->SetController(this);
    238   identity_textfield_->SetEnabled(identity_ui_data_.IsEditable());
    239   layout->AddView(identity_textfield_);
    240   layout->AddView(new ControlledSettingIndicatorView(identity_ui_data_));
    241   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    242 
    243   // Passphrase input
    244   layout->StartRow(0, column_view_set_id);
    245   string16 passphrase_label_text = l10n_util::GetStringUTF16(
    246       IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PASSPHRASE);
    247   passphrase_label_ = new views::Label(passphrase_label_text);
    248   layout->AddView(passphrase_label_);
    249   passphrase_textfield_ = new views::Textfield(
    250       views::Textfield::STYLE_OBSCURED);
    251   passphrase_textfield_->SetController(this);
    252   passphrase_label_->SetEnabled(true);
    253   passphrase_textfield_->SetEnabled(passphrase_ui_data_.IsEditable());
    254   passphrase_textfield_->SetAccessibleName(passphrase_label_text);
    255   layout->AddView(passphrase_textfield_);
    256 
    257   if (passphrase_ui_data_.IsManaged()) {
    258     layout->AddView(new ControlledSettingIndicatorView(passphrase_ui_data_));
    259   } else {
    260     // Password visible button.
    261     passphrase_visible_button_ = new views::ToggleImageButton(this);
    262     passphrase_visible_button_->set_focusable(true);
    263     passphrase_visible_button_->SetTooltipText(
    264         l10n_util::GetStringUTF16(
    265             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PASSPHRASE_SHOW));
    266     passphrase_visible_button_->SetToggledTooltipText(
    267         l10n_util::GetStringUTF16(
    268             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_PASSPHRASE_HIDE));
    269     passphrase_visible_button_->SetImage(
    270         views::ImageButton::STATE_NORMAL,
    271         ResourceBundle::GetSharedInstance().
    272         GetImageSkiaNamed(IDR_NETWORK_SHOW_PASSWORD));
    273     passphrase_visible_button_->SetImage(
    274         views::ImageButton::STATE_HOVERED,
    275         ResourceBundle::GetSharedInstance().
    276         GetImageSkiaNamed(IDR_NETWORK_SHOW_PASSWORD_HOVER));
    277     passphrase_visible_button_->SetToggledImage(
    278         views::ImageButton::STATE_NORMAL,
    279         ResourceBundle::GetSharedInstance().
    280         GetImageSkiaNamed(IDR_NETWORK_HIDE_PASSWORD));
    281     passphrase_visible_button_->SetToggledImage(
    282         views::ImageButton::STATE_HOVERED,
    283         ResourceBundle::GetSharedInstance().
    284         GetImageSkiaNamed(IDR_NETWORK_HIDE_PASSWORD_HOVER));
    285     passphrase_visible_button_->SetImageAlignment(
    286         views::ImageButton::ALIGN_CENTER, views::ImageButton::ALIGN_MIDDLE);
    287     layout->AddView(passphrase_visible_button_);
    288   }
    289 
    290   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    291 
    292   // Checkboxes.
    293 
    294   if (LoginState::Get()->IsUserAuthenticated()) {
    295     // Save credentials
    296     layout->StartRow(0, column_view_set_id);
    297     save_credentials_checkbox_ = new views::Checkbox(
    298         l10n_util::GetStringUTF16(
    299             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SAVE_CREDENTIALS));
    300     save_credentials_checkbox_->SetEnabled(
    301         save_credentials_ui_data_.IsEditable());
    302     layout->SkipColumns(1);
    303     layout->AddView(save_credentials_checkbox_);
    304     layout->AddView(
    305         new ControlledSettingIndicatorView(save_credentials_ui_data_));
    306   }
    307 
    308   // Share network
    309   if (wimax->profile_path().empty()) {
    310     layout->StartRow(0, column_view_set_id);
    311     share_network_checkbox_ = new views::Checkbox(
    312         l10n_util::GetStringUTF16(
    313             IDS_OPTIONS_SETTINGS_INTERNET_OPTIONS_SHARE_NETWORK));
    314     if (LoginState::Get()->IsUserAuthenticated()) {
    315       share_network_checkbox_->SetChecked(false);  // Default to unshared
    316       share_network_checkbox_->SetEnabled(true);
    317     } else {
    318       // Not logged in, must be shared
    319       share_network_checkbox_->SetChecked(true);
    320       share_network_checkbox_->SetEnabled(false);
    321     }
    322     layout->SkipColumns(1);
    323     layout->AddView(share_network_checkbox_);
    324   }
    325   layout->AddPaddingRow(0, views::kRelatedControlVerticalSpacing);
    326 
    327   // Create an error label.
    328   layout->StartRow(0, column_view_set_id);
    329   layout->SkipColumns(1);
    330   error_label_ = new views::Label();
    331   error_label_->SetHorizontalAlignment(gfx::ALIGN_LEFT);
    332   error_label_->SetEnabledColor(SK_ColorRED);
    333   layout->AddView(error_label_);
    334 
    335   UpdateErrorLabel();
    336 
    337   if (wimax) {
    338     NetworkHandler::Get()->network_configuration_handler()->GetProperties(
    339         service_path_,
    340         base::Bind(&WimaxConfigView::InitFromProperties,
    341                    weak_ptr_factory_.GetWeakPtr()),
    342         base::Bind(&ShillError, "GetProperties"));
    343   }
    344 }
    345 
    346 void WimaxConfigView::InitFromProperties(
    347     const std::string& service_path,
    348     const base::DictionaryValue& properties) {
    349   // EapIdentity
    350   std::string eap_identity;
    351   properties.GetStringWithoutPathExpansion(
    352       flimflam::kEapIdentityProperty, &eap_identity);
    353   identity_textfield_->SetText(UTF8ToUTF16(eap_identity));
    354 
    355   // Save credentials
    356   if (save_credentials_checkbox_) {
    357     bool save_credentials = false;
    358     properties.GetBooleanWithoutPathExpansion(
    359         flimflam::kSaveCredentialsProperty, &save_credentials);
    360     save_credentials_checkbox_->SetChecked(save_credentials);
    361   }
    362 }
    363 
    364 void WimaxConfigView::InitFocus() {
    365   views::View* view_to_focus = GetInitiallyFocusedView();
    366   if (view_to_focus)
    367     view_to_focus->RequestFocus();
    368 }
    369 
    370 }  // namespace chromeos
    371