From 6dd580526e35e3eb3353ba3e4da0446927db8d22 Mon Sep 17 00:00:00 2001 From: Cheng Zhao Date: Sun, 27 Jul 2014 10:27:41 +0000 Subject: [PATCH] Refactor notification presenter for new desktop notification interface. --- brightray/browser/browser_client.cc | 20 +-- brightray/browser/browser_client.h | 10 +- .../linux/notification_presenter_linux.cc | 152 +++++++----------- .../linux/notification_presenter_linux.h | 20 ++- brightray/browser/notification_presenter.h | 11 +- 5 files changed, 82 insertions(+), 131 deletions(-) diff --git a/brightray/browser/browser_client.cc b/brightray/browser/browser_client.cc index f96e7f057e..0f558a15ea 100644 --- a/brightray/browser/browser_client.cc +++ b/brightray/browser/browser_client.cc @@ -66,24 +66,12 @@ net::URLRequestContextGetter* BrowserClient::CreateRequestContext( void BrowserClient::ShowDesktopNotification( const content::ShowDesktopNotificationHostMsgParams& params, - int render_process_id, - int render_view_id, - bool worker) { + content::RenderFrameHost* render_frame_host, + content::DesktopNotificationDelegate* delegate, + base::Closure* cancel_callback) { auto presenter = notification_presenter(); if (!presenter) - return; - presenter->ShowNotification(params, render_process_id, render_view_id); -} - -void BrowserClient::CancelDesktopNotification( - int render_process_id, - int render_view_id, - int notification_id) { - auto presenter = notification_presenter(); - if (!presenter) - return; - presenter->CancelNotification( - render_process_id, render_view_id, notification_id); + presenter->ShowNotification(params, delegate, cancel_callback); } content::MediaObserver* BrowserClient::GetMediaObserver() { diff --git a/brightray/browser/browser_client.h b/brightray/browser/browser_client.h index 41b15ea971..b6ff42acd4 100644 --- a/brightray/browser/browser_client.h +++ b/brightray/browser/browser_client.h @@ -43,13 +43,9 @@ class BrowserClient : public content::ContentBrowserClient { const content::MainFunctionParams&) OVERRIDE; virtual void ShowDesktopNotification( const content::ShowDesktopNotificationHostMsgParams&, - int render_process_id, - int render_view_id, - bool worker) OVERRIDE; - virtual void CancelDesktopNotification( - int render_process_id, - int render_view_id, - int notification_id) OVERRIDE; + content::RenderFrameHost* render_frame_host, + content::DesktopNotificationDelegate* delegate, + base::Closure* cancel_callback) OVERRIDE; virtual content::MediaObserver* GetMediaObserver() OVERRIDE; virtual void GetAdditionalAllowedSchemesForFileSystem( std::vector* additional_schemes) OVERRIDE; diff --git a/brightray/browser/linux/notification_presenter_linux.cc b/brightray/browser/linux/notification_presenter_linux.cc index 06a9d0d42d..f734799809 100644 --- a/brightray/browser/linux/notification_presenter_linux.cc +++ b/brightray/browser/linux/notification_presenter_linux.cc @@ -3,13 +3,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE-CHROMIUM file. -#include - #include "browser/linux/notification_presenter_linux.h" -#include "base/strings/stringprintf.h" +#include "base/bind.h" +#include "base/logging.h" #include "base/strings/utf_string_conversions.h" -#include "content/public/browser/render_view_host.h" +#include "content/public/browser/desktop_notification_delegate.h" #include "content/public/common/show_desktop_notification_params.h" #include "common/application_info.h" @@ -17,13 +16,7 @@ namespace brightray { namespace { -const char *kRenderProcessIDKey = "RenderProcessID"; -const char *kRenderViewIDKey = "RenderViewID"; -const char *kNotificationIDKey = "NotificationID"; - -void log_and_clear_error(GError *error, const char *context) { - if (!error) return; - +void log_and_clear_error(GError* error, const char* context) { LOG(ERROR) << context << ": domain=" << error->domain << " code=" << error->code @@ -31,38 +24,15 @@ void log_and_clear_error(GError *error, const char *context) { g_error_free(error); } -int GetObjectInt(NotifyNotification *noti, const char *key) { - return GPOINTER_TO_INT(g_object_get_data(G_OBJECT(noti), key)); -} - -void SetObjectInt(NotifyNotification *noti, const char *key, int value) { - g_object_set_data(G_OBJECT(noti), key, GINT_TO_POINTER(value)); -} - - -void NotificationClosedCallback(NotifyNotification *noti, NotificationPresenterLinux *obj) { - int render_process_id = GetObjectInt(noti, kRenderProcessIDKey); - int render_view_id = GetObjectInt(noti, kRenderViewIDKey); - int notification_id = GetObjectInt(noti, kNotificationIDKey); - - auto host = content::RenderViewHost::FromID(render_process_id, render_view_id); - if (host) host->DesktopNotificationPostClose(notification_id, false); - obj->RemoveNotification(noti); -} - -void NotificationViewCallback(NotifyNotification *noti, const char *action, - NotificationPresenterLinux *obj) { - int render_process_id = GetObjectInt(noti, kRenderProcessIDKey); - int render_view_id = GetObjectInt(noti, kRenderViewIDKey); - int notification_id = GetObjectInt(noti, kNotificationIDKey); - - auto host = content::RenderViewHost::FromID(render_process_id, render_view_id); - if (host) host->DesktopNotificationPostClick(notification_id); - obj->RemoveNotification(noti); +content::DesktopNotificationDelegate* GetDelegateFromNotification( + NotifyNotification* notification) { + return static_cast( + g_object_get_data(G_OBJECT(notification), "delegate")); } } // namespace +// static NotificationPresenter* NotificationPresenter::Create() { if (!notify_is_initted()) { notify_init(GetApplicationName().c_str()); @@ -70,79 +40,71 @@ NotificationPresenter* NotificationPresenter::Create() { return new NotificationPresenterLinux; } -NotificationPresenterLinux::NotificationPresenterLinux() : notifications_(nullptr) { } +NotificationPresenterLinux::NotificationPresenterLinux() + : notifications_(nullptr) { +} NotificationPresenterLinux::~NotificationPresenterLinux() { // unref any outstanding notifications, and then free the list. - if (!notifications_) return; - - for (GList *p = notifications_; p != nullptr; p = p->next) { - g_object_unref(G_OBJECT(p->data)); - } - g_list_free(notifications_); + if (notifications_) + g_list_free_full(notifications_, g_object_unref); } void NotificationPresenterLinux::ShowNotification( const content::ShowDesktopNotificationHostMsgParams& params, - int render_process_id, - int render_view_id) { + content::DesktopNotificationDelegate* delegate, + base::Closure* cancel_callback) { std::string title = base::UTF16ToUTF8(params.title); std::string body = base::UTF16ToUTF8(params.body); - NotifyNotification *noti = notify_notification_new(title.c_str(), body.c_str(), nullptr); - SetObjectInt(noti, kRenderProcessIDKey, render_process_id); - SetObjectInt(noti, kRenderViewIDKey, render_view_id); - SetObjectInt(noti, kNotificationIDKey, params.notification_id); - g_signal_connect(noti, "closed", - G_CALLBACK(NotificationClosedCallback), this); - notify_notification_add_action(noti, "default", "View", - (NotifyActionCallback)NotificationViewCallback, this, nullptr); + NotifyNotification* notification = notify_notification_new(title.c_str(), body.c_str(), nullptr); - notifications_ = g_list_append(notifications_, noti); + g_object_set_data(G_OBJECT(notification), "delegate", delegate); + g_signal_connect(notification, "closed", G_CALLBACK(OnNotificationClosedThunk), this); + notify_notification_add_action(notification, "default", "View", OnNotificationViewThunk, this, + nullptr); - GError *error = nullptr; - notify_notification_show(noti, &error); - log_and_clear_error(error, "notify_notification_show"); - - auto host = content::RenderViewHost::FromID(render_process_id, render_view_id); - if (!host) + GError* error = nullptr; + notify_notification_show(notification, &error); + if (error) { + log_and_clear_error(error, "notify_notification_show"); + delegate->NotificationError(); return; - - host->DesktopNotificationPostDisplay(params.notification_id); -} - -void NotificationPresenterLinux::CancelNotification( - int render_process_id, - int render_view_id, - int notification_id) { - NotifyNotification *noti = nullptr; - for (GList *p = notifications_; p != nullptr; p = p->next) { - int rpid = GetObjectInt(noti, kRenderProcessIDKey); - int rvid = GetObjectInt(noti, kRenderViewIDKey); - int nid = GetObjectInt(noti, kNotificationIDKey); - if (render_process_id == rpid && render_view_id == rvid && notification_id == nid) { - noti = reinterpret_cast(p->data); - notifications_ = g_list_delete_link(notifications_, p); - break; - } } - if (!noti) - return; - GError *error = nullptr; - notify_notification_close(noti, &error); - log_and_clear_error(error, "notify_notification_close"); - g_object_unref(noti); + notifications_ = g_list_append(notifications_, notification); + delegate->NotificationDisplayed(); - auto host = content::RenderViewHost::FromID(render_process_id, render_view_id); - if (!host) - return; - - host->DesktopNotificationPostClose(notification_id, false); + if (cancel_callback) + *cancel_callback = base::Bind( + &NotificationPresenterLinux::CancelNotification, + base::Unretained(this), + notification); } -void NotificationPresenterLinux::RemoveNotification(NotifyNotification *noti) { - notifications_ = g_list_remove(notifications_, noti); - g_object_unref(noti); +void NotificationPresenterLinux::CancelNotification(NotifyNotification* notification) { + GError* error = nullptr; + notify_notification_close(notification, &error); + if (error) + log_and_clear_error(error, "notify_notification_close"); + + GetDelegateFromNotification(notification)->NotificationClosed(false); + DeleteNotification(notification); +} + +void NotificationPresenterLinux::DeleteNotification(NotifyNotification* notification) { + notifications_ = g_list_remove(notifications_, notification); + g_object_unref(notification); +} + +void NotificationPresenterLinux::OnNotificationClosed(NotifyNotification* notification) { + GetDelegateFromNotification(notification)->NotificationClosed(false); + DeleteNotification(notification); +} + +void NotificationPresenterLinux::OnNotificationView( + NotifyNotification* notification, char* action) { + GetDelegateFromNotification(notification)->NotificationClick(); + DeleteNotification(notification); } } // namespace brightray diff --git a/brightray/browser/linux/notification_presenter_linux.h b/brightray/browser/linux/notification_presenter_linux.h index dc868917e3..07e628e29a 100644 --- a/brightray/browser/linux/notification_presenter_linux.h +++ b/brightray/browser/linux/notification_presenter_linux.h @@ -7,10 +7,12 @@ #define BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_LINUX_H_ #include + #include #include "base/compiler_specific.h" #include "browser/notification_presenter.h" +#include "ui/base/glib/glib_signal.h" namespace brightray { @@ -22,14 +24,18 @@ class NotificationPresenterLinux : public NotificationPresenter { void RemoveNotification(NotifyNotification *notification); private: + // NotificationPresenter: virtual void ShowNotification( const content::ShowDesktopNotificationHostMsgParams&, - int render_process_id, - int render_view_id) OVERRIDE; - virtual void CancelNotification( - int render_process_id, - int render_view_id, - int notification_id) OVERRIDE; + content::DesktopNotificationDelegate* delegate, + base::Closure* cancel_callback) OVERRIDE; + + void CancelNotification(NotifyNotification* notification); + void DeleteNotification(NotifyNotification* notification); + + CHROMEG_CALLBACK_0(NotificationPresenterLinux, void, OnNotificationClosed, NotifyNotification*); + CHROMEG_CALLBACK_1(NotificationPresenterLinux, void, OnNotificationView, NotifyNotification*, + char*); // A list of all open NotifyNotification objects. // We do lookups here both by NotifyNotification object (when the user @@ -38,7 +44,7 @@ class NotificationPresenterLinux : public NotificationPresenter { // a map. // Entries in this list count as refs, so removal from this list should // always go with g_object_unref(). - GList *notifications_; + GList* notifications_; }; } // namespace brightray diff --git a/brightray/browser/notification_presenter.h b/brightray/browser/notification_presenter.h index db925f5e92..23420fb9cf 100644 --- a/brightray/browser/notification_presenter.h +++ b/brightray/browser/notification_presenter.h @@ -1,7 +1,10 @@ #ifndef BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_H_ #define BRIGHTRAY_BROWSER_NOTIFICATION_PRESENTER_H_ +#include "base/callback_forward.h" + namespace content { +class DesktopNotificationDelegate; struct ShowDesktopNotificationHostMsgParams; } @@ -15,12 +18,8 @@ class NotificationPresenter { virtual void ShowNotification( const content::ShowDesktopNotificationHostMsgParams&, - int render_process_id, - int render_view_id) = 0; - virtual void CancelNotification( - int render_process_id, - int render_view_id, - int notification_id) = 0; + content::DesktopNotificationDelegate* delegate, + base::Closure* cancel_callback) = 0; }; } // namespace brightray