OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/child/notifications/notification_manager.h" | 5 #include "content/child/notifications/notification_manager.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 for (const auto& action_icon : web_resources->actionIcons) | 36 for (const auto& action_icon : web_resources->actionIcons) |
37 resources.action_icons.push_back(action_icon); | 37 resources.action_icons.push_back(action_icon); |
38 return resources; | 38 return resources; |
39 } | 39 } |
40 | 40 |
41 } // namespace | 41 } // namespace |
42 | 42 |
43 static base::LazyInstance<base::ThreadLocalPointer<NotificationManager>>::Leaky | 43 static base::LazyInstance<base::ThreadLocalPointer<NotificationManager>>::Leaky |
44 g_notification_manager_tls = LAZY_INSTANCE_INITIALIZER; | 44 g_notification_manager_tls = LAZY_INSTANCE_INITIALIZER; |
45 | 45 |
46 NotificationManager::ActiveNotificationData::ActiveNotificationData( | |
47 blink::WebNotificationDelegate* delegate, | |
48 const GURL& origin, | |
49 const std::string& tag) | |
50 : delegate(delegate), origin(origin), tag(tag) {} | |
51 | |
52 NotificationManager::ActiveNotificationData::~ActiveNotificationData() {} | |
53 | |
54 NotificationManager::NotificationManager( | 46 NotificationManager::NotificationManager( |
55 ThreadSafeSender* thread_safe_sender, | 47 ThreadSafeSender* thread_safe_sender, |
56 NotificationDispatcher* notification_dispatcher) | 48 NotificationDispatcher* notification_dispatcher) |
57 : thread_safe_sender_(thread_safe_sender), | 49 : thread_safe_sender_(thread_safe_sender), |
58 notification_dispatcher_(notification_dispatcher) { | 50 notification_dispatcher_(notification_dispatcher) { |
59 g_notification_manager_tls.Pointer()->Set(this); | 51 g_notification_manager_tls.Pointer()->Set(this); |
60 } | 52 } |
61 | 53 |
62 NotificationManager::~NotificationManager() { | 54 NotificationManager::~NotificationManager() { |
63 g_notification_manager_tls.Pointer()->Set(nullptr); | 55 g_notification_manager_tls.Pointer()->Set(nullptr); |
(...skipping 19 matching lines...) Expand all Loading... |
83 void NotificationManager::show( | 75 void NotificationManager::show( |
84 const blink::WebSecurityOrigin& origin, | 76 const blink::WebSecurityOrigin& origin, |
85 const blink::WebNotificationData& notification_data, | 77 const blink::WebNotificationData& notification_data, |
86 std::unique_ptr<blink::WebNotificationResources> notification_resources, | 78 std::unique_ptr<blink::WebNotificationResources> notification_resources, |
87 blink::WebNotificationDelegate* delegate) { | 79 blink::WebNotificationDelegate* delegate) { |
88 DCHECK_EQ(0u, notification_data.actions.size()); | 80 DCHECK_EQ(0u, notification_data.actions.size()); |
89 DCHECK_EQ(0u, notification_resources->actionIcons.size()); | 81 DCHECK_EQ(0u, notification_resources->actionIcons.size()); |
90 | 82 |
91 GURL origin_gurl = blink::WebStringToGURL(origin.toString()); | 83 GURL origin_gurl = blink::WebStringToGURL(origin.toString()); |
92 | 84 |
93 int notification_id = | 85 int non_persistent_notification_id = |
94 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId()); | 86 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId()); |
95 | 87 |
96 active_page_notifications_[notification_id] = ActiveNotificationData( | 88 non_persistent_notifications_[non_persistent_notification_id] = delegate; |
97 delegate, origin_gurl, | |
98 base::UTF16ToUTF8(base::StringPiece16(notification_data.tag))); | |
99 | 89 |
100 // TODO(mkwst): This is potentially doing the wrong thing with unique | 90 // TODO(mkwst): This is potentially doing the wrong thing with unique |
101 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See | 91 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See |
102 // https://crbug.com/490074 for detail. | 92 // https://crbug.com/490074 for detail. |
103 thread_safe_sender_->Send(new PlatformNotificationHostMsg_Show( | 93 thread_safe_sender_->Send(new PlatformNotificationHostMsg_Show( |
104 notification_id, origin_gurl, | 94 non_persistent_notification_id, origin_gurl, |
105 ToPlatformNotificationData(notification_data), | 95 ToPlatformNotificationData(notification_data), |
106 ToNotificationResources(std::move(notification_resources)))); | 96 ToNotificationResources(std::move(notification_resources)))); |
107 } | 97 } |
108 | 98 |
109 void NotificationManager::showPersistent( | 99 void NotificationManager::showPersistent( |
110 const blink::WebSecurityOrigin& origin, | 100 const blink::WebSecurityOrigin& origin, |
111 const blink::WebNotificationData& notification_data, | 101 const blink::WebNotificationData& notification_data, |
112 std::unique_ptr<blink::WebNotificationResources> notification_resources, | 102 std::unique_ptr<blink::WebNotificationResources> notification_resources, |
113 blink::WebServiceWorkerRegistration* service_worker_registration, | 103 blink::WebServiceWorkerRegistration* service_worker_registration, |
114 blink::WebNotificationShowCallbacks* callbacks) { | 104 blink::WebNotificationShowCallbacks* callbacks) { |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 int request_id = | 169 int request_id = |
180 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId()); | 170 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId()); |
181 | 171 |
182 pending_get_notification_requests_.AddWithID(callbacks, request_id); | 172 pending_get_notification_requests_.AddWithID(callbacks, request_id); |
183 | 173 |
184 thread_safe_sender_->Send(new PlatformNotificationHostMsg_GetNotifications( | 174 thread_safe_sender_->Send(new PlatformNotificationHostMsg_GetNotifications( |
185 request_id, service_worker_registration_id, origin, | 175 request_id, service_worker_registration_id, origin, |
186 base::UTF16ToUTF8(base::StringPiece16(filter_tag)))); | 176 base::UTF16ToUTF8(base::StringPiece16(filter_tag)))); |
187 } | 177 } |
188 | 178 |
189 void NotificationManager::close(blink::WebNotificationDelegate* delegate) { | 179 void NotificationManager::close(const blink::WebSecurityOrigin& origin, |
190 for (auto& iter : active_page_notifications_) { | 180 const blink::WebString& tag, |
191 if (iter.second.delegate != delegate) | 181 const blink::WebString& notification_id) { |
192 continue; | 182 const std::string notification_id_str = |
| 183 base::UTF16ToUTF8(base::StringPiece16(notification_id)); |
193 | 184 |
194 thread_safe_sender_->Send(new PlatformNotificationHostMsg_Close( | 185 // Remove the stored local state for non-persistent notifications. |
195 iter.second.origin, iter.second.tag, iter.first)); | 186 auto iter = non_persistent_notification_ids_.find(notification_id_str); |
196 active_page_notifications_.erase(iter.first); | 187 if (iter != non_persistent_notification_ids_.end()) { |
197 return; | 188 int non_persistent_notification_id = iter->second; |
| 189 |
| 190 non_persistent_notifications_.erase(non_persistent_notification_id); |
| 191 non_persistent_notification_ids_.erase(iter); |
198 } | 192 } |
199 | 193 |
200 // It should not be possible for Blink to call close() on a Notification which | 194 thread_safe_sender_->Send(new PlatformNotificationHostMsg_Close( |
201 // does not exist in either the pending or active notification lists. | |
202 NOTREACHED(); | |
203 } | |
204 | |
205 void NotificationManager::closePersistent( | |
206 const blink::WebSecurityOrigin& origin, | |
207 const blink::WebString& tag, | |
208 const blink::WebString& notification_id) { | |
209 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ClosePersistent( | |
210 // TODO(mkwst): This is potentially doing the wrong thing with unique | 195 // TODO(mkwst): This is potentially doing the wrong thing with unique |
211 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See | 196 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See |
212 // https://crbug.com/490074 for detail. | 197 // https://crbug.com/490074 for detail. |
213 blink::WebStringToGURL(origin.toString()), | 198 blink::WebStringToGURL(origin.toString()), |
214 base::UTF16ToUTF8(base::StringPiece16(tag)), | 199 base::UTF16ToUTF8(base::StringPiece16(tag)), notification_id_str)); |
215 base::UTF16ToUTF8(base::StringPiece16(notification_id)))); | |
216 } | 200 } |
217 | 201 |
218 void NotificationManager::notifyDelegateDestroyed( | 202 void NotificationManager::notifyDelegateDestroyed( |
219 blink::WebNotificationDelegate* delegate) { | 203 blink::WebNotificationDelegate* delegate) { |
220 for (auto& iter : active_page_notifications_) { | 204 for (auto iter = non_persistent_notifications_.begin(); |
221 if (iter.second.delegate != delegate) | 205 iter != non_persistent_notifications_.end(); iter++) { |
| 206 if (iter->second != delegate) |
222 continue; | 207 continue; |
223 | 208 |
224 active_page_notifications_.erase(iter.first); | 209 int non_persistent_notification_id = iter->first; |
225 return; | 210 |
| 211 // Remove the notification's ID association from the local state as well. |
| 212 for (auto assoc_iter = non_persistent_notification_ids_.begin(); |
| 213 assoc_iter != non_persistent_notification_ids_.end(); assoc_iter++) { |
| 214 if (assoc_iter->second != non_persistent_notification_id) |
| 215 continue; |
| 216 |
| 217 non_persistent_notification_ids_.erase(assoc_iter); |
| 218 break; |
| 219 } |
| 220 |
| 221 non_persistent_notifications_.erase(iter); |
| 222 break; |
226 } | 223 } |
227 } | 224 } |
228 | 225 |
229 bool NotificationManager::OnMessageReceived(const IPC::Message& message) { | 226 bool NotificationManager::OnMessageReceived(const IPC::Message& message) { |
230 bool handled = true; | 227 bool handled = true; |
231 IPC_BEGIN_MESSAGE_MAP(NotificationManager, message) | 228 IPC_BEGIN_MESSAGE_MAP(NotificationManager, message) |
232 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidShow, OnDidShow); | 229 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidShow, OnDidShow) |
233 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidShowPersistent, | 230 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidShowPersistent, |
234 OnDidShowPersistent) | 231 OnDidShowPersistent) |
235 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidClose, OnDidClose); | 232 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidClose, OnDidClose) |
236 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidClick, OnDidClick); | 233 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidClick, OnDidClick) |
237 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidGetNotifications, | 234 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidGetNotifications, |
238 OnDidGetNotifications) | 235 OnDidGetNotifications) |
239 IPC_MESSAGE_UNHANDLED(handled = false) | 236 IPC_MESSAGE_UNHANDLED(handled = false) |
240 IPC_END_MESSAGE_MAP() | 237 IPC_END_MESSAGE_MAP() |
241 | 238 |
242 return handled; | 239 return handled; |
243 } | 240 } |
244 | 241 |
245 void NotificationManager::OnDidShow(int notification_id) { | 242 void NotificationManager::OnDidShow(int non_persistent_notification_id, |
246 const auto& iter = active_page_notifications_.find(notification_id); | 243 const std::string& notification_id) { |
247 if (iter == active_page_notifications_.end()) | 244 const auto iter = |
248 return; | 245 non_persistent_notifications_.find(non_persistent_notification_id); |
249 | 246 |
250 iter->second.delegate->dispatchShowEvent(); | 247 if (iter == non_persistent_notifications_.end()) |
| 248 return; // The notification has been destroyed by Blink since. |
| 249 |
| 250 non_persistent_notification_ids_[notification_id] = |
| 251 non_persistent_notification_id; |
| 252 |
| 253 blink::WebNotificationDelegate* delegate = iter->second; |
| 254 delegate->didShowNotification(blink::WebString::fromUTF8(notification_id)); |
251 } | 255 } |
252 | 256 |
253 void NotificationManager::OnDidShowPersistent(int request_id, bool success) { | 257 void NotificationManager::OnDidShowPersistent(int request_id, bool success) { |
254 blink::WebNotificationShowCallbacks* callbacks = | 258 blink::WebNotificationShowCallbacks* callbacks = |
255 pending_show_notification_requests_.Lookup(request_id); | 259 pending_show_notification_requests_.Lookup(request_id); |
256 DCHECK(callbacks); | 260 DCHECK(callbacks); |
257 | 261 |
258 if (!callbacks) | 262 if (!callbacks) |
259 return; | 263 return; |
260 | 264 |
261 if (success) | 265 if (success) |
262 callbacks->onSuccess(); | 266 callbacks->onSuccess(); |
263 else | 267 else |
264 callbacks->onError(); | 268 callbacks->onError(); |
265 | 269 |
266 pending_show_notification_requests_.Remove(request_id); | 270 pending_show_notification_requests_.Remove(request_id); |
267 } | 271 } |
268 | 272 |
269 void NotificationManager::OnDidClose(int notification_id) { | 273 void NotificationManager::OnDidClose(int non_persistent_notification_id, |
270 const auto& iter = active_page_notifications_.find(notification_id); | 274 const std::string& notification_id) { |
271 if (iter == active_page_notifications_.end()) | 275 const auto iter = |
| 276 non_persistent_notifications_.find(non_persistent_notification_id); |
| 277 if (iter == non_persistent_notifications_.end()) |
272 return; | 278 return; |
273 | 279 |
274 iter->second.delegate->dispatchCloseEvent(); | 280 iter->second->didCloseNotification(); |
275 | 281 |
276 active_page_notifications_.erase(iter); | 282 non_persistent_notifications_.erase(iter); |
| 283 non_persistent_notification_ids_.erase(notification_id); |
277 } | 284 } |
278 | 285 |
279 void NotificationManager::OnDidClick(int notification_id) { | 286 void NotificationManager::OnDidClick(int non_persistent_notification_id) { |
280 const auto& iter = active_page_notifications_.find(notification_id); | 287 const auto iter = |
281 if (iter == active_page_notifications_.end()) | 288 non_persistent_notifications_.find(non_persistent_notification_id); |
| 289 if (iter == non_persistent_notifications_.end()) |
282 return; | 290 return; |
283 | 291 |
284 iter->second.delegate->dispatchClickEvent(); | 292 iter->second->didClickNotification(); |
285 } | 293 } |
286 | 294 |
287 void NotificationManager::OnDidGetNotifications( | 295 void NotificationManager::OnDidGetNotifications( |
288 int request_id, | 296 int request_id, |
289 const std::vector<PersistentNotificationInfo>& notification_infos) { | 297 const std::vector<PersistentNotificationInfo>& notification_infos) { |
290 blink::WebNotificationGetCallbacks* callbacks = | 298 blink::WebNotificationGetCallbacks* callbacks = |
291 pending_get_notification_requests_.Lookup(request_id); | 299 pending_get_notification_requests_.Lookup(request_id); |
292 DCHECK(callbacks); | 300 DCHECK(callbacks); |
293 if (!callbacks) | 301 if (!callbacks) |
294 return; | 302 return; |
(...skipping 10 matching lines...) Expand all Loading... |
305 | 313 |
306 notifications[i] = web_notification_info; | 314 notifications[i] = web_notification_info; |
307 } | 315 } |
308 | 316 |
309 callbacks->onSuccess(notifications); | 317 callbacks->onSuccess(notifications); |
310 | 318 |
311 pending_get_notification_requests_.Remove(request_id); | 319 pending_get_notification_requests_.Remove(request_id); |
312 } | 320 } |
313 | 321 |
314 } // namespace content | 322 } // namespace content |
OLD | NEW |