summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjohnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-04 21:29:11 +0000
committerjohnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-11-04 21:29:11 +0000
commitb52448bbb0eef4eee4cc025562cd04b1c7d530ef (patch)
treee57c73e0f1cc2ace36357bbef0594ad12addd070
parent48af406a5dc13be98bfef6c902843875399f1033 (diff)
downloadchromium_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.cc9
-rw-r--r--chrome/browser/notifications/balloon.h11
-rw-r--r--chrome/browser/notifications/balloon_collection.cc13
-rw-r--r--chrome/browser/notifications/balloon_collection.h5
-rw-r--r--chrome/browser/notifications/desktop_notification_service.cc10
-rw-r--r--chrome/browser/notifications/desktop_notification_service.h7
-rw-r--r--chrome/browser/notifications/notification.h4
-rw-r--r--chrome/browser/notifications/notification_object_proxy.h10
-rw-r--r--chrome/browser/notifications/notification_ui_manager.cc13
-rw-r--r--chrome/browser/notifications/notification_ui_manager.h3
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc9
-rw-r--r--chrome/browser/renderer_host/render_view_host.h1
-rw-r--r--chrome/browser/views/notifications/balloon_view.cc17
-rw-r--r--chrome/browser/views/notifications/balloon_view.h4
-rw-r--r--chrome/renderer/notification_provider.cc4
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);
}