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 29 const char kJsScreenPath[] = "login.SupervisedUserCreationScreen"; 30 31 namespace chromeos { 32 33 SupervisedUserCreationScreenHandler::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 44 SupervisedUserCreationScreenHandler::~SupervisedUserCreationScreenHandler() { 45 if (delegate_) { 46 delegate_->OnActorDestroyed(this); 47 } 48 } 49 50 void 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 158 void SupervisedUserCreationScreenHandler::Initialize() {} 159 160 void 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 208 void SupervisedUserCreationScreenHandler::PrepareToShow() {} 209 210 void 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 241 void SupervisedUserCreationScreenHandler::Hide() { 242 } 243 244 void SupervisedUserCreationScreenHandler::ShowIntroPage() { 245 CallJS("showIntroPage"); 246 } 247 248 void SupervisedUserCreationScreenHandler::ShowManagerPasswordError() { 249 CallJS("showManagerPasswordError"); 250 } 251 252 void 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 261 void SupervisedUserCreationScreenHandler::ShowUsernamePage() { 262 CallJS("showUsernamePage"); 263 } 264 265 void SupervisedUserCreationScreenHandler::ShowTutorialPage() { 266 CallJS("showTutorialPage"); 267 } 268 269 void 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 276 void SupervisedUserCreationScreenHandler::SetDelegate(Delegate* delegate) { 277 delegate_ = delegate; 278 } 279 280 void SupervisedUserCreationScreenHandler:: 281 HandleFinishLocalSupervisedUserCreation() { 282 delegate_->FinishFlow(); 283 } 284 285 void SupervisedUserCreationScreenHandler:: 286 HandleAbortLocalSupervisedUserCreation() { 287 delegate_->AbortFlow(); 288 } 289 290 void SupervisedUserCreationScreenHandler::HandleManagerSelected( 291 const std::string& manager_id) { 292 if (!delegate_) 293 return; 294 WallpaperManager::Get()->SetUserWallpaperNow(manager_id); 295 } 296 297 void SupervisedUserCreationScreenHandler::HandleImportUserSelected( 298 const std::string& user_id) { 299 if (!delegate_) 300 return; 301 } 302 303 void 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 324 void 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 360 void 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 371 void 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 384 void 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. 394 void 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 413 void 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 424 void SupervisedUserCreationScreenHandler::HandleTakePhoto() { 425 #if !defined(USE_ATHENA) 426 // crbug.com/408733 427 ash::PlaySystemSoundIfSpokenFeedback(SOUND_CAMERA_SNAP); 428 #endif 429 } 430 431 void SupervisedUserCreationScreenHandler::HandleDiscardPhoto() { 432 #if !defined(USE_ATHENA) 433 ash::PlaySystemSoundIfSpokenFeedback(SOUND_OBJECT_DELETE); 434 #endif 435 } 436 437 void 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 444 void SupervisedUserCreationScreenHandler::HandleCurrentSupervisedUserPage( 445 const std::string& page) { 446 if (delegate_) 447 delegate_->OnPageSelected(page); 448 } 449 450 void SupervisedUserCreationScreenHandler::ShowPage( 451 const std::string& page) { 452 CallJS("showPage", page); 453 } 454 455 void SupervisedUserCreationScreenHandler::SetCameraPresent(bool present) { 456 CallJS("setCameraPresent", present); 457 } 458 459 void SupervisedUserCreationScreenHandler::ShowExistingSupervisedUsers( 460 const base::ListValue* users) { 461 CallJS("setExistingSupervisedUsers", *users); 462 } 463 464 } // namespace chromeos 465