OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/login/user_controller.h" | 5 #include "chrome/browser/chromeos/login/user_controller.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "app/l10n_util.h" | 10 #include "app/l10n_util.h" |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "chrome/browser/chromeos/login/wizard_controller.h" | 21 #include "chrome/browser/chromeos/login/wizard_controller.h" |
22 #include "chrome/common/notification_service.h" | 22 #include "chrome/common/notification_service.h" |
23 #include "chrome/common/notification_type.h" | 23 #include "chrome/common/notification_type.h" |
24 #include "cros/chromeos_wm_ipc_enums.h" | 24 #include "cros/chromeos_wm_ipc_enums.h" |
25 #include "gfx/canvas.h" | 25 #include "gfx/canvas.h" |
26 #include "grit/generated_resources.h" | 26 #include "grit/generated_resources.h" |
27 #include "grit/theme_resources.h" | 27 #include "grit/theme_resources.h" |
28 #include "views/background.h" | 28 #include "views/background.h" |
29 #include "views/controls/button/native_button.h" | 29 #include "views/controls/button/native_button.h" |
30 #include "views/controls/label.h" | 30 #include "views/controls/label.h" |
| 31 #include "views/controls/throbber.h" |
31 #include "views/grid_layout.h" | 32 #include "views/grid_layout.h" |
32 #include "views/painter.h" | 33 #include "views/painter.h" |
33 #include "views/screen.h" | 34 #include "views/screen.h" |
34 #include "views/widget/root_view.h" | 35 #include "views/widget/root_view.h" |
35 #include "views/widget/widget_gtk.h" | 36 #include "views/widget/widget_gtk.h" |
36 | 37 |
37 using views::ColumnSet; | 38 using views::ColumnSet; |
38 using views::GridLayout; | 39 using views::GridLayout; |
39 using views::WidgetGtk; | 40 using views::WidgetGtk; |
40 | 41 |
(...skipping 21 matching lines...) Expand all Loading... |
62 public: | 63 public: |
63 ClickNotifyingWidget(views::WidgetGtk::Type type, | 64 ClickNotifyingWidget(views::WidgetGtk::Type type, |
64 UserController* controller) | 65 UserController* controller) |
65 : WidgetGtk(type), | 66 : WidgetGtk(type), |
66 controller_(controller) { | 67 controller_(controller) { |
67 } | 68 } |
68 | 69 |
69 private: | 70 private: |
70 gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event) { | 71 gboolean OnButtonPress(GtkWidget* widget, GdkEventButton* event) { |
71 if (!controller_->is_user_selected()) | 72 if (!controller_->is_user_selected()) |
72 controller_->SelectUser(controller_->user_index()); | 73 controller_->SelectUserRelative(0); |
73 | 74 |
74 return views::WidgetGtk::OnButtonPress(widget, event); | 75 return views::WidgetGtk::OnButtonPress(widget, event); |
75 } | 76 } |
76 | 77 |
77 UserController* controller_; | 78 UserController* controller_; |
78 | 79 |
79 DISALLOW_COPY_AND_ASSIGN(ClickNotifyingWidget); | 80 DISALLOW_COPY_AND_ASSIGN(ClickNotifyingWidget); |
80 }; | 81 }; |
81 | 82 |
82 void CloseWindow(views::WidgetGtk* window) { | 83 void CloseWindow(views::WidgetGtk* window) { |
(...skipping 24 matching lines...) Expand all Loading... |
107 is_guest_(is_guest), | 108 is_guest_(is_guest), |
108 is_owner_(false), | 109 is_owner_(false), |
109 show_name_tooltip_(false), | 110 show_name_tooltip_(false), |
110 delegate_(delegate), | 111 delegate_(delegate), |
111 controls_window_(NULL), | 112 controls_window_(NULL), |
112 image_window_(NULL), | 113 image_window_(NULL), |
113 border_window_(NULL), | 114 border_window_(NULL), |
114 label_window_(NULL), | 115 label_window_(NULL), |
115 unselected_label_window_(NULL), | 116 unselected_label_window_(NULL), |
116 user_view_(NULL), | 117 user_view_(NULL), |
117 new_user_view_(NULL), | |
118 existing_user_view_(NULL), | |
119 guest_user_view_(NULL), | |
120 label_view_(NULL), | 118 label_view_(NULL), |
121 unselected_label_view_(NULL), | 119 unselected_label_view_(NULL), |
| 120 user_input_(NULL), |
| 121 throbber_host_(NULL), |
122 method_factory_(this) { | 122 method_factory_(this) { |
123 registrar_.Add( | 123 registrar_.Add( |
124 this, | 124 this, |
125 NotificationType::LOGIN_USER_IMAGE_CHANGED, | 125 NotificationType::LOGIN_USER_IMAGE_CHANGED, |
126 NotificationService::AllSources()); | 126 NotificationService::AllSources()); |
127 } | 127 } |
128 | 128 |
129 UserController::UserController(Delegate* delegate, | 129 UserController::UserController(Delegate* delegate, |
130 const UserManager::User& user) | 130 const UserManager::User& user) |
131 : user_index_(-1), | 131 : user_index_(-1), |
132 is_user_selected_(false), | 132 is_user_selected_(false), |
133 is_new_user_(false), | 133 is_new_user_(false), |
134 is_guest_(false), | 134 is_guest_(false), |
135 // Empty 'cached_owner()' means that owner hasn't been cached yet, not | 135 // Empty 'cached_owner()' means that owner hasn't been cached yet, not |
136 // that owner has an empty email. | 136 // that owner has an empty email. |
137 is_owner_(user.email() == UserCrosSettingsProvider::cached_owner()), | 137 is_owner_(user.email() == UserCrosSettingsProvider::cached_owner()), |
138 show_name_tooltip_(false), | 138 show_name_tooltip_(false), |
139 user_(user), | 139 user_(user), |
140 delegate_(delegate), | 140 delegate_(delegate), |
141 controls_window_(NULL), | 141 controls_window_(NULL), |
142 image_window_(NULL), | 142 image_window_(NULL), |
143 border_window_(NULL), | 143 border_window_(NULL), |
144 label_window_(NULL), | 144 label_window_(NULL), |
145 unselected_label_window_(NULL), | 145 unselected_label_window_(NULL), |
146 user_view_(NULL), | 146 user_view_(NULL), |
147 new_user_view_(NULL), | |
148 existing_user_view_(NULL), | |
149 guest_user_view_(NULL), | |
150 label_view_(NULL), | 147 label_view_(NULL), |
151 unselected_label_view_(NULL), | 148 unselected_label_view_(NULL), |
| 149 user_input_(NULL), |
| 150 throbber_host_(NULL), |
152 method_factory_(this) { | 151 method_factory_(this) { |
153 DCHECK(!user.email().empty()); | 152 DCHECK(!user.email().empty()); |
154 registrar_.Add( | 153 registrar_.Add( |
155 this, | 154 this, |
156 NotificationType::LOGIN_USER_IMAGE_CHANGED, | 155 NotificationType::LOGIN_USER_IMAGE_CHANGED, |
157 NotificationService::AllSources()); | 156 NotificationService::AllSources()); |
158 } | 157 } |
159 | 158 |
160 UserController::~UserController() { | 159 UserController::~UserController() { |
161 // Reset the widget delegate of every window to NULL, so the user | 160 // Reset the widget delegate of every window to NULL, so the user |
(...skipping 14 matching lines...) Expand all Loading... |
176 controls_window_ = | 175 controls_window_ = |
177 CreateControlsWindow(index, &controls_width, &controls_height, | 176 CreateControlsWindow(index, &controls_width, &controls_height, |
178 need_browse_without_signin); | 177 need_browse_without_signin); |
179 image_window_ = CreateImageWindow(index); | 178 image_window_ = CreateImageWindow(index); |
180 CreateBorderWindow(index, total_user_count, controls_width, controls_height); | 179 CreateBorderWindow(index, total_user_count, controls_width, controls_height); |
181 label_window_ = CreateLabelWindow(index, WM_IPC_WINDOW_LOGIN_LABEL); | 180 label_window_ = CreateLabelWindow(index, WM_IPC_WINDOW_LOGIN_LABEL); |
182 unselected_label_window_ = | 181 unselected_label_window_ = |
183 CreateLabelWindow(index, WM_IPC_WINDOW_LOGIN_UNSELECTED_LABEL); | 182 CreateLabelWindow(index, WM_IPC_WINDOW_LOGIN_UNSELECTED_LABEL); |
184 } | 183 } |
185 | 184 |
186 void UserController::SetPasswordEnabled(bool enable) { | 185 void UserController::StartThrobber() { |
187 DCHECK(!is_new_user_); | 186 throbber_host_->StartThrobber(); |
188 existing_user_view_->password_field()->SetEnabled(enable); | 187 } |
189 if (enable) { | 188 |
190 user_view_->StopThrobber(); | 189 void UserController::StopThrobber() { |
191 delegate_->SetStatusAreaEnabled(enable); | 190 throbber_host_->StopThrobber(); |
192 } else { | |
193 delegate_->SetStatusAreaEnabled(enable); | |
194 user_view_->StartThrobber(); | |
195 } | |
196 } | 191 } |
197 | 192 |
198 std::wstring UserController::GetNameTooltip() const { | 193 std::wstring UserController::GetNameTooltip() const { |
199 if (is_new_user_) | 194 if (is_new_user_) |
200 return l10n_util::GetString(IDS_ADD_USER); | 195 return l10n_util::GetString(IDS_ADD_USER); |
201 if (is_guest_) | 196 if (is_guest_) |
202 return l10n_util::GetString(IDS_GO_INCOGNITO_BUTTON); | 197 return l10n_util::GetString(IDS_GO_INCOGNITO_BUTTON); |
203 | 198 |
204 // Tooltip contains user's display name and his email domain to distinguish | 199 // Tooltip contains user's display name and his email domain to distinguish |
205 // this user from the other one with the same display name. | 200 // this user from the other one with the same display name. |
206 const std::string& email = user_.email(); | 201 const std::string& email = user_.email(); |
207 size_t at_pos = email.rfind('@'); | 202 size_t at_pos = email.rfind('@'); |
208 if (at_pos == std::string::npos) { | 203 if (at_pos == std::string::npos) { |
209 NOTREACHED(); | 204 NOTREACHED(); |
210 return std::wstring(); | 205 return std::wstring(); |
211 } | 206 } |
212 size_t domain_start = at_pos + 1; | 207 size_t domain_start = at_pos + 1; |
213 std::string domain = email.substr(domain_start, | 208 std::string domain = email.substr(domain_start, |
214 email.length() - domain_start); | 209 email.length() - domain_start); |
215 return UTF8ToWide(base::StringPrintf("%s (%s)", | 210 return UTF8ToWide(base::StringPrintf("%s (%s)", |
216 user_.GetDisplayName().c_str(), | 211 user_.GetDisplayName().c_str(), |
217 domain.c_str())); | 212 domain.c_str())); |
218 } | 213 } |
219 | 214 |
220 void UserController::ClearAndEnablePassword() { | 215 void UserController::ClearAndEnableFields() { |
221 if (is_new_user_) { | 216 user_input_->ClearAndFocusControls(); |
222 // TODO(avayvod): This code seems not reachable to me. | 217 user_input_->EnableInputControls(true); |
223 new_user_view_->ClearAndEnablePassword(); | 218 SetStatusAreaEnabled(true); |
224 } else { | 219 StopThrobber(); |
225 existing_user_view_->password_field()->SetText(string16()); | |
226 SetPasswordEnabled(true); | |
227 FocusPasswordField(); | |
228 } | |
229 } | 220 } |
230 | 221 |
231 void UserController::ClearAndEnableFields() { | 222 void UserController::ClearAndEnablePassword() { |
232 if (is_new_user_) { | 223 user_input_->ClearAndFocusPassword(); |
233 new_user_view_->ClearAndEnableFields(); | 224 user_input_->EnableInputControls(true); |
234 } else if (is_guest_) { | 225 SetStatusAreaEnabled(true); |
235 guest_user_view_->FocusSignInButton(); | 226 StopThrobber(); |
236 } else { | 227 } |
237 ClearAndEnablePassword(); | 228 |
238 } | 229 gfx::Rect UserController::GetMainInputScreenBounds() const { |
| 230 return user_input_->GetMainInputScreenBounds(); |
239 } | 231 } |
240 | 232 |
241 void UserController::EnableNameTooltip(bool enable) { | 233 void UserController::EnableNameTooltip(bool enable) { |
242 std::wstring tooltip_text; | 234 std::wstring tooltip_text; |
243 if (enable) | 235 if (enable) |
244 tooltip_text = GetNameTooltip(); | 236 tooltip_text = GetNameTooltip(); |
245 | 237 |
246 if (user_view_) | 238 if (user_view_) |
247 user_view_->SetTooltipText(tooltip_text); | 239 user_view_->SetTooltipText(tooltip_text); |
248 if (label_view_) | 240 if (label_view_) |
249 label_view_->SetTooltipText(tooltip_text); | 241 label_view_->SetTooltipText(tooltip_text); |
250 if (unselected_label_view_) | 242 if (unselected_label_view_) |
251 unselected_label_view_->SetTooltipText(tooltip_text); | 243 unselected_label_view_->SetTooltipText(tooltip_text); |
252 } | 244 } |
253 | 245 |
254 void UserController::ButtonPressed(views::Button* sender, | |
255 const views::Event& event) { | |
256 Login(); | |
257 } | |
258 | |
259 bool UserController::HandleKeystroke( | |
260 views::Textfield* sender, | |
261 const views::Textfield::Keystroke& keystroke) { | |
262 if (keystroke.GetKeyboardCode() == app::VKEY_RETURN) { | |
263 Login(); | |
264 return true; | |
265 } else if (keystroke.GetKeyboardCode() == app::VKEY_LEFT) { | |
266 SelectUser(user_index() - 1); | |
267 return true; | |
268 } else if (keystroke.GetKeyboardCode() == app::VKEY_RIGHT) { | |
269 SelectUser(user_index() + 1); | |
270 return true; | |
271 } | |
272 delegate_->ClearErrors(); | |
273 return false; | |
274 } | |
275 | |
276 void UserController::ContentsChanged(views::Textfield* sender, | |
277 const string16& new_contents) { | |
278 } | |
279 | |
280 void UserController::Observe( | 246 void UserController::Observe( |
281 NotificationType type, | 247 NotificationType type, |
282 const NotificationSource& source, | 248 const NotificationSource& source, |
283 const NotificationDetails& details) { | 249 const NotificationDetails& details) { |
284 if (type != NotificationType::LOGIN_USER_IMAGE_CHANGED || | 250 if (type != NotificationType::LOGIN_USER_IMAGE_CHANGED || |
285 !user_view_) | 251 !user_view_) |
286 return; | 252 return; |
287 | 253 |
288 UserManager::User* user = Details<UserManager::User>(details).ptr(); | 254 UserManager::User* user = Details<UserManager::User>(details).ptr(); |
289 if (user_.email() != user->email()) | 255 if (user_.email() != user->email()) |
290 return; | 256 return; |
291 | 257 |
292 user_.set_image(user->image()); | 258 user_.set_image(user->image()); |
293 user_view_->SetImage(user_.image(), user_.image()); | 259 user_view_->SetImage(user_.image(), user_.image()); |
294 } | 260 } |
295 | 261 |
296 void UserController::Login() { | |
297 if (is_guest_) { | |
298 delegate_->LoginOffTheRecord(); | |
299 } else { | |
300 // Delegate will reenable as necessary. | |
301 SetPasswordEnabled(false); | |
302 | |
303 delegate_->Login(this, existing_user_view_->password_field()->text()); | |
304 } | |
305 } | |
306 | |
307 void UserController::IsActiveChanged(bool active) { | 262 void UserController::IsActiveChanged(bool active) { |
308 is_user_selected_ = active; | 263 is_user_selected_ = active; |
309 if (active) { | 264 if (active) { |
310 delegate_->OnUserSelected(this); | 265 delegate_->OnUserSelected(this); |
311 user_view_->SetRemoveButtonVisible( | 266 user_view_->SetRemoveButtonVisible( |
312 !is_new_user_ && !is_guest_ && !is_owner_); | 267 !is_new_user_ && !is_guest_ && !is_owner_); |
313 } else { | 268 } else { |
314 user_view_->SetRemoveButtonVisible(false); | 269 user_view_->SetRemoveButtonVisible(false); |
315 delegate_->ClearErrors(); | 270 delegate_->ClearErrors(); |
316 } | 271 } |
(...skipping 21 matching lines...) Expand all Loading... |
338 | 293 |
339 window->Show(); | 294 window->Show(); |
340 } | 295 } |
341 | 296 |
342 WidgetGtk* UserController::CreateControlsWindow( | 297 WidgetGtk* UserController::CreateControlsWindow( |
343 int index, | 298 int index, |
344 int* width, int* height, | 299 int* width, int* height, |
345 bool need_browse_without_signin) { | 300 bool need_browse_without_signin) { |
346 views::View* control_view; | 301 views::View* control_view; |
347 if (is_new_user_) { | 302 if (is_new_user_) { |
348 new_user_view_ = | 303 NewUserView* new_user_view = |
349 new NewUserView(this, true, need_browse_without_signin); | 304 new NewUserView(this, true, need_browse_without_signin); |
350 new_user_view_->Init(); | 305 new_user_view->Init(); |
351 control_view = new_user_view_; | 306 control_view = new_user_view; |
| 307 user_input_ = new_user_view; |
| 308 throbber_host_ = new_user_view; |
352 } else if (is_guest_) { | 309 } else if (is_guest_) { |
353 guest_user_view_ = new GuestUserView(this); | 310 GuestUserView* guest_user_view = new GuestUserView(this); |
354 guest_user_view_->RecreateFields(); | 311 guest_user_view->RecreateFields(); |
355 control_view = guest_user_view_; | 312 control_view = guest_user_view; |
| 313 user_input_ = guest_user_view; |
| 314 throbber_host_ = guest_user_view; |
356 } else { | 315 } else { |
357 existing_user_view_ = new ExistingUserView(this); | 316 ExistingUserView* existing_user_view = new ExistingUserView(this); |
358 existing_user_view_->RecreateFields(); | 317 existing_user_view->RecreateFields(); |
359 control_view = existing_user_view_; | 318 control_view = existing_user_view; |
| 319 user_input_ = existing_user_view; |
| 320 throbber_host_ = existing_user_view; |
360 } | 321 } |
361 | 322 |
362 *height = kControlsHeight; | 323 *height = kControlsHeight; |
363 *width = kUserImageSize; | 324 *width = kUserImageSize; |
364 if (is_new_user_) { | 325 if (is_new_user_) { |
365 DCHECK(new_user_view_); | 326 gfx::Size size = control_view->GetPreferredSize(); |
366 gfx::Size size = new_user_view_->GetPreferredSize(); | |
367 *width = size.width(); | 327 *width = size.width(); |
368 *height = size.height(); | 328 *height = size.height(); |
369 } | 329 } |
370 | 330 |
371 WidgetGtk* window = new WidgetGtk(WidgetGtk::TYPE_WINDOW); | 331 WidgetGtk* window = new WidgetGtk(WidgetGtk::TYPE_WINDOW); |
372 ConfigureLoginWindow(window, | 332 ConfigureLoginWindow(window, |
373 index, | 333 index, |
374 gfx::Rect(*width, *height), | 334 gfx::Rect(*width, *height), |
375 WM_IPC_WINDOW_LOGIN_CONTROLS, | 335 WM_IPC_WINDOW_LOGIN_CONTROLS, |
376 control_view); | 336 control_view); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
495 login::kSelectedLabelHeight : login::kUnselectedLabelHeight; | 455 login::kSelectedLabelHeight : login::kUnselectedLabelHeight; |
496 WidgetGtk* window = new ClickNotifyingWidget(WidgetGtk::TYPE_WINDOW, this); | 456 WidgetGtk* window = new ClickNotifyingWidget(WidgetGtk::TYPE_WINDOW, this); |
497 ConfigureLoginWindow(window, | 457 ConfigureLoginWindow(window, |
498 index, | 458 index, |
499 gfx::Rect(0, 0, width, height), | 459 gfx::Rect(0, 0, width, height), |
500 type, | 460 type, |
501 label); | 461 label); |
502 return window; | 462 return window; |
503 } | 463 } |
504 | 464 |
505 gfx::Rect UserController::GetScreenBounds() const { | |
506 if (is_new_user_) | |
507 return new_user_view_->GetUsernameBounds(); | |
508 else | |
509 return existing_user_view_->password_field()->GetScreenBounds(); | |
510 } | |
511 | |
512 void UserController::OnLogin(const std::string& username, | 465 void UserController::OnLogin(const std::string& username, |
513 const std::string& password) { | 466 const std::string& password) { |
514 user_.set_email(username); | 467 if (is_new_user_) |
| 468 user_.set_email(username); |
| 469 |
| 470 user_input_->EnableInputControls(false); |
| 471 SetStatusAreaEnabled(false); |
| 472 StartThrobber(); |
| 473 |
515 delegate_->Login(this, UTF8ToUTF16(password)); | 474 delegate_->Login(this, UTF8ToUTF16(password)); |
516 } | 475 } |
517 | 476 |
518 void UserController::OnCreateAccount() { | 477 void UserController::OnCreateAccount() { |
519 delegate_->ActivateWizard(WizardController::kAccountScreenName); | 478 delegate_->ActivateWizard(WizardController::kAccountScreenName); |
520 } | 479 } |
521 | 480 |
522 void UserController::OnLoginOffTheRecord() { | 481 void UserController::OnLoginOffTheRecord() { |
| 482 user_input_->EnableInputControls(false); |
| 483 SetStatusAreaEnabled(false); |
| 484 StartThrobber(); |
| 485 |
523 delegate_->LoginOffTheRecord(); | 486 delegate_->LoginOffTheRecord(); |
524 } | 487 } |
525 | 488 |
526 void UserController::ClearErrors() { | 489 void UserController::ClearErrors() { |
527 delegate_->ClearErrors(); | 490 delegate_->ClearErrors(); |
528 } | 491 } |
529 | 492 |
530 void UserController::NavigateAway() { | 493 void UserController::NavigateAway() { |
531 SelectUser(user_index() - 1); | 494 SelectUserRelative(-1); |
532 } | 495 } |
533 | 496 |
534 void UserController::OnRemoveUser() { | 497 void UserController::OnRemoveUser() { |
535 // Must not proceed without signature verification. | 498 // Must not proceed without signature verification. |
536 UserCrosSettingsProvider user_settings; | 499 UserCrosSettingsProvider user_settings; |
537 bool trusted_owner_available = user_settings.RequestTrustedOwner( | 500 bool trusted_owner_available = user_settings.RequestTrustedOwner( |
538 method_factory_.NewRunnableMethod(&UserController::OnRemoveUser)); | 501 method_factory_.NewRunnableMethod(&UserController::OnRemoveUser)); |
539 if (!trusted_owner_available) { | 502 if (!trusted_owner_available) { |
540 // Value of owner email is still not verified. | 503 // Value of owner email is still not verified. |
541 // Another attempt will be invoked after verification completion. | 504 // Another attempt will be invoked after verification completion. |
542 return; | 505 return; |
543 } | 506 } |
544 if (user().email() == UserCrosSettingsProvider::cached_owner()) { | 507 if (user().email() == UserCrosSettingsProvider::cached_owner()) { |
545 // Owner is not allowed to be removed from the device. | 508 // Owner is not allowed to be removed from the device. |
546 return; | 509 return; |
547 } | 510 } |
548 delegate_->RemoveUser(this); | 511 delegate_->RemoveUser(this); |
549 } | 512 } |
550 | 513 |
551 void UserController::SelectUser(int index) { | 514 void UserController::SelectUserRelative(int shift) { |
552 delegate_->SelectUser(index); | 515 delegate_->SelectUser(user_index() + shift); |
553 } | |
554 | |
555 void UserController::FocusPasswordField() { | |
556 existing_user_view_->FocusPasswordField(); | |
557 } | 516 } |
558 | 517 |
559 } // namespace chromeos | 518 } // namespace chromeos |
OLD | NEW |