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