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.
4
5 #include "content/renderer/notification_provider.h"
6
7 #include "base/strings/string_util.h"
8 #include "content/common/desktop_notification_messages.h"
9 #include "content/common/frame_messages.h"
10 #include "content/renderer/render_frame_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
17 using blink::WebDocument;
18 using blink::WebNotification;
19 using blink::WebNotificationPresenter;
20 using blink::WebNotificationPermissionCallback;
21 using blink::WebSecurityOrigin;
22 using blink::WebString;
23 using blink::WebURL;
24 using blink::WebUserGestureIndicator;
25
26 namespace content {
27
28
NotificationProvider(RenderFrame * render_frame)29 NotificationProvider::NotificationProvider(RenderFrame* render_frame)
30 : RenderFrameObserver(render_frame) {
31 }
32
~NotificationProvider()33 NotificationProvider::~NotificationProvider() {
34 }
35
show(const WebNotification & notification)36 bool NotificationProvider::show(const WebNotification& notification) {
37 WebDocument document = render_frame()->GetWebFrame()->document();
38 int notification_id = manager_.RegisterNotification(notification);
39
40 ShowDesktopNotificationHostMsgParams params;
41 params.origin = GURL(document.securityOrigin().toString());
42 params.icon_url = notification.iconURL();
43 params.title = notification.title();
44 params.body = notification.body();
45 params.direction = notification.direction();
46 params.replace_id = notification.replaceId();
47 return Send(new DesktopNotificationHostMsg_Show(
48 routing_id(), notification_id, params));
49 }
50
cancel(const WebNotification & notification)51 void NotificationProvider::cancel(const WebNotification& notification) {
52 int id;
53 bool id_found = manager_.GetId(notification, id);
54 // Won't be found if the notification has already been closed by the user.
55 if (id_found)
56 Send(new DesktopNotificationHostMsg_Cancel(routing_id(), id));
57 }
58
objectDestroyed(const WebNotification & notification)59 void NotificationProvider::objectDestroyed(
60 const WebNotification& notification) {
61 int id;
62 bool id_found = manager_.GetId(notification, id);
63 // Won't be found if the notification has already been closed by the user.
64 if (id_found)
65 manager_.UnregisterNotification(id);
66 }
67
checkPermission(const WebSecurityOrigin & origin)68 WebNotificationPresenter::Permission NotificationProvider::checkPermission(
69 const WebSecurityOrigin& origin) {
70 int permission;
71 Send(new DesktopNotificationHostMsg_CheckPermission(
72 routing_id(),
73 GURL(origin.toString()),
74 &permission));
75 return static_cast<WebNotificationPresenter::Permission>(permission);
76 }
77
requestPermission(const WebSecurityOrigin & origin,WebNotificationPermissionCallback * callback)78 void NotificationProvider::requestPermission(
79 const WebSecurityOrigin& origin,
80 WebNotificationPermissionCallback* callback) {
81 int id = manager_.RegisterPermissionRequest(callback);
82
83 Send(new DesktopNotificationHostMsg_RequestPermission(
84 routing_id(), GURL(origin.toString()), id));
85 }
86
OnMessageReceived(const IPC::Message & message)87 bool NotificationProvider::OnMessageReceived(const IPC::Message& message) {
88 bool handled = true;
89 IPC_BEGIN_MESSAGE_MAP(NotificationProvider, message)
90 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostDisplay, OnDisplay);
91 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostError, OnError);
92 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostClose, OnClose);
93 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostClick, OnClick);
94 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PermissionRequestDone,
95 OnPermissionRequestComplete);
96 IPC_MESSAGE_UNHANDLED(handled = false)
97 IPC_END_MESSAGE_MAP()
98
99 if (message.type() == FrameMsg_Navigate::ID)
100 OnNavigate(); // Don't want to swallow the message.
101
102 return handled;
103 }
104
OnDisplay(int id)105 void NotificationProvider::OnDisplay(int id) {
106 WebNotification notification;
107 bool found = manager_.GetNotification(id, ¬ification);
108 // |found| may be false if the WebNotification went out of scope in
109 // the page before it was actually displayed to the user.
110 if (found)
111 notification.dispatchDisplayEvent();
112 }
113
OnError(int id)114 void NotificationProvider::OnError(int id) {
115 WebNotification notification;
116 bool found = manager_.GetNotification(id, ¬ification);
117 // |found| may be false if the WebNotification went out of scope in
118 // the page before the error occurred.
119 if (found)
120 notification.dispatchErrorEvent(WebString());
121 }
122
OnClose(int id,bool by_user)123 void NotificationProvider::OnClose(int id, bool by_user) {
124 WebNotification notification;
125 bool found = manager_.GetNotification(id, ¬ification);
126 // |found| may be false if the WebNotification went out of scope in
127 // the page before the associated toast was closed by the user.
128 if (found) {
129 notification.dispatchCloseEvent(by_user);
130 manager_.UnregisterNotification(id);
131 }
132 }
133
OnClick(int id)134 void NotificationProvider::OnClick(int id) {
135 WebNotification notification;
136 bool found = manager_.GetNotification(id, ¬ification);
137 // |found| may be false if the WebNotification went out of scope in
138 // the page before the associated toast was clicked on.
139 if (found)
140 notification.dispatchClickEvent();
141 }
142
OnPermissionRequestComplete(int id)143 void NotificationProvider::OnPermissionRequestComplete(int id) {
144 WebNotificationPermissionCallback* callback = manager_.GetCallback(id);
145 DCHECK(callback);
146 callback->permissionRequestComplete();
147 manager_.OnPermissionRequestComplete(id);
148 }
149
OnNavigate()150 void NotificationProvider::OnNavigate() {
151 manager_.Clear();
152 }
153
154 } // namespace content
155