blob: 5beb8e1f10951e6ba2720137419a130a511c269a [file] [log] [blame]
[email protected]90e908552009-10-05 01:40:121// Copyright (c) 2009 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]230b7ef2011-03-16 22:30:195#include "content/renderer/notification_provider.h"
[email protected]90e908552009-10-05 01:40:126
[email protected]0ce3f5982010-01-28 23:04:277#include "base/string_util.h"
[email protected]542bdfe2010-11-30 03:55:478#include "base/task.h"
[email protected]cd065c0112010-01-13 05:57:099#include "chrome/common/url_constants.h"
[email protected]e7c21b812011-03-19 18:03:3010#include "chrome/common/render_messages.h"
[email protected]90e908552009-10-05 01:40:1211#include "chrome/renderer/render_thread.h"
[email protected]e7c21b812011-03-19 18:03:3012#include "content/common/desktop_notification_messages.h"
[email protected]60916042011-03-19 00:43:3613#include "content/renderer/render_view.h"
[email protected]8bd0fe62011-01-17 06:44:3714#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
15#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
16#include "third_party/WebKit/Source/WebKit/chromium/public/WebNotificationPermissionCallback.h"
17#include "third_party/WebKit/Source/WebKit/chromium/public/WebURL.h"
18#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
[email protected]90e908552009-10-05 01:40:1219
[email protected]0ce3f5982010-01-28 23:04:2720using WebKit::WebDocument;
[email protected]90e908552009-10-05 01:40:1221using WebKit::WebNotification;
22using WebKit::WebNotificationPresenter;
23using WebKit::WebNotificationPermissionCallback;
[email protected]d5f614f2010-04-06 18:44:2824using WebKit::WebSecurityOrigin;
[email protected]90e908552009-10-05 01:40:1225using WebKit::WebString;
[email protected]0ce3f5982010-01-28 23:04:2726using WebKit::WebURL;
[email protected]90e908552009-10-05 01:40:1227
[email protected]676126f72011-01-15 00:03:5128NotificationProvider::NotificationProvider(RenderView* render_view)
29 : RenderViewObserver(render_view) {
[email protected]90e908552009-10-05 01:40:1230}
31
[email protected]8a2a6a22010-08-17 00:37:2932NotificationProvider::~NotificationProvider() {
33 manager_.DetachAll();
34}
35
[email protected]90e908552009-10-05 01:40:1236bool NotificationProvider::show(const WebNotification& notification) {
37 int notification_id = manager_.RegisterNotification(notification);
38 if (notification.isHTML())
39 return ShowHTML(notification, notification_id);
40 else
41 return ShowText(notification, notification_id);
42}
43
44void NotificationProvider::cancel(const WebNotification& notification) {
45 int id;
46 bool id_found = manager_.GetId(notification, id);
[email protected]b52448bb2009-11-04 21:29:1147 // Won't be found if the notification has already been closed by the user.
[email protected]90e908552009-10-05 01:40:1248 if (id_found)
[email protected]e7c21b812011-03-19 18:03:3049 Send(new DesktopNotificationHostMsg_Cancel(routing_id(), id));
[email protected]90e908552009-10-05 01:40:1250}
51
52void NotificationProvider::objectDestroyed(
53 const WebNotification& notification) {
54 int id;
55 bool id_found = manager_.GetId(notification, id);
[email protected]b52448bb2009-11-04 21:29:1156 // Won't be found if the notification has already been closed by the user.
[email protected]90e908552009-10-05 01:40:1257 if (id_found)
58 manager_.UnregisterNotification(id);
59}
60
61WebNotificationPresenter::Permission NotificationProvider::checkPermission(
[email protected]57a777f72010-03-31 01:09:4262 const WebURL& url) {
[email protected]90e908552009-10-05 01:40:1263 int permission;
[email protected]e7c21b812011-03-19 18:03:3064 Send(new DesktopNotificationHostMsg_CheckPermission(
[email protected]676126f72011-01-15 00:03:5165 routing_id(),
[email protected]0ce3f5982010-01-28 23:04:2766 url,
[email protected]0ce3f5982010-01-28 23:04:2767 &permission));
[email protected]90e908552009-10-05 01:40:1268 return static_cast<WebNotificationPresenter::Permission>(permission);
69}
70
71void NotificationProvider::requestPermission(
[email protected]d5f614f2010-04-06 18:44:2872 const WebSecurityOrigin& origin,
73 WebNotificationPermissionCallback* callback) {
[email protected]4440a58b2009-11-13 22:04:5874 // We only request permission in response to a user gesture.
[email protected]676126f72011-01-15 00:03:5175 if (!render_view()->webview()->mainFrame()->isProcessingUserGesture())
[email protected]4440a58b2009-11-13 22:04:5876 return;
77
[email protected]90e908552009-10-05 01:40:1278 int id = manager_.RegisterPermissionRequest(callback);
79
[email protected]e7c21b812011-03-19 18:03:3080 Send(new DesktopNotificationHostMsg_RequestPermission(
81 routing_id(), GURL(origin.toString()), id));
[email protected]90e908552009-10-05 01:40:1282}
83
[email protected]b6849bda2009-10-14 23:59:2684bool NotificationProvider::OnMessageReceived(const IPC::Message& message) {
85 bool handled = true;
86 IPC_BEGIN_MESSAGE_MAP(NotificationProvider, message)
[email protected]e7c21b812011-03-19 18:03:3087 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostDisplay, OnDisplay);
88 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostError, OnError);
89 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostClose, OnClose);
90 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostClick, OnClick);
91 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PermissionRequestDone,
[email protected]b6849bda2009-10-14 23:59:2692 OnPermissionRequestComplete);
93 IPC_MESSAGE_UNHANDLED(handled = false)
94 IPC_END_MESSAGE_MAP()
[email protected]b6849bda2009-10-14 23:59:2695
[email protected]676126f72011-01-15 00:03:5196 if (message.type() == ViewMsg_Navigate::ID)
97 OnNavigate(); // Don't want to swallow the message.
98
99 return handled;
[email protected]422197532010-01-25 17:38:23100}
101
[email protected]90e908552009-10-05 01:40:12102bool NotificationProvider::ShowHTML(const WebNotification& notification,
103 int id) {
[email protected]1ec4e042010-06-09 21:47:02104 // Disallow HTML notifications from unwanted schemes. javascript:
105 // in particular allows unwanted cross-domain access.
[email protected]cd065c0112010-01-13 05:57:09106 GURL url = notification.url();
[email protected]13347d152010-01-23 01:37:54107 if (!url.SchemeIs(chrome::kHttpScheme) &&
108 !url.SchemeIs(chrome::kHttpsScheme) &&
[email protected]1ec4e042010-06-09 21:47:02109 !url.SchemeIs(chrome::kExtensionScheme) &&
110 !url.SchemeIs(chrome::kDataScheme))
[email protected]cd065c0112010-01-13 05:57:09111 return false;
112
[email protected]90e908552009-10-05 01:40:12113 DCHECK(notification.isHTML());
[email protected]e7c21b812011-03-19 18:03:30114 DesktopNotificationHostMsg_Show_Params params;
[email protected]676126f72011-01-15 00:03:51115 params.origin =
116 GURL(render_view()->webview()->mainFrame()->url()).GetOrigin();
[email protected]04b0c9332010-07-12 17:13:49117 params.is_html = true;
118 params.contents_url = notification.url();
119 params.notification_id = id;
120 params.replace_id = notification.replaceId();
[email protected]e7c21b812011-03-19 18:03:30121 return Send(new DesktopNotificationHostMsg_Show(routing_id(), params));
[email protected]90e908552009-10-05 01:40:12122}
123
124bool NotificationProvider::ShowText(const WebNotification& notification,
125 int id) {
126 DCHECK(!notification.isHTML());
[email protected]e7c21b812011-03-19 18:03:30127 DesktopNotificationHostMsg_Show_Params params;
[email protected]04b0c9332010-07-12 17:13:49128 params.is_html = false;
[email protected]676126f72011-01-15 00:03:51129 params.origin = GURL(
130 render_view()->webview()->mainFrame()->url()).GetOrigin();
[email protected]04b0c9332010-07-12 17:13:49131 params.icon_url = notification.iconURL();
132 params.title = notification.title();
133 params.body = notification.body();
134 params.direction = notification.direction();
135 params.notification_id = id;
136 params.replace_id = notification.replaceId();
[email protected]e7c21b812011-03-19 18:03:30137 return Send(new DesktopNotificationHostMsg_Show(routing_id(), params));
[email protected]90e908552009-10-05 01:40:12138}
139
140void NotificationProvider::OnDisplay(int id) {
[email protected]90e908552009-10-05 01:40:12141 WebNotification notification;
142 bool found = manager_.GetNotification(id, &notification);
143 // |found| may be false if the WebNotification went out of scope in
144 // the page before it was actually displayed to the user.
145 if (found)
146 notification.dispatchDisplayEvent();
147}
148
[email protected]b6849bda2009-10-14 23:59:26149void NotificationProvider::OnError(int id, const WebString& message) {
[email protected]90e908552009-10-05 01:40:12150 WebNotification notification;
151 bool found = manager_.GetNotification(id, &notification);
152 // |found| may be false if the WebNotification went out of scope in
153 // the page before the error occurred.
154 if (found)
155 notification.dispatchErrorEvent(message);
156}
157
[email protected]b6849bda2009-10-14 23:59:26158void NotificationProvider::OnClose(int id, bool by_user) {
[email protected]90e908552009-10-05 01:40:12159 WebNotification notification;
160 bool found = manager_.GetNotification(id, &notification);
161 // |found| may be false if the WebNotification went out of scope in
162 // the page before the associated toast was closed by the user.
[email protected]422197532010-01-25 17:38:23163 if (found) {
[email protected]90e908552009-10-05 01:40:12164 notification.dispatchCloseEvent(by_user);
[email protected]422197532010-01-25 17:38:23165 manager_.UnregisterNotification(id);
166 }
[email protected]90e908552009-10-05 01:40:12167}
168
[email protected]0ff62862010-09-01 05:50:35169void NotificationProvider::OnClick(int id) {
170 WebNotification notification;
171 bool found = manager_.GetNotification(id, &notification);
172 // |found| may be false if the WebNotification went out of scope in
173 // the page before the associated toast was clicked on.
174 if (found)
175 notification.dispatchClickEvent();
176}
177
[email protected]b6849bda2009-10-14 23:59:26178void NotificationProvider::OnPermissionRequestComplete(int id) {
[email protected]90e908552009-10-05 01:40:12179 WebNotificationPermissionCallback* callback = manager_.GetCallback(id);
180 DCHECK(callback);
181 callback->permissionRequestComplete();
182 manager_.OnPermissionRequestComplete(id);
183}
184
[email protected]676126f72011-01-15 00:03:51185void NotificationProvider::OnNavigate() {
186 manager_.Clear();
[email protected]90e908552009-10-05 01:40:12187}