cc: Make picture pile base thread safe.
[chromium-blink-merge.git] / content / renderer / notification_provider.cc
blob3c2a3c6e4e7c6106faf51a8aaa828a5b9e23b260
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 <vector>
9 #include "base/strings/string_util.h"
10 #include "content/common/desktop_notification_messages.h"
11 #include "content/common/frame_messages.h"
12 #include "content/renderer/notification_icon_loader.h"
13 #include "content/renderer/render_frame_impl.h"
14 #include "third_party/WebKit/public/web/WebDocument.h"
15 #include "third_party/WebKit/public/web/WebLocalFrame.h"
17 using blink::WebDocument;
18 using blink::WebNotification;
19 using blink::WebNotificationPresenter;
20 using blink::WebSecurityOrigin;
21 using blink::WebString;
23 namespace content {
25 NotificationProvider::NotificationProvider(RenderFrame* render_frame)
26 : RenderFrameObserver(render_frame) {}
28 NotificationProvider::~NotificationProvider() {}
30 bool NotificationProvider::show(const WebNotification& notification) {
31 int notification_id = manager_.RegisterNotification(notification);
32 if (notification.iconURL().isEmpty()) {
33 DisplayNotification(notification_id, SkBitmap());
34 return true;
37 scoped_ptr<NotificationIconLoader> loader(
38 new NotificationIconLoader(
39 notification_id,
40 base::Bind(&NotificationProvider::DisplayNotification,
41 base::Unretained(this))));
43 loader->Start(notification.iconURL());
45 pending_notifications_.push_back(loader.release());
46 return true;
49 void NotificationProvider::DisplayNotification(int notification_id,
50 const SkBitmap& icon) {
51 WebDocument document = render_frame()->GetWebFrame()->document();
52 WebNotification notification;
54 if (!manager_.GetNotification(notification_id, &notification)) {
55 NOTREACHED();
56 return;
59 RemovePendingNotification(notification_id);
61 ShowDesktopNotificationHostMsgParams params;
62 params.origin = GURL(document.securityOrigin().toString());
63 params.icon = icon;
64 params.title = notification.title();
65 params.body = notification.body();
66 params.direction = notification.direction();
67 params.replace_id = notification.replaceId();
69 Send(new DesktopNotificationHostMsg_Show(routing_id(),
70 notification_id,
71 params));
74 bool NotificationProvider::RemovePendingNotification(int notification_id) {
75 PendingNotifications::iterator iter = pending_notifications_.begin();
76 for (; iter != pending_notifications_.end(); ++iter) {
77 if ((*iter)->notification_id() != notification_id)
78 continue;
80 pending_notifications_.erase(iter);
81 return true;
84 return false;
87 void NotificationProvider::cancel(const WebNotification& notification) {
88 int id;
89 bool id_found = manager_.GetId(notification, id);
90 // Won't be found if the notification has already been closed by the user,
91 // or if the notification's icon is still being requested.
92 if (id_found && !RemovePendingNotification(id))
93 Send(new DesktopNotificationHostMsg_Cancel(routing_id(), id));
96 void NotificationProvider::objectDestroyed(
97 const WebNotification& notification) {
98 int id;
99 bool id_found = manager_.GetId(notification, id);
100 // Won't be found if the notification has already been closed by the user.
101 if (id_found) {
102 RemovePendingNotification(id);
103 manager_.UnregisterNotification(id);
107 WebNotificationPresenter::Permission NotificationProvider::checkPermission(
108 const WebSecurityOrigin& origin) {
109 int permission = WebNotificationPresenter::PermissionNotAllowed;
110 Send(new DesktopNotificationHostMsg_CheckPermission(
111 routing_id(),
112 GURL(origin.toString()),
113 &permission));
114 return static_cast<WebNotificationPresenter::Permission>(permission);
117 bool NotificationProvider::OnMessageReceived(const IPC::Message& message) {
118 bool handled = true;
119 IPC_BEGIN_MESSAGE_MAP(NotificationProvider, message)
120 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostDisplay, OnDisplay);
121 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostError, OnError);
122 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostClose, OnClose);
123 IPC_MESSAGE_HANDLER(DesktopNotificationMsg_PostClick, OnClick);
124 IPC_MESSAGE_UNHANDLED(handled = false)
125 IPC_END_MESSAGE_MAP()
127 if (message.type() == FrameMsg_Navigate::ID)
128 OnNavigate(); // Don't want to swallow the message.
130 return handled;
133 void NotificationProvider::OnDisplay(int id) {
134 WebNotification notification;
135 bool found = manager_.GetNotification(id, &notification);
136 // |found| may be false if the WebNotification went out of scope in
137 // the page before it was actually displayed to the user.
138 if (found)
139 notification.dispatchDisplayEvent();
142 void NotificationProvider::OnError(int id) {
143 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 the error occurred.
147 if (found)
148 notification.dispatchErrorEvent(WebString());
151 void NotificationProvider::OnClose(int id, bool by_user) {
152 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 associated toast was closed by the user.
156 if (found) {
157 notification.dispatchCloseEvent(by_user);
158 manager_.UnregisterNotification(id);
162 void NotificationProvider::OnClick(int id) {
163 WebNotification notification;
164 bool found = manager_.GetNotification(id, &notification);
165 // |found| may be false if the WebNotification went out of scope in
166 // the page before the associated toast was clicked on.
167 if (found)
168 notification.dispatchClickEvent();
171 void NotificationProvider::OnNavigate() {
172 manager_.Clear();
175 } // namespace content