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/ui/webui/chromeos/login/user_image_screen_handler.h" 6 7#include "ash/audio/sounds.h" 8#include "base/command_line.h" 9#include "base/logging.h" 10#include "base/metrics/histogram.h" 11#include "base/values.h" 12#include "chrome/browser/chromeos/login/existing_user_controller.h" 13#include "chrome/browser/chromeos/login/ui/webui_login_display.h" 14#include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" 15#include "chrome/common/chrome_switches.h" 16#include "chrome/common/url_constants.h" 17#include "chrome/grit/generated_resources.h" 18#include "chromeos/audio/chromeos_sounds.h" 19#include "components/user_manager/user.h" 20#include "components/user_manager/user_image/default_user_images.h" 21#include "grit/browser_resources.h" 22#include "net/base/data_url.h" 23#include "ui/base/l10n/l10n_util.h" 24#include "ui/base/resource/resource_bundle.h" 25#include "url/gurl.h" 26 27namespace { 28 29const char kJsScreenPath[] = "login.UserImageScreen"; 30 31} // namespace 32 33namespace chromeos { 34 35UserImageScreenHandler::UserImageScreenHandler() 36 : BaseScreenHandler(kJsScreenPath), 37 screen_(NULL), 38 show_on_init_(false), 39 is_ready_(false) { 40 ui::ResourceBundle& bundle = ui::ResourceBundle::GetSharedInstance(); 41 media::SoundsManager* manager = media::SoundsManager::Get(); 42 manager->Initialize(SOUND_OBJECT_DELETE, 43 bundle.GetRawDataResource(IDR_SOUND_OBJECT_DELETE_WAV)); 44 manager->Initialize(SOUND_CAMERA_SNAP, 45 bundle.GetRawDataResource(IDR_SOUND_CAMERA_SNAP_WAV)); 46} 47 48UserImageScreenHandler::~UserImageScreenHandler() { 49 if (screen_) { 50 screen_->OnActorDestroyed(this); 51 } 52} 53 54void UserImageScreenHandler::Initialize() { 55 if (show_on_init_) { 56 Show(); 57 show_on_init_ = false; 58 } 59} 60 61void UserImageScreenHandler::SetDelegate( 62 UserImageScreenActor::Delegate* screen) { 63 screen_ = screen; 64} 65 66void UserImageScreenHandler::Show() { 67 if (!page_is_ready()) { 68 show_on_init_ = true; 69 return; 70 } 71 screen_show_time_ = base::Time::Now(); 72 ShowScreen(OobeUI::kScreenUserImagePicker, NULL); 73 74 // When shown, query camera presence. 75 if (!screen_) 76 return; 77 if (is_ready_) 78 screen_->OnScreenReady(); 79} 80 81void UserImageScreenHandler::Hide() { 82} 83 84void UserImageScreenHandler::PrepareToShow() { 85} 86 87void UserImageScreenHandler::DeclareLocalizedValues( 88 LocalizedValuesBuilder* builder) { 89 builder->Add("userImageScreenTitle", IDS_USER_IMAGE_SCREEN_TITLE); 90 builder->Add("userImageScreenDescription", 91 IDS_OPTIONS_CHANGE_PICTURE_DIALOG_TEXT); 92 builder->Add("takePhoto", IDS_OPTIONS_CHANGE_PICTURE_TAKE_PHOTO); 93 builder->Add("discardPhoto", IDS_OPTIONS_CHANGE_PICTURE_DISCARD_PHOTO); 94 builder->Add("flipPhoto", IDS_OPTIONS_CHANGE_PICTURE_FLIP_PHOTO); 95 builder->Add("profilePhoto", IDS_IMAGE_SCREEN_PROFILE_PHOTO); 96 builder->Add("profilePhotoLoading", 97 IDS_IMAGE_SCREEN_PROFILE_LOADING_PHOTO); 98 builder->Add("okButtonText", IDS_OK); 99 builder->Add("authorCredit", IDS_OPTIONS_SET_WALLPAPER_AUTHOR_TEXT); 100 builder->Add("photoFromCamera", IDS_OPTIONS_CHANGE_PICTURE_PHOTO_FROM_CAMERA); 101 builder->Add("photoFlippedAccessibleText", 102 IDS_OPTIONS_PHOTO_FLIP_ACCESSIBLE_TEXT); 103 builder->Add("photoFlippedBackAccessibleText", 104 IDS_OPTIONS_PHOTO_FLIPBACK_ACCESSIBLE_TEXT); 105 builder->Add("photoCaptureAccessibleText", 106 IDS_OPTIONS_PHOTO_CAPTURE_ACCESSIBLE_TEXT); 107 builder->Add("photoDiscardAccessibleText", 108 IDS_OPTIONS_PHOTO_DISCARD_ACCESSIBLE_TEXT); 109 builder->Add("syncingPreferences", IDS_IMAGE_SCREEN_SYNCING_PREFERENCES); 110} 111 112void UserImageScreenHandler::RegisterMessages() { 113 AddCallback("getImages", &UserImageScreenHandler::HandleGetImages); 114 AddCallback("screenReady", &UserImageScreenHandler::HandleScreenReady); 115 AddCallback("takePhoto", &UserImageScreenHandler::HandleTakePhoto); 116 AddCallback("discardPhoto", &UserImageScreenHandler::HandleDiscardPhoto); 117 AddCallback("photoTaken", &UserImageScreenHandler::HandlePhotoTaken); 118 AddCallback("selectImage", &UserImageScreenHandler::HandleSelectImage); 119 AddCallback("onUserImageAccepted", 120 &UserImageScreenHandler::HandleImageAccepted); 121 AddCallback("onUserImageScreenShown", 122 &UserImageScreenHandler::HandleScreenShown); 123} 124 125void UserImageScreenHandler::SelectImage(int index) { 126 if (page_is_ready()) 127 CallJS("setSelectedImage", user_manager::GetDefaultImageUrl(index)); 128} 129 130void UserImageScreenHandler::SendProfileImage(const std::string& data_url) { 131 if (page_is_ready()) 132 CallJS("setProfileImage", data_url); 133} 134 135void UserImageScreenHandler::OnProfileImageAbsent() { 136 if (page_is_ready()) { 137 scoped_ptr<base::Value> null_value(base::Value::CreateNullValue()); 138 CallJS("setProfileImage", *null_value); 139 } 140} 141 142// TODO(antrim) : It looks more like parameters for "Init" rather than callback. 143void UserImageScreenHandler::HandleGetImages() { 144 base::ListValue image_urls; 145 for (int i = user_manager::kFirstDefaultImageIndex; 146 i < user_manager::kDefaultImagesCount; 147 ++i) { 148 scoped_ptr<base::DictionaryValue> image_data(new base::DictionaryValue); 149 image_data->SetString("url", user_manager::GetDefaultImageUrl(i)); 150 image_data->SetString( 151 "author", 152 l10n_util::GetStringUTF16(user_manager::kDefaultImageAuthorIDs[i])); 153 image_data->SetString( 154 "website", 155 l10n_util::GetStringUTF16(user_manager::kDefaultImageWebsiteIDs[i])); 156 image_data->SetString("title", user_manager::GetDefaultImageDescription(i)); 157 image_urls.Append(image_data.release()); 158 } 159 CallJS("setDefaultImages", image_urls); 160 if (!screen_) 161 return; 162 if (screen_->selected_image() != user_manager::User::USER_IMAGE_INVALID) 163 SelectImage(screen_->selected_image()); 164 165 if (screen_->profile_picture_data_url() != url::kAboutBlankURL) 166 SendProfileImage(screen_->profile_picture_data_url()); 167 else if (screen_->profile_picture_absent()) 168 OnProfileImageAbsent(); 169} 170 171void UserImageScreenHandler::HandleScreenReady() { 172 is_ready_ = true; 173 if (screen_) 174 screen_->OnScreenReady(); 175} 176 177void UserImageScreenHandler::HandlePhotoTaken(const std::string& image_url) { 178 std::string mime_type, charset, raw_data; 179 if (!net::DataURL::Parse(GURL(image_url), &mime_type, &charset, &raw_data)) 180 NOTREACHED(); 181 DCHECK_EQ("image/png", mime_type); 182 183 if (screen_) 184 screen_->OnPhotoTaken(raw_data); 185} 186 187void UserImageScreenHandler::HandleTakePhoto() { 188 ash::PlaySystemSoundIfSpokenFeedback(SOUND_CAMERA_SNAP); 189} 190 191void UserImageScreenHandler::HandleDiscardPhoto() { 192 ash::PlaySystemSoundIfSpokenFeedback(SOUND_OBJECT_DELETE); 193} 194 195void UserImageScreenHandler::HandleSelectImage(const std::string& image_url, 196 const std::string& image_type, 197 bool is_user_selection) { 198 if (screen_) 199 screen_->OnImageSelected(image_type, image_url, is_user_selection); 200} 201 202void UserImageScreenHandler::HandleImageAccepted() { 203 if (screen_) 204 screen_->OnImageAccepted(); 205} 206 207void UserImageScreenHandler::HandleScreenShown() { 208 DCHECK(!screen_show_time_.is_null()); 209 210 base::TimeDelta delta = base::Time::Now() - screen_show_time_; 211 VLOG(1) << "Screen load time: " << delta.InSecondsF(); 212 UMA_HISTOGRAM_TIMES("UserImage.ScreenIsShownTime", delta); 213} 214 215void UserImageScreenHandler::SetCameraPresent(bool present) { 216 CallJS("setCameraPresent", present); 217} 218 219void UserImageScreenHandler::HideCurtain() { 220 CallJS("hideCurtain"); 221} 222 223} // namespace chromeos 224