Chromium Code Reviews| 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 |