1 // Copyright (c) 2012 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.
5 #include "content/renderer/notification_provider.h"
7 #include "base/strings/string_util.h"
8 #include "content/common/desktop_notification_messages.h"
9 #include "content/common/view_messages.h"
10 #include "content/renderer/render_view_impl.h"
11 #include "third_party/WebKit/public/platform/WebURL.h"
12 #include "third_party/WebKit/public/web/WebDocument.h"
13 #include "third_party/WebKit/public/web/WebFrame.h"
14 #include "third_party/WebKit/public/web/WebNotificationPermissionCallback.h"
15 #include "third_party/WebKit/public/web/WebUserGestureIndicator.h"
16 #include "third_party/WebKit/public/web/WebView.h"
18 using blink::WebDocument
;
19 using blink::WebNotification
;
20 using blink::WebNotificationPresenter
;
21 using blink::WebNotificationPermissionCallback
;
22 using blink::WebSecurityOrigin
;
23 using blink::WebString
;
25 using blink::WebUserGestureIndicator
;
30 NotificationProvider::NotificationProvider(RenderViewImpl
* render_view
)
31 : RenderViewObserver(render_view
) {
34 NotificationProvider::~NotificationProvider() {
37 bool NotificationProvider::show(const WebNotification
& notification
) {
38 int notification_id
= manager_
.RegisterNotification(notification
);
39 if (notification
.isHTML())
40 return ShowHTML(notification
, notification_id
);
42 return ShowText(notification
, notification_id
);
45 void NotificationProvider::cancel(const WebNotification
& notification
) {
47 bool id_found
= manager_
.GetId(notification
, id
);
48 // Won't be found if the notification has already been closed by the user.
50 Send(new DesktopNotificationHostMsg_Cancel(routing_id(), id
));
53 void NotificationProvider::objectDestroyed(
54 const WebNotification
& notification
) {
56 bool id_found
= manager_
.GetId(notification
, id
);
57 // Won't be found if the notification has already been closed by the user.
59 manager_
.UnregisterNotification(id
);
62 WebNotificationPresenter::Permission
NotificationProvider::checkPermission(
63 const WebSecurityOrigin
& origin
) {
65 Send(new DesktopNotificationHostMsg_CheckPermission(
67 GURL(origin
.toString()),
69 return static_cast<WebNotificationPresenter::Permission
>(permission
);
72 void NotificationProvider::requestPermission(
73 const WebSecurityOrigin
& origin
,
74 WebNotificationPermissionCallback
* callback
) {
75 // We only request permission in response to a user gesture.
76 if (!WebUserGestureIndicator::isProcessingUserGesture())
79 int id
= manager_
.RegisterPermissionRequest(callback
);
81 Send(new DesktopNotificationHostMsg_RequestPermission(
82 routing_id(), GURL(origin
.toString()), id
));
85 bool NotificationProvider::OnMessageReceived(const IPC::Message
& message
) {
87 IPC_BEGIN_MESSAGE_MAP(NotificationProvider
, message
)
88 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostDisplay
, OnDisplay
);
89 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostError
, OnError
);
90 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostClose
, OnClose
);
91 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostClick
, OnClick
);
92 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PermissionRequestDone
,
93 OnPermissionRequestComplete
);
94 IPC_MESSAGE_UNHANDLED(handled
= false)
97 if (message
.type() == ViewMsg_Navigate::ID
)
98 OnNavigate(); // Don't want to swallow the message.
103 bool NotificationProvider::ShowHTML(const WebNotification
& notification
,
105 DCHECK(notification
.isHTML());
106 ShowDesktopNotificationHostMsgParams params
;
107 WebDocument document
= render_view()->GetWebView()->mainFrame()->document();
108 params
.origin
= GURL(document
.securityOrigin().toString());
109 params
.is_html
= true;
110 params
.contents_url
= notification
.url();
111 params
.notification_id
= id
;
112 params
.replace_id
= notification
.replaceId();
113 return Send(new DesktopNotificationHostMsg_Show(routing_id(), params
));
116 bool NotificationProvider::ShowText(const WebNotification
& notification
,
118 DCHECK(!notification
.isHTML());
119 ShowDesktopNotificationHostMsgParams params
;
120 params
.is_html
= false;
121 WebDocument document
= render_view()->GetWebView()->mainFrame()->document();
122 params
.origin
= GURL(document
.securityOrigin().toString());
123 params
.icon_url
= notification
.iconURL();
124 params
.title
= notification
.title();
125 params
.body
= notification
.body();
126 params
.direction
= notification
.direction();
127 params
.notification_id
= id
;
128 params
.replace_id
= notification
.replaceId();
129 return Send(new DesktopNotificationHostMsg_Show(routing_id(), params
));
132 void NotificationProvider::OnDisplay(int id
) {
133 WebNotification notification
;
134 bool found
= manager_
.GetNotification(id
, ¬ification
);
135 // |found| may be false if the WebNotification went out of scope in
136 // the page before it was actually displayed to the user.
138 notification
.dispatchDisplayEvent();
141 void NotificationProvider::OnError(int id
, const WebString
& message
) {
142 WebNotification notification
;
143 bool found
= manager_
.GetNotification(id
, ¬ification
);
144 // |found| may be false if the WebNotification went out of scope in
145 // the page before the error occurred.
147 notification
.dispatchErrorEvent(message
);
150 void NotificationProvider::OnClose(int id
, bool by_user
) {
151 WebNotification notification
;
152 bool found
= manager_
.GetNotification(id
, ¬ification
);
153 // |found| may be false if the WebNotification went out of scope in
154 // the page before the associated toast was closed by the user.
156 notification
.dispatchCloseEvent(by_user
);
157 manager_
.UnregisterNotification(id
);
161 void NotificationProvider::OnClick(int id
) {
162 WebNotification notification
;
163 bool found
= manager_
.GetNotification(id
, ¬ification
);
164 // |found| may be false if the WebNotification went out of scope in
165 // the page before the associated toast was clicked on.
167 notification
.dispatchClickEvent();
170 void NotificationProvider::OnPermissionRequestComplete(int id
) {
171 WebNotificationPermissionCallback
* callback
= manager_
.GetCallback(id
);
173 callback
->permissionRequestComplete();
174 manager_
.OnPermissionRequestComplete(id
);
177 void NotificationProvider::OnNavigate() {
181 } // namespace content