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

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_(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,
(...skipping 10 matching lines...) Expand all
66 63
67 void NotificationManager::OnWorkerRunLoopStopped() { 64 void NotificationManager::OnWorkerRunLoopStopped() {
68 delete this; 65 delete this;
69 } 66 }
70 67
71 void NotificationManager::show( 68 void NotificationManager::show(
72 const blink::WebSerializedOrigin& origin, 69 const blink::WebSerializedOrigin& origin,
73 const blink::WebNotificationData& notification_data, 70 const blink::WebNotificationData& notification_data,
74 blink::WebNotificationDelegate* delegate) { 71 blink::WebNotificationDelegate* delegate) {
75 if (notification_data.icon.isEmpty()) { 72 if (notification_data.icon.isEmpty()) {
76 DisplayNotification(origin, notification_data, delegate, 73 DisplayPageNotification(origin, notification_data, delegate, SkBitmap());
77 nullptr /* image_loader */);
78 return; 74 return;
79 } 75 }
80 76
81 pending_page_notifications_[delegate] = CreateImageLoader( 77 pending_notifications_.FetchPageNotificationResources(
82 notification_data.icon, 78 notification_data,
83 base::Bind(&NotificationManager::DisplayNotification, 79 delegate,
84 weak_factory_.GetWeakPtr(), 80 base::Bind(&NotificationManager::DisplayPageNotification,
81 base::Unretained(this),
mlamouri (slow - plz ping) 2015/02/18 21:51:58 nit: could you point that you are using base::Unre
Peter Beverloo 2015/02/18 21:57:49 Done.
85 origin, 82 origin,
86 notification_data, 83 notification_data,
87 delegate)); 84 delegate));
88 } 85 }
89 86
90 void NotificationManager::showPersistent( 87 void NotificationManager::showPersistent(
91 const blink::WebSerializedOrigin& origin, 88 const blink::WebSerializedOrigin& origin,
92 const blink::WebNotificationData& notification_data, 89 const blink::WebNotificationData& notification_data,
93 blink::WebServiceWorkerRegistration* service_worker_registration, 90 blink::WebServiceWorkerRegistration* service_worker_registration,
94 blink::WebNotificationShowCallbacks* callbacks) { 91 blink::WebNotificationShowCallbacks* callbacks) {
95 DCHECK(service_worker_registration); 92 DCHECK(service_worker_registration);
96
97 int64 service_worker_registration_id = 93 int64 service_worker_registration_id =
98 static_cast<WebServiceWorkerRegistrationImpl*>( 94 static_cast<WebServiceWorkerRegistrationImpl*>(
99 service_worker_registration)->registration_id(); 95 service_worker_registration)->registration_id();
100 96
101 int request_id = persistent_notification_requests_.Add(callbacks); 97 scoped_ptr<blink::WebNotificationShowCallbacks> owned_callbacks(callbacks);
102 if (notification_data.icon.isEmpty()) { 98 if (notification_data.icon.isEmpty()) {
103 DisplayPersistentNotification(origin, 99 DisplayPersistentNotification(origin,
104 notification_data, 100 notification_data,
105 service_worker_registration_id, 101 service_worker_registration_id,
106 request_id, 102 owned_callbacks.Pass(),
107 nullptr /* image_loader */); 103 SkBitmap());
108 return; 104 return;
109 } 105 }
110 106
111 pending_persistent_notifications_.insert(CreateImageLoader( 107 pending_notifications_.FetchPersistentNotificationResources(
112 notification_data.icon, 108 notification_data,
113 base::Bind(&NotificationManager::DisplayPersistentNotification, 109 base::Bind(&NotificationManager::DisplayPersistentNotification,
114 weak_factory_.GetWeakPtr(), 110 base::Unretained(this),
mlamouri (slow - plz ping) 2015/02/18 21:51:58 ditto.
mlamouri (slow - plz ping) 2015/02/18 21:51:58 ditto.
Peter Beverloo 2015/02/18 21:57:49 Done.
115 origin, 111 origin,
116 notification_data, 112 notification_data,
117 service_worker_registration_id, 113 service_worker_registration_id,
118 request_id))); 114 base::Passed(&owned_callbacks)));
119 } 115 }
120 116
121 void NotificationManager::close(blink::WebNotificationDelegate* delegate) { 117 void NotificationManager::close(blink::WebNotificationDelegate* delegate) {
122 if (RemovePendingPageNotification(delegate)) 118 if (pending_notifications_.CancelPageNotificationFetches(delegate))
123 return; 119 return;
124 120
125 auto iter = active_notifications_.begin(); 121 for (auto& iter : active_page_notifications_) {
126 for (; iter != active_notifications_.end(); ++iter) { 122 if (iter.second != delegate)
127 if (iter->second != delegate)
128 continue; 123 continue;
129 124
130 thread_safe_sender_->Send( 125 thread_safe_sender_->Send(
131 new PlatformNotificationHostMsg_Close(iter->first)); 126 new PlatformNotificationHostMsg_Close(iter.first));
132 active_notifications_.erase(iter); 127 active_page_notifications_.erase(iter.first);
133 return; 128 return;
134 } 129 }
135 130
136 // It should not be possible for Blink to call close() on a Notification which 131 // It should not be possible for Blink to call close() on a Notification which
137 // does not exist anymore in the manager. 132 // does not exist in either the pending or active notification lists.
138 NOTREACHED(); 133 NOTREACHED();
139 } 134 }
140 135
141 void NotificationManager::closePersistent( 136 void NotificationManager::closePersistent(
142 const blink::WebString& persistent_notification_id) { 137 const blink::WebString& persistent_notification_id) {
143 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ClosePersistent( 138 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ClosePersistent(
144 base::UTF16ToUTF8(persistent_notification_id))); 139 base::UTF16ToUTF8(persistent_notification_id)));
145 } 140 }
146 141
147 void NotificationManager::notifyDelegateDestroyed( 142 void NotificationManager::notifyDelegateDestroyed(
148 blink::WebNotificationDelegate* delegate) { 143 blink::WebNotificationDelegate* delegate) {
149 if (RemovePendingPageNotification(delegate)) 144 if (pending_notifications_.CancelPageNotificationFetches(delegate))
150 return; 145 return;
151 146
152 auto iter = active_notifications_.begin(); 147 for (auto& iter : active_page_notifications_) {
153 for (; iter != active_notifications_.end(); ++iter) { 148 if (iter.second != delegate)
154 if (iter->second != delegate)
155 continue; 149 continue;
156 150
157 active_notifications_.erase(iter); 151 active_page_notifications_.erase(iter.first);
158 return; 152 return;
159 } 153 }
160 } 154 }
161 155
162 WebNotificationPermission NotificationManager::checkPermission( 156 WebNotificationPermission NotificationManager::checkPermission(
163 const blink::WebSerializedOrigin& origin) { 157 const blink::WebSerializedOrigin& origin) {
164 WebNotificationPermission permission = 158 WebNotificationPermission permission =
165 blink::WebNotificationPermissionAllowed; 159 blink::WebNotificationPermissionAllowed;
166 thread_safe_sender_->Send(new PlatformNotificationHostMsg_CheckPermission( 160 thread_safe_sender_->Send(new PlatformNotificationHostMsg_CheckPermission(
167 GURL(origin.string()), &permission)); 161 GURL(origin.string()), &permission));
168 162
169 return permission; 163 return permission;
170 } 164 }
171 165
172 bool NotificationManager::OnMessageReceived(const IPC::Message& message) { 166 bool NotificationManager::OnMessageReceived(const IPC::Message& message) {
173 bool handled = true; 167 bool handled = true;
174 IPC_BEGIN_MESSAGE_MAP(NotificationManager, message) 168 IPC_BEGIN_MESSAGE_MAP(NotificationManager, message)
175 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidShow, OnDidShow); 169 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidShow, OnDidShow);
176 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidClose, OnDidClose); 170 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidClose, OnDidClose);
177 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidClick, OnDidClick); 171 IPC_MESSAGE_HANDLER(PlatformNotificationMsg_DidClick, OnDidClick);
178 IPC_MESSAGE_UNHANDLED(handled = false) 172 IPC_MESSAGE_UNHANDLED(handled = false)
179 IPC_END_MESSAGE_MAP() 173 IPC_END_MESSAGE_MAP()
180 174
181 return handled; 175 return handled;
182 } 176 }
183 177
184 void NotificationManager::OnDidShow(int notification_id) { 178 void NotificationManager::OnDidShow(int notification_id) {
185 const auto& iter = active_notifications_.find(notification_id); 179 const auto& iter = active_page_notifications_.find(notification_id);
186 if (iter == active_notifications_.end()) 180 if (iter == active_page_notifications_.end())
187 return; 181 return;
188 182
189 iter->second->dispatchShowEvent(); 183 iter->second->dispatchShowEvent();
190 } 184 }
191 185
192 void NotificationManager::OnDidClose(int notification_id) { 186 void NotificationManager::OnDidClose(int notification_id) {
193 const auto& iter = active_notifications_.find(notification_id); 187 const auto& iter = active_page_notifications_.find(notification_id);
194 if (iter == active_notifications_.end()) 188 if (iter == active_page_notifications_.end())
195 return; 189 return;
196 190
197 iter->second->dispatchCloseEvent(); 191 iter->second->dispatchCloseEvent();
198 active_notifications_.erase(iter); 192 active_page_notifications_.erase(iter);
199 } 193 }
200 194
201 void NotificationManager::OnDidClick(int notification_id) { 195 void NotificationManager::OnDidClick(int notification_id) {
202 const auto& iter = active_notifications_.find(notification_id); 196 const auto& iter = active_page_notifications_.find(notification_id);
203 if (iter == active_notifications_.end()) 197 if (iter == active_page_notifications_.end())
204 return; 198 return;
205 199
206 iter->second->dispatchClickEvent(); 200 iter->second->dispatchClickEvent();
207 } 201 }
208 202
209 scoped_refptr<NotificationImageLoader> NotificationManager::CreateImageLoader( 203 void NotificationManager::DisplayPageNotification(
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, 204 const blink::WebSerializedOrigin& origin,
225 const blink::WebNotificationData& notification_data, 205 const blink::WebNotificationData& notification_data,
226 blink::WebNotificationDelegate* delegate, 206 blink::WebNotificationDelegate* delegate,
227 scoped_refptr<NotificationImageLoader> image_loader) { 207 const SkBitmap& icon) {
228 int notification_id = 208 int notification_id =
229 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId()); 209 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId());
230 210
231 active_notifications_[notification_id] = delegate; 211 active_page_notifications_[notification_id] = delegate;
232
233 SkBitmap icon;
234 if (image_loader)
235 icon = image_loader->GetDecodedImage();
236
237 thread_safe_sender_->Send( 212 thread_safe_sender_->Send(
238 new PlatformNotificationHostMsg_Show( 213 new PlatformNotificationHostMsg_Show(
239 notification_id, 214 notification_id,
240 GURL(origin.string()), 215 GURL(origin.string()),
241 icon, 216 icon,
242 ToPlatformNotificationData(notification_data))); 217 ToPlatformNotificationData(notification_data)));
243
244 // If this Notification contained an icon, it can be safely deleted now.
245 RemovePendingPageNotification(delegate);
246 } 218 }
247 219
248 void NotificationManager::DisplayPersistentNotification( 220 void NotificationManager::DisplayPersistentNotification(
249 const blink::WebSerializedOrigin& origin, 221 const blink::WebSerializedOrigin& origin,
250 const blink::WebNotificationData& notification_data, 222 const blink::WebNotificationData& notification_data,
251 int64 service_worker_registration_id, 223 int64 service_worker_registration_id,
252 int request_id, 224 scoped_ptr<blink::WebNotificationShowCallbacks> callbacks,
253 scoped_refptr<NotificationImageLoader> image_loader) { 225 const SkBitmap& icon) {
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( 226 thread_safe_sender_->Send(
265 new PlatformNotificationHostMsg_ShowPersistent( 227 new PlatformNotificationHostMsg_ShowPersistent(
266 service_worker_registration_id, 228 service_worker_registration_id,
267 GURL(origin.string()), 229 GURL(origin.string()),
268 icon, 230 icon,
269 ToPlatformNotificationData(notification_data))); 231 ToPlatformNotificationData(notification_data)));
270 232
271 // There currently isn't a case in which the promise would be rejected per 233 // There currently isn't a case in which the promise would be rejected per
272 // our implementation, so always resolve it here. 234 // our implementation, so always resolve it here.
273 callbacks->onSuccess(); 235 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 } 236 }
287 237
288 } // namespace content 238 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698