Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / login / managed / locally_managed_user_creation_screen.cc
1 // Copyright (c) 2013 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/managed/locally_managed_user_creation_screen.h"
6
7 #include "ash/desktop_background/desktop_background_controller.h"
8 #include "ash/shell.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/existing_user_controller.h"
13 #include "chrome/browser/chromeos/login/managed/managed_user_creation_controller.h"
14 #include "chrome/browser/chromeos/login/managed/managed_user_creation_controller_new.h"
15 #include "chrome/browser/chromeos/login/managed/managed_user_creation_controller_old.h"
16 #include "chrome/browser/chromeos/login/managed/supervised_user_authentication.h"
17 #include "chrome/browser/chromeos/login/screens/error_screen.h"
18 #include "chrome/browser/chromeos/login/screens/screen_observer.h"
19 #include "chrome/browser/chromeos/login/supervised_user_manager.h"
20 #include "chrome/browser/chromeos/login/user_image.h"
21 #include "chrome/browser/chromeos/login/user_image_manager.h"
22 #include "chrome/browser/chromeos/login/wizard_controller.h"
23 #include "chrome/browser/managed_mode/managed_user_constants.h"
24 #include "chrome/browser/managed_mode/managed_user_shared_settings_service.h"
25 #include "chrome/browser/managed_mode/managed_user_shared_settings_service_factory.h"
26 #include "chrome/browser/managed_mode/managed_user_sync_service.h"
27 #include "chrome/browser/managed_mode/managed_user_sync_service_factory.h"
28 #include "chromeos/network/network_state.h"
29 #include "content/public/browser/browser_thread.h"
30 #include "grit/generated_resources.h"
31 #include "third_party/skia/include/core/SkBitmap.h"
32 #include "ui/base/l10n/l10n_util.h"
33 #include "ui/gfx/image/image_skia.h"
34
35 namespace chromeos {
36
37 namespace {
38
39 // Key for (boolean) value that indicates that user already exists on device.
40 const char kUserExists[] = "exists";
41 // Key for  value that indicates why user can not be imported.
42 const char kUserConflict[] = "conflict";
43 // User is already imported.
44 const char kUserConflictImported[] = "imported";
45 // There is another supervised user with same name.
46 const char kUserConflictName[] = "name";
47
48 const char kUserNeedPassword[] = "needPassword";
49
50 const char kAvatarURLKey[] = "avatarurl";
51 const char kRandomAvatarKey[] = "randomAvatar";
52 const char kNameOfIntroScreen[] = "intro";
53 const char kNameOfNewUserParametersScreen[] = "username";
54
55 void ConfigureErrorScreen(ErrorScreen* screen,
56     const NetworkState* network,
57     const NetworkPortalDetector::CaptivePortalStatus status) {
58   switch (status) {
59     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_UNKNOWN:
60     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE:
61       NOTREACHED();
62       break;
63     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_OFFLINE:
64       screen->SetErrorState(ErrorScreen::ERROR_STATE_OFFLINE,
65                             std::string());
66       break;
67     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PORTAL:
68       screen->SetErrorState(ErrorScreen::ERROR_STATE_PORTAL,
69                             network ? network->name() : std::string());
70       screen->FixCaptivePortal();
71       break;
72     case NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_PROXY_AUTH_REQUIRED:
73       screen->SetErrorState(ErrorScreen::ERROR_STATE_PROXY,
74                             std::string());
75       break;
76     default:
77       NOTREACHED();
78       break;
79   }
80 }
81
82 } // namespace
83
84 LocallyManagedUserCreationScreen::LocallyManagedUserCreationScreen(
85     ScreenObserver* observer,
86     LocallyManagedUserCreationScreenHandler* actor)
87     : WizardScreen(observer),
88       weak_factory_(this),
89       actor_(actor),
90       on_error_screen_(false),
91       last_page_(kNameOfIntroScreen),
92       sync_service_(NULL),
93       image_decoder_(NULL),
94       apply_photo_after_decoding_(false),
95       selected_image_(0) {
96   DCHECK(actor_);
97   if (actor_)
98     actor_->SetDelegate(this);
99 }
100
101 LocallyManagedUserCreationScreen::~LocallyManagedUserCreationScreen() {
102   CameraPresenceNotifier::GetInstance()->RemoveObserver(this);
103   if (sync_service_)
104     sync_service_->RemoveObserver(this);
105   if (actor_)
106     actor_->SetDelegate(NULL);
107   if (image_decoder_.get())
108     image_decoder_->set_delegate(NULL);
109   NetworkPortalDetector::Get()->RemoveObserver(this);
110 }
111
112 void LocallyManagedUserCreationScreen::PrepareToShow() {
113   if (actor_)
114     actor_->PrepareToShow();
115 }
116
117 void LocallyManagedUserCreationScreen::Show() {
118   CameraPresenceNotifier::GetInstance()->AddObserver(this);
119   if (actor_) {
120     actor_->Show();
121     // TODO(antrim) : temorary hack (until upcoming hackaton). Should be
122     // removed once we have screens reworked.
123     if (on_error_screen_)
124       actor_->ShowPage(last_page_);
125     else
126       actor_->ShowIntroPage();
127   }
128
129   if (!on_error_screen_)
130     NetworkPortalDetector::Get()->AddAndFireObserver(this);
131   on_error_screen_ = false;
132 }
133
134 void LocallyManagedUserCreationScreen::OnPageSelected(const std::string& page) {
135   last_page_ = page;
136 }
137
138 void LocallyManagedUserCreationScreen::OnPortalDetectionCompleted(
139     const NetworkState* network,
140     const NetworkPortalDetector::CaptivePortalState& state)  {
141   if (state.status == NetworkPortalDetector::CAPTIVE_PORTAL_STATUS_ONLINE) {
142     get_screen_observer()->HideErrorScreen(this);
143   } else {
144     on_error_screen_ = true;
145     ErrorScreen* screen = get_screen_observer()->GetErrorScreen();
146     ConfigureErrorScreen(screen, network, state.status);
147     screen->SetUIState(ErrorScreen::UI_STATE_LOCALLY_MANAGED);
148     get_screen_observer()->ShowErrorScreen();
149   }
150 }
151
152 void LocallyManagedUserCreationScreen::
153     ShowManagerInconsistentStateErrorScreen() {
154   if (!actor_)
155     return;
156   actor_->ShowErrorPage(
157       l10n_util::GetStringUTF16(
158           IDS_CREATE_LOCALLY_MANAGED_USER_MANAGER_INCONSISTENT_STATE_TITLE),
159       l10n_util::GetStringUTF16(
160           IDS_CREATE_LOCALLY_MANAGED_USER_MANAGER_INCONSISTENT_STATE),
161       l10n_util::GetStringUTF16(
162           IDS_CREATE_LOCALLY_MANAGED_USER_MANAGER_INCONSISTENT_STATE_BUTTON));
163 }
164
165 void LocallyManagedUserCreationScreen::ShowInitialScreen() {
166   if (actor_)
167     actor_->ShowIntroPage();
168 }
169
170 void LocallyManagedUserCreationScreen::Hide() {
171   CameraPresenceNotifier::GetInstance()->RemoveObserver(this);
172   if (actor_)
173     actor_->Hide();
174   if (!on_error_screen_)
175     NetworkPortalDetector::Get()->RemoveObserver(this);
176 }
177
178 std::string LocallyManagedUserCreationScreen::GetName() const {
179   return WizardController::kLocallyManagedUserCreationScreenName;
180 }
181
182 void LocallyManagedUserCreationScreen::AbortFlow() {
183   controller_->CancelCreation();
184 }
185
186 void LocallyManagedUserCreationScreen::FinishFlow() {
187   controller_->FinishCreation();
188 }
189
190 void LocallyManagedUserCreationScreen::AuthenticateManager(
191     const std::string& manager_id,
192     const std::string& manager_password) {
193   // Make sure no two controllers exist at the same time.
194   controller_.reset();
195   SupervisedUserAuthentication* authentication =
196       UserManager::Get()->GetSupervisedUserManager()->GetAuthentication();
197
198   if (authentication->GetStableSchema() ==
199       SupervisedUserAuthentication::SCHEMA_PLAIN) {
200     controller_.reset(new ManagedUserCreationControllerOld(this, manager_id));
201   } else {
202     controller_.reset(new ManagedUserCreationControllerNew(this, manager_id));
203   }
204
205   ExistingUserController::current_controller()->
206       Login(UserContext(manager_id,
207                         manager_password,
208                         std::string()  /* auth_code */));
209 }
210
211 void LocallyManagedUserCreationScreen::CreateManagedUser(
212     const base::string16& display_name,
213     const std::string& managed_user_password) {
214   DCHECK(controller_.get());
215   int image;
216   if (selected_image_ == User::kExternalImageIndex)
217     // TODO(dzhioev): crbug/249660
218     image = ManagedUserCreationController::kDummyAvatarIndex;
219   else
220     image = selected_image_;
221   controller_->StartCreation(display_name, managed_user_password, image);
222 }
223
224 void LocallyManagedUserCreationScreen::ImportManagedUser(
225     const std::string& user_id) {
226   DCHECK(controller_.get());
227   DCHECK(existing_users_.get());
228   VLOG(1) << "Importing user " << user_id;
229   base::DictionaryValue* user_info;
230   if (!existing_users_->GetDictionary(user_id, &user_info)) {
231     LOG(ERROR) << "Can not import non-existing user " << user_id;
232     return;
233   }
234   base::string16 display_name;
235   std::string master_key;
236   std::string signature_key;
237   std::string encryption_key;
238   std::string avatar;
239   bool exists;
240   int avatar_index = ManagedUserCreationController::kDummyAvatarIndex;
241   user_info->GetString(ManagedUserSyncService::kName, &display_name);
242   user_info->GetString(ManagedUserSyncService::kMasterKey, &master_key);
243   user_info->GetString(ManagedUserSyncService::kPasswordSignatureKey,
244                        &signature_key);
245   user_info->GetString(ManagedUserSyncService::kPasswordEncryptionKey,
246                        &encryption_key);
247   user_info->GetString(ManagedUserSyncService::kChromeOsAvatar, &avatar);
248   user_info->GetBoolean(kUserExists, &exists);
249
250   // We should not get here with existing user selected, so just display error.
251   if (exists) {
252     actor_->ShowErrorPage(
253         l10n_util::GetStringUTF16(
254             IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR_TITLE),
255         l10n_util::GetStringUTF16(
256             IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR),
257         l10n_util::GetStringUTF16(
258             IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR_BUTTON));
259     return;
260   }
261
262   ManagedUserSyncService::GetAvatarIndex(avatar, &avatar_index);
263
264   const base::DictionaryValue* password_data = NULL;
265   ManagedUserSharedSettingsService* shared_settings_service =
266       ManagedUserSharedSettingsServiceFactory::GetForBrowserContext(
267           controller_->GetManagerProfile());
268   const base::Value* value = shared_settings_service->GetValue(
269       user_id, managed_users::kChromeOSPasswordData);
270
271   bool password_right_here = value && value->GetAsDictionary(&password_data) &&
272                              !password_data->empty();
273
274   if (password_right_here) {
275     controller_->StartImport(display_name,
276                              avatar_index,
277                              user_id,
278                              master_key,
279                              password_data,
280                              encryption_key,
281                              signature_key);
282   } else {
283     NOTREACHED() << " Oops, no password";
284   }
285 }
286
287 // TODO(antrim): Code duplication with previous method will be removed once
288 // password sync is implemented.
289 void LocallyManagedUserCreationScreen::ImportManagedUserWithPassword(
290     const std::string& user_id,
291     const std::string& password) {
292   DCHECK(controller_.get());
293   DCHECK(existing_users_.get());
294   VLOG(1) << "Importing user " << user_id;
295   base::DictionaryValue* user_info;
296   if (!existing_users_->GetDictionary(user_id, &user_info)) {
297     LOG(ERROR) << "Can not import non-existing user " << user_id;
298     return;
299   }
300   base::string16 display_name;
301   std::string master_key;
302   std::string avatar;
303   bool exists;
304   int avatar_index = ManagedUserCreationController::kDummyAvatarIndex;
305   user_info->GetString(ManagedUserSyncService::kName, &display_name);
306   user_info->GetString(ManagedUserSyncService::kMasterKey, &master_key);
307   user_info->GetString(ManagedUserSyncService::kChromeOsAvatar, &avatar);
308   user_info->GetBoolean(kUserExists, &exists);
309
310   // We should not get here with existing user selected, so just display error.
311   if (exists) {
312     actor_->ShowErrorPage(
313         l10n_util::GetStringUTF16(
314             IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR_TITLE),
315         l10n_util::GetStringUTF16(
316             IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR),
317         l10n_util::GetStringUTF16(
318             IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR_BUTTON));
319     return;
320   }
321
322   ManagedUserSyncService::GetAvatarIndex(avatar, &avatar_index);
323
324   controller_->StartImport(display_name,
325                            password,
326                            avatar_index,
327                            user_id,
328                            master_key);
329 }
330
331 void LocallyManagedUserCreationScreen::OnManagerLoginFailure() {
332   if (actor_)
333     actor_->ShowManagerPasswordError();
334 }
335
336 void LocallyManagedUserCreationScreen::OnManagerFullyAuthenticated(
337     Profile* manager_profile) {
338   LOG(ERROR) << "-----------------------------OnManagerFullyAuthenticated";
339   DCHECK(controller_.get());
340   // For manager user, move desktop to locked container so that windows created
341   // during the user image picker step are below it.
342   ash::Shell::GetInstance()->
343       desktop_background_controller()->MoveDesktopToLockedContainer();
344
345   controller_->SetManagerProfile(manager_profile);
346   if (actor_)
347     actor_->ShowUsernamePage();
348
349   last_page_ = kNameOfNewUserParametersScreen;
350   CHECK(!sync_service_);
351   sync_service_ = ManagedUserSyncServiceFactory::GetForProfile(manager_profile);
352   sync_service_->AddObserver(this);
353   OnManagedUsersChanged();
354 }
355
356 void LocallyManagedUserCreationScreen::OnManagedUsersChanged() {
357   CHECK(sync_service_);
358   sync_service_->GetManagedUsersAsync(
359       base::Bind(&LocallyManagedUserCreationScreen::OnGetManagedUsers,
360                  weak_factory_.GetWeakPtr()));
361 }
362
363 void LocallyManagedUserCreationScreen::OnManagerCryptohomeAuthenticated() {
364   if (actor_) {
365     actor_->ShowStatusMessage(true /* progress */, l10n_util::GetStringUTF16(
366             IDS_CREATE_LOCALLY_MANAGED_USER_CREATION_AUTH_PROGRESS_MESSAGE));
367   }
368 }
369
370 void LocallyManagedUserCreationScreen::OnActorDestroyed(
371     LocallyManagedUserCreationScreenHandler* actor) {
372   if (actor_ == actor)
373     actor_ = NULL;
374 }
375
376 void LocallyManagedUserCreationScreen::OnCreationError(
377     ManagedUserCreationController::ErrorCode code) {
378   base::string16 title;
379   base::string16 message;
380   base::string16 button;
381   // TODO(antrim) : find out which errors do we really have.
382   // We might reuse some error messages from ordinary user flow.
383   switch (code) {
384     case ManagedUserCreationController::CRYPTOHOME_NO_MOUNT:
385     case ManagedUserCreationController::CRYPTOHOME_FAILED_MOUNT:
386     case ManagedUserCreationController::CRYPTOHOME_FAILED_TPM:
387       title = l10n_util::GetStringUTF16(
388           IDS_CREATE_LOCALLY_MANAGED_USER_TPM_ERROR_TITLE);
389       message = l10n_util::GetStringUTF16(
390           IDS_CREATE_LOCALLY_MANAGED_USER_TPM_ERROR);
391       button = l10n_util::GetStringUTF16(
392           IDS_CREATE_LOCALLY_MANAGED_USER_TPM_ERROR_BUTTON);
393       break;
394     case ManagedUserCreationController::CLOUD_SERVER_ERROR:
395     case ManagedUserCreationController::TOKEN_WRITE_FAILED:
396       title = l10n_util::GetStringUTF16(
397           IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR_TITLE);
398       message = l10n_util::GetStringUTF16(
399           IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR);
400       button = l10n_util::GetStringUTF16(
401           IDS_CREATE_LOCALLY_MANAGED_USER_GENERIC_ERROR_BUTTON);
402       break;
403     case ManagedUserCreationController::NO_ERROR:
404       NOTREACHED();
405   }
406   if (actor_)
407     actor_->ShowErrorPage(title, message, button);
408 }
409
410 void LocallyManagedUserCreationScreen::OnCreationTimeout() {
411   if (actor_) {
412     actor_->ShowStatusMessage(false /* error */, l10n_util::GetStringUTF16(
413         IDS_CREATE_LOCALLY_MANAGED_USER_CREATION_CREATION_TIMEOUT_MESSAGE));
414   }
415 }
416
417 void LocallyManagedUserCreationScreen::OnLongCreationWarning() {
418   if (actor_) {
419     actor_->ShowStatusMessage(true /* progress */, l10n_util::GetStringUTF16(
420         IDS_PROFILES_CREATE_MANAGED_JUST_SIGNED_IN));
421   }
422 }
423
424 bool LocallyManagedUserCreationScreen::FindUserByDisplayName(
425     const base::string16& display_name,
426     std::string *out_id) const {
427   if (!existing_users_.get())
428     return false;
429   for (base::DictionaryValue::Iterator it(*existing_users_.get());
430        !it.IsAtEnd(); it.Advance()) {
431     const base::DictionaryValue* user_info =
432         static_cast<const base::DictionaryValue*>(&it.value());
433     base::string16 user_display_name;
434     if (user_info->GetString(ManagedUserSyncService::kName,
435                              &user_display_name)) {
436       if (display_name == user_display_name) {
437         if (out_id)
438           *out_id = it.key();
439         return true;
440       }
441     }
442   }
443   return false;
444 }
445
446 // TODO(antrim) : this is an explicit code duplications with UserImageScreen.
447 // It should be removed by issue 251179.
448
449 void LocallyManagedUserCreationScreen::ApplyPicture() {
450   std::string user_id = controller_->GetManagedUserId();
451   UserManager* user_manager = UserManager::Get();
452   UserImageManager* image_manager = user_manager->GetUserImageManager(user_id);
453   switch (selected_image_) {
454     case User::kExternalImageIndex:
455       // Photo decoding may not have been finished yet.
456       if (user_photo_.isNull()) {
457         apply_photo_after_decoding_ = true;
458         return;
459       }
460       image_manager->SaveUserImage(UserImage::CreateAndEncode(user_photo_));
461       break;
462     case User::kProfileImageIndex:
463       NOTREACHED() << "Supervised users have no profile pictures";
464       break;
465     default:
466       DCHECK(selected_image_ >= 0 && selected_image_ < kDefaultImagesCount);
467       image_manager->SaveUserDefaultImageIndex(selected_image_);
468       break;
469   }
470   // Proceed to tutorial.
471   actor_->ShowTutorialPage();
472 }
473
474 void LocallyManagedUserCreationScreen::OnCreationSuccess() {
475   ApplyPicture();
476 }
477
478 void LocallyManagedUserCreationScreen::OnCameraPresenceCheckDone(
479     bool is_camera_present) {
480   if (actor_)
481     actor_->SetCameraPresent(is_camera_present);
482 }
483
484 void LocallyManagedUserCreationScreen::OnGetManagedUsers(
485     const base::DictionaryValue* users) {
486   // Copy for passing to WebUI, contains only id, name and avatar URL.
487   scoped_ptr<base::ListValue> ui_users(new base::ListValue());
488   SupervisedUserManager* supervised_user_manager =
489       UserManager::Get()->GetSupervisedUserManager();
490
491   // Stored copy, contains all necessary information.
492   existing_users_.reset(new base::DictionaryValue());
493   for (base::DictionaryValue::Iterator it(*users); !it.IsAtEnd();
494        it.Advance()) {
495     // Copy that would be stored in this class.
496     base::DictionaryValue* local_copy =
497         static_cast<base::DictionaryValue*>(it.value().DeepCopy());
498     // Copy that would be passed to WebUI. It has some extra values for
499     // displaying, but does not contain sensitive data, such as master password.
500     base::DictionaryValue* ui_copy =
501         static_cast<base::DictionaryValue*>(new base::DictionaryValue());
502
503     int avatar_index = ManagedUserCreationController::kDummyAvatarIndex;
504     std::string chromeos_avatar;
505     if (local_copy->GetString(ManagedUserSyncService::kChromeOsAvatar,
506                               &chromeos_avatar) &&
507         !chromeos_avatar.empty() &&
508         ManagedUserSyncService::GetAvatarIndex(
509             chromeos_avatar, &avatar_index)) {
510       ui_copy->SetString(kAvatarURLKey, GetDefaultImageUrl(avatar_index));
511     } else {
512       int i = base::RandInt(kFirstDefaultImageIndex, kDefaultImagesCount - 1);
513       local_copy->SetString(
514           ManagedUserSyncService::kChromeOsAvatar,
515           ManagedUserSyncService::BuildAvatarString(i));
516       local_copy->SetBoolean(kRandomAvatarKey, true);
517       ui_copy->SetString(kAvatarURLKey, GetDefaultImageUrl(i));
518     }
519
520     local_copy->SetBoolean(kUserExists, false);
521     ui_copy->SetBoolean(kUserExists, false);
522
523     base::string16 display_name;
524     local_copy->GetString(ManagedUserSyncService::kName, &display_name);
525
526     if (supervised_user_manager->FindBySyncId(it.key())) {
527       local_copy->SetBoolean(kUserExists, true);
528       ui_copy->SetBoolean(kUserExists, true);
529       local_copy->SetString(kUserConflict, kUserConflictImported);
530       ui_copy->SetString(kUserConflict, kUserConflictImported);
531     } else if (supervised_user_manager->FindByDisplayName(display_name)) {
532       local_copy->SetBoolean(kUserExists, true);
533       ui_copy->SetBoolean(kUserExists, true);
534       local_copy->SetString(kUserConflict, kUserConflictName);
535       ui_copy->SetString(kUserConflict, kUserConflictName);
536     }
537     ui_copy->SetString(ManagedUserSyncService::kName, display_name);
538
539     std::string signature_key;
540     bool has_password =
541         local_copy->GetString(ManagedUserSyncService::kPasswordSignatureKey,
542                               &signature_key) &&
543         !signature_key.empty();
544
545     ui_copy->SetBoolean(kUserNeedPassword, !has_password);
546     ui_copy->SetString("id", it.key());
547
548     existing_users_->Set(it.key(), local_copy);
549     ui_users->Append(ui_copy);
550   }
551   actor_->ShowExistingManagedUsers(ui_users.get());
552 }
553
554 void LocallyManagedUserCreationScreen::OnPhotoTaken(
555     const std::string& raw_data) {
556   DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
557   user_photo_ = gfx::ImageSkia();
558   if (image_decoder_.get())
559     image_decoder_->set_delegate(NULL);
560   image_decoder_ = new ImageDecoder(this, raw_data,
561                                     ImageDecoder::DEFAULT_CODEC);
562   scoped_refptr<base::MessageLoopProxy> task_runner =
563       content::BrowserThread::GetMessageLoopProxyForThread(
564           content::BrowserThread::UI);
565   image_decoder_->Start(task_runner);
566 }
567
568 void LocallyManagedUserCreationScreen::OnImageDecoded(
569     const ImageDecoder* decoder,
570     const SkBitmap& decoded_image) {
571   DCHECK_EQ(image_decoder_.get(), decoder);
572   user_photo_ = gfx::ImageSkia::CreateFrom1xBitmap(decoded_image);
573   if (apply_photo_after_decoding_)
574     ApplyPicture();
575 }
576
577 void LocallyManagedUserCreationScreen::OnDecodeImageFailed(
578     const ImageDecoder* decoder) {
579   NOTREACHED() << "Failed to decode PNG image from WebUI";
580 }
581
582 void LocallyManagedUserCreationScreen::OnImageSelected(
583     const std::string& image_type,
584     const std::string& image_url) {
585   if (image_url.empty())
586     return;
587   int user_image_index = User::kInvalidImageIndex;
588   if (image_type == "default" &&
589       IsDefaultImageUrl(image_url, &user_image_index)) {
590     selected_image_ = user_image_index;
591   } else if (image_type == "camera") {
592     selected_image_ = User::kExternalImageIndex;
593   } else {
594     NOTREACHED() << "Unexpected image type: " << image_type;
595   }
596 }
597
598 void LocallyManagedUserCreationScreen::OnImageAccepted() {
599 }
600
601 }  // namespace chromeos