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

Side by Side Diff: chrome/browser/notifications/message_center_notification_manager.cc

Issue 14631005: Enable users of NotificationUIManager to specify binary images. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Remove fake image from synced notification, stop checking icon_url in unit test. Created 7 years, 6 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
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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/notifications/message_center_notification_manager.h" 5 #include "chrome/browser/notifications/message_center_notification_manager.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/prefs/pref_service.h" 9 #include "base/prefs/pref_service.h"
10 #include "chrome/browser/extensions/extension_info_map.h" 10 #include "chrome/browser/extensions/extension_info_map.h"
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 old_notification->profile()->IsSameProfile(profile)) { 156 old_notification->profile()->IsSameProfile(profile)) {
157 std::string old_id = 157 std::string old_id =
158 old_notification->notification().notification_id(); 158 old_notification->notification().notification_id();
159 DCHECK(message_center_->HasNotification(old_id)); 159 DCHECK(message_center_->HasNotification(old_id));
160 160
161 // Add/remove notification in the local list but just update the same 161 // Add/remove notification in the local list but just update the same
162 // one in MessageCenter. 162 // one in MessageCenter.
163 old_notification->notification().Close(false); // Not by user. 163 old_notification->notification().Close(false); // Not by user.
164 delete old_notification; 164 delete old_notification;
165 profile_notifications_.erase(old_id); 165 profile_notifications_.erase(old_id);
166 ProfileNotification* new_notification = 166 ProfileNotification* new_notification = new ProfileNotification(
167 new ProfileNotification(profile, notification, message_center_); 167 profile, notification, message_center_, old_id);
168 profile_notifications_[notification.notification_id()] = new_notification; 168 profile_notifications_[notification.notification_id()] = new_notification;
169 message_center_->UpdateNotification(old_id,
170 notification.notification_id(),
171 notification.title(),
172 notification.body(),
173 notification.optional_fields(),
174 notification.delegate());
175 new_notification->StartDownloads();
176 return true; 169 return true;
177 } 170 }
178 } 171 }
179 return false; 172 return false;
180 } 173 }
181 174
182 //////////////////////////////////////////////////////////////////////////////// 175 ////////////////////////////////////////////////////////////////////////////////
183 // MessageCenter::Delegate 176 // MessageCenter::Delegate
184 177
185 void MessageCenterNotificationManager::DisableExtension( 178 void MessageCenterNotificationManager::DisableExtension(
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 NotificationMap::const_iterator iter = 252 NotificationMap::const_iterator iter =
260 profile_notifications_.find(notification_id); 253 profile_notifications_.find(notification_id);
261 if (iter != profile_notifications_.end()) 254 if (iter != profile_notifications_.end())
262 RemoveProfileNotification(iter->second, by_user); 255 RemoveProfileNotification(iter->second, by_user);
263 } 256 }
264 257
265 //////////////////////////////////////////////////////////////////////////////// 258 ////////////////////////////////////////////////////////////////////////////////
266 // ImageDownloads 259 // ImageDownloads
267 260
268 MessageCenterNotificationManager::ImageDownloads::ImageDownloads( 261 MessageCenterNotificationManager::ImageDownloads::ImageDownloads(
269 message_center::MessageCenter* message_center, 262 message_center::Notification* notification,
270 ImageDownloadsObserver* observer) 263 ImageDownloadsObserver* observer)
271 : message_center_(message_center), 264 : message_center_notification_(notification),
272 pending_downloads_(0), 265 pending_downloads_(0),
273 observer_(observer) { 266 observer_(observer) {}
274 }
275 267
276 MessageCenterNotificationManager::ImageDownloads::~ImageDownloads() { } 268 MessageCenterNotificationManager::ImageDownloads::~ImageDownloads() { }
277 269
278 void MessageCenterNotificationManager::ImageDownloads::StartDownloads( 270 void MessageCenterNotificationManager::ImageDownloads::StartDownloads(
279 const Notification& notification) { 271 const Notification& notification) {
272
280 // In case all downloads are synchronous, assume a pending download. 273 // In case all downloads are synchronous, assume a pending download.
281 AddPendingDownload(); 274 AddPendingDownload();
282 275
283 // Notification primary icon. 276 content::RenderViewHost* host = notification.GetRenderViewHost();
284 StartDownloadWithImage( 277 if (!host) {
285 notification, 278 DVLOG(1) << "Unable to download images due to a missing RenderViewHost.";
286 &notification.icon(), 279 PendingDownloadCompleted();
287 notification.icon_url(), 280 return;
288 message_center::kNotificationIconSize, 281 }
289 base::Bind(&message_center::MessageCenter::SetNotificationIcon, 282
290 base::Unretained(message_center_), 283 if (notification.icon().IsEmpty()) {
291 notification.notification_id())); 284 // Notification primary icon.
285 StartDownloadByURL(host,
286 notification.icon_url(),
287 message_center::kNotificationIconSize,
288 base::Bind(&ImageDownloads::SetIcon, AsWeakPtr()));
289 } else {
290 SetIcon(notification.icon());
291 }
292
293 const base::DictionaryValue* optional_fields = notification.optional_fields();
294 if (!optional_fields) {
295 // Unable to download anything else because no URLs were specified in
296 // optional_fields.
297 PendingDownloadCompleted();
298 return;
299 }
292 300
293 // Notification image. 301 // Notification image.
294 StartDownloadByKey( 302 StartDownloadByKey(host,
295 notification, 303 optional_fields,
296 message_center::kImageUrlKey, 304 message_center::kImageUrlKey,
297 message_center::kNotificationPreferredImageSize, 305 message_center::kNotificationPreferredImageSize,
298 base::Bind(&message_center::MessageCenter::SetNotificationImage, 306 base::Bind(&ImageDownloads::SetImage, AsWeakPtr()));
299 base::Unretained(message_center_),
300 notification.notification_id()));
301 307
302 // Notification button icons. 308 // Notification button icons.
303 StartDownloadByKey( 309 StartDownloadByKey(
304 notification, 310 host,
311 optional_fields,
305 message_center::kButtonOneIconUrlKey, 312 message_center::kButtonOneIconUrlKey,
306 message_center::kNotificationButtonIconSize, 313 message_center::kNotificationButtonIconSize,
307 base::Bind(&message_center::MessageCenter::SetNotificationButtonIcon, 314 base::Bind(&ImageDownloads::SetButtonIcon, AsWeakPtr(), 0));
308 base::Unretained(message_center_),
309 notification.notification_id(), 0));
310 StartDownloadByKey( 315 StartDownloadByKey(
311 notification, message_center::kButtonTwoIconUrlKey, 316 host,
317 optional_fields,
318 message_center::kButtonTwoIconUrlKey,
312 message_center::kNotificationButtonIconSize, 319 message_center::kNotificationButtonIconSize,
313 base::Bind(&message_center::MessageCenter::SetNotificationButtonIcon, 320 base::Bind(&ImageDownloads::SetButtonIcon, AsWeakPtr(), 1));
314 base::Unretained(message_center_),
315 notification.notification_id(), 1));
316 321
317 // This should tell the observer we're done if everything was synchronous. 322 // This should tell the observer we're done if everything was synchronous.
318 PendingDownloadCompleted(); 323 PendingDownloadCompleted();
319 } 324 }
320 325
321 void MessageCenterNotificationManager::ImageDownloads::StartDownloadWithImage( 326 void MessageCenterNotificationManager::ImageDownloads::StartDownloadByKey(
322 const Notification& notification, 327 content::RenderViewHost* host,
323 const gfx::Image* image, 328 const base::DictionaryValue* optional_fields,
329 const char* key,
330 int size,
331 const SetImageCallback& callback) {
332 DCHECK(optional_fields);
333 DCHECK(key);
334
335 if (!optional_fields->HasKey(key)) {
336 return;
337 }
338
339 string16 url_str;
340 optional_fields->GetString(key, &url_str);
341
342 GURL url(url_str);
343
344 // Leave the image null if there's no URL.
345 if (!url.is_valid())
346 return;
347
348 StartDownloadByURL(host, url, size, callback);
349 }
350
351 void MessageCenterNotificationManager::ImageDownloads::StartDownloadByURL(
352 content::RenderViewHost* host,
324 const GURL& url, 353 const GURL& url,
325 int size, 354 int size,
326 const SetImageCallback& callback) { 355 const SetImageCallback& callback) {
327 // Set the image directly if we have it. 356
328 if (image && !image->IsEmpty()) { 357 if (!host) {
329 callback.Run(*image); 358 LOG(WARNING) << "Notification needs an image but has no RenderViewHost";
359 callback.Run(gfx::Image());
330 return; 360 return;
331 } 361 }
332 362
333 // Leave the image null if there's no URL.
334 if (url.is_empty())
335 return;
336
337 content::RenderViewHost* host = notification.GetRenderViewHost();
338 if (!host) {
339 LOG(WARNING) << "Notification needs an image but has no RenderViewHost";
340 return;
341 }
342
343 content::WebContents* contents = 363 content::WebContents* contents =
344 content::WebContents::FromRenderViewHost(host); 364 content::WebContents::FromRenderViewHost(host);
345 if (!contents) { 365 if (!contents) {
346 LOG(WARNING) << "Notification needs an image but has no WebContents"; 366 LOG(WARNING) << "Notification needs an image but has no WebContents";
367 callback.Run(gfx::Image());
347 return; 368 return;
348 } 369 }
349 370
350 AddPendingDownload(); 371 AddPendingDownload();
351 372
352 contents->DownloadImage( 373 contents->DownloadImage(
353 url, 374 url,
354 false, 375 false,
355 size, 376 size,
356 base::Bind( 377 base::Bind(
357 &MessageCenterNotificationManager::ImageDownloads::DownloadComplete, 378 &MessageCenterNotificationManager::ImageDownloads::DownloadComplete,
358 AsWeakPtr(), 379 AsWeakPtr(),
359 callback)); 380 callback));
360 } 381 }
361 382
362 void MessageCenterNotificationManager::ImageDownloads::StartDownloadByKey(
363 const Notification& notification,
364 const char* key,
365 int size,
366 const SetImageCallback& callback) {
367 const base::DictionaryValue* optional_fields = notification.optional_fields();
368 if (optional_fields && optional_fields->HasKey(key)) {
369 string16 url;
370 optional_fields->GetString(key, &url);
371 StartDownloadWithImage(notification, NULL, GURL(url), size, callback);
372 }
373 }
374
375 void MessageCenterNotificationManager::ImageDownloads::DownloadComplete( 383 void MessageCenterNotificationManager::ImageDownloads::DownloadComplete(
376 const SetImageCallback& callback, 384 const SetImageCallback& callback,
377 int download_id, 385 int download_id,
378 int http_status_code, 386 int http_status_code,
379 const GURL& image_url, 387 const GURL& image_url,
380 int requested_size, 388 int requested_size,
381 const std::vector<SkBitmap>& bitmaps) { 389 const std::vector<SkBitmap>& bitmaps) {
390 if (!bitmaps.empty()) {
391 gfx::Image image = gfx::Image::CreateFrom1xBitmap(bitmaps[0]);
392 callback.Run(image);
393 }
394
382 PendingDownloadCompleted(); 395 PendingDownloadCompleted();
383
384 if (bitmaps.empty())
385 return;
386 gfx::Image image = gfx::Image::CreateFrom1xBitmap(bitmaps[0]);
387 callback.Run(image);
388 } 396 }
389 397
390 // Private methods. 398 // Private methods.
391 399
392 void MessageCenterNotificationManager::ImageDownloads::AddPendingDownload() { 400 void MessageCenterNotificationManager::ImageDownloads::AddPendingDownload() {
393 ++pending_downloads_; 401 ++pending_downloads_;
394 } 402 }
395 403
396 void 404 void
397 MessageCenterNotificationManager::ImageDownloads::PendingDownloadCompleted() { 405 MessageCenterNotificationManager::ImageDownloads::PendingDownloadCompleted() {
398 DCHECK(pending_downloads_ > 0); 406 DCHECK(pending_downloads_ > 0);
399 if (--pending_downloads_ == 0 && observer_) 407 if (--pending_downloads_ == 0 && observer_)
400 observer_->OnDownloadsCompleted(); 408 observer_->OnDownloadsCompleted();
401 } 409 }
402 410
411 void MessageCenterNotificationManager::ImageDownloads::SetIcon(
412 const gfx::Image& image) {
413 message_center_notification_->set_icon(image);
414 }
415 void MessageCenterNotificationManager::ImageDownloads::SetImage(
416 const gfx::Image& image) {
417 message_center_notification_->set_image(image);
418 }
419 void MessageCenterNotificationManager::ImageDownloads::SetButtonIcon(
420 size_t button_number,
421 const gfx::Image& image) {
422 message_center_notification_->SetButtonIcon(button_number, image);
423 }
424
403 //////////////////////////////////////////////////////////////////////////////// 425 ////////////////////////////////////////////////////////////////////////////////
404 // ProfileNotification 426 // ProfileNotification
405 427
406 MessageCenterNotificationManager::ProfileNotification::ProfileNotification( 428 MessageCenterNotificationManager::ProfileNotification::ProfileNotification(
407 Profile* profile, 429 Profile* profile,
408 const Notification& notification, 430 const Notification& notification,
409 message_center::MessageCenter* message_center) 431 message_center::MessageCenter* message_center)
410 : profile_(profile), 432 : profile_(profile),
411 notification_(notification), 433 notification_(notification),
412 downloads_(new ImageDownloads(message_center, this)) { 434 message_center_(message_center),
413 DCHECK(profile); 435 update_(false),
436 updated_id_(std::string()),
437 downloads_(NULL) {
438 Init();
439 }
440
441 MessageCenterNotificationManager::ProfileNotification::ProfileNotification(
442 Profile* profile,
443 const Notification& notification,
444 message_center::MessageCenter* message_center,
445 const std::string& updated_id)
446 : profile_(profile),
447 notification_(notification),
448 message_center_(message_center),
449 update_(true),
450 updated_id_(updated_id),
451 downloads_(NULL) {
452 Init();
453 }
454
455 void MessageCenterNotificationManager::ProfileNotification::Init() {
456 DCHECK(profile_);
457
458 bool has_rich_notification = notification_.has_rich_notification();
459 if (has_rich_notification) {
460 const message_center::RichNotificationData& data =
461 notification_.rich_notification_data();
462 message_center_notification_.reset(
463 new message_center::Notification(notification_.type(),
464 notification_.notification_id(),
465 notification_.title(),
466 notification_.body(),
467 notification_.display_source(),
468 GetExtensionId(),
469 data,
470 notification_.delegate()));
471 OnDownloadsCompleted();
472 } else {
473 message_center_notification_.reset(
474 new message_center::Notification(notification_.type(),
475 notification_.notification_id(),
476 notification_.title(),
477 notification_.body(),
478 notification_.icon(),
479 notification_.display_source(),
480 GetExtensionId(),
481 notification_.optional_fields(),
482 notification_.delegate()));
483 StartDownloads();
484 }
414 } 485 }
415 486
416 MessageCenterNotificationManager::ProfileNotification::~ProfileNotification() { 487 MessageCenterNotificationManager::ProfileNotification::~ProfileNotification() {
417 } 488 }
418 489
419 void MessageCenterNotificationManager::ProfileNotification::StartDownloads() { 490 void MessageCenterNotificationManager::ProfileNotification::StartDownloads() {
491 DCHECK(message_center_notification_.get());
492 downloads_.reset(
493 new ImageDownloads(message_center_notification_.get(), this));
420 downloads_->StartDownloads(notification_); 494 downloads_->StartDownloads(notification_);
421 } 495 }
422 496
423 void 497 void
424 MessageCenterNotificationManager::ProfileNotification::OnDownloadsCompleted() { 498 MessageCenterNotificationManager::ProfileNotification::OnDownloadsCompleted() {
425 notification_.DoneRendering(); 499 notification_.DoneRendering();
500 if (update_) {
501 message_center_->UpdateNotification(updated_id_,
Jun Mukai 2013/05/31 17:08:10 It seems that UpdateNotification will still be cal
502 message_center_notification_.Pass());
503 } else {
504 message_center_->AddNotification(message_center_notification_.Pass());
505 }
426 } 506 }
427 507
428 std::string 508 std::string
429 MessageCenterNotificationManager::ProfileNotification::GetExtensionId() { 509 MessageCenterNotificationManager::ProfileNotification::GetExtensionId() {
430 ExtensionInfoMap* extension_info_map = 510 ExtensionInfoMap* extension_info_map =
431 extensions::ExtensionSystem::Get(profile())->info_map(); 511 extensions::ExtensionSystem::Get(profile())->info_map();
432 ExtensionSet extensions; 512 ExtensionSet extensions;
433 extension_info_map->GetExtensionsWithAPIPermissionForSecurityOrigin( 513 extension_info_map->GetExtensionsWithAPIPermissionForSecurityOrigin(
434 notification().origin_url(), notification().process_id(), 514 notification().origin_url(), notification().process_id(),
435 extensions::APIPermission::kNotification, &extensions); 515 extensions::APIPermission::kNotification, &extensions);
(...skipping 12 matching lines...) Expand all
448 // private 528 // private
449 529
450 void MessageCenterNotificationManager::AddProfileNotification( 530 void MessageCenterNotificationManager::AddProfileNotification(
451 ProfileNotification* profile_notification) { 531 ProfileNotification* profile_notification) {
452 const Notification& notification = profile_notification->notification(); 532 const Notification& notification = profile_notification->notification();
453 std::string id = notification.notification_id(); 533 std::string id = notification.notification_id();
454 // Notification ids should be unique. 534 // Notification ids should be unique.
455 DCHECK(profile_notifications_.find(id) == profile_notifications_.end()); 535 DCHECK(profile_notifications_.find(id) == profile_notifications_.end());
456 profile_notifications_[id] = profile_notification; 536 profile_notifications_[id] = profile_notification;
457 537
458 message_center_->AddNotification(notification.type(),
459 notification.notification_id(),
460 notification.title(),
461 notification.body(),
462 notification.display_source(),
463 profile_notification->GetExtensionId(),
464 notification.optional_fields(),
465 notification.delegate());
466 profile_notification->StartDownloads();
467 } 538 }
468 539
469 void MessageCenterNotificationManager::RemoveProfileNotification( 540 void MessageCenterNotificationManager::RemoveProfileNotification(
470 ProfileNotification* profile_notification, 541 ProfileNotification* profile_notification,
471 bool by_user) { 542 bool by_user) {
472 profile_notification->notification().Close(by_user); 543 profile_notification->notification().Close(by_user);
473 std::string id = profile_notification->notification().notification_id(); 544 std::string id = profile_notification->notification().notification_id();
474 profile_notifications_.erase(id); 545 profile_notifications_.erase(id);
475 delete profile_notification; 546 delete profile_notification;
476 } 547 }
477 548
478 MessageCenterNotificationManager::ProfileNotification* 549 MessageCenterNotificationManager::ProfileNotification*
479 MessageCenterNotificationManager::FindProfileNotification( 550 MessageCenterNotificationManager::FindProfileNotification(
480 const std::string& id) const { 551 const std::string& id) const {
481 NotificationMap::const_iterator iter = profile_notifications_.find(id); 552 NotificationMap::const_iterator iter = profile_notifications_.find(id);
482 if (iter == profile_notifications_.end()) 553 if (iter == profile_notifications_.end())
483 return NULL; 554 return NULL;
484 555
485 return (*iter).second; 556 return (*iter).second;
486 } 557 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698