summaryrefslogtreecommitdiffstats
path: root/chrome/browser/notifications
diff options
context:
space:
mode:
authordewittj@chromium.org <dewittj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-08 21:39:18 +0000
committerdewittj@chromium.org <dewittj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-02-08 21:39:18 +0000
commit744411c89138de27e950eecfe4526adf70867844 (patch)
tree2df3ef72be85d0719e4e3c6d56c7b268d8fefdb4 /chrome/browser/notifications
parent6ad55bb2e39f944d1aac989b77ca3df03dd35f90 (diff)
downloadchromium_src-744411c89138de27e950eecfe4526adf70867844.zip
chromium_src-744411c89138de27e950eecfe4526adf70867844.tar.gz
chromium_src-744411c89138de27e950eecfe4526adf70867844.tar.bz2
Add ImageDownload to MessageCenterNotificationManager.
This ports the current icon download functionality from ChromeOS to the Windows/ChromeOS MessageCenterNotificatioNManager. BUG=169538 Review URL: https://chromiumcodereview.appspot.com/12194018 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@181553 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/notifications')
-rw-r--r--chrome/browser/notifications/message_center_notification_manager.cc140
-rw-r--r--chrome/browser/notifications/message_center_notification_manager.h67
-rw-r--r--chrome/browser/notifications/notification_ui_manager_impl.cc5
3 files changed, 190 insertions, 22 deletions
diff --git a/chrome/browser/notifications/message_center_notification_manager.cc b/chrome/browser/notifications/message_center_notification_manager.cc
index 44f3352..8fd12db 100644
--- a/chrome/browser/notifications/message_center_notification_manager.cc
+++ b/chrome/browser/notifications/message_center_notification_manager.cc
@@ -17,6 +17,8 @@
#include "chrome/browser/ui/host_desktop.h"
#include "chrome/common/extensions/extension_set.h"
#include "chrome/common/pref_names.h"
+#include "content/public/browser/web_contents.h"
+#include "ui/message_center/message_center_constants.h"
#include "ui/message_center/message_center_tray.h"
MessageCenterNotificationManager::MessageCenterNotificationManager(
@@ -34,6 +36,7 @@ MessageCenterNotificationManager::MessageCenterNotificationManager(
MessageCenterNotificationManager::~MessageCenterNotificationManager() {
}
+
////////////////////////////////////////////////////////////////////////////////
// NotificationUIManager
@@ -107,7 +110,8 @@ void MessageCenterNotificationManager::CancelAll() {
bool MessageCenterNotificationManager::ShowNotification(
const Notification& notification, Profile* profile) {
// There is always space in MessageCenter, it never rejects Notifications.
- AddProfileNotification(new ProfileNotification(profile, notification));
+ AddProfileNotification(
+ new ProfileNotification(profile, notification, message_center_));
return true;
}
@@ -136,14 +140,15 @@ bool MessageCenterNotificationManager::UpdateNotification(
old_notification->notification().Close(false); // Not by user.
delete old_notification;
profile_notifications_.erase(old_id);
- profile_notifications_[notification.notification_id()] =
- new ProfileNotification(profile, notification);
-
+ ProfileNotification* new_notification =
+ new ProfileNotification(profile, notification, message_center_);
+ profile_notifications_[notification.notification_id()] = new_notification;
message_center_->UpdateNotification(old_id,
notification.notification_id(),
notification.title(),
notification.body(),
notification.optional_fields());
+ new_notification->StartDownloads();
notification.Display();
return true;
}
@@ -211,15 +216,135 @@ void MessageCenterNotificationManager::OnButtonClicked(
}
////////////////////////////////////////////////////////////////////////////////
+// ImageDownloads
+
+MessageCenterNotificationManager::ImageDownloads::ImageDownloads(
+ message_center::MessageCenter* message_center)
+ : message_center_(message_center) {
+}
+
+MessageCenterNotificationManager::ImageDownloads::~ImageDownloads() { }
+
+void MessageCenterNotificationManager::ImageDownloads::StartDownloads(
+ const Notification& notification) {
+ // Notification primary icon.
+ StartDownloadWithImage(
+ notification,
+ &notification.icon(),
+ notification.icon_url(),
+ message_center::kNotificationIconSize,
+ base::Bind(&message_center::MessageCenter::SetNotificationIcon,
+ base::Unretained(message_center_),
+ notification.notification_id()));
+
+ // Notification image.
+ StartDownloadByKey(
+ notification,
+ ui::notifications::kImageUrlKey,
+ message_center::kNotificationPreferredImageSize,
+ base::Bind(&message_center::MessageCenter::SetNotificationImage,
+ base::Unretained(message_center_),
+ notification.notification_id()));
+
+ // Notification button icons.
+ StartDownloadByKey(
+ notification,
+ ui::notifications::kButtonOneIconUrlKey,
+ message_center::kNotificationButtonIconSize,
+ base::Bind(&message_center::MessageCenter::SetNotificationButtonIcon,
+ base::Unretained(message_center_),
+ notification.notification_id(), 0));
+ StartDownloadByKey(
+ notification, ui::notifications::kButtonTwoIconUrlKey,
+ message_center::kNotificationButtonIconSize,
+ base::Bind(&message_center::MessageCenter::SetNotificationButtonIcon,
+ base::Unretained(message_center_),
+ notification.notification_id(), 1));
+}
+
+void MessageCenterNotificationManager::ImageDownloads::StartDownloadWithImage(
+ const Notification& notification,
+ const gfx::ImageSkia* image,
+ const GURL& url,
+ int size,
+ const SetImageCallback& callback) {
+ // Set the image directly if we have it.
+ if (image && !image->isNull()) {
+ callback.Run(*image);
+ return;
+ }
+
+ // Leave the image null if there's no URL.
+ if (url.is_empty())
+ return;
+
+ content::RenderViewHost* host = notification.GetRenderViewHost();
+ if (!host) {
+ LOG(WARNING) << "Notification needs an image but has no RenderViewHost";
+ return;
+ }
+
+ content::WebContents* contents =
+ content::WebContents::FromRenderViewHost(host);
+ if (!contents) {
+ LOG(WARNING) << "Notification needs an image but has no WebContents";
+ return;
+ }
+
+ contents->DownloadFavicon(
+ url,
+ size,
+ base::Bind(
+ &MessageCenterNotificationManager::ImageDownloads::DownloadComplete,
+ AsWeakPtr(),
+ callback));
+}
+
+void MessageCenterNotificationManager::ImageDownloads::StartDownloadByKey(
+ const Notification& notification,
+ const char* key,
+ int size,
+ const SetImageCallback& callback) {
+ const base::DictionaryValue* optional_fields = notification.optional_fields();
+ if (optional_fields && optional_fields->HasKey(key)) {
+ string16 url;
+ optional_fields->GetString(key, &url);
+ StartDownloadWithImage(notification, NULL, GURL(url), size, callback);
+ }
+}
+
+void MessageCenterNotificationManager::ImageDownloads::DownloadComplete(
+ const SetImageCallback& callback,
+ int download_id,
+ const GURL& image_url,
+ int requested_size,
+ const std::vector<SkBitmap>& bitmaps) {
+ if (bitmaps.empty())
+ return;
+ gfx::ImageSkia image = gfx::ImageSkia::CreateFrom1xBitmap(bitmaps[0]);
+ callback.Run(image);
+}
+
+////////////////////////////////////////////////////////////////////////////////
// ProfileNotification
MessageCenterNotificationManager::ProfileNotification::ProfileNotification(
- Profile* profile, const Notification& notification)
- : profile_(profile),
- notification_(notification) {
+ Profile* profile,
+ const Notification& notification,
+ message_center::MessageCenter* message_center)
+ : profile_(profile),
+ notification_(notification),
+ downloads_(new ImageDownloads(message_center)) {
DCHECK(profile);
}
+MessageCenterNotificationManager::ProfileNotification::~ProfileNotification() {
+}
+
+void MessageCenterNotificationManager::ProfileNotification::StartDownloads() {
+ downloads_->StartDownloads(notification_);
+}
+
std::string
MessageCenterNotificationManager::ProfileNotification::GetExtensionId() {
const ExtensionURLInfo url(notification().origin_url());
@@ -247,6 +372,7 @@ void MessageCenterNotificationManager::AddProfileNotification(
notification.display_source(),
profile_notification->GetExtensionId(),
notification.optional_fields());
+ profile_notification->StartDownloads();
notification.Display();
}
diff --git a/chrome/browser/notifications/message_center_notification_manager.h b/chrome/browser/notifications/message_center_notification_manager.h
index 0f4939b..b837466 100644
--- a/chrome/browser/notifications/message_center_notification_manager.h
+++ b/chrome/browser/notifications/message_center_notification_manager.h
@@ -53,23 +53,56 @@ class MessageCenterNotificationManager
int button_index) OVERRIDE;
private:
- scoped_ptr<message_center::MessageCenterTrayDelegate> tray_;
- message_center::MessageCenter* message_center_; // Weak, global.
+ typedef base::Callback<void(const gfx::ImageSkia&)> SetImageCallback;
+ class ImageDownloads
+ : public base::SupportsWeakPtr<ImageDownloads> {
+ public:
+ explicit ImageDownloads(message_center::MessageCenter* message_center);
+ virtual ~ImageDownloads();
+
+ void StartDownloads(const Notification& notification);
+ void StartDownloadWithImage(const Notification& notification,
+ const gfx::ImageSkia* image,
+ const GURL& url,
+ int size,
+ const SetImageCallback& callback);
+ void StartDownloadByKey(const Notification& notification,
+ const char* key,
+ int size,
+ const SetImageCallback& callback);
+
+ // FaviconHelper callback.
+ void DownloadComplete(const SetImageCallback& callback,
+ int download_id,
+ const GURL& image_url,
+ int requested_size,
+ const std::vector<SkBitmap>& bitmaps);
+ private:
+ // Weak reference to global message center.
+ message_center::MessageCenter* message_center_;
+ DISALLOW_COPY_AND_ASSIGN(ImageDownloads);
+ };
-// This class keeps a set of original Notification objects and corresponding
-// Profiles, so when MessageCenter calls back with a notification_id, this
-// class has necessary mapping to other source info - for example, it calls
-// NotificationDelegate supplied by client when someone clicks on a Notification
-// in MessageCenter. Likewise, if a Profile or Extension is being removed, the
-// map makes it possible to revoke the notifications from MessageCenter.
-// To keep that set, we use the private ProfileNotification class that stores
-// a superset of all information about a notification.
-
-// TODO(dimich): Consider merging all 4 types (Notification, QueuedNotification,
-// ProfileNotification and NotificationList::Notification) into a single class.
+ // This class keeps a set of original Notification objects and corresponding
+ // Profiles, so when MessageCenter calls back with a notification_id, this
+ // class has necessary mapping to other source info - for example, it calls
+ // NotificationDelegate supplied by client when someone clicks on a
+ // Notification in MessageCenter. Likewise, if a Profile or Extension is
+ // being removed, the map makes it possible to revoke the notifications from
+ // MessageCenter. To keep that set, we use the private ProfileNotification
+ // class that stores a superset of all information about a notification.
+
+ // TODO(dimich): Consider merging all 4 types (Notification,
+ // QueuedNotification, ProfileNotification and NotificationList::Notification)
+ // into a single class.
class ProfileNotification {
public:
- ProfileNotification(Profile* profile, const Notification& notification);
+ ProfileNotification(Profile* profile,
+ const Notification& notification,
+ message_center::MessageCenter* message_center);
+ virtual ~ProfileNotification();
+
+ void StartDownloads();
Profile* profile() const { return profile_; }
const Notification& notification() const { return notification_; }
@@ -82,8 +115,14 @@ class MessageCenterNotificationManager
// Weak, guaranteed not to be used after profile removal by parent class.
Profile* profile_;
Notification notification_;
+ // Track the downloads for this notification so the notification can be
+ // updated properly.
+ scoped_ptr<ImageDownloads> downloads_;
};
+ scoped_ptr<message_center::MessageCenterTrayDelegate> tray_;
+ message_center::MessageCenter* message_center_; // Weak, global.
+
// Use a map by notification_id since this mapping is the most often used.
typedef std::map<std::string, ProfileNotification*> NotificationMap;
NotificationMap profile_notifications_;
diff --git a/chrome/browser/notifications/notification_ui_manager_impl.cc b/chrome/browser/notifications/notification_ui_manager_impl.cc
index e6563ea..fcf56e8 100644
--- a/chrome/browser/notifications/notification_ui_manager_impl.cc
+++ b/chrome/browser/notifications/notification_ui_manager_impl.cc
@@ -5,6 +5,7 @@
#include "chrome/browser/notifications/notification_ui_manager_impl.h"
#include "base/logging.h"
+#include "base/memory/linked_ptr.h"
#include "base/stl_util.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/fullscreen.h"
@@ -145,7 +146,9 @@ void NotificationUIManagerImpl::CheckUserState() {
}
}
-// TODO(dewittj): Eliminate recursion.
+// Attempts to show each notification, leaving any failures in the queue.
+// TODO(dewittj): Eliminate recursion when BallonCollection is used to render
+// the Notification UI surfaces.
void NotificationUIManagerImpl::ShowNotifications() {
while (!show_queue_.empty()) {
linked_ptr<QueuedNotification> queued_notification(show_queue_.front());