Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(76)

Side by Side Diff: chrome/browser/ui/webui/options2/chromeos/change_picture_options_handler2.cc

Issue 10698140: Remove "2" suffixes from options2 code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix tests Created 8 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2012 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/options2/chromeos/change_picture_options_handl er2.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/command_line.h"
10 #include "base/metrics/histogram.h"
11 #include "base/path_service.h"
12 #include "base/string_util.h"
13 #include "base/utf_string_conversions.h"
14 #include "base/values.h"
15 #include "chrome/browser/chromeos/login/camera_detector.h"
16 #include "chrome/browser/chromeos/login/default_user_images.h"
17 #include "chrome/browser/chromeos/login/user_image.h"
18 #include "chrome/browser/chromeos/login/user_manager.h"
19 #include "chrome/browser/chromeos/options/take_photo_dialog.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/ui/browser_finder.h"
22 #include "chrome/browser/ui/browser_window.h"
23 #include "chrome/browser/ui/chrome_select_file_policy.h"
24 #include "chrome/browser/ui/webui/web_ui_util.h"
25 #include "chrome/common/chrome_notification_types.h"
26 #include "chrome/common/chrome_paths.h"
27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/url_constants.h"
29 #include "content/public/browser/notification_service.h"
30 #include "content/public/browser/web_ui.h"
31 #include "content/public/common/url_constants.h"
32 #include "googleurl/src/gurl.h"
33 #include "grit/generated_resources.h"
34 #include "grit/theme_resources.h"
35 #include "net/base/data_url.h"
36 #include "ui/base/l10n/l10n_util.h"
37 #include "ui/base/resource/resource_bundle.h"
38 #include "ui/views/widget/widget.h"
39
40 namespace chromeos {
41 namespace options2 {
42
43 namespace {
44
45 // Returns info about extensions for files we support as user images.
46 SelectFileDialog::FileTypeInfo GetUserImageFileTypeInfo() {
47 SelectFileDialog::FileTypeInfo file_type_info;
48 file_type_info.extensions.resize(5);
49
50 file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("bmp"));
51
52 file_type_info.extensions[1].push_back(FILE_PATH_LITERAL("gif"));
53
54 file_type_info.extensions[2].push_back(FILE_PATH_LITERAL("jpg"));
55 file_type_info.extensions[2].push_back(FILE_PATH_LITERAL("jpeg"));
56
57 file_type_info.extensions[3].push_back(FILE_PATH_LITERAL("png"));
58
59 file_type_info.extensions[4].push_back(FILE_PATH_LITERAL("tif"));
60 file_type_info.extensions[4].push_back(FILE_PATH_LITERAL("tiff"));
61
62 return file_type_info;
63 }
64
65 // Time histogram suffix for profile image download.
66 const char kProfileDownloadReason[] = "Preferences";
67
68 } // namespace
69
70 ChangePictureOptionsHandler::ChangePictureOptionsHandler()
71 : previous_image_data_url_(chrome::kAboutBlankURL),
72 previous_image_index_(User::kInvalidImageIndex),
73 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)) {
74 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_IMAGE_UPDATED,
75 content::NotificationService::AllSources());
76 registrar_.Add(this, chrome::NOTIFICATION_PROFILE_IMAGE_UPDATE_FAILED,
77 content::NotificationService::AllSources());
78 }
79
80 ChangePictureOptionsHandler::~ChangePictureOptionsHandler() {
81 if (select_file_dialog_.get())
82 select_file_dialog_->ListenerDestroyed();
83 if (image_decoder_.get())
84 image_decoder_->set_delegate(NULL);
85 }
86
87 void ChangePictureOptionsHandler::GetLocalizedValues(
88 DictionaryValue* localized_strings) {
89 DCHECK(localized_strings);
90 localized_strings->SetString("changePicturePage",
91 l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_DIALOG_TITLE));
92 localized_strings->SetString("changePicturePageDescription",
93 l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_DIALOG_TEXT));
94 localized_strings->SetString("takePhoto",
95 l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_TAKE_PHOTO));
96 localized_strings->SetString("chooseFile",
97 l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_CHOOSE_FILE));
98 localized_strings->SetString("profilePhoto",
99 l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_PROFILE_PHOTO));
100 localized_strings->SetString("profilePhotoLoading",
101 l10n_util::GetStringUTF16(
102 IDS_OPTIONS_CHANGE_PICTURE_PROFILE_LOADING_PHOTO));
103 localized_strings->SetString("previewAltText",
104 l10n_util::GetStringUTF16(IDS_OPTIONS_CHANGE_PICTURE_PREVIEW_ALT));
105 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableHtml5Camera))
106 localized_strings->SetString("cameraType", "webrtc");
107 else
108 localized_strings->SetString("cameraType", "old");
109 }
110
111 void ChangePictureOptionsHandler::RegisterMessages() {
112 web_ui()->RegisterMessageCallback("chooseFile",
113 base::Bind(&ChangePictureOptionsHandler::HandleChooseFile,
114 base::Unretained(this)));
115 web_ui()->RegisterMessageCallback("takePhoto",
116 base::Bind(&ChangePictureOptionsHandler::HandleTakePhoto,
117 base::Unretained(this)));
118 web_ui()->RegisterMessageCallback("photoTaken",
119 base::Bind(&ChangePictureOptionsHandler::HandlePhotoTaken,
120 base::Unretained(this)));
121 web_ui()->RegisterMessageCallback("onChangePicturePageShown",
122 base::Bind(&ChangePictureOptionsHandler::HandlePageShown,
123 base::Unretained(this)));
124 web_ui()->RegisterMessageCallback("onChangePicturePageInitialized",
125 base::Bind(&ChangePictureOptionsHandler::HandlePageInitialized,
126 base::Unretained(this)));
127 web_ui()->RegisterMessageCallback("selectImage",
128 base::Bind(&ChangePictureOptionsHandler::HandleSelectImage,
129 base::Unretained(this)));
130 }
131
132 void ChangePictureOptionsHandler::SendDefaultImages() {
133 ListValue image_urls;
134 for (int i = 0; i < kDefaultImagesCount; ++i) {
135 image_urls.Append(new StringValue(GetDefaultImageUrl(i)));
136 }
137 web_ui()->CallJavascriptFunction("ChangePictureOptions.setDefaultImages",
138 image_urls);
139 }
140
141 void ChangePictureOptionsHandler::HandleChooseFile(const ListValue* args) {
142 DCHECK(args && args->empty());
143 select_file_dialog_ = SelectFileDialog::Create(
144 this, new ChromeSelectFilePolicy(web_ui()->GetWebContents()));
145
146 FilePath downloads_path;
147 if (!PathService::Get(chrome::DIR_DEFAULT_DOWNLOADS, &downloads_path)) {
148 NOTREACHED();
149 return;
150 }
151
152 // Static so we initialize it only once.
153 CR_DEFINE_STATIC_LOCAL(SelectFileDialog::FileTypeInfo, file_type_info,
154 (GetUserImageFileTypeInfo()));
155
156 select_file_dialog_->SelectFile(
157 SelectFileDialog::SELECT_OPEN_FILE,
158 l10n_util::GetStringUTF16(IDS_DOWNLOAD_TITLE),
159 downloads_path,
160 &file_type_info,
161 0,
162 FILE_PATH_LITERAL(""),
163 GetBrowserWindow(),
164 NULL);
165 }
166
167 void ChangePictureOptionsHandler::HandleTakePhoto(const ListValue* args) {
168 DCHECK(args && args->empty());
169 views::Widget* window = views::Widget::CreateWindowWithParent(
170 new TakePhotoDialog(this), GetBrowserWindow());
171 window->SetAlwaysOnTop(true);
172 window->Show();
173 }
174
175 void ChangePictureOptionsHandler::HandlePhotoTaken(
176 const base::ListValue* args) {
177 std::string image_url;
178 if (!args || args->GetSize() != 1 || !args->GetString(0, &image_url))
179 NOTREACHED();
180 DCHECK(!image_url.empty());
181
182 std::string mime_type, charset, raw_data;
183 if (!net::DataURL::Parse(GURL(image_url), &mime_type, &charset, &raw_data))
184 NOTREACHED();
185 DCHECK_EQ("image/png", mime_type);
186
187 user_photo_ = gfx::ImageSkia();
188 user_photo_data_url_ = image_url;
189
190 if (image_decoder_.get())
191 image_decoder_->set_delegate(NULL);
192 image_decoder_ = new ImageDecoder(this, raw_data);
193 image_decoder_->Start();
194 }
195
196 void ChangePictureOptionsHandler::HandlePageInitialized(
197 const base::ListValue* args) {
198 DCHECK(args && args->empty());
199
200 if (!CommandLine::ForCurrentProcess()->
201 HasSwitch(switches::kEnableHtml5Camera)) {
202 // If no camera presence check has been performed in this session,
203 // start one now.
204 if (CameraDetector::camera_presence() ==
205 CameraDetector::kCameraPresenceUnknown) {
206 CheckCameraPresence();
207 }
208
209 // While the check is in progress, use previous camera presence state and
210 // presume it is present if no check has been performed yet.
211 SetCameraPresent(CameraDetector::camera_presence() !=
212 CameraDetector::kCameraAbsent);
213 }
214
215 SendDefaultImages();
216 }
217
218 void ChangePictureOptionsHandler::HandlePageShown(const base::ListValue* args) {
219 DCHECK(args && args->empty());
220 // TODO(ivankr): If user opens settings and goes to Change Picture page right
221 // after the check started |HandlePageInitialized| has been completed,
222 // |CheckCameraPresence| will be called twice, should be throttled.
223 CheckCameraPresence();
224 SendSelectedImage();
225 UpdateProfileImage();
226 }
227
228 void ChangePictureOptionsHandler::SendSelectedImage() {
229 const User& user = UserManager::Get()->GetLoggedInUser();
230 DCHECK(!user.email().empty());
231
232 previous_image_index_ = user.image_index();
233 switch (previous_image_index_) {
234 case User::kExternalImageIndex: {
235 // User has image from camera/file, record it and add to the image list.
236 previous_image_ = user.image();
237 previous_image_data_url_ = web_ui_util::GetImageDataUrl(previous_image_);
238 web_ui()->CallJavascriptFunction("ChangePictureOptions.setOldImage");
239 break;
240 }
241 case User::kProfileImageIndex: {
242 // User has his/her Profile image as the current image.
243 SendProfileImage(user.image(), true);
244 break;
245 }
246 default: {
247 DCHECK(previous_image_index_ >= 0 &&
248 previous_image_index_ < kDefaultImagesCount);
249 // User has image from the set of default images.
250 base::StringValue image_url(GetDefaultImageUrl(previous_image_index_));
251 web_ui()->CallJavascriptFunction("ChangePictureOptions.setSelectedImage",
252 image_url);
253 }
254 }
255 }
256
257 void ChangePictureOptionsHandler::SendProfileImage(const gfx::ImageSkia& image,
258 bool should_select) {
259 base::StringValue data_url(web_ui_util::GetImageDataUrl(image));
260 base::FundamentalValue select(should_select);
261 web_ui()->CallJavascriptFunction("ChangePictureOptions.setProfileImage",
262 data_url, select);
263 }
264
265 void ChangePictureOptionsHandler::UpdateProfileImage() {
266 UserManager* user_manager = UserManager::Get();
267
268 // If we have a downloaded profile image and haven't sent it in
269 // |SendSelectedImage|, send it now (without selecting).
270 if (previous_image_index_ != User::kProfileImageIndex &&
271 !user_manager->DownloadedProfileImage().empty())
272 SendProfileImage(user_manager->DownloadedProfileImage(), false);
273
274 user_manager->DownloadProfileImage(kProfileDownloadReason);
275 }
276
277 void ChangePictureOptionsHandler::HandleSelectImage(const ListValue* args) {
278 std::string image_url;
279 if (!args ||
280 args->GetSize() != 1 ||
281 !args->GetString(0, &image_url)) {
282 NOTREACHED();
283 return;
284 }
285 DCHECK(!image_url.empty());
286
287 UserManager* user_manager = UserManager::Get();
288 const User& user = user_manager->GetLoggedInUser();
289 int image_index = User::kInvalidImageIndex;
290 bool waiting_for_camera_photo = false;
291
292 if (StartsWithASCII(image_url, chrome::kChromeUIUserImageURL, false)) {
293 // Image from file/camera uses kChromeUIUserImageURL as URL while
294 // current profile image always has a full data URL.
295 // This way transition from (current profile image) to
296 // (profile image, current image from file) is easier.
297
298 DCHECK(!previous_image_.empty());
299 user_manager->SaveUserImage(user.email(),
300 chromeos::UserImage(previous_image_));
301
302 UMA_HISTOGRAM_ENUMERATION("UserImage.ChangeChoice",
303 kHistogramImageOld,
304 kHistogramImagesCount);
305 VLOG(1) << "Selected old user image";
306 } else if (IsDefaultImageUrl(image_url, &image_index)) {
307 // One of the default user images.
308 user_manager->SaveUserDefaultImageIndex(user.email(), image_index);
309
310 UMA_HISTOGRAM_ENUMERATION("UserImage.ChangeChoice",
311 image_index,
312 kHistogramImagesCount);
313 VLOG(1) << "Selected default user image: " << image_index;
314 } else if (image_url == user_photo_data_url_) {
315 // Camera image is selected.
316 if (user_photo_.empty()) {
317 DCHECK(image_decoder_.get());
318 waiting_for_camera_photo = true;
319 VLOG(1) << "Still waiting for camera image to decode";
320 } else {
321 OnPhotoAccepted(user_photo_);
322 }
323 } else {
324 // Profile image selected. Could be previous (old) user image.
325 user_manager->SaveUserImageFromProfileImage(user.email());
326
327 if (previous_image_index_ == User::kProfileImageIndex) {
328 UMA_HISTOGRAM_ENUMERATION("UserImage.ChangeChoice",
329 kHistogramImageOld,
330 kHistogramImagesCount);
331 VLOG(1) << "Selected old (profile) user image";
332 } else {
333 UMA_HISTOGRAM_ENUMERATION("UserImage.ChangeChoice",
334 kHistogramImageFromProfile,
335 kHistogramImagesCount);
336 VLOG(1) << "Selected profile image";
337 }
338 }
339
340 // Ignore the result of the previous decoding if it's no longer needed.
341 if (!waiting_for_camera_photo && image_decoder_.get())
342 image_decoder_->set_delegate(NULL);
343 }
344
345 void ChangePictureOptionsHandler::FileSelected(const FilePath& path,
346 int index,
347 void* params) {
348 UserManager* user_manager = UserManager::Get();
349 user_manager->SaveUserImageFromFile(user_manager->GetLoggedInUser().email(),
350 path);
351 UMA_HISTOGRAM_ENUMERATION("UserImage.ChangeChoice",
352 kHistogramImageFromFile,
353 kHistogramImagesCount);
354 VLOG(1) << "Selected image from file";
355 }
356
357 void ChangePictureOptionsHandler::OnPhotoAccepted(const gfx::ImageSkia& photo) {
358 UserManager* user_manager = UserManager::Get();
359 user_manager->SaveUserImage(user_manager->GetLoggedInUser().email(),
360 chromeos::UserImage(photo));
361 UMA_HISTOGRAM_ENUMERATION("UserImage.ChangeChoice",
362 kHistogramImageFromCamera,
363 kHistogramImagesCount);
364 VLOG(1) << "Selected camera photo";
365 }
366
367 void ChangePictureOptionsHandler::CheckCameraPresence() {
368 // For WebRTC, camera presence checked is done on JS side.
369 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableHtml5Camera))
370 return;
371 CameraDetector::StartPresenceCheck(
372 base::Bind(&ChangePictureOptionsHandler::OnCameraPresenceCheckDone,
373 weak_factory_.GetWeakPtr()));
374 }
375
376 void ChangePictureOptionsHandler::SetCameraPresent(bool present) {
377 base::FundamentalValue present_value(present);
378 web_ui()->CallJavascriptFunction("ChangePictureOptions.setCameraPresent",
379 present_value);
380 }
381
382 void ChangePictureOptionsHandler::OnCameraPresenceCheckDone() {
383 SetCameraPresent(CameraDetector::camera_presence() ==
384 CameraDetector::kCameraPresent);
385 }
386
387 void ChangePictureOptionsHandler::Observe(
388 int type,
389 const content::NotificationSource& source,
390 const content::NotificationDetails& details) {
391 OptionsPageUIHandler::Observe(type, source, details);
392 if (type == chrome::NOTIFICATION_PROFILE_IMAGE_UPDATED) {
393 // User profile image has been updated.
394 SendProfileImage(*content::Details<const gfx::ImageSkia>(details).ptr(),
395 false);
396 }
397 }
398
399 gfx::NativeWindow ChangePictureOptionsHandler::GetBrowserWindow() const {
400 Browser* browser =
401 browser::FindBrowserWithProfile(Profile::FromWebUI(web_ui()));
402 if (!browser)
403 return NULL;
404 return browser->window()->GetNativeWindow();
405 }
406
407 void ChangePictureOptionsHandler::OnImageDecoded(
408 const ImageDecoder* decoder,
409 const SkBitmap& decoded_image) {
410 DCHECK_EQ(image_decoder_.get(), decoder);
411 image_decoder_ = NULL;
412 user_photo_ = gfx::ImageSkia(decoded_image);
413 OnPhotoAccepted(user_photo_);
414 }
415
416 void ChangePictureOptionsHandler::OnDecodeImageFailed(
417 const ImageDecoder* decoder) {
418 NOTREACHED() << "Failed to decode PNG image from WebUI";
419 }
420
421 } // namespace options2
422 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698