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
3 // found in the LICENSE file.
5 #include "chrome/browser/chromeos/login/supervised/supervised_user_creation_screen.h"
7 #include "ash/desktop_background/desktop_background_controller.h"
9 #include "base/rand_util.h"
10 #include "base/values.h"
11 #include "chrome/browser/chromeos/camera_detector.h"
12 #include "chrome/browser/chromeos/login/error_screens_histogram_helper.h"
13 #include "chrome/browser/chromeos/login/existing_user_controller.h"
14 #include "chrome/browser/chromeos/login/screen_manager.h"
15 #include "chrome/browser/chromeos/login/screens/base_screen_delegate.h"
16 #include "chrome/browser/chromeos/login/screens/error_screen.h"
17 #include "chrome/browser/chromeos/login/screens/network_error.h"
18 #include "chrome/browser/chromeos/login/signin_specifics.h"
19 #include "chrome/browser/chromeos/login/supervised/supervised_user_authentication.h"
20 #include "chrome/browser/chromeos/login/supervised/supervised_user_creation_controller.h"
21 #include "chrome/browser/chromeos/login/supervised/supervised_user_creation_controller_new.h"
22 #include "chrome/browser/chromeos/login/supervised/supervised_user_creation_flow.h"
23 #include "chrome/browser/chromeos/login/users/avatar/user_image_manager.h"
24 #include "chrome/browser/chromeos/login/users/chrome_user_manager.h"
25 #include "chrome/browser/chromeos/login/users/supervised_user_manager.h"
26 #include "chrome/browser/chromeos/login/wizard_controller.h"
27 #include "chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service.h"
28 #include "chrome/browser/supervised_user/legacy/supervised_user_shared_settings_service_factory.h"
29 #include "chrome/browser/supervised_user/legacy/supervised_user_sync_service.h"
30 #include "chrome/browser/supervised_user/legacy/supervised_user_sync_service_factory.h"
31 #include "chrome/browser/supervised_user/supervised_user_constants.h"
32 #include "chrome/grit/generated_resources.h"
33 #include "chromeos/dbus/dbus_thread_manager.h"
34 #include "chromeos/dbus/session_manager_client.h"
35 #include "chromeos/login/auth/key.h"
36 #include "chromeos/login/auth/user_context.h"
37 #include "chromeos/network/network_state.h"
38 #include "components/user_manager/user.h"
39 #include "components/user_manager/user_image/user_image.h"
40 #include "content/public/browser/browser_thread.h"
41 #include "third_party/skia/include/core/SkBitmap.h"
42 #include "ui/base/l10n/l10n_util.h"
43 #include "ui/gfx/image/image_skia.h"
49 // Key for (boolean) value that indicates that user already exists on device.
50 const char kUserExists
[] = "exists";
51 // Key for value that indicates why user can not be imported.
52 const char kUserConflict
[] = "conflict";
53 // User is already imported.
54 const char kUserConflictImported
[] = "imported";
55 // There is another supervised user with same name.
56 const char kUserConflictName
[] = "name";
58 const char kUserNeedPassword
[] = "needPassword";
60 const char kAvatarURLKey
[] = "avatarurl";
61 const char kRandomAvatarKey
[] = "randomAvatar";
62 const char kNameOfIntroScreen
[] = "intro";
63 const char kNameOfNewUserParametersScreen
[] = "username";
65 void ConfigureErrorScreen(ErrorScreen
* screen
,
66 const NetworkState
* network
,
67 const NetworkPortalDetector::CaptivePortalStatus status
) {
69 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN
:
70 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE
:
73 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE
:
74 screen
->SetErrorState(NetworkError::ERROR_STATE_OFFLINE
, std::string());
76 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL
:
77 screen
->SetErrorState(NetworkError::ERROR_STATE_PORTAL
,
78 network
? network
->name() : std::string());
79 screen
->FixCaptivePortal();
81 case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED
:
82 screen
->SetErrorState(NetworkError::ERROR_STATE_PROXY
, std::string());
93 SupervisedUserCreationScreen
* SupervisedUserCreationScreen::Get(
94 ScreenManager
* manager
) {
95 return static_cast<SupervisedUserCreationScreen
*>(
96 manager
->GetScreen(WizardController::kSupervisedUserCreationScreenName
));
99 SupervisedUserCreationScreen::SupervisedUserCreationScreen(
100 BaseScreenDelegate
* base_screen_delegate
,
101 SupervisedUserCreationScreenHandler
* actor
)
102 : BaseScreen(base_screen_delegate
),
104 on_error_screen_(false),
105 manager_signin_in_progress_(false),
106 last_page_(kNameOfIntroScreen
),
108 apply_photo_after_decoding_(false),
110 histogram_helper_(new ErrorScreensHistogramHelper("Supervised")),
111 weak_factory_(this) {
114 actor_
->SetDelegate(this);
117 SupervisedUserCreationScreen::~SupervisedUserCreationScreen() {
118 CameraPresenceNotifier::GetInstance()->RemoveObserver(this);
120 sync_service_
->RemoveObserver(this);
122 actor_
->SetDelegate(NULL
);
123 NetworkPortalDetector::Get()->RemoveObserver(this);
126 void SupervisedUserCreationScreen::PrepareToShow() {
128 actor_
->PrepareToShow();
131 void SupervisedUserCreationScreen::Show() {
132 CameraPresenceNotifier::GetInstance()->AddObserver(this);
135 // TODO(antrim) : temorary hack (until upcoming hackaton). Should be
136 // removed once we have screens reworked.
137 if (on_error_screen_
)
138 actor_
->ShowPage(last_page_
);
140 actor_
->ShowIntroPage();
143 if (!on_error_screen_
)
144 NetworkPortalDetector::Get()->AddAndFireObserver(this);
145 on_error_screen_
= false;
146 histogram_helper_
->OnScreenShow();
149 void SupervisedUserCreationScreen::OnPageSelected(const std::string
& page
) {
153 void SupervisedUserCreationScreen::OnPortalDetectionCompleted(
154 const NetworkState
* network
,
155 const NetworkPortalDetector::CaptivePortalState
& state
) {
156 if (state
.status
== NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE
) {
157 get_base_screen_delegate()->HideErrorScreen(this);
158 histogram_helper_
->OnErrorHide();
159 } else if (state
.status
!=
160 NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN
) {
161 on_error_screen_
= true;
162 ErrorScreen
* screen
= get_base_screen_delegate()->GetErrorScreen();
163 ConfigureErrorScreen(screen
, network
, state
.status
);
164 screen
->SetUIState(NetworkError::UI_STATE_SUPERVISED
);
165 get_base_screen_delegate()->ShowErrorScreen();
166 histogram_helper_
->OnErrorShow(screen
->GetErrorState());
170 void SupervisedUserCreationScreen::ShowManagerInconsistentStateErrorScreen() {
171 manager_signin_in_progress_
= false;
174 actor_
->ShowErrorPage(
175 l10n_util::GetStringUTF16(
176 IDS_CREATE_SUPERVISED_USER_MANAGER_INCONSISTENT_STATE_TITLE
),
177 l10n_util::GetStringUTF16(
178 IDS_CREATE_SUPERVISED_USER_MANAGER_INCONSISTENT_STATE
),
179 l10n_util::GetStringUTF16(
180 IDS_CREATE_SUPERVISED_USER_MANAGER_INCONSISTENT_STATE_BUTTON
));
183 void SupervisedUserCreationScreen::ShowInitialScreen() {
185 actor_
->ShowIntroPage();
188 void SupervisedUserCreationScreen::Hide() {
189 CameraPresenceNotifier::GetInstance()->RemoveObserver(this);
192 if (!on_error_screen_
)
193 NetworkPortalDetector::Get()->RemoveObserver(this);
196 std::string
SupervisedUserCreationScreen::GetName() const {
197 return WizardController::kSupervisedUserCreationScreenName
;
200 void SupervisedUserCreationScreen::AbortFlow() {
201 DBusThreadManager::Get()
202 ->GetSessionManagerClient()
203 ->NotifySupervisedUserCreationFinished();
204 controller_
->CancelCreation();
207 void SupervisedUserCreationScreen::FinishFlow() {
208 DBusThreadManager::Get()
209 ->GetSessionManagerClient()
210 ->NotifySupervisedUserCreationFinished();
211 controller_
->FinishCreation();
214 void SupervisedUserCreationScreen::HideFlow() {
218 void SupervisedUserCreationScreen::AuthenticateManager(
219 const std::string
& manager_id
,
220 const std::string
& manager_password
) {
221 if (manager_signin_in_progress_
)
223 manager_signin_in_progress_
= true;
225 UserFlow
* flow
= new SupervisedUserCreationFlow(manager_id
);
226 ChromeUserManager::Get()->SetUserFlow(manager_id
, flow
);
228 // Make sure no two controllers exist at the same time.
231 controller_
.reset(new SupervisedUserCreationControllerNew(this, manager_id
));
233 UserContext
user_context(manager_id
);
234 user_context
.SetKey(Key(manager_password
));
235 ExistingUserController::current_controller()->Login(user_context
,
239 void SupervisedUserCreationScreen::CreateSupervisedUser(
240 const base::string16
& display_name
,
241 const std::string
& supervised_user_password
) {
242 DCHECK(controller_
.get());
244 if (selected_image_
== user_manager::User::USER_IMAGE_EXTERNAL
)
245 // TODO(dzhioev): crbug/249660
246 image
= SupervisedUserCreationController::kDummyAvatarIndex
;
248 image
= selected_image_
;
249 controller_
->StartCreation(display_name
, supervised_user_password
, image
);
252 void SupervisedUserCreationScreen::ImportSupervisedUser(
253 const std::string
& user_id
) {
254 DCHECK(controller_
.get());
255 DCHECK(existing_users_
.get());
256 VLOG(1) << "Importing user " << user_id
;
257 base::DictionaryValue
* user_info
;
258 if (!existing_users_
->GetDictionary(user_id
, &user_info
)) {
259 LOG(ERROR
) << "Can not import non-existing user " << user_id
;
262 base::string16 display_name
;
263 std::string master_key
;
264 std::string signature_key
;
265 std::string encryption_key
;
268 int avatar_index
= SupervisedUserCreationController::kDummyAvatarIndex
;
269 user_info
->GetString(SupervisedUserSyncService::kName
, &display_name
);
270 user_info
->GetString(SupervisedUserSyncService::kMasterKey
, &master_key
);
271 user_info
->GetString(SupervisedUserSyncService::kPasswordSignatureKey
,
273 user_info
->GetString(SupervisedUserSyncService::kPasswordEncryptionKey
,
275 user_info
->GetString(SupervisedUserSyncService::kChromeOsAvatar
, &avatar
);
276 user_info
->GetBoolean(kUserExists
, &exists
);
278 // We should not get here with existing user selected, so just display error.
280 actor_
->ShowErrorPage(
281 l10n_util::GetStringUTF16(
282 IDS_CREATE_SUPERVISED_USER_GENERIC_ERROR_TITLE
),
283 l10n_util::GetStringUTF16(
284 IDS_CREATE_SUPERVISED_USER_GENERIC_ERROR
),
285 l10n_util::GetStringUTF16(
286 IDS_CREATE_SUPERVISED_USER_GENERIC_ERROR_BUTTON
));
290 SupervisedUserSyncService::GetAvatarIndex(avatar
, &avatar_index
);
292 const base::DictionaryValue
* password_data
= NULL
;
293 SupervisedUserSharedSettingsService
* shared_settings_service
=
294 SupervisedUserSharedSettingsServiceFactory::GetForBrowserContext(
295 controller_
->GetManagerProfile());
296 const base::Value
* value
= shared_settings_service
->GetValue(
297 user_id
, supervised_users::kChromeOSPasswordData
);
299 bool password_right_here
= value
&& value
->GetAsDictionary(&password_data
) &&
300 !password_data
->empty();
302 if (password_right_here
) {
303 controller_
->StartImport(display_name
,
311 NOTREACHED() << " Oops, no password";
315 // TODO(antrim): Code duplication with previous method will be removed once
316 // password sync is implemented.
317 void SupervisedUserCreationScreen::ImportSupervisedUserWithPassword(
318 const std::string
& user_id
,
319 const std::string
& password
) {
320 DCHECK(controller_
.get());
321 DCHECK(existing_users_
.get());
322 VLOG(1) << "Importing user " << user_id
;
323 base::DictionaryValue
* user_info
;
324 if (!existing_users_
->GetDictionary(user_id
, &user_info
)) {
325 LOG(ERROR
) << "Can not import non-existing user " << user_id
;
328 base::string16 display_name
;
329 std::string master_key
;
332 int avatar_index
= SupervisedUserCreationController::kDummyAvatarIndex
;
333 user_info
->GetString(SupervisedUserSyncService::kName
, &display_name
);
334 user_info
->GetString(SupervisedUserSyncService::kMasterKey
, &master_key
);
335 user_info
->GetString(SupervisedUserSyncService::kChromeOsAvatar
, &avatar
);
336 user_info
->GetBoolean(kUserExists
, &exists
);
338 // We should not get here with existing user selected, so just display error.
340 actor_
->ShowErrorPage(
341 l10n_util::GetStringUTF16(
342 IDS_CREATE_SUPERVISED_USER_GENERIC_ERROR_TITLE
),
343 l10n_util::GetStringUTF16(
344 IDS_CREATE_SUPERVISED_USER_GENERIC_ERROR
),
345 l10n_util::GetStringUTF16(
346 IDS_CREATE_SUPERVISED_USER_GENERIC_ERROR_BUTTON
));
350 SupervisedUserSyncService::GetAvatarIndex(avatar
, &avatar_index
);
352 controller_
->StartImport(display_name
,
359 void SupervisedUserCreationScreen::OnManagerLoginFailure() {
360 manager_signin_in_progress_
= false;
362 actor_
->ShowManagerPasswordError();
365 void SupervisedUserCreationScreen::OnManagerFullyAuthenticated(
366 Profile
* manager_profile
) {
367 DBusThreadManager::Get()
368 ->GetSessionManagerClient()
369 ->NotifySupervisedUserCreationStarted();
370 manager_signin_in_progress_
= false;
371 DCHECK(controller_
.get());
372 // For manager user, move desktop to locked container so that windows created
373 // during the user image picker step are below it.
374 ash::Shell::GetInstance()->
375 desktop_background_controller()->MoveDesktopToLockedContainer();
377 controller_
->SetManagerProfile(manager_profile
);
379 actor_
->ShowUsernamePage();
381 last_page_
= kNameOfNewUserParametersScreen
;
382 CHECK(!sync_service_
);
383 sync_service_
= SupervisedUserSyncServiceFactory::GetForProfile(
385 sync_service_
->AddObserver(this);
386 OnSupervisedUsersChanged();
389 void SupervisedUserCreationScreen::OnSupervisedUsersChanged() {
390 CHECK(sync_service_
);
391 sync_service_
->GetSupervisedUsersAsync(
392 base::Bind(&SupervisedUserCreationScreen::OnGetSupervisedUsers
,
393 weak_factory_
.GetWeakPtr()));
396 void SupervisedUserCreationScreen::OnManagerCryptohomeAuthenticated() {
398 actor_
->ShowStatusMessage(true /* progress */, l10n_util::GetStringUTF16(
399 IDS_CREATE_SUPERVISED_USER_CREATION_AUTH_PROGRESS_MESSAGE
));
403 void SupervisedUserCreationScreen::OnActorDestroyed(
404 SupervisedUserCreationScreenHandler
* actor
) {
409 void SupervisedUserCreationScreen::OnCreationError(
410 SupervisedUserCreationController::ErrorCode code
) {
411 LOG(ERROR
) << "Supervised user creation failure, code: " << code
;
413 base::string16 title
;
414 base::string16 message
;
415 base::string16 button
;
416 // TODO(antrim) : find out which errors do we really have.
417 // We might reuse some error messages from ordinary user flow.
419 case SupervisedUserCreationController::CRYPTOHOME_NO_MOUNT
:
420 case SupervisedUserCreationController::CRYPTOHOME_FAILED_MOUNT
:
421 case SupervisedUserCreationController::CRYPTOHOME_FAILED_TPM
:
422 title
= l10n_util::GetStringUTF16(
423 IDS_CREATE_SUPERVISED_USER_TPM_ERROR_TITLE
);
424 message
= l10n_util::GetStringUTF16(
425 IDS_CREATE_SUPERVISED_USER_TPM_ERROR
);
426 button
= l10n_util::GetStringUTF16(
427 IDS_CREATE_SUPERVISED_USER_TPM_ERROR_BUTTON
);
429 case SupervisedUserCreationController::CLOUD_SERVER_ERROR
:
430 case SupervisedUserCreationController::TOKEN_WRITE_FAILED
:
431 title
= l10n_util::GetStringUTF16(
432 IDS_CREATE_SUPERVISED_USER_GENERIC_ERROR_TITLE
);
433 message
= l10n_util::GetStringUTF16(
434 IDS_CREATE_SUPERVISED_USER_GENERIC_ERROR
);
435 button
= l10n_util::GetStringUTF16(
436 IDS_CREATE_SUPERVISED_USER_GENERIC_ERROR_BUTTON
);
438 case SupervisedUserCreationController::NO_ERROR
:
442 actor_
->ShowErrorPage(title
, message
, button
);
445 void SupervisedUserCreationScreen::OnCreationTimeout() {
447 actor_
->ShowStatusMessage(false /* error */, l10n_util::GetStringUTF16(
448 IDS_CREATE_SUPERVISED_USER_CREATION_CREATION_TIMEOUT_MESSAGE
));
452 void SupervisedUserCreationScreen::OnLongCreationWarning() {
454 actor_
->ShowStatusMessage(true /* progress */, l10n_util::GetStringUTF16(
455 IDS_PROFILES_CREATE_SUPERVISED_JUST_SIGNED_IN
));
459 bool SupervisedUserCreationScreen::FindUserByDisplayName(
460 const base::string16
& display_name
,
461 std::string
*out_id
) const {
462 if (!existing_users_
.get())
464 for (base::DictionaryValue::Iterator
it(*existing_users_
.get());
465 !it
.IsAtEnd(); it
.Advance()) {
466 const base::DictionaryValue
* user_info
=
467 static_cast<const base::DictionaryValue
*>(&it
.value());
468 base::string16 user_display_name
;
469 if (user_info
->GetString(SupervisedUserSyncService::kName
,
470 &user_display_name
)) {
471 if (display_name
== user_display_name
) {
481 // TODO(antrim) : this is an explicit code duplications with UserImageScreen.
482 // It should be removed by issue 251179.
484 void SupervisedUserCreationScreen::ApplyPicture() {
485 std::string user_id
= controller_
->GetSupervisedUserId();
486 UserImageManager
* image_manager
=
487 ChromeUserManager::Get()->GetUserImageManager(user_id
);
488 switch (selected_image_
) {
489 case user_manager::User::USER_IMAGE_EXTERNAL
:
490 // Photo decoding may not have been finished yet.
491 if (user_photo_
.isNull()) {
492 apply_photo_after_decoding_
= true;
495 image_manager
->SaveUserImage(
496 user_manager::UserImage::CreateAndEncode(user_photo_
));
498 case user_manager::User::USER_IMAGE_PROFILE
:
499 NOTREACHED() << "Supervised users have no profile pictures";
502 DCHECK(selected_image_
>= 0 &&
503 selected_image_
< user_manager::kDefaultImagesCount
);
504 image_manager
->SaveUserDefaultImageIndex(selected_image_
);
507 // Proceed to tutorial.
508 actor_
->ShowTutorialPage();
511 void SupervisedUserCreationScreen::OnCreationSuccess() {
515 void SupervisedUserCreationScreen::OnCameraPresenceCheckDone(
516 bool is_camera_present
) {
518 actor_
->SetCameraPresent(is_camera_present
);
521 void SupervisedUserCreationScreen::OnGetSupervisedUsers(
522 const base::DictionaryValue
* users
) {
523 // Copy for passing to WebUI, contains only id, name and avatar URL.
524 scoped_ptr
<base::ListValue
> ui_users(new base::ListValue());
525 SupervisedUserManager
* supervised_user_manager
=
526 ChromeUserManager::Get()->GetSupervisedUserManager();
528 // Stored copy, contains all necessary information.
529 existing_users_
.reset(new base::DictionaryValue());
530 for (base::DictionaryValue::Iterator
it(*users
); !it
.IsAtEnd();
532 // Copy that would be stored in this class.
533 base::DictionaryValue
* local_copy
=
534 static_cast<base::DictionaryValue
*>(it
.value().DeepCopy());
535 // Copy that would be passed to WebUI. It has some extra values for
536 // displaying, but does not contain sensitive data, such as master password.
537 base::DictionaryValue
* ui_copy
=
538 static_cast<base::DictionaryValue
*>(new base::DictionaryValue());
540 int avatar_index
= SupervisedUserCreationController::kDummyAvatarIndex
;
541 std::string chromeos_avatar
;
542 if (local_copy
->GetString(SupervisedUserSyncService::kChromeOsAvatar
,
544 !chromeos_avatar
.empty() &&
545 SupervisedUserSyncService::GetAvatarIndex(
546 chromeos_avatar
, &avatar_index
)) {
547 ui_copy
->SetString(kAvatarURLKey
,
548 user_manager::GetDefaultImageUrl(avatar_index
));
550 int i
= base::RandInt(user_manager::kFirstDefaultImageIndex
,
551 user_manager::kDefaultImagesCount
- 1);
552 local_copy
->SetString(
553 SupervisedUserSyncService::kChromeOsAvatar
,
554 SupervisedUserSyncService::BuildAvatarString(i
));
555 local_copy
->SetBoolean(kRandomAvatarKey
, true);
556 ui_copy
->SetString(kAvatarURLKey
, user_manager::GetDefaultImageUrl(i
));
559 local_copy
->SetBoolean(kUserExists
, false);
560 ui_copy
->SetBoolean(kUserExists
, false);
562 base::string16 display_name
;
563 local_copy
->GetString(SupervisedUserSyncService::kName
, &display_name
);
565 if (supervised_user_manager
->FindBySyncId(it
.key())) {
566 local_copy
->SetBoolean(kUserExists
, true);
567 ui_copy
->SetBoolean(kUserExists
, true);
568 local_copy
->SetString(kUserConflict
, kUserConflictImported
);
569 ui_copy
->SetString(kUserConflict
, kUserConflictImported
);
570 } else if (supervised_user_manager
->FindByDisplayName(display_name
)) {
571 local_copy
->SetBoolean(kUserExists
, true);
572 ui_copy
->SetBoolean(kUserExists
, true);
573 local_copy
->SetString(kUserConflict
, kUserConflictName
);
574 ui_copy
->SetString(kUserConflict
, kUserConflictName
);
576 ui_copy
->SetString(SupervisedUserSyncService::kName
, display_name
);
578 std::string signature_key
;
580 local_copy
->GetString(SupervisedUserSyncService::kPasswordSignatureKey
,
582 !signature_key
.empty();
584 ui_copy
->SetBoolean(kUserNeedPassword
, !has_password
);
585 ui_copy
->SetString("id", it
.key());
587 existing_users_
->Set(it
.key(), local_copy
);
588 ui_users
->Append(ui_copy
);
590 actor_
->ShowExistingSupervisedUsers(ui_users
.get());
593 void SupervisedUserCreationScreen::OnPhotoTaken(
594 const std::string
& raw_data
) {
595 DCHECK_CURRENTLY_ON(content::BrowserThread::UI
);
596 user_photo_
= gfx::ImageSkia();
597 ImageDecoder::Cancel(this);
598 ImageDecoder::Start(this, raw_data
);
601 void SupervisedUserCreationScreen::OnImageDecoded(
602 const SkBitmap
& decoded_image
) {
603 user_photo_
= gfx::ImageSkia::CreateFrom1xBitmap(decoded_image
);
604 if (apply_photo_after_decoding_
)
608 void SupervisedUserCreationScreen::OnDecodeImageFailed() {
609 NOTREACHED() << "Failed to decode PNG image from WebUI";
612 void SupervisedUserCreationScreen::OnImageSelected(
613 const std::string
& image_type
,
614 const std::string
& image_url
) {
615 if (image_url
.empty())
617 int user_image_index
= user_manager::User::USER_IMAGE_INVALID
;
618 if (image_type
== "default" &&
619 user_manager::IsDefaultImageUrl(image_url
, &user_image_index
)) {
620 selected_image_
= user_image_index
;
621 } else if (image_type
== "camera") {
622 selected_image_
= user_manager::User::USER_IMAGE_EXTERNAL
;
624 NOTREACHED() << "Unexpected image type: " << image_type
;
628 void SupervisedUserCreationScreen::OnImageAccepted() {
631 } // namespace chromeos