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