Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(156)

Side by Side Diff: content/child/notifications/notification_manager.cc

Issue 939513002: Factor out a PendingNotificationTracker from the NotificationManager. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@n-sounds
Patch Set: Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 "base/lazy_instance.h" 7 #include "base/lazy_instance.h"
8 #include "base/strings/utf_string_conversions.h" 8 #include "base/strings/utf_string_conversions.h"
9 #include "base/thread_task_runner_handle.h" 9 #include "base/thread_task_runner_handle.h"
10 #include "base/threading/thread_local.h" 10 #include "base/threading/thread_local.h"
11 #include "content/child/notifications/notification_data_conversions.h" 11 #include "content/child/notifications/notification_data_conversions.h"
12 #include "content/child/notifications/notification_dispatcher.h" 12 #include "content/child/notifications/notification_dispatcher.h"
13 #include "content/child/notifications/notification_image_loader.h"
14 #include "content/child/service_worker/web_service_worker_registration_impl.h" 13 #include "content/child/service_worker/web_service_worker_registration_impl.h"
15 #include "content/child/thread_safe_sender.h" 14 #include "content/child/thread_safe_sender.h"
16 #include "content/child/worker_task_runner.h" 15 #include "content/child/worker_task_runner.h"
17 #include "content/common/platform_notification_messages.h" 16 #include "content/common/platform_notification_messages.h"
18 #include "content/public/common/platform_notification_data.h" 17 #include "content/public/common/platform_notification_data.h"
19 #include "third_party/WebKit/public/platform/WebSerializedOrigin.h" 18 #include "third_party/WebKit/public/platform/WebSerializedOrigin.h"
20 #include "third_party/WebKit/public/platform/modules/notifications/WebNotificati onData.h"
21 #include "third_party/WebKit/public/platform/modules/notifications/WebNotificati onDelegate.h" 19 #include "third_party/WebKit/public/platform/modules/notifications/WebNotificati onDelegate.h"
22 #include "third_party/skia/include/core/SkBitmap.h" 20 #include "third_party/skia/include/core/SkBitmap.h"
23 21
24 using blink::WebNotificationPermission; 22 using blink::WebNotificationPermission;
25 23
26 namespace content { 24 namespace content {
27 namespace { 25 namespace {
28 26
29 int CurrentWorkerId() { 27 int CurrentWorkerId() {
30 return WorkerTaskRunner::Instance()->CurrentWorkerId(); 28 return WorkerTaskRunner::Instance()->CurrentWorkerId();
31 } 29 }
32 30
33 } // namespace 31 } // namespace
34 32
35 static base::LazyInstance<base::ThreadLocalPointer<NotificationManager>>::Leaky 33 static base::LazyInstance<base::ThreadLocalPointer<NotificationManager>>::Leaky
36 g_notification_manager_tls = LAZY_INSTANCE_INITIALIZER; 34 g_notification_manager_tls = LAZY_INSTANCE_INITIALIZER;
37 35
38 NotificationManager::NotificationManager( 36 NotificationManager::NotificationManager(
39 ThreadSafeSender* thread_safe_sender, 37 ThreadSafeSender* thread_safe_sender,
40 base::SingleThreadTaskRunner* main_thread_task_runner, 38 base::SingleThreadTaskRunner* main_thread_task_runner,
41 NotificationDispatcher* notification_dispatcher) 39 NotificationDispatcher* notification_dispatcher)
42 : thread_safe_sender_(thread_safe_sender), 40 : thread_safe_sender_(thread_safe_sender),
43 main_thread_task_runner_(main_thread_task_runner),
44 notification_dispatcher_(notification_dispatcher), 41 notification_dispatcher_(notification_dispatcher),
45 weak_factory_(this) { 42 pending_notifications_(this, main_thread_task_runner) {
46 g_notification_manager_tls.Pointer()->Set(this); 43 g_notification_manager_tls.Pointer()->Set(this);
47 } 44 }
48 45
49 NotificationManager::~NotificationManager() { 46 NotificationManager::~NotificationManager() {
50 g_notification_manager_tls.Pointer()->Set(nullptr); 47 g_notification_manager_tls.Pointer()->Set(nullptr);
51 } 48 }
52 49
53 NotificationManager* NotificationManager::ThreadSpecificInstance( 50 NotificationManager* NotificationManager::ThreadSpecificInstance(
54 ThreadSafeSender* thread_safe_sender, 51 ThreadSafeSender* thread_safe_sender,
55 base::SingleThreadTaskRunner* main_thread_task_runner, 52 base::SingleThreadTaskRunner* main_thread_task_runner,
56 NotificationDispatcher* notification_dispatcher) { 53 NotificationDispatcher* notification_dispatcher) {
57 if (g_notification_manager_tls.Pointer()->Get()) 54 if (g_notification_manager_tls.Pointer()->Get())
58 return g_notification_manager_tls.Pointer()->Get(); 55 return g_notification_manager_tls.Pointer()->Get();
59 56
60 NotificationManager* manager = new NotificationManager( 57 NotificationManager* manager = new NotificationManager(
61 thread_safe_sender, main_thread_task_runner, notification_dispatcher); 58 thread_safe_sender, main_thread_task_runner, notification_dispatcher);
62 if (CurrentWorkerId()) 59 if (CurrentWorkerId())
63 WorkerTaskRunner::Instance()->AddStopObserver(manager); 60 WorkerTaskRunner::Instance()->AddStopObserver(manager);
64 return manager; 61 return manager;
65 } 62 }
66 63
64 void NotificationManager::DisplayPageNotification(
65 const blink::WebSerializedOrigin& origin,
66 const blink::WebNotificationData& notification_data,
67 blink::WebNotificationDelegate* delegate,
68 const SkBitmap& icon) {
69 int notification_id =
70 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId());
71
72 active_page_notifications_[notification_id] = delegate;
73 thread_safe_sender_->Send(
74 new PlatformNotificationHostMsg_Show(
75 notification_id,
76 GURL(origin.string()),
77 icon,
78 ToPlatformNotificationData(notification_data)));
79 }
80
81 void NotificationManager::DisplayPersistentNotification(
82 const blink::WebSerializedOrigin& origin,
83 const blink::WebNotificationData& notification_data,
84 int64 service_worker_registration_id,
85 scoped_ptr<blink::WebNotificationShowCallbacks> callbacks,
86 const SkBitmap& icon) {
87 thread_safe_sender_->Send(
88 new PlatformNotificationHostMsg_ShowPersistent(
89 service_worker_registration_id,
90 GURL(origin.string()),
91 icon,
92 ToPlatformNotificationData(notification_data)));
93
94 // There currently isn't a case in which the promise would be rejected per
95 // our implementation, so always resolve it here.
96 callbacks->onSuccess();
97 }
98
67 void NotificationManager::OnWorkerRunLoopStopped() { 99 void NotificationManager::OnWorkerRunLoopStopped() {
68 delete this; 100 delete this;
69 } 101 }
70 102
71 void NotificationManager::show( 103 void NotificationManager::show(
72 const blink::WebSerializedOrigin& origin, 104 const blink::WebSerializedOrigin& origin,
73 const blink::WebNotificationData& notification_data, 105 const blink::WebNotificationData& notification_data,
74 blink::WebNotificationDelegate* delegate) { 106 blink::WebNotificationDelegate* delegate) {
75 if (notification_data.icon.isEmpty()) { 107 if (notification_data.icon.isEmpty()) {
76 DisplayNotification(origin, notification_data, delegate, 108 DisplayPageNotification(origin, notification_data, delegate,
77 nullptr /* image_loader */); 109 SkBitmap() /* icon */);
mlamouri (slow - plz ping) 2015/02/18 14:53:58 nit: you probably don't need that /* icon */ comme
Peter Beverloo 2015/02/18 15:11:50 Done.
78 return; 110 return;
79 } 111 }
80 112
81 pending_page_notifications_[delegate] = CreateImageLoader( 113 pending_notifications_.FetchPageNotification(
82 notification_data.icon, 114 origin, notification_data, delegate);
83 base::Bind(&NotificationManager::DisplayNotification,
84 weak_factory_.GetWeakPtr(),
85 origin,
86 notification_data,
87 delegate));
88 } 115 }
89 116
90 void NotificationManager::showPersistent( 117 void NotificationManager::showPersistent(
91 const blink::WebSerializedOrigin& origin, 118 const blink::WebSerializedOrigin& origin,
92 const blink::WebNotificationData& notification_data, 119 const blink::WebNotificationData& notification_data,
93 blink::WebServiceWorkerRegistration* service_worker_registration, 120 blink::WebServiceWorkerRegistration* service_worker_registration,
94 blink::WebNotificationShowCallbacks* callbacks) { 121 blink::WebNotificationShowCallbacks* callbacks) {
95 DCHECK(service_worker_registration); 122 DCHECK(service_worker_registration);
96
97 int64 service_worker_registration_id = 123 int64 service_worker_registration_id =
98 static_cast<WebServiceWorkerRegistrationImpl*>( 124 static_cast<WebServiceWorkerRegistrationImpl*>(
99 service_worker_registration)->registration_id(); 125 service_worker_registration)->registration_id();
100 126
101 int request_id = persistent_notification_requests_.Add(callbacks); 127 scoped_ptr<blink::WebNotificationShowCallbacks> owned_callbacks(callbacks);
102 if (notification_data.icon.isEmpty()) { 128 if (notification_data.icon.isEmpty()) {
103 DisplayPersistentNotification(origin, 129 DisplayPersistentNotification(origin,
104 notification_data, 130 notification_data,
105 service_worker_registration_id, 131 service_worker_registration_id,
106 request_id, 132 owned_callbacks.Pass(),
107 nullptr /* image_loader */); 133 SkBitmap() /* icon */);
mlamouri (slow - plz ping) 2015/02/18 14:53:58 nit: /* icon */ is probably not needed.
Peter Beverloo 2015/02/18 15:11:50 Done.
108 return; 134 return;
109 } 135 }
110 136
111 pending_persistent_notifications_.insert(CreateImageLoader( 137 pending_notifications_.FetchPersistentNotification(
112 notification_data.icon, 138 origin, notification_data, service_worker_registration_id,
113 base::Bind(&NotificationManager::DisplayPersistentNotification, 139 owned_callbacks.Pass());
114 weak_factory_.GetWeakPtr(),
115 origin,
116 notification_data,
117 service_worker_registration_id,
118 request_id)));
119 } 140 }
120 141
121 void NotificationManager::close(blink::WebNotificationDelegate* delegate) { 142 void NotificationManager::close(blink::WebNotificationDelegate* delegate) {
122 if (RemovePendingPageNotification(delegate)) 143 if (pending_notifications_.CancelPageNotificationFetches(delegate))
123 return; 144 return;
124 145
125 auto iter = active_notifications_.begin(); 146 auto iter = active_page_notifications_.begin();
126 for (; iter != active_notifications_.end(); ++iter) { 147 for (; iter != active_page_notifications_.end(); ++iter) {
mlamouri (slow - plz ping) 2015/02/18 14:53:58 Here and below, could that be: for (auto iter :
Peter Beverloo 2015/02/18 15:11:50 Done.
127 if (iter->second != delegate) 148 if (iter->second != delegate)
128 continue; 149 continue;
129 150
130 thread_safe_sender_->Send( 151 thread_safe_sender_->Send(
131 new PlatformNotificationHostMsg_Close(iter->first)); 152 new PlatformNotificationHostMsg_Close(iter->first));
132 active_notifications_.erase(iter); 153 active_page_notifications_.erase(iter);
133 return; 154 return;
134 } 155 }
135 156
136 // It should not be possible for Blink to call close() on a Notification which 157 // It should not be possible for Blink to call close() on a Notification which
137 // does not exist anymore in the manager. 158 // does not exist in either the pending or active notification lists.
138 NOTREACHED(); 159 NOTREACHED();
139 } 160 }
140 161
141 void NotificationManager::closePersistent( 162 void NotificationManager::closePersistent(
142 const blink::WebString& persistent_notification_id) { 163 const blink::WebString& persistent_notification_id) {
143 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ClosePersistent( 164 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ClosePersistent(
144 base::UTF16ToUTF8(persistent_notification_id))); 165 base::UTF16ToUTF8(persistent_notification_id)));
145 } 166 }
146 167
147 void NotificationManager::notifyDelegateDestroyed( 168 void NotificationManager::notifyDelegateDestroyed(
148 blink::WebNotificationDelegate* delegate) { 169 blink::WebNotificationDelegate* delegate) {
149 if (RemovePendingPageNotification(delegate)) 170 if (pending_notifications_.CancelPageNotificationFetches(delegate))
150 return; 171 return;
151 172
152 auto iter = active_notifications_.begin(); 173 auto iter = active_page_notifications_.begin();
153 for (; iter != active_notifications_.end(); ++iter) { 174 for (; iter != active_page_notifications_.end(); ++iter) {
154 if (iter->second != delegate) 175 if (iter->second != delegate)
155 continue; 176 continue;
156 177
157 active_notifications_.erase(iter); 178 active_page_notifications_.erase(iter);
158 return; 179 return;
159 } 180 }
160 } 181 }
161 182
162 WebNotificationPermission NotificationManager::checkPermission( 183 WebNotificationPermission NotificationManager::checkPermission(
163 const blink::WebSerializedOrigin& origin) { 184 const blink::WebSerializedOrigin& origin) {
164 WebNotificationPermission permission = 185 WebNotificationPermission permission =
165 blink::WebNotificationPermissionAllowed; 186 blink::WebNotificationPermissionAllowed;
166 thread_safe_sender_->Send(new PlatformNotificationHostMsg_CheckPermission( 187 thread_safe_sender_->Send(new PlatformNotificationHostMsg_CheckPermission(
167 GURL(origin.string()), &permission)); 188 GURL(origin.string()), &permission));
168 189
169 return permission; 190 return permission;
170 } 191 }
171 192
172 bool NotificationManager::OnMessageReceived(const IPC::Message& message) { 193 bool NotificationManager::OnMessageReceived(const IPC::Message& message) {
173 bool handled = true; 194 bool handled = true;
174 IPC_BEGIN_MESSAGE_MAP(NotificationManager, message) 195 IPC_BEGIN_MESSAGE_MAP(NotificationManager, message)
175 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidShow, OnDidShow); 196 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidShow, OnDidShow);
176 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidClose, OnDidClose); 197 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidClose, OnDidClose);
177 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidClick, OnDidClick); 198 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidClick, OnDidClick);
178 IPC_MESSAGE_UNHANDLED(handled = false) 199 IPC_MESSAGE_UNHANDLED(handled = false)
179 IPC_END_MESSAGE_MAP() 200 IPC_END_MESSAGE_MAP()
180 201
181 return handled; 202 return handled;
182 } 203 }
183 204
184 void NotificationManager::OnDidShow(int notification_id) { 205 void NotificationManager::OnDidShow(int notification_id) {
185 const auto& iter = active_notifications_.find(notification_id); 206 const auto& iter = active_page_notifications_.find(notification_id);
186 if (iter == active_notifications_.end()) 207 if (iter == active_page_notifications_.end())
187 return; 208 return;
188 209
189 iter->second->dispatchShowEvent(); 210 iter->second->dispatchShowEvent();
190 } 211 }
191 212
192 void NotificationManager::OnDidClose(int notification_id) { 213 void NotificationManager::OnDidClose(int notification_id) {
193 const auto& iter = active_notifications_.find(notification_id); 214 const auto& iter = active_page_notifications_.find(notification_id);
194 if (iter == active_notifications_.end()) 215 if (iter == active_page_notifications_.end())
195 return; 216 return;
196 217
197 iter->second->dispatchCloseEvent(); 218 iter->second->dispatchCloseEvent();
198 active_notifications_.erase(iter); 219 active_page_notifications_.erase(iter);
199 } 220 }
200 221
201 void NotificationManager::OnDidClick(int notification_id) { 222 void NotificationManager::OnDidClick(int notification_id) {
202 const auto& iter = active_notifications_.find(notification_id); 223 const auto& iter = active_page_notifications_.find(notification_id);
203 if (iter == active_notifications_.end()) 224 if (iter == active_page_notifications_.end())
204 return; 225 return;
205 226
206 iter->second->dispatchClickEvent(); 227 iter->second->dispatchClickEvent();
207 } 228 }
208 229
209 scoped_refptr<NotificationImageLoader> NotificationManager::CreateImageLoader(
210 const blink::WebURL& image_url,
211 const NotificationImageLoadedCallback& callback) const {
212 scoped_refptr<NotificationImageLoader> pending_notification(
213 new NotificationImageLoader(callback));
214
215 main_thread_task_runner_->PostTask(
216 FROM_HERE, base::Bind(&NotificationImageLoader::StartOnMainThread,
217 pending_notification, image_url,
218 base::ThreadTaskRunnerHandle::Get()));
219
220 return pending_notification;
221 }
222
223 void NotificationManager::DisplayNotification(
224 const blink::WebSerializedOrigin& origin,
225 const blink::WebNotificationData& notification_data,
226 blink::WebNotificationDelegate* delegate,
227 scoped_refptr<NotificationImageLoader> image_loader) {
228 int notification_id =
229 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId());
230
231 active_notifications_[notification_id] = delegate;
232
233 SkBitmap icon;
234 if (image_loader)
235 icon = image_loader->GetDecodedImage();
236
237 thread_safe_sender_->Send(
238 new PlatformNotificationHostMsg_Show(
239 notification_id,
240 GURL(origin.string()),
241 icon,
242 ToPlatformNotificationData(notification_data)));
243
244 // If this Notification contained an icon, it can be safely deleted now.
245 RemovePendingPageNotification(delegate);
246 }
247
248 void NotificationManager::DisplayPersistentNotification(
249 const blink::WebSerializedOrigin& origin,
250 const blink::WebNotificationData& notification_data,
251 int64 service_worker_registration_id,
252 int request_id,
253 scoped_refptr<NotificationImageLoader> image_loader) {
254 blink::WebNotificationShowCallbacks* callbacks =
255 persistent_notification_requests_.Lookup(request_id);
256 DCHECK(callbacks);
257
258 SkBitmap icon;
259 if (image_loader) {
260 pending_persistent_notifications_.erase(image_loader);
261 icon = image_loader->GetDecodedImage();
262 }
263
264 thread_safe_sender_->Send(
265 new PlatformNotificationHostMsg_ShowPersistent(
266 service_worker_registration_id,
267 GURL(origin.string()),
268 icon,
269 ToPlatformNotificationData(notification_data)));
270
271 // There currently isn't a case in which the promise would be rejected per
272 // our implementation, so always resolve it here.
273 callbacks->onSuccess();
274
275 persistent_notification_requests_.Remove(request_id);
276 }
277
278 bool NotificationManager::RemovePendingPageNotification(
279 blink::WebNotificationDelegate* delegate) {
280 const auto& iter = pending_page_notifications_.find(delegate);
281 if (iter == pending_page_notifications_.end())
282 return false;
283
284 pending_page_notifications_.erase(iter);
285 return true;
286 }
287
288 } // namespace content 230 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698