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