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