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

Side by Side Diff: chrome/browser/chromeos/login/screens/user_selection_screen.cc

Issue 426063005: Allow recommended locales to be set for public sessions (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 months 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/screens/user_selection_screen.h" 5 #include "chrome/browser/chromeos/login/screens/user_selection_screen.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "ash/shell.h" 9 #include "ash/shell.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
11 #include "base/location.h" 11 #include "base/location.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/message_loop/message_loop.h" 13 #include "base/message_loop/message_loop.h"
14 #include "base/prefs/pref_service.h" 14 #include "base/prefs/pref_service.h"
15 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
16 #include "base/values.h" 16 #include "base/values.h"
17 #include "chrome/browser/browser_process.h" 17 #include "chrome/browser/browser_process.h"
18 #include "chrome/browser/browser_process_platform_part.h" 18 #include "chrome/browser/browser_process_platform_part.h"
19 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h" 19 #include "chrome/browser/chromeos/login/ui/login_display_host_impl.h"
20 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h" 20 #include "chrome/browser/chromeos/login/users/multi_profile_user_controller.h"
21 #include "chrome/browser/chromeos/login/users/user_manager.h" 21 #include "chrome/browser/chromeos/login/users/user_manager.h"
22 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h" 22 #include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
23 #include "chrome/browser/signin/screenlock_bridge.h" 23 #include "chrome/browser/signin/screenlock_bridge.h"
24 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h" 24 #include "chrome/browser/ui/webui/chromeos/login/l10n_util.h"
25 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h" 25 #include "chrome/browser/ui/webui/chromeos/login/signin_screen_handler.h"
26 #include "chrome/common/pref_names.h" 26 #include "chrome/common/pref_names.h"
27 #include "components/policy/core/common/cloud/cloud_policy_core.h"
28 #include "components/policy/core/common/cloud/cloud_policy_store.h"
29 #include "components/policy/core/common/policy_map.h"
30 #include "components/policy/core/common/policy_types.h"
27 #include "components/user_manager/user_type.h" 31 #include "components/user_manager/user_type.h"
32 #include "policy/policy_constants.h"
28 #include "ui/wm/core/user_activity_detector.h" 33 #include "ui/wm/core/user_activity_detector.h"
29 34
30 namespace chromeos { 35 namespace chromeos {
31 36
32 namespace { 37 namespace {
33 38
34 // User dictionary keys. 39 // User dictionary keys.
35 const char kKeyUsername[] = "username"; 40 const char kKeyUsername[] = "username";
36 const char kKeyDisplayName[] = "displayName"; 41 const char kKeyDisplayName[] = "displayName";
37 const char kKeyEmailAddress[] = "emailAddress"; 42 const char kKeyEmailAddress[] = "emailAddress";
38 const char kKeyEnterpriseDomain[] = "enterpriseDomain"; 43 const char kKeyEnterpriseDomain[] = "enterpriseDomain";
39 const char kKeyPublicAccount[] = "publicAccount"; 44 const char kKeyPublicAccount[] = "publicAccount";
40 const char kKeySupervisedUser[] = "locallyManagedUser"; 45 const char kKeySupervisedUser[] = "locallyManagedUser";
41 const char kKeySignedIn[] = "signedIn"; 46 const char kKeySignedIn[] = "signedIn";
42 const char kKeyCanRemove[] = "canRemove"; 47 const char kKeyCanRemove[] = "canRemove";
43 const char kKeyIsOwner[] = "isOwner"; 48 const char kKeyIsOwner[] = "isOwner";
44 const char kKeyInitialAuthType[] = "initialAuthType"; 49 const char kKeyInitialAuthType[] = "initialAuthType";
45 const char kKeyMultiProfilesAllowed[] = "isMultiProfilesAllowed"; 50 const char kKeyMultiProfilesAllowed[] = "isMultiProfilesAllowed";
46 const char kKeyMultiProfilesPolicy[] = "multiProfilesPolicy"; 51 const char kKeyMultiProfilesPolicy[] = "multiProfilesPolicy";
47 const char kKeyInitialLocales[] = "initialLocales"; 52 const char kKeyInitialLocales[] = "initialLocales";
53 const char kKeyInitialLocale[] = "initialLocale";
54 const char kKeyInitialMultipleRecommendedLocales[] =
55 "initialMultipleRecommendedLocales";
48 const char kKeyInitialKeyboardLayout[] = "initialKeyboardLayout"; 56 const char kKeyInitialKeyboardLayout[] = "initialKeyboardLayout";
49 57
50 // Max number of users to show. 58 // Max number of users to show.
51 // Please keep synced with one in signin_userlist_unittest.cc. 59 // Please keep synced with one in signin_userlist_unittest.cc.
52 const size_t kMaxUsers = 18; 60 const size_t kMaxUsers = 18;
53 61
54 const int kPasswordClearTimeoutSec = 60; 62 const int kPasswordClearTimeoutSec = 60;
55 63
56 } // namespace 64 } // namespace
57 65
(...skipping 13 matching lines...) Expand all
71 if (activity_detector->HasObserver(this)) 79 if (activity_detector->HasObserver(this))
72 activity_detector->RemoveObserver(this); 80 activity_detector->RemoveObserver(this);
73 } 81 }
74 82
75 // static 83 // static
76 void UserSelectionScreen::FillUserDictionary( 84 void UserSelectionScreen::FillUserDictionary(
77 user_manager::User* user, 85 user_manager::User* user,
78 bool is_owner, 86 bool is_owner,
79 bool is_signin_to_add, 87 bool is_signin_to_add,
80 ScreenlockBridge::LockHandler::AuthType auth_type, 88 ScreenlockBridge::LockHandler::AuthType auth_type,
89 const std::vector<std::string>* public_session_recommended_locales,
81 base::DictionaryValue* user_dict) { 90 base::DictionaryValue* user_dict) {
82 const std::string& user_id = user->email(); 91 const std::string& user_id = user->email();
83 const bool is_public_account = 92 const bool is_public_account =
84 user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT; 93 user->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT;
85 const bool is_supervised_user = 94 const bool is_supervised_user =
86 user->GetType() == user_manager::USER_TYPE_SUPERVISED; 95 user->GetType() == user_manager::USER_TYPE_SUPERVISED;
87 96
88 user_dict->SetString(kKeyUsername, user_id); 97 user_dict->SetString(kKeyUsername, user_id);
89 user_dict->SetString(kKeyEmailAddress, user->display_email()); 98 user_dict->SetString(kKeyEmailAddress, user->display_email());
90 user_dict->SetString(kKeyDisplayName, user->GetDisplayName()); 99 user_dict->SetString(kKeyDisplayName, user->GetDisplayName());
(...skipping 11 matching lines...) Expand all
102 multi_profile_user_controller->GetCachedValue(user_id); 111 multi_profile_user_controller->GetCachedValue(user_id);
103 user_dict->SetBoolean(kKeyMultiProfilesAllowed, 112 user_dict->SetBoolean(kKeyMultiProfilesAllowed,
104 multi_profile_user_controller->IsUserAllowedInSession( 113 multi_profile_user_controller->IsUserAllowedInSession(
105 user_id) == MultiProfileUserController::ALLOWED); 114 user_id) == MultiProfileUserController::ALLOWED);
106 user_dict->SetString(kKeyMultiProfilesPolicy, behavior); 115 user_dict->SetString(kKeyMultiProfilesPolicy, behavior);
107 } else { 116 } else {
108 user_dict->SetBoolean(kKeyMultiProfilesAllowed, true); 117 user_dict->SetBoolean(kKeyMultiProfilesAllowed, true);
109 } 118 }
110 119
111 if (is_public_account) { 120 if (is_public_account) {
112 policy::BrowserPolicyConnectorChromeOS* policy_connector = 121 policy::BrowserPolicyConnectorChromeOS* policy_connector =
Nikita (slow) 2014/07/30 11:22:59 I suggest extracting code that's under if (is_publ
bartfab (slow) 2014/08/05 17:16:23 Done.
113 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 122 g_browser_process->platform_part()->browser_policy_connector_chromeos();
114 123
115 if (policy_connector->IsEnterpriseManaged()) { 124 if (policy_connector->IsEnterpriseManaged()) {
116 user_dict->SetString(kKeyEnterpriseDomain, 125 user_dict->SetString(kKeyEnterpriseDomain,
117 policy_connector->GetEnterpriseDomain()); 126 policy_connector->GetEnterpriseDomain());
118 } 127 }
119 128
120 // TODO(bartfab): Initialize |most_relevant_languages| and |locale| based on 129 std::vector<std::string> kEmptyRecommendedLocales;
121 // policy. 130 const std::vector<std::string>* recommended_locales =
122 const std::string locale = g_browser_process->GetApplicationLocale(); 131 public_session_recommended_locales ?
123 std::vector<std::string> most_relevant_languages; 132 public_session_recommended_locales : &kEmptyRecommendedLocales;
133 // Set |kKeyInitialLocales| to the list of available locales. This list
Nikita (slow) 2014/07/30 11:22:59 nit: insert empty line before comment here and bel
bartfab (slow) 2014/08/05 17:16:23 Done.
134 // consists of the recommended locales, followed by all others.
124 user_dict->Set( 135 user_dict->Set(
125 kKeyInitialLocales, 136 kKeyInitialLocales,
126 GetUILanguageList(&most_relevant_languages, locale).release()); 137 GetUILanguageList(recommended_locales, std::string()).release());
138 // Set |kKeyInitialLocale| to the initially selected locale. If the list of
139 // recommended locales is not empty, select its first entry. Otherwise,
140 // select the current UI locale.
141 user_dict->SetString(kKeyInitialLocale,
142 recommended_locales->empty() ?
143 g_browser_process->GetApplicationLocale() :
144 recommended_locales->front());
145 // Set |kKeyInitialMultipleRecommendedLocales| to indicate whether the list
146 // of recommended locales contains at least two entries. This is used to
147 // decide whether the public session pod expands to its basic form (for zero
148 // or one recommended locales) or the advanced form (two or more recommended
149 // locales).
150 user_dict->SetBoolean(kKeyInitialMultipleRecommendedLocales,
151 recommended_locales->size() >= 2);
152 // Set |kKeyInitialKeyboardLayout| to the current keyboard layout. This
153 // value will be used temporarily only because the UI immediately requests a
154 // list of keyboard layouts suitable for the currently selected locale.
127 user_dict->Set(kKeyInitialKeyboardLayout, 155 user_dict->Set(kKeyInitialKeyboardLayout,
128 GetCurrentKeyboardLayout().release()); 156 GetCurrentKeyboardLayout().release());
129 } 157 }
130 } 158 }
131 159
132 // static 160 // static
133 bool UserSelectionScreen::ShouldForceOnlineSignIn( 161 bool UserSelectionScreen::ShouldForceOnlineSignIn(
134 const user_manager::User* user) { 162 const user_manager::User* user) {
135 // Public sessions are always allowed to log in offline. 163 // Public sessions are always allowed to log in offline.
136 // Supervised user are allowed to log in offline if their OAuth token status 164 // Supervised user are allowed to log in offline if their OAuth token status
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 password_clear_timer_.Reset(); 257 password_clear_timer_.Reset();
230 } 258 }
231 259
232 void UserSelectionScreen::OnPolicyUpdated(const std::string& user_id) { 260 void UserSelectionScreen::OnPolicyUpdated(const std::string& user_id) {
233 policy::DeviceLocalAccountPolicyBroker* broker = 261 policy::DeviceLocalAccountPolicyBroker* broker =
234 device_local_account_policy_service_->GetBrokerForUser(user_id); 262 device_local_account_policy_service_->GetBrokerForUser(user_id);
235 if (!broker) 263 if (!broker)
236 return; 264 return;
237 265
238 CheckForPublicSessionDisplayNameChange(broker); 266 CheckForPublicSessionDisplayNameChange(broker);
267 CheckForPublicSessionLocalePolicyChange(broker);
239 } 268 }
240 269
241 void UserSelectionScreen::OnDeviceLocalAccountsChanged() { 270 void UserSelectionScreen::OnDeviceLocalAccountsChanged() {
242 // Nothing to do here. When the list of device-local accounts changes, the 271 // Nothing to do here. When the list of device-local accounts changes, the
243 // entire UI is reloaded. 272 // entire UI is reloaded.
244 } 273 }
245 274
246 // static 275 // static
247 const user_manager::UserList UserSelectionScreen::PrepareUserListForSending( 276 const user_manager::UserList UserSelectionScreen::PrepareUserListForSending(
248 const user_manager::UserList& users, 277 const user_manager::UserList& users,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 322
294 policy::BrowserPolicyConnectorChromeOS* connector = 323 policy::BrowserPolicyConnectorChromeOS* connector =
295 g_browser_process->platform_part()->browser_policy_connector_chromeos(); 324 g_browser_process->platform_part()->browser_policy_connector_chromeos();
296 bool is_enterprise_managed = connector->IsEnterpriseManaged(); 325 bool is_enterprise_managed = connector->IsEnterpriseManaged();
297 326
298 const user_manager::UserList users_to_send = 327 const user_manager::UserList users_to_send =
299 PrepareUserListForSending(users, owner, is_signin_to_add); 328 PrepareUserListForSending(users, owner, is_signin_to_add);
300 329
301 user_auth_type_map_.clear(); 330 user_auth_type_map_.clear();
302 331
332 const std::vector<std::string> kEmptyRecommendedLocales;
303 for (user_manager::UserList::const_iterator it = users_to_send.begin(); 333 for (user_manager::UserList::const_iterator it = users_to_send.begin();
304 it != users_to_send.end(); 334 it != users_to_send.end();
305 ++it) { 335 ++it) {
306 const std::string& user_id = (*it)->email(); 336 const std::string& user_id = (*it)->email();
307 bool is_owner = (user_id == owner); 337 bool is_owner = (user_id == owner);
308 const bool is_public_account = 338 const bool is_public_account =
309 ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT); 339 ((*it)->GetType() == user_manager::USER_TYPE_PUBLIC_ACCOUNT);
310 const ScreenlockBridge::LockHandler::AuthType initial_auth_type = 340 const ScreenlockBridge::LockHandler::AuthType initial_auth_type =
311 is_public_account 341 is_public_account
312 ? ScreenlockBridge::LockHandler::EXPAND_THEN_USER_CLICK 342 ? ScreenlockBridge::LockHandler::EXPAND_THEN_USER_CLICK
313 : (ShouldForceOnlineSignIn(*it) 343 : (ShouldForceOnlineSignIn(*it)
314 ? ScreenlockBridge::LockHandler::ONLINE_SIGN_IN 344 ? ScreenlockBridge::LockHandler::ONLINE_SIGN_IN
315 : ScreenlockBridge::LockHandler::OFFLINE_PASSWORD); 345 : ScreenlockBridge::LockHandler::OFFLINE_PASSWORD);
316 user_auth_type_map_[user_id] = initial_auth_type; 346 user_auth_type_map_[user_id] = initial_auth_type;
317 347
318 base::DictionaryValue* user_dict = new base::DictionaryValue(); 348 base::DictionaryValue* user_dict = new base::DictionaryValue();
319 FillUserDictionary( 349 FillUserDictionary(*it,
320 *it, is_owner, is_signin_to_add, initial_auth_type, user_dict); 350 is_owner,
351 is_signin_to_add,
352 initial_auth_type,
353 public_session_recommended_locales_.find(user_id) ==
Nikita (slow) 2014/07/30 11:22:59 nit: please extract public_session_recommended_loc
bartfab (slow) 2014/08/05 17:16:23 Done.
354 public_session_recommended_locales_.end() ?
355 &kEmptyRecommendedLocales :
356 &public_session_recommended_locales_[user_id],
357 user_dict);
321 bool signed_in = (*it)->is_logged_in(); 358 bool signed_in = (*it)->is_logged_in();
322 // Single user check here is necessary because owner info might not be 359 // Single user check here is necessary because owner info might not be
323 // available when running into login screen on first boot. 360 // available when running into login screen on first boot.
324 // See http://crosbug.com/12723 361 // See http://crosbug.com/12723
325 bool can_remove_user = 362 bool can_remove_user =
326 ((!single_user || is_enterprise_managed) && !user_id.empty() && 363 ((!single_user || is_enterprise_managed) && !user_id.empty() &&
327 !is_owner && !is_public_account && !signed_in && !is_signin_to_add); 364 !is_owner && !is_public_account && !signed_in && !is_signin_to_add);
328 user_dict->SetBoolean(kKeyCanRemove, can_remove_user); 365 user_dict->SetBoolean(kKeyCanRemove, can_remove_user);
329 users_list.Append(user_dict); 366 users_list.Append(user_dict);
330 } 367 }
(...skipping 16 matching lines...) Expand all
347 const std::string& username) const { 384 const std::string& username) const {
348 if (user_auth_type_map_.find(username) == user_auth_type_map_.end()) 385 if (user_auth_type_map_.find(username) == user_auth_type_map_.end())
349 return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD; 386 return ScreenlockBridge::LockHandler::OFFLINE_PASSWORD;
350 return user_auth_type_map_.find(username)->second; 387 return user_auth_type_map_.find(username)->second;
351 } 388 }
352 389
353 void UserSelectionScreen::CheckForPublicSessionDisplayNameChange( 390 void UserSelectionScreen::CheckForPublicSessionDisplayNameChange(
354 policy::DeviceLocalAccountPolicyBroker* broker) { 391 policy::DeviceLocalAccountPolicyBroker* broker) {
355 const std::string& user_id = broker->user_id(); 392 const std::string& user_id = broker->user_id();
356 const std::string& display_name = broker->GetDisplayName(); 393 const std::string& display_name = broker->GetDisplayName();
394
395 // If the display name has not changed, do nothing.
357 if (display_name == public_session_display_names_[user_id]) 396 if (display_name == public_session_display_names_[user_id])
358 return; 397 return;
359 398
360 public_session_display_names_[user_id] = display_name; 399 public_session_display_names_[user_id] = display_name;
361 400
362 if (!handler_initialized_) 401 if (!handler_initialized_)
363 return; 402 return;
364 403
365 if (!display_name.empty()) { 404 if (!display_name.empty()) {
366 // If a new display name was set by policy, notify the UI about it. 405 // If a new display name was set by policy, notify the UI about it.
(...skipping 17 matching lines...) Expand all
384 const std::string& user_id) { 423 const std::string& user_id) {
385 const user_manager::User* user = UserManager::Get()->FindUser(user_id); 424 const user_manager::User* user = UserManager::Get()->FindUser(user_id);
386 if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT) 425 if (!user || user->GetType() != user_manager::USER_TYPE_PUBLIC_ACCOUNT)
387 return; 426 return;
388 427
389 handler_->SetPublicSessionDisplayName( 428 handler_->SetPublicSessionDisplayName(
390 user_id, 429 user_id,
391 base::UTF16ToUTF8(user->GetDisplayName())); 430 base::UTF16ToUTF8(user->GetDisplayName()));
392 } 431 }
393 432
433 void UserSelectionScreen::CheckForPublicSessionLocalePolicyChange(
434 policy::DeviceLocalAccountPolicyBroker* broker) {
435 const std::string& user_id = broker->user_id();
436 const policy::PolicyMap::Entry* entry =
437 broker->core()->store()->policy_map().Get(policy::key::kSessionLocales);
438
439 // Parse the list of recommended locales set by policy.
440 std::vector<std::string> new_recommended_locales;
441 base::ListValue const* list = NULL;
442 if (entry &&
443 entry->level == policy::POLICY_LEVEL_RECOMMENDED &&
444 entry->value &&
445 entry->value->GetAsList(&list)) {
446 for (base::ListValue::const_iterator it = list->begin(); it != list->end();
447 ++it) {
448 std::string locale;
449 if (!(*it)->GetAsString(&locale)) {
450 new_recommended_locales.clear();
Nikita (slow) 2014/07/30 11:22:59 NOTREACHED()?
bartfab (slow) 2014/08/05 17:16:23 Done.
451 break;
452 }
453 new_recommended_locales.push_back(locale);
454 }
455 }
456
457 if (new_recommended_locales.empty()) {
458 // There are no recommended locales.
459 PublicSessionRecommendedLocaleMap::iterator it =
460 public_session_recommended_locales_.find(user_id);
461 if (it != public_session_recommended_locales_.end()) {
462 // If there previously were recommended locales, remove them from
463 // |public_session_recommended_locales_| and notify the UI.
464 public_session_recommended_locales_.erase(it);
465 SetPublicSessionLocales(user_id, &new_recommended_locales);
466 }
467 return;
468 }
469
470 // There are recommended locales.
471 std::vector<std::string>& recommended_locales =
472 public_session_recommended_locales_[user_id];
473 if (new_recommended_locales != recommended_locales) {
474 // If the list of recommended locales has changed, update
475 // |public_session_recommended_locales_| and notify the UI.
476 recommended_locales = new_recommended_locales;
477 SetPublicSessionLocales(user_id, &new_recommended_locales);
478 }
479 }
480
481 void UserSelectionScreen::SetPublicSessionLocales(
482 const std::string& user_id,
483 const std::vector<std::string>* recommended_locales) {
484 if (!handler_initialized_)
485 return;
486
487 // Construct the list of available locales. This list consists of the
488 // recommended locales, followed by all others.
489 scoped_ptr<base::ListValue> locales =
490 GetUILanguageList(recommended_locales, std::string());
491
492 // Set the initially selected locale. If the list of recommended locales is
493 // not empty, select its first entry. Otherwise, select the current UI locale.
494 const std::string& default_locale = recommended_locales->empty() ?
495 g_browser_process->GetApplicationLocale() : recommended_locales->front();
496
497 // Set a flag to indicate whether the list of recommended locales contains at
498 // least two entries. This is used to decide whether the public session pod
499 // expands to its basic form (for zero or one recommended locales) or the
500 // advanced form (two or more recommended locales).
501 const bool two_or_more_recommended_locales = recommended_locales->size() >= 2;
502
503 // Notify the UI.
504 handler_->SetPublicSessionLocales(user_id,
505 locales.Pass(),
506 default_locale,
507 two_or_more_recommended_locales);
508 }
509
394 } // namespace chromeos 510 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698