wimax_config_view.cc revision ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16
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
40namespace chromeos {
41
42namespace {
43
44void 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
52WimaxConfigView::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
68WimaxConfigView::~WimaxConfigView() {
69}
70
71string16 WimaxConfigView::GetTitle() const {
72  return l10n_util::GetStringUTF16(IDS_OPTIONS_SETTINGS_JOIN_WIMAX_NETWORKS);
73}
74
75views::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
83bool 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
94void WimaxConfigView::UpdateDialogButtons() {
95  parent_->GetDialogClientView()->UpdateDialogButtons();
96}
97
98void 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
114void WimaxConfigView::ContentsChanged(views::Textfield* sender,
115                                      const string16& new_contents) {
116  UpdateDialogButtons();
117}
118
119bool 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
128void 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
141bool 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
165std::string WimaxConfigView::GetEapIdentity() const {
166  DCHECK(identity_textfield_);
167  return UTF16ToUTF8(identity_textfield_->text());
168}
169
170std::string WimaxConfigView::GetEapPassphrase() const {
171  return passphrase_textfield_ ? UTF16ToUTF8(passphrase_textfield_->text()) :
172                                 std::string();
173}
174
175bool WimaxConfigView::GetSaveCredentials() const {
176  return save_credentials_checkbox_ ? save_credentials_checkbox_->checked() :
177                                      false;
178}
179
180bool WimaxConfigView::GetShareNetwork(bool share_default) const {
181  return share_network_checkbox_ ? share_network_checkbox_->checked() :
182                                   share_default;
183}
184
185void WimaxConfigView::Cancel() {
186}
187
188void 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
346void 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
364void 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