diff options
author | johnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-04 21:29:11 +0000 |
---|---|---|
committer | johnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-11-04 21:29:11 +0000 |
commit | b52448bbb0eef4eee4cc025562cd04b1c7d530ef (patch) | |
tree | e57c73e0f1cc2ace36357bbef0594ad12addd070 | |
parent | 48af406a5dc13be98bfef6c902843875399f1033 (diff) | |
download | chromium_src-b52448bbb0eef4eee4cc025562cd04b1c7d530ef.zip chromium_src-b52448bbb0eef4eee4cc025562cd04b1c7d530ef.tar.gz chromium_src-b52448bbb0eef4eee4cc025562cd04b1c7d530ef.tar.bz2 |
Implement cancel() API on a Notification object so that script can cancel or tear down a toast.
BUG=26360
TEST=cancel a notification
Review URL: http://codereview.chromium.org/363003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@31004 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/notifications/balloon.cc | 9 | ||||
-rw-r--r-- | chrome/browser/notifications/balloon.h | 11 | ||||
-rw-r--r-- | chrome/browser/notifications/balloon_collection.cc | 13 | ||||
-rw-r--r-- | chrome/browser/notifications/balloon_collection.h | 5 | ||||
-rw-r--r-- | chrome/browser/notifications/desktop_notification_service.cc | 10 | ||||
-rw-r--r-- | chrome/browser/notifications/desktop_notification_service.h | 7 | ||||
-rw-r--r-- | chrome/browser/notifications/notification.h | 4 | ||||
-rw-r--r-- | chrome/browser/notifications/notification_object_proxy.h | 10 | ||||
-rw-r--r-- | chrome/browser/notifications/notification_ui_manager.cc | 13 | ||||
-rw-r--r-- | chrome/browser/notifications/notification_ui_manager.h | 3 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.cc | 9 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_view_host.h | 1 | ||||
-rw-r--r-- | chrome/browser/views/notifications/balloon_view.cc | 17 | ||||
-rw-r--r-- | chrome/browser/views/notifications/balloon_view.h | 4 | ||||
-rw-r--r-- | chrome/renderer/notification_provider.cc | 4 |
15 files changed, 104 insertions, 16 deletions
diff --git a/chrome/browser/notifications/balloon.cc b/chrome/browser/notifications/balloon.cc index 71abe66..d9d4c1f 100644 --- a/chrome/browser/notifications/balloon.cc +++ b/chrome/browser/notifications/balloon.cc @@ -36,8 +36,15 @@ void Balloon::Show() { } } -void Balloon::Close(bool by_user) { +void Balloon::OnClose(bool by_user) { notification_.Close(by_user); if (close_listener_) close_listener_->OnBalloonClosed(this); } + +void Balloon::CloseByScript() { + // A user-initiated close begins with the view and then closes this object; + // we simulate that with a script-initiated close but pass |by_user|=false. + DCHECK(balloon_view_.get()); + balloon_view_->Close(false); +} diff --git a/chrome/browser/notifications/balloon.h b/chrome/browser/notifications/balloon.h index 5559f09..b0f49b4 100644 --- a/chrome/browser/notifications/balloon.h +++ b/chrome/browser/notifications/balloon.h @@ -32,7 +32,7 @@ class BalloonView { virtual void RepositionToBalloon() = 0; // Close the view. - virtual void Close() = 0; + virtual void Close(bool by_user) = 0; }; // Represents a Notification on the screen. @@ -65,8 +65,15 @@ class Balloon { // to this object. void set_view(BalloonView* balloon_view); + // Shows the balloon. virtual void Show(); - virtual void Close(bool by_user); + + // Called when the balloon is closed, either by user (through the UI) + // or by a script. + virtual void OnClose(bool by_user); + + // Called by script to cause the balloon to close. + virtual void CloseByScript(); private: // Non-owned pointer to the profile. diff --git a/chrome/browser/notifications/balloon_collection.cc b/chrome/browser/notifications/balloon_collection.cc index d979ddd..b0d2ea6 100644 --- a/chrome/browser/notifications/balloon_collection.cc +++ b/chrome/browser/notifications/balloon_collection.cc @@ -45,6 +45,19 @@ void BalloonCollectionImpl::Add(const Notification& notification, space_change_listener_->OnBalloonSpaceChanged(); } +bool BalloonCollectionImpl::Remove(const Notification& notification) { + Balloons::iterator iter; + for (iter = balloons_.begin(); iter != balloons_.end(); ++iter) { + if (notification.IsSame((*iter)->notification())) { + // Balloon.CloseByScript() will cause OnBalloonClosed() to be called on + // this object, which will remove it from the collection and free it. + (*iter)->CloseByScript(); + return true; + } + } + return false; +} + bool BalloonCollectionImpl::HasSpace() const { if (count() < kMinAllowedBalloonCount) return true; diff --git a/chrome/browser/notifications/balloon_collection.h b/chrome/browser/notifications/balloon_collection.h index a756936..8241f19 100644 --- a/chrome/browser/notifications/balloon_collection.h +++ b/chrome/browser/notifications/balloon_collection.h @@ -26,6 +26,10 @@ class BalloonCollection { virtual void Add(const Notification& notification, Profile* profile) = 0; + // Removes a balloon from the collection if present. Returns + // true if anything was removed. + virtual bool Remove(const Notification& notification) = 0; + // Is there room to add another notification? virtual bool HasSpace() const = 0; }; @@ -59,6 +63,7 @@ class BalloonCollectionImpl : public BalloonCollection, // BalloonCollectionInterface overrides virtual void Add(const Notification& notification, Profile* profile); + virtual bool Remove(const Notification& notification); virtual bool HasSpace() const; // Balloon::BalloonCloseListener interface diff --git a/chrome/browser/notifications/desktop_notification_service.cc b/chrome/browser/notifications/desktop_notification_service.cc index 1cd0b31..477b505 100644 --- a/chrome/browser/notifications/desktop_notification_service.cc +++ b/chrome/browser/notifications/desktop_notification_service.cc @@ -267,6 +267,16 @@ void DesktopNotificationService::ShowNotification( ui_manager_->Add(notification, profile_); } +bool DesktopNotificationService::CancelDesktopNotification( + int process_id, int route_id, int notification_id) { + scoped_refptr<NotificationObjectProxy> proxy( + new NotificationObjectProxy(process_id, route_id, notification_id, + false)); + Notification notif(GURL(), GURL(), proxy); + return ui_manager_->Cancel(notif); +} + + bool DesktopNotificationService::ShowDesktopNotification( const GURL& origin, const GURL& url, int process_id, int route_id, NotificationSource source, int notification_id) { diff --git a/chrome/browser/notifications/desktop_notification_service.h b/chrome/browser/notifications/desktop_notification_service.h index d7fbfda..1e1fb16 100644 --- a/chrome/browser/notifications/desktop_notification_service.h +++ b/chrome/browser/notifications/desktop_notification_service.h @@ -52,6 +52,13 @@ class DesktopNotificationService { const string16& title, const string16& text, int process_id, int route_id, NotificationSource 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 + // shown. + bool CancelDesktopNotification(int process_id, + int route_id, + int notification_id); + // Methods to setup and modify permission preferences. void GrantPermission(const GURL& origin); void DenyPermission(const GURL& origin); diff --git a/chrome/browser/notifications/notification.h b/chrome/browser/notifications/notification.h index ed63e04..e7f46bd 100644 --- a/chrome/browser/notifications/notification.h +++ b/chrome/browser/notifications/notification.h @@ -37,6 +37,10 @@ class Notification { void Error() const { proxy()->Error(); } void Close(bool by_user) const { proxy()->Close(by_user); } + bool IsSame(const Notification& other) const { + return (*proxy_).IsSame(*(other.proxy())); + } + private: NotificationObjectProxy* proxy() const { return proxy_.get(); } diff --git a/chrome/browser/notifications/notification_object_proxy.h b/chrome/browser/notifications/notification_object_proxy.h index 168bd8a..a5ad53b 100644 --- a/chrome/browser/notifications/notification_object_proxy.h +++ b/chrome/browser/notifications/notification_object_proxy.h @@ -31,9 +31,17 @@ class NotificationObjectProxy : void Error(); // To be called when the desktop notification is closed. If closed by a - // user explicitly (as opposed to timeout), |by_user| should be true. + // user explicitly (as opposed to timeout/script), |by_user| should be true. 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_); + } + private: // Called on UI thread to schedule a message for sending. void DeliverMessage(IPC::Message* message); diff --git a/chrome/browser/notifications/notification_ui_manager.cc b/chrome/browser/notifications/notification_ui_manager.cc index 6818a42..0330570 100644 --- a/chrome/browser/notifications/notification_ui_manager.cc +++ b/chrome/browser/notifications/notification_ui_manager.cc @@ -58,6 +58,19 @@ void NotificationUIManager::Add(const Notification& notification, CheckAndShowNotifications(); } +bool NotificationUIManager::Cancel(const Notification& notification) { + // First look through the notifications that haven't been shown. If not + // found there, call to the active balloon collection to tear it down. + NotificationDeque::iterator iter; + for (iter = show_queue_.begin(); iter != show_queue_.end(); ++iter) { + if (notification.IsSame((*iter)->notification())) { + show_queue_.erase(iter); + return true; + } + } + return balloon_collection_->Remove(notification); +} + void NotificationUIManager::CheckAndShowNotifications() { // TODO(johnnyg): http://crbug.com/25061 - Check for user idle/presentation. ShowNotifications(); diff --git a/chrome/browser/notifications/notification_ui_manager.h b/chrome/browser/notifications/notification_ui_manager.h index 192058f..b386ba6 100644 --- a/chrome/browser/notifications/notification_ui_manager.h +++ b/chrome/browser/notifications/notification_ui_manager.h @@ -42,6 +42,9 @@ class NotificationUIManager : virtual void Add(const Notification& notification, Profile* profile); + // Removes a notification. + virtual bool Cancel(const Notification& notification); + private: // Attempts to display notifications from the show_queue if the user // is active. diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc index 5c5b120..a2749a7 100644 --- a/chrome/browser/renderer_host/render_view_host.cc +++ b/chrome/browser/renderer_host/render_view_host.cc @@ -831,6 +831,8 @@ void RenderViewHost::OnMessageReceived(const IPC::Message& msg) { OnShowDesktopNotification) IPC_MESSAGE_HANDLER(ViewHostMsg_ShowDesktopNotificationText, OnShowDesktopNotificationText) + IPC_MESSAGE_HANDLER(ViewHostMsg_CancelDesktopNotification, + OnCancelDesktopNotification) IPC_MESSAGE_HANDLER(ViewHostMsg_RequestNotificationPermission, OnRequestNotificationPermission) IPC_MESSAGE_HANDLER(ViewHostMsg_ExtensionRequest, OnExtensionRequest) @@ -1677,6 +1679,13 @@ void RenderViewHost::OnShowDesktopNotificationText(const GURL& source_origin, DesktopNotificationService::PageNotification, notification_id); } +void RenderViewHost::OnCancelDesktopNotification(int notification_id) { + DesktopNotificationService* service= + process()->profile()->GetDesktopNotificationService(); + service->CancelDesktopNotification( + process()->id(), routing_id(), notification_id); +} + void RenderViewHost::OnRequestNotificationPermission( const GURL& source_origin, int callback_context) { DesktopNotificationService* service = diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h index 6d1dfc8..7d9337f 100644 --- a/chrome/browser/renderer_host/render_view_host.h +++ b/chrome/browser/renderer_host/render_view_host.h @@ -585,6 +585,7 @@ class RenderViewHost : public RenderWidgetHost, const string16& title, const string16& text, int notification_id); + void OnCancelDesktopNotification(int notification_id); void OnRequestNotificationPermission(const GURL& origin, int callback_id); void OnExtensionRequest(const std::string& name, const ListValue& args, diff --git a/chrome/browser/views/notifications/balloon_view.cc b/chrome/browser/views/notifications/balloon_view.cc index cb0ef1e..43a8554 100644 --- a/chrome/browser/views/notifications/balloon_view.cc +++ b/chrome/browser/views/notifications/balloon_view.cc @@ -71,7 +71,7 @@ class BalloonCloseButtonListener : public views::ButtonListener { // The only button currently is the close button. virtual void ButtonPressed(views::Button* sender, const views::Event&) { - view_->Close(); + view_->Close(true); } private: @@ -110,16 +110,17 @@ BalloonViewImpl::BalloonViewImpl() BalloonViewImpl::~BalloonViewImpl() { } -void BalloonViewImpl::Close() { +void BalloonViewImpl::Close(bool by_user) { MessageLoop::current()->PostTask(FROM_HERE, - method_factory_.NewRunnableMethod(&BalloonViewImpl::DelayedClose)); + method_factory_.NewRunnableMethod( + &BalloonViewImpl::DelayedClose, by_user)); } -void BalloonViewImpl::DelayedClose() { +void BalloonViewImpl::DelayedClose(bool by_user) { html_contents_->Shutdown(); html_container_->CloseNow(); frame_container_->CloseNow(); - balloon_->Close(true); + balloon_->OnClose(by_user); } void BalloonViewImpl::DidChangeBounds(const gfx::Rect& previous, @@ -339,8 +340,8 @@ void BalloonViewImpl::Paint(gfx::Canvas* canvas) { } void BalloonViewImpl::Observe(NotificationType type, - const NotificationSource& source, - const NotificationDetails& details) { + const NotificationSource& source, + const NotificationDetails& details) { if (type != NotificationType::NOTIFY_BALLOON_DISCONNECTED) { NOTREACHED(); return; @@ -350,5 +351,5 @@ void BalloonViewImpl::Observe(NotificationType type, // (e.g., because of a crash), we want to close the balloon. notification_registrar_.Remove(this, NotificationType::NOTIFY_BALLOON_DISCONNECTED, Source<Balloon>(balloon_)); - Close(); + Close(false); } diff --git a/chrome/browser/views/notifications/balloon_view.h b/chrome/browser/views/notifications/balloon_view.h index 35f6db2..0d7dd0a 100644 --- a/chrome/browser/views/notifications/balloon_view.h +++ b/chrome/browser/views/notifications/balloon_view.h @@ -45,7 +45,7 @@ class BalloonViewImpl : public BalloonView, // BalloonView interface. void Show(Balloon* balloon); void RepositionToBalloon(); - void Close(); + void Close(bool by_user); private: // Overridden from views::View. @@ -72,7 +72,7 @@ class BalloonViewImpl : public BalloonView, void SizeContentsWindow(); // Do the delayed close work. - void DelayedClose(); + void DelayedClose(bool by_user); // The height of the balloon's shelf. // The shelf is where is close button is located. diff --git a/chrome/renderer/notification_provider.cc b/chrome/renderer/notification_provider.cc index b439b60..6d142fe 100644 --- a/chrome/renderer/notification_provider.cc +++ b/chrome/renderer/notification_provider.cc @@ -31,7 +31,7 @@ bool NotificationProvider::show(const WebNotification& notification) { void NotificationProvider::cancel(const WebNotification& notification) { int id; bool id_found = manager_.GetId(notification, id); - DCHECK(id_found); + // Won't be found if the notification has already been closed by the user. if (id_found) Send(new ViewHostMsg_CancelDesktopNotification(view_->routing_id(), id)); } @@ -40,7 +40,7 @@ void NotificationProvider::objectDestroyed( const WebNotification& notification) { int id; bool id_found = manager_.GetId(notification, id); - DCHECK(id_found); + // Won't be found if the notification has already been closed by the user. if (id_found) manager_.UnregisterNotification(id); } |