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