diff options
Diffstat (limited to 'chrome/browser/notifications')
11 files changed, 114 insertions, 106 deletions
diff --git a/chrome/browser/notifications/balloon.cc b/chrome/browser/notifications/balloon.cc index 040abec..4d9a94f 100644 --- a/chrome/browser/notifications/balloon.cc +++ b/chrome/browser/notifications/balloon.cc @@ -6,13 +6,14 @@ #include "base/logging.h" #include "chrome/browser/notifications/balloon_collection.h" +#include "chrome/browser/notifications/notification.h" #include "chrome/browser/renderer_host/site_instance.h" #include "gfx/rect.h" Balloon::Balloon(const Notification& notification, Profile* profile, BalloonCollection* collection) : profile_(profile), - notification_(notification), + notification_(new Notification(notification)), collection_(collection) { } @@ -34,14 +35,22 @@ void Balloon::set_view(BalloonView* balloon_view) { } void Balloon::Show() { - notification_.Display(); + notification_->Display(); if (balloon_view_.get()) { balloon_view_->Show(this); } } +void Balloon::Update(const Notification& notification) { + notification_.reset(new Notification(notification)); + notification_->Display(); + if (balloon_view_.get()) { + balloon_view_->Update(); + } +} + void Balloon::OnClose(bool by_user) { - notification_.Close(by_user); + notification_->Close(by_user); collection_->OnBalloonClosed(this); } diff --git a/chrome/browser/notifications/balloon.h b/chrome/browser/notifications/balloon.h index 0136a9c..ddaa14d 100644 --- a/chrome/browser/notifications/balloon.h +++ b/chrome/browser/notifications/balloon.h @@ -11,13 +11,13 @@ #include "base/basictypes.h" #include "base/scoped_ptr.h" -#include "chrome/browser/notifications/notification.h" #include "gfx/point.h" #include "gfx/rect.h" #include "gfx/size.h" class Balloon; class BalloonCollection; +class Notification; class Profile; class SiteInstance; @@ -29,6 +29,9 @@ class BalloonView { // Show the view on the screen. virtual void Show(Balloon* balloon) = 0; + // Notify that the content of notification has chagned. + virtual void Update() = 0; + // Reposition the view to match the position of its balloon. virtual void RepositionToBalloon() = 0; @@ -47,7 +50,7 @@ class Balloon { BalloonCollection* collection); virtual ~Balloon(); - const Notification& notification() const { return notification_; } + const Notification& notification() const { return *notification_.get(); } Profile* profile() const { return profile_; } const gfx::Point& position() const { return position_; } @@ -76,6 +79,9 @@ class Balloon { // Shows the balloon. virtual void Show(); + // Notify that the content of notification has changed. + virtual void Update(const Notification& notification); + // Called when the balloon is closed, either by user (through the UI) // or by a script. virtual void OnClose(bool by_user); @@ -88,7 +94,7 @@ class Balloon { Profile* profile_; // The notification being shown in this balloon. - Notification notification_; + scoped_ptr<Notification> notification_; // The collection that this balloon belongs to. Non-owned pointer. BalloonCollection* collection_; diff --git a/chrome/browser/notifications/desktop_notification_service.cc b/chrome/browser/notifications/desktop_notification_service.cc index 55613f5..d351880 100644 --- a/chrome/browser/notifications/desktop_notification_service.cc +++ b/chrome/browser/notifications/desktop_notification_service.cc @@ -36,14 +36,9 @@ using WebKit::WebNotificationPresenter; -namespace { - -// Creates a data:xxxx URL which contains the full HTML for a notification -// using supplied icon, title, and text, run through a template which contains -// the standard formatting for notifications. -static string16 CreateDataUrl(const GURL& icon_url, const string16& title, - const string16& body) { - +// static +string16 DesktopNotificationService::CreateDataUrl( + const GURL& icon_url, const string16& title, const string16& body) { int resource; string16 line_name; string16 line; @@ -81,8 +76,6 @@ static string16 CreateDataUrl(const GURL& icon_url, const string16& title, return ReplaceStringPlaceholders(format_string, subst, NULL); } -} - // A task object which calls the renderer to inform the web page that the // permission request has completed. class NotificationPermissionCallbackTask : public Task { @@ -334,21 +327,20 @@ bool DesktopNotificationService::CancelDesktopNotification( scoped_refptr<NotificationObjectProxy> proxy( new NotificationObjectProxy(process_id, route_id, notification_id, false)); - Notification notif(GURL(), GURL(), L"", proxy, false); + Notification notif(GURL(), GURL(), L"", proxy); return ui_manager_->Cancel(notif); } bool DesktopNotificationService::ShowDesktopNotification( const GURL& origin, const GURL& url, int process_id, int route_id, - DesktopNotificationSource source, int notification_id, - bool sticky) { + DesktopNotificationSource source, int notification_id) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); NotificationObjectProxy* proxy = new NotificationObjectProxy(process_id, route_id, notification_id, source == WorkerNotification); - Notification notif(origin, url, DisplayNameForOrigin(origin), proxy, sticky); + Notification notif(origin, url, DisplayNameForOrigin(origin), proxy); ShowNotification(notif); return true; } @@ -356,8 +348,7 @@ bool DesktopNotificationService::ShowDesktopNotification( bool DesktopNotificationService::ShowDesktopNotificationText( const GURL& origin, const GURL& icon, const string16& title, const string16& text, int process_id, int route_id, - DesktopNotificationSource source, int notification_id, - bool sticky) { + DesktopNotificationSource source, int notification_id) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); NotificationObjectProxy* proxy = new NotificationObjectProxy(process_id, route_id, @@ -366,7 +357,7 @@ bool DesktopNotificationService::ShowDesktopNotificationText( // "upconvert" the string parameters to a data: URL. string16 data_url = CreateDataUrl(icon, title, text); Notification notif( - origin, GURL(data_url), DisplayNameForOrigin(origin), proxy, sticky); + origin, GURL(data_url), DisplayNameForOrigin(origin), proxy); ShowNotification(notif); return true; } diff --git a/chrome/browser/notifications/desktop_notification_service.h b/chrome/browser/notifications/desktop_notification_service.h index b1050c9..6e9a6d8 100644 --- a/chrome/browser/notifications/desktop_notification_service.h +++ b/chrome/browser/notifications/desktop_notification_service.h @@ -49,16 +49,14 @@ class DesktopNotificationService : public NotificationObserver { // is the origin of the script. |source| indicates whether the // script is in a worker or page. |notification_id| is an opaque // value to be passed back to the process when events occur on - // this notification. |sticky| is used to indicate that the notification - // is sticky and cannot be dismissed by a user. + // this notification. bool ShowDesktopNotification(const GURL& origin, const GURL& url, int process_id, int route_id, DesktopNotificationSource source, - int notification_id, - bool sticky); + int notification_id); bool ShowDesktopNotificationText(const GURL& origin, const GURL& icon, const string16& title, const string16& text, int process_id, - int route_id, DesktopNotificationSource source, int notification_id, - bool sticky); + int route_id, DesktopNotificationSource source, int notification_id); + // Cancels a notification. If it has already been shown, it will be // removed from the screen. If it hasn't been shown yet, it won't be @@ -78,6 +76,11 @@ class DesktopNotificationService : public NotificationObserver { const NotificationSource& source, const NotificationDetails& details); + // Creates a data:xxxx URL which contains the full HTML for a notification + // using supplied icon, title, and text, run through a template which contains + // the standard formatting for notifications. + static string16 CreateDataUrl(const GURL& icon_url, const string16& title, + const string16& body); private: void InitPrefs(); diff --git a/chrome/browser/notifications/desktop_notifications_unittest.cc b/chrome/browser/notifications/desktop_notifications_unittest.cc index ecc8f73..b15a46e 100644 --- a/chrome/browser/notifications/desktop_notifications_unittest.cc +++ b/chrome/browser/notifications/desktop_notifications_unittest.cc @@ -21,8 +21,7 @@ void MockBalloonCollection::Add(const Notification& notification, Notification test_notification(notification.origin_url(), notification.content_url(), notification.display_source(), - log_proxy_.get(), - notification.sticky()); + log_proxy_.get()); BalloonCollectionImpl::Add(test_notification, profile); } @@ -30,8 +29,7 @@ bool MockBalloonCollection::Remove(const Notification& notification) { Notification test_notification(notification.origin_url(), notification.content_url(), notification.display_source(), - log_proxy_.get(), - notification.sticky()); + log_proxy_.get()); return BalloonCollectionImpl::Remove(test_notification); } @@ -87,25 +85,20 @@ TEST_F(DesktopNotificationsTest, TestShow) { EXPECT_TRUE(service_->ShowDesktopNotificationText( GURL("http://www.google.com"), GURL("/icon.png"), ASCIIToUTF16("Title"), ASCIIToUTF16("Text"), - 0, 0, DesktopNotificationService::PageNotification, 1, false)); + 0, 0, DesktopNotificationService::PageNotification, 1)); MessageLoopForUI::current()->RunAllPending(); EXPECT_EQ(1, balloon_collection_->count()); EXPECT_TRUE(service_->ShowDesktopNotification( GURL("http://www.google.com"), GURL("http://www.google.com/notification.html"), - 0, 0, DesktopNotificationService::PageNotification, 2, false)); + 0, 0, DesktopNotificationService::PageNotification, 2)); MessageLoopForUI::current()->RunAllPending(); EXPECT_EQ(2, balloon_collection_->count()); EXPECT_EQ("notification displayed\n" "notification displayed\n", log_output_); - - std::set<Balloon*>::iterator iter = balloon_collection_->balloons().begin(); - EXPECT_FALSE((*iter)->notification().sticky()); - iter++; - EXPECT_FALSE((*iter)->notification().sticky()); } TEST_F(DesktopNotificationsTest, TestClose) { @@ -113,7 +106,7 @@ TEST_F(DesktopNotificationsTest, TestClose) { EXPECT_TRUE(service_->ShowDesktopNotificationText( GURL("http://www.google.com"), GURL("/icon.png"), ASCIIToUTF16("Title"), ASCIIToUTF16("Text"), - 0, 0, DesktopNotificationService::PageNotification, 1, false)); + 0, 0, DesktopNotificationService::PageNotification, 1)); MessageLoopForUI::current()->RunAllPending(); EXPECT_EQ(1, balloon_collection_->count()); @@ -141,7 +134,7 @@ TEST_F(DesktopNotificationsTest, TestCancel) { GURL("http://www.google.com"), GURL("/icon.png"), ASCIIToUTF16("Title"), ASCIIToUTF16("Text"), process_id, route_id, DesktopNotificationService::PageNotification, - notification_id, false)); + notification_id)); MessageLoopForUI::current()->RunAllPending(); EXPECT_EQ(1, balloon_collection_->count()); @@ -168,7 +161,7 @@ TEST_F(DesktopNotificationsTest, TestPositioning) { EXPECT_TRUE(service_->ShowDesktopNotificationText( GURL("http://www.google.com"), GURL("/icon.png"), ASCIIToUTF16("Title"), ASCIIToUTF16("Text"), - 0, 0, DesktopNotificationService::PageNotification, id, false)); + 0, 0, DesktopNotificationService::PageNotification, id)); expected_log.append("notification displayed\n"); int top = balloon_collection_->UppermostVerticalPosition(); if (id > 0) @@ -189,12 +182,12 @@ TEST_F(DesktopNotificationsTest, TestVariableSize) { "Really Really Really Really Really Really " "Really Really Really Really Really Really Really Long Title"), ASCIIToUTF16("Text"), - 0, 0, DesktopNotificationService::PageNotification, 0, false)); + 0, 0, DesktopNotificationService::PageNotification, 0)); expected_log.append("notification displayed\n"); EXPECT_TRUE(service_->ShowDesktopNotificationText( GURL("http://short.google.com"), GURL("/icon.png"), ASCIIToUTF16("Short title"), ASCIIToUTF16("Text"), - 0, 0, DesktopNotificationService::PageNotification, 1, false)); + 0, 0, DesktopNotificationService::PageNotification, 1)); expected_log.append("notification displayed\n"); std::set<Balloon*>& balloons = balloon_collection_->balloons(); @@ -225,7 +218,7 @@ TEST_F(DesktopNotificationsTest, TestQueueing) { GURL("http://www.google.com"), GURL("/icon.png"), ASCIIToUTF16("Title"), ASCIIToUTF16("Text"), process_id, route_id, - DesktopNotificationService::PageNotification, id, false)); + DesktopNotificationService::PageNotification, id)); } MessageLoopForUI::current()->RunAllPending(); @@ -275,7 +268,7 @@ TEST_F(DesktopNotificationsTest, TestEarlyDestruction) { EXPECT_TRUE(service_->ShowDesktopNotificationText( GURL("http://www.google.com"), GURL("/icon.png"), ASCIIToUTF16("Title"), ASCIIToUTF16("Text"), - 0, 0, DesktopNotificationService::PageNotification, id, false)); + 0, 0, DesktopNotificationService::PageNotification, id)); } service_.reset(NULL); } @@ -288,7 +281,7 @@ TEST_F(DesktopNotificationsTest, TestUserInputEscaping) { GURL("/icon.png"), ASCIIToUTF16("<script>window.alert('uh oh');</script>"), ASCIIToUTF16("<i>this text is in italics</i>"), - 0, 0, DesktopNotificationService::PageNotification, 1, false)); + 0, 0, DesktopNotificationService::PageNotification, 1)); MessageLoopForUI::current()->RunAllPending(); EXPECT_EQ(1, balloon_collection_->count()); @@ -297,21 +290,3 @@ TEST_F(DesktopNotificationsTest, TestUserInputEscaping) { EXPECT_EQ(std::string::npos, data_url.spec().find("<script>")); EXPECT_EQ(std::string::npos, data_url.spec().find("<i>")); } - -TEST_F(DesktopNotificationsTest, TestSticky) { - EXPECT_TRUE(service_->ShowDesktopNotificationText( - GURL("http://www.google.com"), - GURL("/icon.png"), ASCIIToUTF16("Title"), ASCIIToUTF16("Text"), - 0, 0, DesktopNotificationService::PageNotification, 1, true)); - MessageLoopForUI::current()->RunAllPending(); - EXPECT_TRUE(service_->ShowDesktopNotification( - GURL("http://www.google.com"), - GURL("http://www.google.com/notification.html"), - 0, 0, DesktopNotificationService::PageNotification, 2, true)); - MessageLoopForUI::current()->RunAllPending(); - - std::set<Balloon*>::iterator iter = balloon_collection_->balloons().begin(); - EXPECT_TRUE((*iter)->notification().sticky()); - iter++; - EXPECT_TRUE((*iter)->notification().sticky()); -} diff --git a/chrome/browser/notifications/notification.h b/chrome/browser/notifications/notification.h index f80a65f..a58c2ad 100644 --- a/chrome/browser/notifications/notification.h +++ b/chrome/browser/notifications/notification.h @@ -1,16 +1,16 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. +// Copyright (c) 2010 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_H_ #define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_H_ -#include <string> - #include "base/basictypes.h" #include "chrome/browser/notifications/notification_object_proxy.h" #include "googleurl/src/gurl.h" +class NotificationDelegate; + // Representation of an notification to be shown to the user. All // notifications at this level are HTML, although they may be // data: URLs representing simple text+icon notifications. @@ -18,21 +18,18 @@ class Notification { public: Notification(const GURL& origin_url, const GURL& content_url, const std::wstring& display_source, - NotificationObjectProxy* proxy, - bool sticky) + NotificationDelegate* delegate) : origin_url_(origin_url), content_url_(content_url), display_source_(display_source), - proxy_(proxy), - sticky_(sticky) { + delegate_(delegate) { } Notification(const Notification& notification) : origin_url_(notification.origin_url()), content_url_(notification.content_url()), display_source_(notification.display_source()), - proxy_(notification.proxy()), - sticky_(notification.sticky()) { + delegate_(notification.delegate()) { } // The URL (may be data:) containing the contents for the notification. @@ -44,20 +41,16 @@ class Notification { // A display string for the source of the notification. const std::wstring& display_source() const { return display_source_; } - void Display() const { proxy()->Display(); } - void Error() const { proxy()->Error(); } - void Close(bool by_user) const { proxy()->Close(by_user); } - - bool sticky() const { - return sticky_; - } + void Display() const { delegate()->Display(); } + void Error() const { delegate()->Error(); } + void Close(bool by_user) const { delegate()->Close(by_user); } bool IsSame(const Notification& other) const { - return (*proxy_).IsSame(*(other.proxy())); + return delegate()->id() == other.delegate()->id(); } private: - NotificationObjectProxy* proxy() const { return proxy_.get(); } + NotificationDelegate* delegate() const { return delegate_.get(); } // The Origin of the page/worker which created this notification. GURL origin_url_; @@ -72,11 +65,7 @@ class Notification { // A proxy object that allows access back to the JavaScript object that // represents the notification, for firing events. - scoped_refptr<NotificationObjectProxy> proxy_; - - // A sticky flag. A sticky notification cannot be dismissed by a - // user. - bool sticky_; + scoped_refptr<NotificationDelegate> delegate_; // Disallow assign. Copy constructor written above. void operator=(const Notification&); diff --git a/chrome/browser/notifications/notification_delegate.h b/chrome/browser/notifications/notification_delegate.h new file mode 100644 index 0000000..6d69335 --- /dev/null +++ b/chrome/browser/notifications/notification_delegate.h @@ -0,0 +1,34 @@ +// Copyright (c) 2010 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_DELEGATE_H_ +#define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_DELEGATE_H_ + +#include <string> + +#include "base/ref_counted.h" + +// Delegate for a notification. This class has two role, to implement +// callback methods for notification, and provides an identify of +// the associated notification. +class NotificationDelegate + : public base::RefCountedThreadSafe<NotificationDelegate> { + public: + + // To be called when the desktop notification is actually shown. + virtual void Display() = 0; + + // To be called when the desktop notification cannot be shown due to an + // error. + virtual void Error() = 0; + + // To be called when the desktop notification is closed. If closed by a + // user explicitly (as opposed to timeout/script), |by_user| should be true. + virtual void Close(bool by_user) = 0; + + // Returns unique id of the notification. + virtual std::string id() const = 0; +}; + +#endif // CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_DELEGATE_H_ diff --git a/chrome/browser/notifications/notification_object_proxy.cc b/chrome/browser/notifications/notification_object_proxy.cc index 3b45ddf..76363e5 100644 --- a/chrome/browser/notifications/notification_object_proxy.cc +++ b/chrome/browser/notifications/notification_object_proxy.cc @@ -49,6 +49,12 @@ void NotificationObjectProxy::Close(bool by_user) { } } +std::string NotificationObjectProxy::id() const { + return StringPrintf("%d:%d:%d:%d", process_id_, route_id_, + notification_id_, worker_); +} + + void NotificationObjectProxy::DeliverMessage(IPC::Message* message) { DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); ChromeThread::PostTask( diff --git a/chrome/browser/notifications/notification_object_proxy.h b/chrome/browser/notifications/notification_object_proxy.h index 46c56f5..a956b3a 100644 --- a/chrome/browser/notifications/notification_object_proxy.h +++ b/chrome/browser/notifications/notification_object_proxy.h @@ -5,7 +5,9 @@ #ifndef CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_OBJECT_PROXY_H_ #define CHROME_BROWSER_NOTIFICATIONS_NOTIFICATION_OBJECT_PROXY_H_ -#include "base/ref_counted.h" +#include <string> + +#include "chrome/browser/notifications/notification_delegate.h" class MessageLoop; namespace IPC { @@ -17,30 +19,17 @@ class Message; // when various events occur regarding the desktop notification, and the // attached JS listeners will be invoked in the renderer or worker process. class NotificationObjectProxy - : public base::RefCountedThreadSafe<NotificationObjectProxy> { + : public NotificationDelegate { public: // Creates a Proxy object with the necessary callback information. NotificationObjectProxy(int process_id, int route_id, int notification_id, bool worker); - // To be called when the desktop notification is actually shown. + // NotificationDelegate implementation. virtual void Display(); - - // To be called when the desktop notification cannot be shown due to an - // error. virtual void Error(); - - // To be called when the desktop notification is closed. If closed by a - // user explicitly (as opposed to timeout/script), |by_user| should be true. virtual void Close(bool by_user); - - // Compares two proxies by ids to decide if they are equal. - bool IsSame(const NotificationObjectProxy& other) const { - return (notification_id_ == other.notification_id_ && - route_id_ == other.route_id_ && - process_id_ == other.process_id_ && - worker_ == other.worker_); - } + virtual std::string id() const; protected: friend class base::RefCountedThreadSafe<NotificationObjectProxy>; diff --git a/chrome/browser/notifications/notification_test_util.h b/chrome/browser/notifications/notification_test_util.h index b4530f5..95e8fd1 100644 --- a/chrome/browser/notifications/notification_test_util.h +++ b/chrome/browser/notifications/notification_test_util.h @@ -40,6 +40,7 @@ class MockBalloonView : public BalloonView { explicit MockBalloonView(Balloon * balloon) : balloon_(balloon) {} void Show(Balloon* balloon) {} + void Update() {} void RepositionToBalloon() {} void Close(bool by_user) { balloon_->OnClose(by_user); } gfx::Size GetSize() const { return balloon_->content_size(); } diff --git a/chrome/browser/notifications/notification_ui_manager.h b/chrome/browser/notifications/notification_ui_manager.h index 9e2cf18..2eaedd3 100644 --- a/chrome/browser/notifications/notification_ui_manager.h +++ b/chrome/browser/notifications/notification_ui_manager.h @@ -45,6 +45,11 @@ class NotificationUIManager // Removes a notification. virtual bool Cancel(const Notification& notification); + // Returns balloon collection. + BalloonCollection* balloon_collection() { + return balloon_collection_.get(); + } + private: // Attempts to display notifications from the show_queue if the user // is active. |