OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 ¬ification.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 Loading... | |
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 } |
OLD | NEW |