diff options
author | johnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-05 01:40:12 +0000 |
---|---|---|
committer | johnnyg@chromium.org <johnnyg@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-05 01:40:12 +0000 |
commit | 90e908552cd4ed902be34e354775e3f711f06511 (patch) | |
tree | 61a3e4873856c60280a803925fcd6113e6512c10 /chrome/renderer | |
parent | 9e7a2378237e231b395c1faddd19fb349b8e8a23 (diff) | |
download | chromium_src-90e908552cd4ed902be34e354775e3f711f06511.zip chromium_src-90e908552cd4ed902be34e354775e3f711f06511.tar.gz chromium_src-90e908552cd4ed902be34e354775e3f711f06511.tar.bz2 |
Adds desktop notification support for renderer process, and enables the build flag for chromium build of webkit. Doesn't expose the feature to any websites yet.
BUG=none
TEST=none (This is part 1 of 3 for this feature; tests will follow).
Review URL: http://codereview.chromium.org/194079
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27973 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/renderer')
-rw-r--r-- | chrome/renderer/notification_provider.cc | 160 | ||||
-rw-r--r-- | chrome/renderer/notification_provider.h | 70 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 5 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 8 |
4 files changed, 243 insertions, 0 deletions
diff --git a/chrome/renderer/notification_provider.cc b/chrome/renderer/notification_provider.cc new file mode 100644 index 0000000..f6baba8 --- /dev/null +++ b/chrome/renderer/notification_provider.cc @@ -0,0 +1,160 @@ +// Copyright (c) 2009 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. + +#include "chrome/renderer/notification_provider.h" + +#include "base/task.h" +#include "chrome/common/render_messages.h" +#include "chrome/renderer/render_thread.h" +#include "chrome/renderer/render_view.h" +#include "webkit/api/public/WebNotificationPermissionCallback.h" + +using WebKit::WebNotification; +using WebKit::WebNotificationPresenter; +using WebKit::WebNotificationPermissionCallback; +using WebKit::WebString; + +NotificationProvider::NotificationProvider(RenderView* view) + : view_(view) { +} + +bool NotificationProvider::show(const WebNotification& notification) { + int notification_id = manager_.RegisterNotification(notification); + if (notification.isHTML()) + return ShowHTML(notification, notification_id); + else + return ShowText(notification, notification_id); +} + +void NotificationProvider::cancel(const WebNotification& notification) { + int id; + bool id_found = manager_.GetId(notification, id); + DCHECK(id_found); + if (id_found) + Send(new ViewHostMsg_CancelDesktopNotification(view_->routing_id(), id)); +} + +void NotificationProvider::objectDestroyed( + const WebNotification& notification) { + int id; + bool id_found = manager_.GetId(notification, id); + DCHECK(id_found); + if (id_found) + manager_.UnregisterNotification(id); +} + +WebNotificationPresenter::Permission NotificationProvider::checkPermission( + const WebString& origin) { + int permission; + Send(new ViewHostMsg_CheckNotificationPermission(view_->routing_id(), origin, + &permission)); + return static_cast<WebNotificationPresenter::Permission>(permission); +} + +void NotificationProvider::requestPermission( + const WebString& origin, WebNotificationPermissionCallback* callback) { + int id = manager_.RegisterPermissionRequest(callback); + + Send(new ViewHostMsg_RequestNotificationPermission(view_->routing_id(), + origin, id)); +} + +bool NotificationProvider::ShowHTML(const WebNotification& notification, + int id) { + DCHECK(notification.isHTML()); + return Send(new ViewHostMsg_ShowDesktopNotification(view_->routing_id(), + GURL(view_->webview()->mainFrame()->url()), + notification.url(), id)); +} + +bool NotificationProvider::ShowText(const WebNotification& notification, + int id) { + DCHECK(!notification.isHTML()); + return Send(new ViewHostMsg_ShowDesktopNotificationText(view_->routing_id(), + GURL(view_->webview()->mainFrame()->url()), + GURL(notification.icon()), + notification.title(), notification.body(), id)); +} + +void NotificationProvider::OnDisplay(int id) { + RenderProcess::current()->main_thread()->message_loop()->PostTask(FROM_HERE, + NewRunnableMethod(this, &NotificationProvider::HandleOnDisplay, id)); +} + +void NotificationProvider::OnError(int id, const WebString& message) { + RenderProcess::current()->main_thread()->message_loop()->PostTask(FROM_HERE, + NewRunnableMethod(this, &NotificationProvider::HandleOnError, + id, message)); +} + +void NotificationProvider::OnClose(int id, bool by_user) { + RenderProcess::current()->main_thread()->message_loop()->PostTask(FROM_HERE, + NewRunnableMethod(this, &NotificationProvider::HandleOnClose, + id, by_user)); +} + +void NotificationProvider::OnPermissionRequestComplete(int id) { + RenderProcess::current()->main_thread()->message_loop()->PostTask(FROM_HERE, + NewRunnableMethod(this, + &NotificationProvider::HandleOnPermissionRequestComplete, id)); +} + +void NotificationProvider::HandleOnDisplay(int id) { + DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI); + WebNotification notification; + bool found = manager_.GetNotification(id, ¬ification); + // |found| may be false if the WebNotification went out of scope in + // the page before it was actually displayed to the user. + if (found) + notification.dispatchDisplayEvent(); +} + +void NotificationProvider::HandleOnError(int id, const WebString& message) { + DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI); + WebNotification notification; + bool found = manager_.GetNotification(id, ¬ification); + // |found| may be false if the WebNotification went out of scope in + // the page before the error occurred. + if (found) + notification.dispatchErrorEvent(message); +} + +void NotificationProvider::HandleOnClose(int id, bool by_user) { + DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI); + WebNotification notification; + bool found = manager_.GetNotification(id, ¬ification); + // |found| may be false if the WebNotification went out of scope in + // the page before the associated toast was closed by the user. + if (found) + notification.dispatchCloseEvent(by_user); + manager_.UnregisterNotification(id); +} + +void NotificationProvider::HandleOnPermissionRequestComplete(int id) { + DCHECK(MessageLoop::current()->type() == MessageLoop::TYPE_UI); + WebNotificationPermissionCallback* callback = manager_.GetCallback(id); + DCHECK(callback); + callback->permissionRequestComplete(); + manager_.OnPermissionRequestComplete(id); +} + +bool NotificationProvider::OnMessageReceived(const IPC::Message& message) { + if (message.routing_id() != view_->routing_id()) + return false; + + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(NotificationProvider, message) + IPC_MESSAGE_HANDLER(ViewMsg_PostDisplayToNotificationObject, OnDisplay); + IPC_MESSAGE_HANDLER(ViewMsg_PostErrorToNotificationObject, OnError); + IPC_MESSAGE_HANDLER(ViewMsg_PostCloseToNotificationObject, OnClose); + IPC_MESSAGE_HANDLER(ViewMsg_PermissionRequestDone, + OnPermissionRequestComplete); + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + return handled; +} + +bool NotificationProvider::Send(IPC::Message* message) { + return RenderThread::current()->Send(message); +} diff --git a/chrome/renderer/notification_provider.h b/chrome/renderer/notification_provider.h new file mode 100644 index 0000000..ec0a05c --- /dev/null +++ b/chrome/renderer/notification_provider.h @@ -0,0 +1,70 @@ +// Copyright (c) 2009 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_RENDERER_NOTIFICATION_PROVIDER_H_ +#define CHROME_RENDERER_NOTIFICATION_PROVIDER_H_ + +#include <map> + +#include "chrome/common/desktop_notifications/active_notification_tracker.h" +#include "ipc/ipc_channel.h" +#include "ipc/ipc_channel_proxy.h" +#include "webkit/api/public/WebNotification.h" +#include "webkit/api/public/WebNotificationPresenter.h" + +class RenderView; +namespace WebKit { +class WebNotificationPermissionCallback; +} + +class NotificationProvider : public WebKit::WebNotificationPresenter, + public IPC::ChannelProxy::MessageFilter { + public: + explicit NotificationProvider(RenderView* view); + ~NotificationProvider() {} + + // WebKit::WebNotificationPresenter interface. Called from WebKit + // on the UI thread. + virtual bool show(const WebKit::WebNotification& proxy); + virtual void cancel(const WebKit::WebNotification& proxy); + virtual void objectDestroyed(const WebKit::WebNotification& proxy); + virtual WebKit::WebNotificationPresenter::Permission checkPermission( + const WebKit::WebString& origin); + virtual void requestPermission(const WebKit::WebString& origin, + WebKit::WebNotificationPermissionCallback* callback); + +private: + // Internal methods used on the UI thread. + bool ShowHTML(const WebKit::WebNotification& notification, int id); + bool ShowText(const WebKit::WebNotification& notification, int id); + + // Callback methods invoked when events happen on active notifications. + void OnDisplay(int id); + void OnError(int id, const WebKit::WebString& message); + void OnClose(int id, bool by_user); + void OnPermissionRequestComplete(int id); + + // Internal versions of the IPC handlers which run on the UI thread. + void HandleOnDisplay(int id); + void HandleOnError(int id, const WebKit::WebString& message); + void HandleOnClose(int id, bool by_user); + void HandleOnPermissionRequestComplete(int id); + + // IPC::ChannelProxy::MessageFilter override + virtual bool OnMessageReceived(const IPC::Message& message); + + bool Send(IPC::Message* message); + + // Non-owned pointer to the RenderView object which created and owns + // this object. + RenderView* view_; + + // A tracker object which manages the active notifications and the IDs + // that are used to refer to them over IPC. + ActiveNotificationTracker manager_; + + DISALLOW_COPY_AND_ASSIGN(NotificationProvider); +}; + +#endif // CHROME_RENDERER_NOTIFICATION_PROVIDER_H_ diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index 89fba21..bcbda08 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -44,6 +44,7 @@ #include "chrome/renderer/localized_error.h" #include "chrome/renderer/media/audio_renderer_impl.h" #include "chrome/renderer/navigation_state.h" +#include "chrome/renderer/notification_provider.h" #include "chrome/renderer/plugin_channel_host.h" #include "chrome/renderer/print_web_view_helper.h" #include "chrome/renderer/render_process.h" @@ -252,6 +253,7 @@ RenderView::~RenderView() { #endif render_thread_->RemoveFilter(audio_message_filter_); + render_thread_->RemoveFilter(notification_provider_.get()); } /*static*/ @@ -312,6 +314,8 @@ void RenderView::Init(gfx::NativeViewId parent_hwnd, devtools_agent_.reset(new DevToolsAgent(routing_id, this)); + notification_provider_ = new NotificationProvider(this); + webwidget_ = WebView::Create(this); webkit_preferences_.Apply(webview()); webview()->initializeMainFrame(this); @@ -339,6 +343,7 @@ void RenderView::Init(gfx::NativeViewId parent_hwnd, audio_message_filter_ = new AudioMessageFilter(routing_id_); render_thread_->AddFilter(audio_message_filter_); + render_thread_->AddFilter(notification_provider_.get()); } void RenderView::OnMessageReceived(const IPC::Message& message) { diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 5a7dcdd..cdd1c2c 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -29,6 +29,7 @@ #include "chrome/renderer/dom_ui_bindings.h" #include "chrome/renderer/extensions/extension_process_bindings.h" #include "chrome/renderer/external_host_bindings.h" +#include "chrome/renderer/notification_provider.h" #include "chrome/renderer/render_widget.h" #include "third_party/skia/include/core/SkBitmap.h" #include "testing/gtest/include/gtest/gtest_prod.h" @@ -268,6 +269,10 @@ class RenderView : public RenderWidget, virtual void didAddHistoryItem(); virtual void didUpdateInspectorSettings(); + virtual WebKit::WebNotificationPresenter* GetNotificationPresenter() { + return notification_provider_.get(); + } + // WebKit::WebWidgetClient // Most methods are handled by RenderWidget. virtual void show(WebKit::WebNavigationPolicy policy); @@ -903,6 +908,9 @@ class RenderView : public RenderWidget, // The text selection the last time DidChangeSelection got called. std::string last_selection_; + // Hopds a reference to the service which provides desktop notifications. + scoped_refptr<NotificationProvider> notification_provider_; + // Set to true if request for capturing page text has been made. bool determine_page_text_after_loading_stops_; |