blob: 0196d0cfdd412a556d96b4a029eb4caad6077c98 [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
5#include "chrome/renderer/notification_provider.h"
6
[email protected]0ce3f5982010-01-28 23:04:277#include "base/string_util.h"
[email protected]90e908552009-10-05 01:40:128#include "base/task.h"
9#include "chrome/common/render_messages.h"
[email protected]939856a2010-08-24 20:29:0210#include "chrome/common/render_messages_params.h"
[email protected]cd065c0112010-01-13 05:57:0911#include "chrome/common/url_constants.h"
[email protected]90e908552009-10-05 01:40:1212#include "chrome/renderer/render_thread.h"
13#include "chrome/renderer/render_view.h"
[email protected]0ce3f5982010-01-28 23:04:2714#include "third_party/WebKit/WebKit/chromium/public/WebDocument.h"
[email protected]418ed5ab2009-11-12 01:14:4915#include "third_party/WebKit/WebKit/chromium/public/WebFrame.h"
16#include "third_party/WebKit/WebKit/chromium/public/WebNotificationPermissionCallback.h"
[email protected]0ce3f5982010-01-28 23:04:2717#include "third_party/WebKit/WebKit/chromium/public/WebURL.h"
[email protected]4d51d5bf2010-07-26 18:48:2618#include "third_party/WebKit/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
28NotificationProvider::NotificationProvider(RenderView* view)
29 : view_(view) {
30}
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)
49 Send(new ViewHostMsg_CancelDesktopNotification(view_->routing_id(), id));
50}
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]0ce3f5982010-01-28 23:04:2764 Send(new ViewHostMsg_CheckNotificationPermission(
65 view_->routing_id(),
66 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.
75 if (!view_->webview()->mainFrame()->isProcessingUserGesture())
76 return;
77
[email protected]90e908552009-10-05 01:40:1278 int id = manager_.RegisterPermissionRequest(callback);
79
80 Send(new ViewHostMsg_RequestNotificationPermission(view_->routing_id(),
[email protected]d5f614f2010-04-06 18:44:2881 GURL(origin.toString()),
82 id));
[email protected]90e908552009-10-05 01:40:1283}
84
[email protected]b6849bda2009-10-14 23:59:2685bool NotificationProvider::OnMessageReceived(const IPC::Message& message) {
86 bool handled = true;
87 IPC_BEGIN_MESSAGE_MAP(NotificationProvider, message)
88 IPC_MESSAGE_HANDLER(ViewMsg_PostDisplayToNotificationObject, OnDisplay);
89 IPC_MESSAGE_HANDLER(ViewMsg_PostErrorToNotificationObject, OnError);
90 IPC_MESSAGE_HANDLER(ViewMsg_PostCloseToNotificationObject, OnClose);
[email protected]0ff62862010-09-01 05:50:3591 IPC_MESSAGE_HANDLER(ViewMsg_PostClickToNotificationObject, OnClick);
[email protected]b6849bda2009-10-14 23:59:2692 IPC_MESSAGE_HANDLER(ViewMsg_PermissionRequestDone,
93 OnPermissionRequestComplete);
94 IPC_MESSAGE_UNHANDLED(handled = false)
95 IPC_END_MESSAGE_MAP()
96 return handled;
97}
98
[email protected]422197532010-01-25 17:38:2399void NotificationProvider::OnNavigate() {
[email protected]3db53702010-03-03 22:38:13100 manager_.Clear();
[email protected]422197532010-01-25 17:38:23101}
102
[email protected]90e908552009-10-05 01:40:12103bool NotificationProvider::ShowHTML(const WebNotification& notification,
104 int id) {
[email protected]1ec4e042010-06-09 21:47:02105 // Disallow HTML notifications from unwanted schemes. javascript:
106 // in particular allows unwanted cross-domain access.
[email protected]cd065c0112010-01-13 05:57:09107 GURL url = notification.url();
[email protected]13347d152010-01-23 01:37:54108 if (!url.SchemeIs(chrome::kHttpScheme) &&
109 !url.SchemeIs(chrome::kHttpsScheme) &&
[email protected]1ec4e042010-06-09 21:47:02110 !url.SchemeIs(chrome::kExtensionScheme) &&
111 !url.SchemeIs(chrome::kDataScheme))
[email protected]cd065c0112010-01-13 05:57:09112 return false;
113
[email protected]90e908552009-10-05 01:40:12114 DCHECK(notification.isHTML());
[email protected]04b0c9332010-07-12 17:13:49115 ViewHostMsg_ShowNotification_Params params;
116 params.origin = GURL(view_->webview()->mainFrame()->url()).GetOrigin();
117 params.is_html = true;
118 params.contents_url = notification.url();
119 params.notification_id = id;
120 params.replace_id = notification.replaceId();
[email protected]90e908552009-10-05 01:40:12121 return Send(new ViewHostMsg_ShowDesktopNotification(view_->routing_id(),
[email protected]04b0c9332010-07-12 17:13:49122 params));
[email protected]90e908552009-10-05 01:40:12123}
124
125bool NotificationProvider::ShowText(const WebNotification& notification,
126 int id) {
127 DCHECK(!notification.isHTML());
[email protected]04b0c9332010-07-12 17:13:49128 ViewHostMsg_ShowNotification_Params params;
129 params.is_html = false;
130 params.origin = GURL(view_->webview()->mainFrame()->url()).GetOrigin();
131 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();
137
138 return Send(new ViewHostMsg_ShowDesktopNotification(view_->routing_id(),
139 params));
[email protected]90e908552009-10-05 01:40:12140}
141
142void NotificationProvider::OnDisplay(int id) {
[email protected]90e908552009-10-05 01:40:12143 WebNotification notification;
144 bool found = manager_.GetNotification(id, &notification);
145 // |found| may be false if the WebNotification went out of scope in
146 // the page before it was actually displayed to the user.
147 if (found)
148 notification.dispatchDisplayEvent();
149}
150
[email protected]b6849bda2009-10-14 23:59:26151void NotificationProvider::OnError(int id, const WebString& message) {
[email protected]90e908552009-10-05 01:40:12152 WebNotification notification;
153 bool found = manager_.GetNotification(id, &notification);
154 // |found| may be false if the WebNotification went out of scope in
155 // the page before the error occurred.
156 if (found)
157 notification.dispatchErrorEvent(message);
158}
159
[email protected]b6849bda2009-10-14 23:59:26160void NotificationProvider::OnClose(int id, bool by_user) {
[email protected]90e908552009-10-05 01:40:12161 WebNotification notification;
162 bool found = manager_.GetNotification(id, &notification);
163 // |found| may be false if the WebNotification went out of scope in
164 // the page before the associated toast was closed by the user.
[email protected]422197532010-01-25 17:38:23165 if (found) {
[email protected]90e908552009-10-05 01:40:12166 notification.dispatchCloseEvent(by_user);
[email protected]422197532010-01-25 17:38:23167 manager_.UnregisterNotification(id);
168 }
[email protected]90e908552009-10-05 01:40:12169}
170
[email protected]0ff62862010-09-01 05:50:35171void NotificationProvider::OnClick(int id) {
172 WebNotification notification;
173 bool found = manager_.GetNotification(id, &notification);
174 // |found| may be false if the WebNotification went out of scope in
175 // the page before the associated toast was clicked on.
176 if (found)
177 notification.dispatchClickEvent();
178}
179
[email protected]b6849bda2009-10-14 23:59:26180void NotificationProvider::OnPermissionRequestComplete(int id) {
[email protected]90e908552009-10-05 01:40:12181 WebNotificationPermissionCallback* callback = manager_.GetCallback(id);
182 DCHECK(callback);
183 callback->permissionRequestComplete();
184 manager_.OnPermissionRequestComplete(id);
185}
186
[email protected]90e908552009-10-05 01:40:12187bool NotificationProvider::Send(IPC::Message* message) {
188 return RenderThread::current()->Send(message);
189}