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 624