| 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 |