Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(179)

Side by Side Diff: chrome/browser/chromeos/login/views_login_display.cc

Issue 8436002: [cros] Remove Views implementation for login/OOBE. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: merge Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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/login/views_login_display.h"
6
7 #include <algorithm>
8 #include <vector>
9
10 #include "base/stl_util.h"
11 #include "base/utf_string_conversions.h"
12 #include "chrome/browser/chromeos/input_method/xkeyboard.h"
13 #include "chrome/browser/chromeos/login/help_app_launcher.h"
14 #include "chrome/browser/chromeos/login/message_bubble.h"
15 #include "chrome/browser/chromeos/login/wizard_accessibility_helper.h"
16 #include "chrome/browser/chromeos/view_ids.h"
17 #include "chrome/browser/ui/views/window.h"
18 #include "grit/chromium_strings.h"
19 #include "grit/generated_resources.h"
20 #include "grit/theme_resources.h"
21 #include "ui/base/l10n/l10n_util.h"
22 #include "ui/base/resource/resource_bundle.h"
23 #include "views/widget/widget.h"
24
25 #if defined(TOOLKIT_USES_GTK)
26 #include "chrome/browser/chromeos/wm_ipc.h"
27 #endif
28
29 namespace {
30
31 // Max number of users we'll show. The true max is the min of this and the
32 // number of windows that fit on the screen.
33 const size_t kMaxUsers = 6;
34
35 // Minimum number of users we'll show (including Guest and New User pods).
36 const size_t kMinUsers = 3;
37
38 // Used to indicate no user has been selected.
39 const size_t kNotSelected = -1;
40
41 // Offset of cursor in first position from edit left side. It's used to position
42 // info bubble arrow to cursor.
43 const int kCursorOffset = 5;
44
45 // Checks if display names are unique. If there are duplicates, enables
46 // tooltips with full emails to let users distinguish their accounts.
47 // Otherwise, disables the tooltips.
48 void EnableTooltipsIfNeeded(
49 const std::vector<chromeos::UserController*>& controllers) {
50 for (size_t i = 0; i < controllers.size(); ++i) {
51 bool show_tooltip = controllers[i]->is_new_user() ||
52 controllers[i]->is_guest() ||
53 controllers[i]->user().NeedsNameTooltip();
54 controllers[i]->EnableNameTooltip(show_tooltip);
55 }
56 }
57
58 } // namespace
59
60 namespace chromeos {
61
62 ViewsLoginDisplay::ViewsLoginDisplay(LoginDisplay::Delegate* delegate,
63 const gfx::Rect& background_bounds)
64 : LoginDisplay(delegate, background_bounds),
65 bubble_(NULL),
66 controller_for_removal_(NULL),
67 selected_view_index_(kNotSelected) {
68 }
69
70 ViewsLoginDisplay::~ViewsLoginDisplay() {
71 ClearErrors();
72 STLDeleteElements(&controllers_);
73 STLDeleteElements(&invisible_controllers_);
74 }
75
76 ////////////////////////////////////////////////////////////////////////////////
77 // ViewsLoginDisplay, LoginDisplay implementation:
78 //
79
80 void ViewsLoginDisplay::Init(const std::vector<UserManager::User>& users,
81 bool show_guest,
82 bool show_new_user) {
83 size_t max_users = kMaxUsers;
84 if (width() > 0) {
85 size_t users_per_screen = (width() - login::kUserImageSize) /
86 (UserController::kUnselectedSize + UserController::kPadding);
87 max_users = std::max(kMinUsers, std::min(kMaxUsers, users_per_screen));
88 }
89
90 size_t visible_users_count = std::min(users.size(), max_users -
91 static_cast<int>(show_guest) - static_cast<int>(show_new_user));
92 for (size_t i = 0; i < users.size(); ++i) {
93 UserController* user_controller = new UserController(this, users[i]);
94 if (controllers_.size() < visible_users_count) {
95 controllers_.push_back(user_controller);
96 } else if (user_controller->is_owner()) {
97 // Make sure that owner of the device is always visible on login screen.
98 invisible_controllers_.insert(invisible_controllers_.begin(),
99 controllers_.back());
100 controllers_.back() = user_controller;
101 } else {
102 invisible_controllers_.push_back(user_controller);
103 }
104 }
105 if (show_guest)
106 controllers_.push_back(new UserController(this, true));
107
108 if (show_new_user)
109 controllers_.push_back(new UserController(this, false));
110
111 // If there's only new user pod, show the guest session link on it.
112 bool show_guest_link = controllers_.size() == 1;
113 for (size_t i = 0; i < controllers_.size(); ++i) {
114 (controllers_[i])->Init(static_cast<int>(i),
115 static_cast<int>(controllers_.size()),
116 show_guest_link);
117 }
118 EnableTooltipsIfNeeded(controllers_);
119 }
120
121 void ViewsLoginDisplay::OnBeforeUserRemoved(const std::string& username) {
122 controller_for_removal_ = controllers_[selected_view_index_];
123 controllers_.erase(controllers_.begin() + selected_view_index_);
124 EnableTooltipsIfNeeded(controllers_);
125
126 // Update user count before unmapping windows, otherwise window manager won't
127 // be in the right state.
128 int new_size = static_cast<int>(controllers_.size());
129 for (int i = 0; i < new_size; ++i)
130 controllers_[i]->UpdateUserCount(i, new_size);
131 }
132
133 void ViewsLoginDisplay::OnUserImageChanged(UserManager::User* user) {
134 UserController* controller = GetUserControllerByEmail(user->email());
135 if (controller)
136 controller->OnUserImageChanged(user);
137 }
138
139 void ViewsLoginDisplay::OnUserRemoved(const std::string& username) {
140 // We need to unmap entry windows, the windows will be unmapped in destructor.
141 MessageLoop::current()->DeleteSoon(FROM_HERE, controller_for_removal_);
142 controller_for_removal_ = NULL;
143
144 // Nothing to insert.
145 if (invisible_controllers_.empty())
146 return;
147
148 // Insert just before guest or add new user pods if any.
149 size_t new_size = controllers_.size();
150 size_t insert_position = new_size;
151 while (insert_position > 0 &&
152 (controllers_[insert_position - 1]->is_new_user() ||
153 controllers_[insert_position - 1]->is_guest())) {
154 --insert_position;
155 }
156
157 controllers_.insert(controllers_.begin() + insert_position,
158 invisible_controllers_[0]);
159 invisible_controllers_.erase(invisible_controllers_.begin());
160
161 // Update counts for exiting pods.
162 new_size = controllers_.size();
163 for (size_t i = 0; i < new_size; ++i) {
164 if (i != insert_position)
165 controllers_[i]->UpdateUserCount(i, new_size);
166 }
167
168 // And initialize new one that was invisible.
169 controllers_[insert_position]->Init(insert_position, new_size, false);
170
171 EnableTooltipsIfNeeded(controllers_);
172 }
173
174 void ViewsLoginDisplay::OnFadeOut() {
175 controllers_[selected_view_index_]->StopThrobber();
176 }
177
178 void ViewsLoginDisplay::OnLoginSuccess(const std::string& username) {
179 }
180
181 void ViewsLoginDisplay::SetUIEnabled(bool is_enabled) {
182 #if defined(TOOLKIT_USES_GTK)
183 // Send message to WM to enable/disable click on windows.
184 WmIpc::Message message(WM_IPC_MESSAGE_WM_SET_LOGIN_STATE);
185 message.set_param(0, is_enabled);
186 WmIpc::instance()->SendMessage(message);
187 #endif
188
189 if (is_enabled)
190 controllers_[selected_view_index_]->ClearAndEnablePassword();
191 }
192
193 void ViewsLoginDisplay::SelectPod(int index) {
194 SelectUser(index);
195 }
196
197 void ViewsLoginDisplay::ShowError(int error_msg_id,
198 int login_attempts,
199 HelpAppLauncher::HelpTopic help_topic_id) {
200 ClearErrors();
201 string16 error_text;
202 error_msg_id_ = error_msg_id;
203 help_topic_id_ = help_topic_id;
204
205 // GetStringF fails on debug build if there's no replacement in the string.
206 if (error_msg_id == IDS_LOGIN_ERROR_AUTHENTICATING_HOSTED) {
207 error_text = l10n_util::GetStringFUTF16(
208 error_msg_id, l10n_util::GetStringUTF16(IDS_PRODUCT_OS_NAME));
209 } else if (error_msg_id == IDS_LOGIN_ERROR_CAPTIVE_PORTAL) {
210 error_text = l10n_util::GetStringFUTF16(
211 error_msg_id, delegate()->GetConnectedNetworkName());
212 } else {
213 error_text = l10n_util::GetStringUTF16(error_msg_id);
214 }
215
216 // Display a warning if Caps Lock is on and error is authentication-related.
217 if (input_method::XKeyboard::CapsLockIsEnabled() &&
218 error_msg_id != IDS_LOGIN_ERROR_WHITELIST) {
219 // TODO(ivankr): use a format string instead of concatenation.
220 error_text += ASCIIToUTF16("\n") +
221 l10n_util::GetStringUTF16(IDS_LOGIN_ERROR_CAPS_LOCK_HINT);
222 }
223
224 gfx::Rect bounds =
225 controllers_[selected_view_index_]->GetMainInputScreenBounds();
226 views::BubbleBorder::ArrowLocation arrow;
227 if (controllers_[selected_view_index_]->is_new_user()) {
228 arrow = views::BubbleBorder::LEFT_TOP;
229 } else {
230 // Point info bubble arrow to cursor position (approximately).
231 bounds.set_width(kCursorOffset * 2);
232 arrow = views::BubbleBorder::BOTTOM_LEFT;
233 }
234
235 string16 help_link;
236 if (error_msg_id == IDS_LOGIN_ERROR_CAPTIVE_PORTAL) {
237 help_link = l10n_util::GetStringUTF16(IDS_LOGIN_FIX_CAPTIVE_PORTAL);
238 } else if (error_msg_id == IDS_LOGIN_ERROR_CAPTIVE_PORTAL_NO_GUEST_MODE) {
239 // No help link is needed.
240 } else if (error_msg_id == IDS_LOGIN_ERROR_AUTHENTICATING_HOSTED ||
241 login_attempts > 1) {
242 help_link = l10n_util::GetStringUTF16(IDS_LEARN_MORE);
243 }
244
245 bubble_ = MessageBubble::Show(
246 controllers_[selected_view_index_]->controls_widget(),
247 bounds,
248 arrow,
249 ResourceBundle::GetSharedInstance().GetBitmapNamed(IDR_WARNING),
250 UTF16ToWide(error_text),
251 UTF16ToWide(help_link),
252 this);
253 WizardAccessibilityHelper::GetInstance()->MaybeSpeak(
254 UTF16ToUTF8(error_text).c_str(), false, false);
255 }
256
257 ////////////////////////////////////////////////////////////////////////////////
258 // ViewsLoginDisplay, UserController::Delegate implementation:
259 //
260
261 void ViewsLoginDisplay::CreateAccount() {
262 delegate()->CreateAccount();
263 }
264
265 void ViewsLoginDisplay::Login(UserController* source,
266 const string16& password) {
267 delegate()->Login(source->user().email(), UTF16ToUTF8(password));
268 }
269
270 void ViewsLoginDisplay::LoginAsGuest() {
271 delegate()->LoginAsGuest();
272 }
273
274 void ViewsLoginDisplay::ClearErrors() {
275 // bubble_ will be set to NULL in callback.
276 if (bubble_)
277 bubble_->Close();
278 }
279
280 void ViewsLoginDisplay::OnUserSelected(UserController* source) {
281 std::vector<UserController*>::const_iterator i =
282 std::find(controllers_.begin(), controllers_.end(), source);
283 DCHECK(i != controllers_.end());
284 size_t new_selected_index = i - controllers_.begin();
285 if (new_selected_index != selected_view_index_ &&
286 selected_view_index_ != kNotSelected) {
287 controllers_[selected_view_index_]->ClearAndEnableFields();
288 controllers_[new_selected_index]->ClearAndEnableFields();
289 delegate()->OnUserSelected(source->user().email());
290 }
291 selected_view_index_ = new_selected_index;
292 WizardAccessibilityHelper::GetInstance()->MaybeSpeak(
293 source->GetAccessibleUserLabel().c_str(), false, true);
294 }
295
296 void ViewsLoginDisplay::RemoveUser(UserController* source) {
297 ClearErrors();
298 UserManager::Get()->RemoveUser(source->user().email(), this);
299 }
300
301 void ViewsLoginDisplay::SelectUser(int index) {
302 #if defined(TOOLKIT_USES_GTK)
303 if (index >= 0 && index < static_cast<int>(controllers_.size()) &&
304 index != static_cast<int>(selected_view_index_)) {
305 WmIpc::Message message(WM_IPC_MESSAGE_WM_SELECT_LOGIN_USER);
306 message.set_param(0, index);
307 WmIpc::instance()->SendMessage(message);
308 }
309 #endif
310 }
311
312 void ViewsLoginDisplay::StartEnterpriseEnrollment() {
313 delegate()->OnStartEnterpriseEnrollment();
314 }
315
316 ////////////////////////////////////////////////////////////////////////////////
317 // ViewsLoginDisplay, views::MessageBubbleDelegate implementation:
318 //
319
320 void ViewsLoginDisplay::BubbleClosing(Bubble* bubble, bool closed_by_escape) {
321 bubble_ = NULL;
322 }
323
324 bool ViewsLoginDisplay::CloseOnEscape() {
325 return true;
326 }
327
328 bool ViewsLoginDisplay::FadeInOnShow() {
329 return false;
330 }
331
332 void ViewsLoginDisplay::OnLinkActivated(size_t index) {
333 ClearErrors();
334 if (error_msg_id_ == IDS_LOGIN_ERROR_CAPTIVE_PORTAL) {
335 delegate()->FixCaptivePortal();
336 return;
337 }
338 if (!parent_window())
339 return;
340 if (!help_app_.get())
341 help_app_ = new HelpAppLauncher(parent_window());
342 help_app_->ShowHelpTopic(help_topic_id_);
343 }
344
345 ////////////////////////////////////////////////////////////////////////////////
346 // ViewsLoginDisplay, private:
347 //
348
349 UserController* ViewsLoginDisplay::GetUserControllerByEmail(
350 const std::string& email) {
351 std::vector<UserController*>::iterator i;
352 for (i = controllers_.begin(); i != controllers_.end(); ++i) {
353 if ((*i)->user().email() == email)
354 return *i;
355 }
356 for (i = invisible_controllers_.begin();
357 i != invisible_controllers_.end(); ++i) {
358 if ((*i)->user().email() == email)
359 return *i;
360 }
361 return NULL;
362 }
363
364 } // namespace chromeos
OLDNEW
« no previous file with comments | « chrome/browser/chromeos/login/views_login_display.h ('k') | chrome/browser/chromeos/login/views_login_display_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698