OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.h" | 5 #include "chrome/browser/ui/webui/chromeos/login/user_image_screen_handler.h" |
6 | 6 |
7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/values.h" | 10 #include "base/values.h" |
11 #include "chrome/browser/chromeos/camera_detector.h" | |
12 #include "chrome/browser/chromeos/login/default_user_images.h" | 11 #include "chrome/browser/chromeos/login/default_user_images.h" |
13 #include "chrome/browser/chromeos/login/user.h" | 12 #include "chrome/browser/chromeos/login/user.h" |
14 #include "chrome/browser/chromeos/login/webui_login_display.h" | 13 #include "chrome/browser/chromeos/login/webui_login_display.h" |
15 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" | 14 #include "chrome/browser/ui/webui/chromeos/login/oobe_ui.h" |
16 #include "chrome/common/chrome_switches.h" | 15 #include "chrome/common/chrome_switches.h" |
17 #include "chrome/common/url_constants.h" | 16 #include "chrome/common/url_constants.h" |
18 #include "content/public/browser/browser_thread.h" | |
19 #include "googleurl/src/gurl.h" | 17 #include "googleurl/src/gurl.h" |
20 #include "grit/generated_resources.h" | 18 #include "grit/generated_resources.h" |
21 #include "net/base/data_url.h" | 19 #include "net/base/data_url.h" |
22 #include "ui/base/l10n/l10n_util.h" | 20 #include "ui/base/l10n/l10n_util.h" |
23 #include "ui/views/widget/widget.h" | |
24 #include "ui/webui/web_ui_util.h" | |
25 | |
26 using content::BrowserThread; | |
27 | 21 |
28 namespace chromeos { | 22 namespace chromeos { |
29 | 23 |
30 UserImageScreenHandler::UserImageScreenHandler() | 24 UserImageScreenHandler::UserImageScreenHandler() |
31 : screen_(NULL), | 25 : screen_(NULL), |
32 show_on_init_(false), | 26 show_on_init_(false) { |
33 selected_image_(User::kInvalidImageIndex), | |
34 accept_photo_after_decoding_(false), | |
35 user_photo_data_url_(chrome::kAboutBlankURL), | |
36 profile_picture_data_url_(chrome::kAboutBlankURL), | |
37 profile_picture_absent_(false), | |
38 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) { | |
39 } | 27 } |
40 | 28 |
41 UserImageScreenHandler::~UserImageScreenHandler() { | 29 UserImageScreenHandler::~UserImageScreenHandler() { |
42 if (screen_) | 30 if (screen_) |
43 screen_->OnActorDestroyed(this); | 31 screen_->OnActorDestroyed(this); |
44 if (image_decoder_.get()) | |
45 image_decoder_->set_delegate(NULL); | |
46 } | |
47 | |
48 void UserImageScreenHandler::DeclareLocalizedValues( | |
49 LocalizedValuesBuilder* builder) { | |
50 // TODO(ivankr): string should be renamed to something like | |
51 // IDS_USER_IMAGE_SCREEN_TITLE (currently used for Take Photo dialog). | |
52 builder->Add("userImageScreenTitle", IDS_OOBE_PICTURE); | |
53 builder->Add("userImageScreenDescription", | |
54 IDS_OPTIONS_CHANGE_PICTURE_DIALOG_TEXT); | |
55 builder->Add("takePhoto", IDS_OPTIONS_CHANGE_PICTURE_TAKE_PHOTO); | |
56 builder->Add("discardPhoto", IDS_OPTIONS_CHANGE_PICTURE_DISCARD_PHOTO); | |
57 builder->Add("flipPhoto", IDS_OPTIONS_CHANGE_PICTURE_FLIP_PHOTO); | |
58 builder->Add("profilePhoto", IDS_IMAGE_SCREEN_PROFILE_PHOTO); | |
59 builder->Add("profilePhotoLoading", | |
60 IDS_IMAGE_SCREEN_PROFILE_LOADING_PHOTO); | |
61 builder->Add("okButtonText", IDS_OK); | |
62 builder->Add("authorCredit", IDS_OPTIONS_SET_WALLPAPER_AUTHOR_TEXT); | |
63 builder->Add("photoFromCamera", IDS_OPTIONS_CHANGE_PICTURE_PHOTO_FROM_CAMERA); | |
64 builder->Add("photoCaptureAccessibleText", | |
65 IDS_OPTIONS_PHOTO_CAPTURE_ACCESSIBLE_TEXT); | |
66 builder->Add("photoDiscardAccessibleText", | |
67 IDS_OPTIONS_PHOTO_DISCARD_ACCESSIBLE_TEXT); | |
68 } | 32 } |
69 | 33 |
70 void UserImageScreenHandler::Initialize() { | 34 void UserImageScreenHandler::Initialize() { |
71 if (show_on_init_) { | 35 if (show_on_init_) { |
72 Show(); | 36 Show(); |
73 show_on_init_ = false; | 37 show_on_init_ = false; |
74 } | 38 } |
75 } | 39 } |
76 | 40 |
77 void UserImageScreenHandler::SetDelegate( | 41 void UserImageScreenHandler::SetDelegate( |
78 UserImageScreenActor::Delegate* screen) { | 42 UserImageScreenActor::Delegate* screen) { |
79 screen_ = screen; | 43 screen_ = screen; |
80 } | 44 } |
81 | 45 |
82 void UserImageScreenHandler::Show() { | 46 void UserImageScreenHandler::Show() { |
83 if (!page_is_ready()) { | 47 if (!page_is_ready()) { |
84 show_on_init_ = true; | 48 show_on_init_ = true; |
85 return; | 49 return; |
86 } | 50 } |
87 screen_show_time_ = base::Time::Now(); | 51 screen_show_time_ = base::Time::Now(); |
88 ShowScreen(OobeUI::kScreenUserImagePicker, NULL); | 52 ShowScreen(OobeUI::kScreenUserImagePicker, NULL); |
89 | 53 |
90 // When shown, query camera presence. | 54 // When shown, query camera presence. |
91 CheckCameraPresence(); | 55 if (!screen_) |
| 56 return; |
| 57 screen_->CheckCameraPresence(); |
92 } | 58 } |
93 | 59 |
94 void UserImageScreenHandler::Hide() { | 60 void UserImageScreenHandler::Hide() { |
95 } | 61 } |
96 | 62 |
97 void UserImageScreenHandler::PrepareToShow() { | 63 void UserImageScreenHandler::PrepareToShow() { |
98 } | 64 } |
99 | 65 |
100 void UserImageScreenHandler::SelectImage(int index) { | 66 void UserImageScreenHandler::DeclareLocalizedValues( |
101 selected_image_ = index; | 67 LocalizedValuesBuilder* builder) { |
102 if (page_is_ready()) | 68 // TODO(ivankr): string should be renamed to something like |
103 CallJS("oobe.UserImageScreen.setSelectedImage", GetDefaultImageUrl(index)); | 69 // IDS_USER_IMAGE_SCREEN_TITLE (currently used for Take Photo dialog). |
104 } | 70 builder->Add("userImageScreenTitle", IDS_OOBE_PICTURE); |
105 | 71 builder->Add("userImageScreenDescription", |
106 void UserImageScreenHandler::CheckCameraPresence() { | 72 IDS_OPTIONS_CHANGE_PICTURE_DIALOG_TEXT); |
107 CameraDetector::StartPresenceCheck( | 73 builder->Add("takePhoto", IDS_OPTIONS_CHANGE_PICTURE_TAKE_PHOTO); |
108 base::Bind(&UserImageScreenHandler::OnCameraPresenceCheckDone, | 74 builder->Add("discardPhoto", IDS_OPTIONS_CHANGE_PICTURE_DISCARD_PHOTO); |
109 weak_factory_.GetWeakPtr())); | 75 builder->Add("flipPhoto", IDS_OPTIONS_CHANGE_PICTURE_FLIP_PHOTO); |
| 76 builder->Add("profilePhoto", IDS_IMAGE_SCREEN_PROFILE_PHOTO); |
| 77 builder->Add("profilePhotoLoading", |
| 78 IDS_IMAGE_SCREEN_PROFILE_LOADING_PHOTO); |
| 79 builder->Add("okButtonText", IDS_OK); |
| 80 builder->Add("authorCredit", IDS_OPTIONS_SET_WALLPAPER_AUTHOR_TEXT); |
| 81 builder->Add("photoFromCamera", IDS_OPTIONS_CHANGE_PICTURE_PHOTO_FROM_CAMERA); |
| 82 builder->Add("photoCaptureAccessibleText", |
| 83 IDS_OPTIONS_PHOTO_CAPTURE_ACCESSIBLE_TEXT); |
| 84 builder->Add("photoDiscardAccessibleText", |
| 85 IDS_OPTIONS_PHOTO_DISCARD_ACCESSIBLE_TEXT); |
110 } | 86 } |
111 | 87 |
112 void UserImageScreenHandler::RegisterMessages() { | 88 void UserImageScreenHandler::RegisterMessages() { |
113 AddCallback("getImages", &UserImageScreenHandler::HandleGetImages); | 89 AddCallback("getImages", &UserImageScreenHandler::HandleGetImages); |
114 AddCallback("photoTaken", &UserImageScreenHandler::HandlePhotoTaken); | 90 AddCallback("photoTaken", &UserImageScreenHandler::HandlePhotoTaken); |
115 AddCallback("selectImage", &UserImageScreenHandler::HandleSelectImage); | 91 AddCallback("selectImage", &UserImageScreenHandler::HandleSelectImage); |
116 AddCallback("checkCameraPresence", | 92 AddCallback("checkCameraPresence", |
117 &UserImageScreenHandler::HandleCheckCameraPresence); | 93 &UserImageScreenHandler::HandleCheckCameraPresence); |
118 AddCallback("onUserImageAccepted", | 94 AddCallback("onUserImageAccepted", |
119 &UserImageScreenHandler::HandleImageAccepted); | 95 &UserImageScreenHandler::HandleImageAccepted); |
120 AddCallback("onUserImageScreenShown", | 96 AddCallback("onUserImageScreenShown", |
121 &UserImageScreenHandler::HandleScreenShown); | 97 &UserImageScreenHandler::HandleScreenShown); |
122 } | 98 } |
123 | 99 |
124 void UserImageScreenHandler::AddProfileImage(const gfx::ImageSkia& image) { | 100 void UserImageScreenHandler::SelectImage(int index) { |
125 profile_picture_data_url_ = webui::GetBitmapDataUrl(*image.bitmap()); | 101 if (page_is_ready()) |
126 SendProfileImage(profile_picture_data_url_); | 102 CallJS("oobe.UserImageScreen.setSelectedImage", GetDefaultImageUrl(index)); |
127 } | 103 } |
128 | 104 |
129 void UserImageScreenHandler::SendProfileImage(const std::string& data_url) { | 105 void UserImageScreenHandler::SendProfileImage(const std::string& data_url) { |
130 if (page_is_ready()) | 106 if (page_is_ready()) |
131 CallJS("oobe.UserImageScreen.setProfileImage", data_url); | 107 CallJS("oobe.UserImageScreen.setProfileImage", data_url); |
132 } | 108 } |
133 | 109 |
134 void UserImageScreenHandler::OnProfileImageAbsent() { | 110 void UserImageScreenHandler::OnProfileImageAbsent() { |
135 profile_picture_absent_ = true; | |
136 if (page_is_ready()) { | 111 if (page_is_ready()) { |
137 scoped_ptr<base::Value> null_value(base::Value::CreateNullValue()); | 112 scoped_ptr<base::Value> null_value(base::Value::CreateNullValue()); |
138 CallJS("oobe.UserImageScreen.setProfileImage", *null_value); | 113 CallJS("oobe.UserImageScreen.setProfileImage", *null_value); |
139 } | 114 } |
140 } | 115 } |
141 | 116 |
| 117 // TODO(antrim) : It looks more like parameters for "Init" rather than callback. |
142 void UserImageScreenHandler::HandleGetImages() { | 118 void UserImageScreenHandler::HandleGetImages() { |
143 base::ListValue image_urls; | 119 base::ListValue image_urls; |
144 for (int i = kFirstDefaultImageIndex; i < kDefaultImagesCount; ++i) { | 120 for (int i = kFirstDefaultImageIndex; i < kDefaultImagesCount; ++i) { |
145 scoped_ptr<base::DictionaryValue> image_data(new base::DictionaryValue); | 121 scoped_ptr<base::DictionaryValue> image_data(new base::DictionaryValue); |
146 image_data->SetString("url", GetDefaultImageUrl(i)); | 122 image_data->SetString("url", GetDefaultImageUrl(i)); |
147 image_data->SetString( | 123 image_data->SetString( |
148 "author", l10n_util::GetStringUTF16(kDefaultImageAuthorIDs[i])); | 124 "author", l10n_util::GetStringUTF16(kDefaultImageAuthorIDs[i])); |
149 image_data->SetString( | 125 image_data->SetString( |
150 "website", l10n_util::GetStringUTF16(kDefaultImageWebsiteIDs[i])); | 126 "website", l10n_util::GetStringUTF16(kDefaultImageWebsiteIDs[i])); |
151 image_data->SetString("title", GetDefaultImageDescription(i)); | 127 image_data->SetString("title", GetDefaultImageDescription(i)); |
152 image_urls.Append(image_data.release()); | 128 image_urls.Append(image_data.release()); |
153 } | 129 } |
154 CallJS("oobe.UserImageScreen.setDefaultImages", image_urls); | 130 CallJS("oobe.UserImageScreen.setDefaultImages", image_urls); |
| 131 if (!screen_) |
| 132 return; |
| 133 if (screen_->selected_image() != User::kInvalidImageIndex) |
| 134 SelectImage(screen_->selected_image()); |
155 | 135 |
156 if (selected_image_ != User::kInvalidImageIndex) | 136 if (screen_->profile_picture_data_url() != chrome::kAboutBlankURL) |
157 SelectImage(selected_image_); | 137 SendProfileImage(screen_->profile_picture_data_url()); |
158 | 138 else if (screen_->profile_picture_absent()) |
159 if (profile_picture_data_url_ != chrome::kAboutBlankURL) | |
160 SendProfileImage(profile_picture_data_url_); | |
161 else if (profile_picture_absent_) | |
162 OnProfileImageAbsent(); | 139 OnProfileImageAbsent(); |
163 } | 140 } |
164 | 141 |
165 void UserImageScreenHandler::HandlePhotoTaken(const std::string& image_url) { | 142 void UserImageScreenHandler::HandlePhotoTaken(const std::string& image_url) { |
166 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
167 std::string mime_type, charset, raw_data; | 143 std::string mime_type, charset, raw_data; |
168 if (!net::DataURL::Parse(GURL(image_url), &mime_type, &charset, &raw_data)) | 144 if (!net::DataURL::Parse(GURL(image_url), &mime_type, &charset, &raw_data)) |
169 NOTREACHED(); | 145 NOTREACHED(); |
170 DCHECK_EQ("image/png", mime_type); | 146 DCHECK_EQ("image/png", mime_type); |
171 | 147 |
172 user_photo_ = gfx::ImageSkia(); | 148 if (screen_) |
173 user_photo_data_url_ = image_url; | 149 screen_->OnPhotoTaken(raw_data); |
174 | |
175 if (image_decoder_.get()) | |
176 image_decoder_->set_delegate(NULL); | |
177 image_decoder_ = new ImageDecoder(this, raw_data, | |
178 ImageDecoder::DEFAULT_CODEC); | |
179 scoped_refptr<base::MessageLoopProxy> task_runner = | |
180 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::UI); | |
181 image_decoder_->Start(task_runner); | |
182 } | 150 } |
183 | 151 |
184 void UserImageScreenHandler::HandleCheckCameraPresence() { | 152 void UserImageScreenHandler::HandleCheckCameraPresence() { |
185 CheckCameraPresence(); | 153 if (!screen_) |
| 154 return; |
| 155 screen_->CheckCameraPresence(); |
186 } | 156 } |
187 | 157 |
188 void UserImageScreenHandler::HandleSelectImage(const std::string& image_url, | 158 void UserImageScreenHandler::HandleSelectImage(const std::string& image_url, |
189 const std::string& image_type) { | 159 const std::string& image_type) { |
190 if (image_url.empty()) | 160 if (screen_) |
191 return; | 161 screen_->OnImageSelected(image_type, image_url); |
192 | |
193 int user_image_index = User::kInvalidImageIndex; | |
194 if (image_type == "default" && | |
195 IsDefaultImageUrl(image_url, &user_image_index)) { | |
196 selected_image_ = user_image_index; | |
197 } else if (image_type == "camera") { | |
198 selected_image_ = User::kExternalImageIndex; | |
199 } else if (image_type == "profile") { | |
200 selected_image_ = User::kProfileImageIndex; | |
201 } else { | |
202 NOTREACHED() << "Unexpected image type: " << image_type; | |
203 } | |
204 } | 162 } |
205 | 163 |
206 void UserImageScreenHandler::HandleImageAccepted() { | 164 void UserImageScreenHandler::HandleImageAccepted() { |
207 if (!screen_) | 165 if (screen_) |
208 return; | 166 screen_->OnImageAccepted(); |
209 switch (selected_image_) { | |
210 case User::kExternalImageIndex: | |
211 // Photo decoding may not have been finished yet. | |
212 if (user_photo_.isNull()) | |
213 accept_photo_after_decoding_ = true; | |
214 else | |
215 screen_->OnPhotoTaken(user_photo_); | |
216 break; | |
217 | |
218 case User::kProfileImageIndex: | |
219 screen_->OnProfileImageSelected(); | |
220 break; | |
221 | |
222 default: | |
223 DCHECK(selected_image_ >= 0 && selected_image_ < kDefaultImagesCount); | |
224 screen_->OnDefaultImageSelected(selected_image_); | |
225 } | |
226 } | 167 } |
227 | 168 |
228 void UserImageScreenHandler::HandleScreenShown() { | 169 void UserImageScreenHandler::HandleScreenShown() { |
229 DCHECK(!screen_show_time_.is_null()); | 170 DCHECK(!screen_show_time_.is_null()); |
230 | 171 |
231 base::TimeDelta delta = base::Time::Now() - screen_show_time_; | 172 base::TimeDelta delta = base::Time::Now() - screen_show_time_; |
232 VLOG(1) << "Screen load time: " << delta.InSecondsF(); | 173 VLOG(1) << "Screen load time: " << delta.InSecondsF(); |
233 UMA_HISTOGRAM_TIMES("UserImage.ScreenIsShownTime", delta); | 174 UMA_HISTOGRAM_TIMES("UserImage.ScreenIsShownTime", delta); |
234 } | 175 } |
235 | 176 |
236 void UserImageScreenHandler::OnCameraPresenceCheckDone() { | 177 void UserImageScreenHandler::SetCameraPresent(bool present) { |
237 CallJS("oobe.UserImageScreen.setCameraPresent", | 178 CallJS("oobe.UserImageScreen.setCameraPresent", present); |
238 CameraDetector::camera_presence() == CameraDetector::kCameraPresent); | |
239 } | |
240 | |
241 void UserImageScreenHandler::OnImageDecoded(const ImageDecoder* decoder, | |
242 const SkBitmap& decoded_image) { | |
243 DCHECK_EQ(image_decoder_.get(), decoder); | |
244 user_photo_ = gfx::ImageSkia::CreateFrom1xBitmap(decoded_image); | |
245 if (screen_ && accept_photo_after_decoding_) | |
246 screen_->OnPhotoTaken(user_photo_); | |
247 } | |
248 | |
249 void UserImageScreenHandler::OnDecodeImageFailed(const ImageDecoder* decoder) { | |
250 NOTREACHED() << "Failed to decode PNG image from WebUI"; | |
251 } | 179 } |
252 | 180 |
253 void UserImageScreenHandler::SetProfilePictureEnabled(bool enabled) { | 181 void UserImageScreenHandler::SetProfilePictureEnabled(bool enabled) { |
254 CallJS("oobe.UserImageScreen.setProfilePictureEnabled", enabled); | 182 CallJS("oobe.UserImageScreen.setProfilePictureEnabled", enabled); |
255 } | 183 } |
256 | 184 |
257 } // namespace chromeos | 185 } // namespace chromeos |
OLD | NEW |