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/ui/webui/chromeos/login/supervised_user_creation_screen_handler.h" 6 7#include "ash/audio/sounds.h" 8#include "base/strings/utf_string_conversions.h" 9#include "base/values.h" 10#include "chrome/browser/chromeos/login/screens/user_selection_screen.h" 11#include "chrome/browser/chromeos/login/supervised/supervised_user_creation_flow.h" 12#include "chrome/browser/chromeos/login/users/chrome_user_manager.h" 13#include "chrome/browser/chromeos/login/users/supervised_user_manager.h" 14#include "chrome/browser/chromeos/login/users/wallpaper/wallpaper_manager.h" 15#include "chrome/browser/chromeos/settings/cros_settings.h" 16#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" 17#include "chrome/common/url_constants.h" 18#include "chrome/grit/generated_resources.h" 19#include "chromeos/audio/chromeos_sounds.h" 20#include "components/user_manager/user_manager.h" 21#include "components/user_manager/user_type.h" 22#include "google_apis/gaia/gaia_auth_util.h" 23#include "grit/browser_resources.h" 24#include "net/base/data_url.h" 25#include "net/base/escape.h" 26#include "ui/base/l10n/l10n_util.h" 27#include "ui/base/resource/resource_bundle.h" 28 29const char kJsScreenPath[] = "login.SupervisedUserCreationScreen"; 30 31namespace chromeos { 32 33SupervisedUserCreationScreenHandler::SupervisedUserCreationScreenHandler() 34 : BaseScreenHandler(kJsScreenPath), 35 delegate_(NULL) { 36 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); 37 media::SoundsManager* manager = media::SoundsManager::Get(); 38 manager->Initialize(SOUND_OBJECT_DELETE, 39 bundle.GetRawDataResource(IDR_SOUND_OBJECT_DELETE_WAV)); 40 manager->Initialize(SOUND_CAMERA_SNAP, 41 bundle.GetRawDataResource(IDR_SOUND_CAMERA_SNAP_WAV)); 42} 43 44SupervisedUserCreationScreenHandler::~SupervisedUserCreationScreenHandler() { 45 if (delegate_) { 46 delegate_->OnActorDestroyed(this); 47 } 48} 49 50void SupervisedUserCreationScreenHandler::DeclareLocalizedValues( 51 LocalizedValuesBuilder* builder) { 52 builder->Add( 53 "supervisedUserCreationFlowRetryButtonTitle", 54 IDS_CREATE_SUPERVISED_USER_CREATION_ERROR_RETRY_BUTTON_TITLE); 55 builder->Add( 56 "supervisedUserCreationFlowCancelButtonTitle", 57 IDS_CREATE_SUPERVISED_USER_CREATION_ERROR_CANCEL_BUTTON_TITLE); 58 builder->Add( 59 "supervisedUserCreationFlowGotitButtonTitle", 60 IDS_CREATE_SUPERVISED_USER_CREATION_GOT_IT_BUTTON_TITLE); 61 62 builder->Add("createSupervisedUserIntroTextTitle", 63 IDS_CREATE_SUPERVISED_INTRO_TEXT_TITLE); 64 builder->Add("createSupervisedUserIntroAlternateText", 65 IDS_CREATE_SUPERVISED_INTRO_ALTERNATE_TEXT); 66 builder->Add("createSupervisedUserIntroText1", 67 IDS_CREATE_SUPERVISED_INTRO_TEXT_1); 68 builder->Add("createSupervisedUserIntroManagerItem1", 69 IDS_CREATE_SUPERVISED_INTRO_MANAGER_ITEM_1); 70 builder->Add("createSupervisedUserIntroManagerItem2", 71 IDS_CREATE_SUPERVISED_INTRO_MANAGER_ITEM_2); 72 builder->Add("createSupervisedUserIntroManagerItem3", 73 IDS_CREATE_SUPERVISED_INTRO_MANAGER_ITEM_3); 74 builder->Add("createSupervisedUserIntroText2", 75 IDS_CREATE_SUPERVISED_INTRO_TEXT_2); 76 builder->AddF("createSupervisedUserIntroText3", 77 IDS_CREATE_SUPERVISED_INTRO_TEXT_3, 78 base::UTF8ToUTF16(chrome::kSupervisedUserManagementDisplayURL)); 79 80 builder->Add("createSupervisedUserPickManagerTitle", 81 IDS_CREATE_SUPERVISED_USER_CREATE_PICK_MANAGER_TITLE); 82 builder->AddF("createSupervisedUserPickManagerTitleExplanation", 83 IDS_CREATE_SUPERVISED_USER_CREATE_PICK_MANAGER_EXPLANATION, 84 base::UTF8ToUTF16(chrome::kSupervisedUserManagementDisplayURL)); 85 builder->Add("createSupervisedUserManagerPasswordHint", 86 IDS_CREATE_SUPERVISED_USER_CREATE_MANAGER_PASSWORD_HINT); 87 builder->Add("createSupervisedUserWrongManagerPasswordText", 88 IDS_CREATE_SUPERVISED_USER_MANAGER_PASSWORD_ERROR); 89 90 builder->Add("createSupervisedUserNameTitle", 91 IDS_CREATE_SUPERVISED_USER_CREATE_ACCOUNT_NAME_TITLE); 92 builder->Add("createSupervisedUserNameAccessibleTitle", 93 IDS_CREATE_SUPERVISED_USER_SETUP_ACCESSIBLE_TITLE); 94 builder->Add("createSupervisedUserNameExplanation", 95 IDS_CREATE_SUPERVISED_USER_CREATE_ACCOUNT_NAME_EXPLANATION); 96 builder->Add("createSupervisedUserNameHint", 97 IDS_CREATE_SUPERVISED_USER_CREATE_ACCOUNT_NAME_HINT); 98 builder->Add("createSupervisedUserPasswordTitle", 99 IDS_CREATE_SUPERVISED_USER_CREATE_PASSWORD_TITLE); 100 builder->Add("createSupervisedUserPasswordExplanation", 101 IDS_CREATE_SUPERVISED_USER_CREATE_PASSWORD_EXPLANATION); 102 builder->Add("createSupervisedUserPasswordHint", 103 IDS_CREATE_SUPERVISED_USER_CREATE_PASSWORD_HINT); 104 builder->Add("createSupervisedUserPasswordConfirmHint", 105 IDS_CREATE_SUPERVISED_USER_CREATE_PASSWORD_CONFIRM_HINT); 106 builder->Add("supervisedUserCreationFlowProceedButtonTitle", 107 IDS_CREATE_SUPERVISED_USER_CREATE_CONTINUE_BUTTON_TEXT); 108 builder->Add("supervisedUserCreationFlowStartButtonTitle", 109 IDS_CREATE_SUPERVISED_USER_CREATE_START_BUTTON_TEXT); 110 builder->Add("supervisedUserCreationFlowPrevButtonTitle", 111 IDS_CREATE_SUPERVISED_USER_CREATE_PREVIOUS_BUTTON_TEXT); 112 builder->Add("supervisedUserCreationFlowNextButtonTitle", 113 IDS_CREATE_SUPERVISED_USER_CREATE_NEXT_BUTTON_TEXT); 114 builder->Add("supervisedUserCreationFlowHandleErrorButtonTitle", 115 IDS_CREATE_SUPERVISED_USER_CREATE_HANDLE_ERROR_BUTTON_TEXT); 116 builder->Add("createSupervisedUserPasswordMismatchError", 117 IDS_CREATE_SUPERVISED_USER_CREATE_PASSWORD_MISMATCH_ERROR); 118 119 builder->Add("createSupervisedUserCreatedText1", 120 IDS_CREATE_SUPERVISED_USER_CREATED_1_TEXT_1); 121 builder->Add("createSupervisedUserCreatedText2", 122 IDS_CREATE_SUPERVISED_USER_CREATED_1_TEXT_2); 123 builder->Add("createSupervisedUserCreatedText3", 124 IDS_CREATE_SUPERVISED_USER_CREATED_1_TEXT_3); 125 126 builder->Add("importExistingSupervisedUserTitle", 127 IDS_IMPORT_EXISTING_SUPERVISED_USER_TITLE); 128 builder->Add("importExistingSupervisedUserText", 129 IDS_IMPORT_EXISTING_SUPERVISED_USER_TEXT); 130 builder->Add("supervisedUserCreationFlowImportButtonTitle", 131 IDS_IMPORT_EXISTING_SUPERVISED_USER_OK); 132 builder->Add("importSupervisedUserLink", 133 IDS_PROFILES_IMPORT_EXISTING_SUPERVISED_USER_LINK); 134 builder->Add("createSupervisedUserLink", 135 IDS_CREATE_NEW_USER_LINK); 136 builder->Add("importBubbleText", IDS_SUPERVISED_USER_IMPORT_BUBBLE_TEXT); 137 builder->Add("importUserExists", IDS_SUPERVISED_USER_IMPORT_USER_EXIST); 138 builder->Add("importUsernameExists", 139 IDS_SUPERVISED_USER_IMPORT_USERNAME_EXIST); 140 141 builder->Add("managementURL", chrome::kSupervisedUserManagementDisplayURL); 142 143 // TODO(antrim) : this is an explicit code duplications with UserImageScreen. 144 // It should be removed by issue 251179. 145 builder->Add("takePhoto", IDS_OPTIONS_CHANGE_PICTURE_TAKE_PHOTO); 146 builder->Add("discardPhoto", IDS_OPTIONS_CHANGE_PICTURE_DISCARD_PHOTO); 147 builder->Add("flipPhoto", IDS_OPTIONS_CHANGE_PICTURE_FLIP_PHOTO); 148 builder->Add("photoFlippedAccessibleText", 149 IDS_OPTIONS_PHOTO_FLIP_ACCESSIBLE_TEXT); 150 builder->Add("photoFlippedBackAccessibleText", 151 IDS_OPTIONS_PHOTO_FLIPBACK_ACCESSIBLE_TEXT); 152 builder->Add("photoCaptureAccessibleText", 153 IDS_OPTIONS_PHOTO_CAPTURE_ACCESSIBLE_TEXT); 154 builder->Add("photoDiscardAccessibleText", 155 IDS_OPTIONS_PHOTO_DISCARD_ACCESSIBLE_TEXT); 156} 157 158void SupervisedUserCreationScreenHandler::Initialize() {} 159 160void SupervisedUserCreationScreenHandler::RegisterMessages() { 161 AddCallback("finishLocalSupervisedUserCreation", 162 &SupervisedUserCreationScreenHandler:: 163 HandleFinishLocalSupervisedUserCreation); 164 AddCallback("abortLocalSupervisedUserCreation", 165 &SupervisedUserCreationScreenHandler:: 166 HandleAbortLocalSupervisedUserCreation); 167 AddCallback("checkSupervisedUserName", 168 &SupervisedUserCreationScreenHandler:: 169 HandleCheckSupervisedUserName); 170 AddCallback("authenticateManagerInSupervisedUserCreationFlow", 171 &SupervisedUserCreationScreenHandler:: 172 HandleAuthenticateManager); 173 AddCallback("specifySupervisedUserCreationFlowUserData", 174 &SupervisedUserCreationScreenHandler:: 175 HandleCreateSupervisedUser); 176 AddCallback("managerSelectedOnSupervisedUserCreationFlow", 177 &SupervisedUserCreationScreenHandler:: 178 HandleManagerSelected); 179 AddCallback("userSelectedForImportInSupervisedUserCreationFlow", 180 &SupervisedUserCreationScreenHandler:: 181 HandleImportUserSelected); 182 AddCallback("importSupervisedUser", 183 &SupervisedUserCreationScreenHandler:: 184 HandleImportSupervisedUser); 185 AddCallback("importSupervisedUserWithPassword", 186 &SupervisedUserCreationScreenHandler:: 187 HandleImportSupervisedUserWithPassword); 188 189 190 // TODO(antrim) : this is an explicit code duplications with UserImageScreen. 191 // It should be removed by issue 251179. 192 AddCallback("supervisedUserGetImages", 193 &SupervisedUserCreationScreenHandler::HandleGetImages); 194 195 AddCallback("supervisedUserPhotoTaken", 196 &SupervisedUserCreationScreenHandler::HandlePhotoTaken); 197 AddCallback("supervisedUserTakePhoto", 198 &SupervisedUserCreationScreenHandler::HandleTakePhoto); 199 AddCallback("supervisedUserDiscardPhoto", 200 &SupervisedUserCreationScreenHandler::HandleDiscardPhoto); 201 AddCallback("supervisedUserSelectImage", 202 &SupervisedUserCreationScreenHandler::HandleSelectImage); 203 AddCallback("currentSupervisedUserPage", 204 &SupervisedUserCreationScreenHandler:: 205 HandleCurrentSupervisedUserPage); 206} 207 208void SupervisedUserCreationScreenHandler::PrepareToShow() {} 209 210void SupervisedUserCreationScreenHandler::Show() { 211 scoped_ptr<base::DictionaryValue> data(new base::DictionaryValue()); 212 scoped_ptr<base::ListValue> users_list(new base::ListValue()); 213 const user_manager::UserList& users = 214 user_manager::UserManager::Get()->GetUsers(); 215 std::string owner; 216 chromeos::CrosSettings::Get()->GetString(chromeos::kDeviceOwner, &owner); 217 218 for (user_manager::UserList::const_iterator it = users.begin(); 219 it != users.end(); 220 ++it) { 221 if ((*it)->GetType() != user_manager::USER_TYPE_REGULAR) 222 continue; 223 bool is_owner = ((*it)->email() == owner); 224 base::DictionaryValue* user_dict = new base::DictionaryValue(); 225 UserSelectionScreen::FillUserDictionary( 226 *it, 227 is_owner, 228 false, /* is_signin_to_add */ 229 ScreenlockBridge::LockHandler::OFFLINE_PASSWORD, 230 NULL, /* public_session_recommended_locales */ 231 user_dict); 232 users_list->Append(user_dict); 233 } 234 data->Set("managers", users_list.release()); 235 ShowScreen(OobeUI::kScreenSupervisedUserCreationFlow, data.get()); 236 237 if (!delegate_) 238 return; 239} 240 241void SupervisedUserCreationScreenHandler::Hide() { 242} 243 244void SupervisedUserCreationScreenHandler::ShowIntroPage() { 245 CallJS("showIntroPage"); 246} 247 248void SupervisedUserCreationScreenHandler::ShowManagerPasswordError() { 249 CallJS("showManagerPasswordError"); 250} 251 252void SupervisedUserCreationScreenHandler::ShowStatusMessage( 253 bool is_progress, 254 const base::string16& message) { 255 if (is_progress) 256 CallJS("showProgress", message); 257 else 258 CallJS("showStatusError", message); 259} 260 261void SupervisedUserCreationScreenHandler::ShowUsernamePage() { 262 CallJS("showUsernamePage"); 263} 264 265void SupervisedUserCreationScreenHandler::ShowTutorialPage() { 266 CallJS("showTutorialPage"); 267} 268 269void SupervisedUserCreationScreenHandler::ShowErrorPage( 270 const base::string16& title, 271 const base::string16& message, 272 const base::string16& button_text) { 273 CallJS("showErrorPage", title, message, button_text); 274} 275 276void SupervisedUserCreationScreenHandler::SetDelegate(Delegate* delegate) { 277 delegate_ = delegate; 278} 279 280void SupervisedUserCreationScreenHandler:: 281 HandleFinishLocalSupervisedUserCreation() { 282 delegate_->FinishFlow(); 283} 284 285void SupervisedUserCreationScreenHandler:: 286 HandleAbortLocalSupervisedUserCreation() { 287 delegate_->AbortFlow(); 288} 289 290void SupervisedUserCreationScreenHandler::HandleManagerSelected( 291 const std::string& manager_id) { 292 if (!delegate_) 293 return; 294 WallpaperManager::Get()->SetUserWallpaperNow(manager_id); 295} 296 297void SupervisedUserCreationScreenHandler::HandleImportUserSelected( 298 const std::string& user_id) { 299 if (!delegate_) 300 return; 301} 302 303void SupervisedUserCreationScreenHandler::HandleCheckSupervisedUserName( 304 const base::string16& name) { 305 std::string user_id; 306 if (NULL != 307 ChromeUserManager::Get()->GetSupervisedUserManager()->FindByDisplayName( 308 base::CollapseWhitespace(name, true))) { 309 CallJS("supervisedUserNameError", name, 310 l10n_util::GetStringUTF16( 311 IDS_CREATE_SUPERVISED_USER_CREATE_USERNAME_ALREADY_EXISTS)); 312 } else if (net::EscapeForHTML(name) != name) { 313 CallJS("supervisedUserNameError", name, 314 l10n_util::GetStringUTF16( 315 IDS_CREATE_SUPERVISED_USER_CREATE_ILLEGAL_USERNAME)); 316 } else if (delegate_ && delegate_->FindUserByDisplayName( 317 base::CollapseWhitespace(name, true), &user_id)) { 318 CallJS("supervisedUserSuggestImport", name, user_id); 319 } else { 320 CallJS("supervisedUserNameOk", name); 321 } 322} 323 324void SupervisedUserCreationScreenHandler::HandleCreateSupervisedUser( 325 const base::string16& new_raw_user_name, 326 const std::string& new_user_password) { 327 if (!delegate_) 328 return; 329 const base::string16 new_user_name = 330 base::CollapseWhitespace(new_raw_user_name, true); 331 if (NULL != 332 ChromeUserManager::Get()->GetSupervisedUserManager()->FindByDisplayName( 333 new_user_name)) { 334 CallJS("supervisedUserNameError", new_user_name, 335 l10n_util::GetStringFUTF16( 336 IDS_CREATE_SUPERVISED_USER_CREATE_USERNAME_ALREADY_EXISTS, 337 new_user_name)); 338 return; 339 } 340 if (net::EscapeForHTML(new_user_name) != new_user_name) { 341 CallJS("supervisedUserNameError", new_user_name, 342 l10n_util::GetStringUTF16( 343 IDS_CREATE_SUPERVISED_USER_CREATE_ILLEGAL_USERNAME)); 344 return; 345 } 346 347 if (new_user_password.length() == 0) { 348 CallJS("showPasswordError", 349 l10n_util::GetStringUTF16( 350 IDS_CREATE_SUPERVISED_USER_CREATE_PASSWORD_TOO_SHORT)); 351 return; 352 } 353 354 ShowStatusMessage(true /* progress */, l10n_util::GetStringUTF16( 355 IDS_CREATE_SUPERVISED_USER_CREATION_CREATION_PROGRESS_MESSAGE)); 356 357 delegate_->CreateSupervisedUser(new_user_name, new_user_password); 358} 359 360void SupervisedUserCreationScreenHandler::HandleImportSupervisedUser( 361 const std::string& user_id) { 362 if (!delegate_) 363 return; 364 365 ShowStatusMessage(true /* progress */, l10n_util::GetStringUTF16( 366 IDS_CREATE_SUPERVISED_USER_CREATION_CREATION_PROGRESS_MESSAGE)); 367 368 delegate_->ImportSupervisedUser(user_id); 369} 370 371void SupervisedUserCreationScreenHandler:: 372 HandleImportSupervisedUserWithPassword( 373 const std::string& user_id, 374 const std::string& password) { 375 if (!delegate_) 376 return; 377 378 ShowStatusMessage(true /* progress */, l10n_util::GetStringUTF16( 379 IDS_CREATE_SUPERVISED_USER_CREATION_CREATION_PROGRESS_MESSAGE)); 380 381 delegate_->ImportSupervisedUserWithPassword(user_id, password); 382} 383 384void SupervisedUserCreationScreenHandler::HandleAuthenticateManager( 385 const std::string& raw_manager_username, 386 const std::string& manager_password) { 387 const std::string manager_username = 388 gaia::SanitizeEmail(raw_manager_username); 389 delegate_->AuthenticateManager(manager_username, manager_password); 390} 391 392// TODO(antrim) : this is an explicit code duplications with UserImageScreen. 393// It should be removed by issue 251179. 394void SupervisedUserCreationScreenHandler::HandleGetImages() { 395 base::ListValue image_urls; 396 for (int i = user_manager::kFirstDefaultImageIndex; 397 i < user_manager::kDefaultImagesCount; 398 ++i) { 399 scoped_ptr<base::DictionaryValue> image_data(new base::DictionaryValue); 400 image_data->SetString("url", user_manager::GetDefaultImageUrl(i)); 401 image_data->SetString( 402 "author", 403 l10n_util::GetStringUTF16(user_manager::kDefaultImageAuthorIDs[i])); 404 image_data->SetString( 405 "website", 406 l10n_util::GetStringUTF16(user_manager::kDefaultImageWebsiteIDs[i])); 407 image_data->SetString("title", user_manager::GetDefaultImageDescription(i)); 408 image_urls.Append(image_data.release()); 409 } 410 CallJS("setDefaultImages", image_urls); 411} 412 413void SupervisedUserCreationScreenHandler::HandlePhotoTaken 414 (const std::string& image_url) { 415 std::string mime_type, charset, raw_data; 416 if (!net::DataURL::Parse(GURL(image_url), &mime_type, &charset, &raw_data)) 417 NOTREACHED(); 418 DCHECK_EQ("image/png", mime_type); 419 420 if (delegate_) 421 delegate_->OnPhotoTaken(raw_data); 422} 423 424void SupervisedUserCreationScreenHandler::HandleTakePhoto() { 425#if !defined(USE_ATHENA) 426 // crbug.com/408733 427 ash::PlaySystemSoundIfSpokenFeedback(SOUND_CAMERA_SNAP); 428#endif 429} 430 431void SupervisedUserCreationScreenHandler::HandleDiscardPhoto() { 432#if !defined(USE_ATHENA) 433 ash::PlaySystemSoundIfSpokenFeedback(SOUND_OBJECT_DELETE); 434#endif 435} 436 437void SupervisedUserCreationScreenHandler::HandleSelectImage( 438 const std::string& image_url, 439 const std::string& image_type) { 440 if (delegate_) 441 delegate_->OnImageSelected(image_type, image_url); 442} 443 444void SupervisedUserCreationScreenHandler::HandleCurrentSupervisedUserPage( 445 const std::string& page) { 446 if (delegate_) 447 delegate_->OnPageSelected(page); 448} 449 450void SupervisedUserCreationScreenHandler::ShowPage( 451 const std::string& page) { 452 CallJS("showPage", page); 453} 454 455void SupervisedUserCreationScreenHandler::SetCameraPresent(bool present) { 456 CallJS("setCameraPresent", present); 457} 458 459void SupervisedUserCreationScreenHandler::ShowExistingSupervisedUsers( 460 const base::ListValue* users) { 461 CallJS("setExistingSupervisedUsers", *users); 462} 463 464} // namespace chromeos 465