Home | History | Annotate | Download | only in managed
      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