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