diff options
Diffstat (limited to 'chromium/content/renderer/notification_provider.cc')
-rw-r--r-- | chromium/content/renderer/notification_provider.cc | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/chromium/content/renderer/notification_provider.cc b/chromium/content/renderer/notification_provider.cc new file mode 100644 index 00000000000..fc7504226b6 --- /dev/null +++ b/chromium/content/renderer/notification_provider.cc @@ -0,0 +1,182 @@ +// Copyright (c) 2012 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 "content/renderer/notification_provider.h" + +#include "base/strings/string_util.h" +#include "content/common/desktop_notification_messages.h" +#include "content/common/view_messages.h" +#include "content/renderer/render_view_impl.h" +#include "third_party/WebKit/public/platform/WebURL.h" +#include "third_party/WebKit/public/web/WebDocument.h" +#include "third_party/WebKit/public/web/WebFrame.h" +#include "third_party/WebKit/public/web/WebNotificationPermissionCallback.h" +#include "third_party/WebKit/public/web/WebUserGestureIndicator.h" +#include "third_party/WebKit/public/web/WebView.h" + +using WebKit::WebDocument; +using WebKit::WebNotification; +using WebKit::WebNotificationPresenter; +using WebKit::WebNotificationPermissionCallback; +using WebKit::WebSecurityOrigin; +using WebKit::WebString; +using WebKit::WebURL; +using WebKit::WebUserGestureIndicator; + +namespace content { + + +NotificationProvider::NotificationProvider(RenderViewImpl* render_view) + : RenderViewObserver(render_view) { +} + +NotificationProvider::~NotificationProvider() { + manager_.DetachAll(); +} + +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); + // Won't be found if the notification has already been closed by the user. + if (id_found) + Send(new DesktopNotificationHostMsg_Cancel(routing_id(), id)); +} + +void NotificationProvider::objectDestroyed( + const WebNotification& notification) { + int id; + bool id_found = manager_.GetId(notification, id); + // Won't be found if the notification has already been closed by the user. + if (id_found) + manager_.UnregisterNotification(id); +} + +WebNotificationPresenter::Permission NotificationProvider::checkPermission( + const WebSecurityOrigin& origin) { + int permission; + Send(new DesktopNotificationHostMsg_CheckPermission( + routing_id(), + GURL(origin.toString()), + &permission)); + return static_cast<WebNotificationPresenter::Permission>(permission); +} + +void NotificationProvider::requestPermission( + const WebSecurityOrigin& origin, + WebNotificationPermissionCallback* callback) { + // We only request permission in response to a user gesture. + if (!WebUserGestureIndicator::isProcessingUserGesture()) + return; + + int id = manager_.RegisterPermissionRequest(callback); + + Send(new DesktopNotificationHostMsg_RequestPermission( + routing_id(), GURL(origin.toString()), id)); +} + +bool NotificationProvider::OnMessageReceived(const IPC::Message& message) { + bool handled = true; + IPC_BEGIN_MESSAGE_MAP(NotificationProvider, message) + IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostDisplay, OnDisplay); + IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostError, OnError); + IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostClose, OnClose); + IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostClick, OnClick); + IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PermissionRequestDone, + OnPermissionRequestComplete); + IPC_MESSAGE_UNHANDLED(handled = false) + IPC_END_MESSAGE_MAP() + + if (message.type() == ViewMsg_Navigate::ID) + OnNavigate(); // Don't want to swallow the message. + + return handled; +} + +bool NotificationProvider::ShowHTML(const WebNotification& notification, + int id) { + DCHECK(notification.isHTML()); + ShowDesktopNotificationHostMsgParams params; + WebDocument document = render_view()->GetWebView()->mainFrame()->document(); + params.origin = GURL(document.securityOrigin().toString()); + params.is_html = true; + params.contents_url = notification.url(); + params.notification_id = id; + params.replace_id = notification.replaceId(); + return Send(new DesktopNotificationHostMsg_Show(routing_id(), params)); +} + +bool NotificationProvider::ShowText(const WebNotification& notification, + int id) { + DCHECK(!notification.isHTML()); + ShowDesktopNotificationHostMsgParams params; + params.is_html = false; + WebDocument document = render_view()->GetWebView()->mainFrame()->document(); + params.origin = GURL(document.securityOrigin().toString()); + params.icon_url = notification.iconURL(); + params.title = notification.title(); + params.body = notification.body(); + params.direction = notification.direction(); + params.notification_id = id; + params.replace_id = notification.replaceId(); + return Send(new DesktopNotificationHostMsg_Show(routing_id(), params)); +} + +void NotificationProvider::OnDisplay(int id) { + 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::OnError(int id, const WebString& message) { + 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::OnClose(int id, bool by_user) { + 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::OnClick(int id) { + 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 clicked on. + if (found) + notification.dispatchClickEvent(); +} + +void NotificationProvider::OnPermissionRequestComplete(int id) { + WebNotificationPermissionCallback* callback = manager_.GetCallback(id); + DCHECK(callback); + callback->permissionRequestComplete(); + manager_.OnPermissionRequestComplete(id); +} + +void NotificationProvider::OnNavigate() { + manager_.Clear(); +} + +} // namespace content |