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

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

Issue 1644083002: Fetch notification action icons and pass them through in resources. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@ActionIconBlink
Patch Set: Rebase. Created 4 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 <cmath> 7 #include <cmath>
8 #include <utility> 8 #include <utility>
9 9
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
(...skipping 14 matching lines...) Expand all
25 25
26 using blink::WebNotificationPermission; 26 using blink::WebNotificationPermission;
27 27
28 namespace content { 28 namespace content {
29 namespace { 29 namespace {
30 30
31 int CurrentWorkerId() { 31 int CurrentWorkerId() {
32 return WorkerThread::GetCurrentId(); 32 return WorkerThread::GetCurrentId();
33 } 33 }
34 34
35 // Checks whether |notification_data| specifies any non-empty resources that
36 // need to be fetched.
37 bool HasResourcesToFetch(const blink::WebNotificationData& notification_data) {
38 if (!notification_data.icon.isEmpty())
39 return true;
40 for (const auto& action : notification_data.actions) {
41 if (!action.icon.isEmpty())
42 return true;
43 }
44 return false;
45 }
46
35 } // namespace 47 } // namespace
36 48
37 static base::LazyInstance<base::ThreadLocalPointer<NotificationManager>>::Leaky 49 static base::LazyInstance<base::ThreadLocalPointer<NotificationManager>>::Leaky
38 g_notification_manager_tls = LAZY_INSTANCE_INITIALIZER; 50 g_notification_manager_tls = LAZY_INSTANCE_INITIALIZER;
39 51
40 NotificationManager::NotificationManager( 52 NotificationManager::NotificationManager(
41 ThreadSafeSender* thread_safe_sender, 53 ThreadSafeSender* thread_safe_sender,
42 base::SingleThreadTaskRunner* main_thread_task_runner, 54 base::SingleThreadTaskRunner* main_thread_task_runner,
43 NotificationDispatcher* notification_dispatcher) 55 NotificationDispatcher* notification_dispatcher)
44 : thread_safe_sender_(thread_safe_sender), 56 : thread_safe_sender_(thread_safe_sender),
(...skipping 21 matching lines...) Expand all
66 } 78 }
67 79
68 void NotificationManager::WillStopCurrentWorkerThread() { 80 void NotificationManager::WillStopCurrentWorkerThread() {
69 delete this; 81 delete this;
70 } 82 }
71 83
72 void NotificationManager::show( 84 void NotificationManager::show(
73 const blink::WebSecurityOrigin& origin, 85 const blink::WebSecurityOrigin& origin,
74 const blink::WebNotificationData& notification_data, 86 const blink::WebNotificationData& notification_data,
75 blink::WebNotificationDelegate* delegate) { 87 blink::WebNotificationDelegate* delegate) {
76 if (notification_data.icon.isEmpty()) { 88 DCHECK_EQ(0u, notification_data.actions.size());
89
90 if (!HasResourcesToFetch(notification_data)) {
77 DisplayPageNotification(origin, notification_data, delegate, 91 DisplayPageNotification(origin, notification_data, delegate,
78 NotificationResources()); 92 NotificationResources());
79 return; 93 return;
80 } 94 }
81 95
82 notifications_tracker_.FetchPageNotificationResources( 96 notifications_tracker_.FetchResources(
83 notification_data, delegate, 97 notification_data, delegate,
84 base::Bind(&NotificationManager::DisplayPageNotification, 98 base::Bind(&NotificationManager::DisplayPageNotification,
85 base::Unretained(this), // this owns |notifications_tracker_| 99 base::Unretained(this), // this owns |notifications_tracker_|
86 origin, notification_data, delegate)); 100 origin, notification_data, delegate));
87 } 101 }
88 102
89 void NotificationManager::showPersistent( 103 void NotificationManager::showPersistent(
90 const blink::WebSecurityOrigin& origin, 104 const blink::WebSecurityOrigin& origin,
91 const blink::WebNotificationData& notification_data, 105 const blink::WebNotificationData& notification_data,
92 blink::WebServiceWorkerRegistration* service_worker_registration, 106 blink::WebServiceWorkerRegistration* service_worker_registration,
93 blink::WebNotificationShowCallbacks* callbacks) { 107 blink::WebNotificationShowCallbacks* callbacks) {
94 DCHECK(service_worker_registration); 108 DCHECK(service_worker_registration);
109
95 int64_t service_worker_registration_id = 110 int64_t service_worker_registration_id =
96 static_cast<WebServiceWorkerRegistrationImpl*>( 111 static_cast<WebServiceWorkerRegistrationImpl*>(
97 service_worker_registration) 112 service_worker_registration)
98 ->registration_id(); 113 ->registration_id();
99 114
100 scoped_ptr<blink::WebNotificationShowCallbacks> owned_callbacks(callbacks); 115 scoped_ptr<blink::WebNotificationShowCallbacks> owned_callbacks(callbacks);
101 116
102 // Verify that the author-provided payload size does not exceed our limit. 117 // Verify that the author-provided payload size does not exceed our limit.
103 // This is an implementation-defined limit to prevent abuse of notification 118 // This is an implementation-defined limit to prevent abuse of notification
104 // data as a storage mechanism. A UMA histogram records the requested sizes, 119 // data as a storage mechanism. A UMA histogram records the requested sizes,
105 // which enables us to track how much data authors are attempting to store. 120 // which enables us to track how much data authors are attempting to store.
106 // 121 //
107 // If the size exceeds this limit, reject the showNotification() promise. This 122 // If the size exceeds this limit, reject the showNotification() promise. This
108 // is outside of the boundaries set by the specification, but it gives authors 123 // is outside of the boundaries set by the specification, but it gives authors
109 // an indication that something has gone wrong. 124 // an indication that something has gone wrong.
110 size_t author_data_size = notification_data.data.size(); 125 size_t author_data_size = notification_data.data.size();
111 UMA_HISTOGRAM_MEMORY_KB("Notifications.AuthorDataSizeKB", 126 UMA_HISTOGRAM_MEMORY_KB("Notifications.AuthorDataSizeKB",
112 static_cast<int>(ceil(author_data_size / 1024.0))); 127 static_cast<int>(ceil(author_data_size / 1024.0)));
113 128
114 if (author_data_size > PlatformNotificationData::kMaximumDeveloperDataSize) { 129 if (author_data_size > PlatformNotificationData::kMaximumDeveloperDataSize) {
115 owned_callbacks->onError(); 130 owned_callbacks->onError();
116 return; 131 return;
117 } 132 }
118 133
119 if (notification_data.icon.isEmpty()) { 134 if (!HasResourcesToFetch(notification_data)) {
135 NotificationResources notification_resources;
136
137 // Action indices are expected to have a corresponding icon bitmap, which
138 // may be empty when the developer provided no (or an invalid) icon.
139 if (!notification_data.actions.isEmpty()) {
140 notification_resources.action_icons.resize(
141 notification_data.actions.size());
142 }
143
120 DisplayPersistentNotification( 144 DisplayPersistentNotification(
121 origin, notification_data, service_worker_registration_id, 145 origin, notification_data, service_worker_registration_id,
122 std::move(owned_callbacks), NotificationResources()); 146 std::move(owned_callbacks), notification_resources);
123 return; 147 return;
124 } 148 }
125 149
126 notifications_tracker_.FetchPersistentNotificationResources( 150 notifications_tracker_.FetchResources(
127 notification_data, 151 notification_data, nullptr /* delegate */,
128 base::Bind(&NotificationManager::DisplayPersistentNotification, 152 base::Bind(&NotificationManager::DisplayPersistentNotification,
129 base::Unretained(this), // this owns |notifications_tracker_| 153 base::Unretained(this), // this owns |notifications_tracker_|
130 origin, notification_data, service_worker_registration_id, 154 origin, notification_data, service_worker_registration_id,
131 base::Passed(&owned_callbacks))); 155 base::Passed(&owned_callbacks)));
132 } 156 }
133 157
134 void NotificationManager::getNotifications( 158 void NotificationManager::getNotifications(
135 const blink::WebString& filter_tag, 159 const blink::WebString& filter_tag,
136 blink::WebServiceWorkerRegistration* service_worker_registration, 160 blink::WebServiceWorkerRegistration* service_worker_registration,
137 blink::WebNotificationGetCallbacks* callbacks) { 161 blink::WebNotificationGetCallbacks* callbacks) {
(...skipping 14 matching lines...) Expand all
152 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId()); 176 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId());
153 177
154 pending_get_notification_requests_.AddWithID(callbacks, request_id); 178 pending_get_notification_requests_.AddWithID(callbacks, request_id);
155 179
156 thread_safe_sender_->Send(new PlatformNotificationHostMsg_GetNotifications( 180 thread_safe_sender_->Send(new PlatformNotificationHostMsg_GetNotifications(
157 request_id, service_worker_registration_id, origin, 181 request_id, service_worker_registration_id, origin,
158 base::UTF16ToUTF8(base::StringPiece16(filter_tag)))); 182 base::UTF16ToUTF8(base::StringPiece16(filter_tag))));
159 } 183 }
160 184
161 void NotificationManager::close(blink::WebNotificationDelegate* delegate) { 185 void NotificationManager::close(blink::WebNotificationDelegate* delegate) {
162 if (notifications_tracker_.CancelPageNotificationFetches(delegate)) 186 if (notifications_tracker_.CancelResourceFetches(delegate))
163 return; 187 return;
164 188
165 for (auto& iter : active_page_notifications_) { 189 for (auto& iter : active_page_notifications_) {
166 if (iter.second != delegate) 190 if (iter.second != delegate)
167 continue; 191 continue;
168 192
169 thread_safe_sender_->Send( 193 thread_safe_sender_->Send(
170 new PlatformNotificationHostMsg_Close(iter.first)); 194 new PlatformNotificationHostMsg_Close(iter.first));
171 active_page_notifications_.erase(iter.first); 195 active_page_notifications_.erase(iter.first);
172 return; 196 return;
173 } 197 }
174 198
175 // It should not be possible for Blink to call close() on a Notification which 199 // It should not be possible for Blink to call close() on a Notification which
176 // does not exist in either the pending or active notification lists. 200 // does not exist in either the pending or active notification lists.
177 NOTREACHED(); 201 NOTREACHED();
178 } 202 }
179 203
180 void NotificationManager::closePersistent( 204 void NotificationManager::closePersistent(
181 const blink::WebSecurityOrigin& origin, 205 const blink::WebSecurityOrigin& origin,
182 int64_t persistent_notification_id) { 206 int64_t persistent_notification_id) {
183 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ClosePersistent( 207 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ClosePersistent(
184 // TODO(mkwst): This is potentially doing the wrong thing with unique 208 // TODO(mkwst): This is potentially doing the wrong thing with unique
185 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See 209 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See
186 // https://crbug.com/490074 for detail. 210 // https://crbug.com/490074 for detail.
187 blink::WebStringToGURL(origin.toString()), persistent_notification_id)); 211 blink::WebStringToGURL(origin.toString()), persistent_notification_id));
188 } 212 }
189 213
190 void NotificationManager::notifyDelegateDestroyed( 214 void NotificationManager::notifyDelegateDestroyed(
191 blink::WebNotificationDelegate* delegate) { 215 blink::WebNotificationDelegate* delegate) {
192 if (notifications_tracker_.CancelPageNotificationFetches(delegate)) 216 if (notifications_tracker_.CancelResourceFetches(delegate))
193 return; 217 return;
194 218
195 for (auto& iter : active_page_notifications_) { 219 for (auto& iter : active_page_notifications_) {
196 if (iter.second != delegate) 220 if (iter.second != delegate)
197 continue; 221 continue;
198 222
199 active_page_notifications_.erase(iter.first); 223 active_page_notifications_.erase(iter.first);
200 return; 224 return;
201 } 225 }
202 } 226 }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 callbacks->onSuccess(notifications); 323 callbacks->onSuccess(notifications);
300 324
301 pending_get_notification_requests_.Remove(request_id); 325 pending_get_notification_requests_.Remove(request_id);
302 } 326 }
303 327
304 void NotificationManager::DisplayPageNotification( 328 void NotificationManager::DisplayPageNotification(
305 const blink::WebSecurityOrigin& origin, 329 const blink::WebSecurityOrigin& origin,
306 const blink::WebNotificationData& notification_data, 330 const blink::WebNotificationData& notification_data,
307 blink::WebNotificationDelegate* delegate, 331 blink::WebNotificationDelegate* delegate,
308 const NotificationResources& notification_resources) { 332 const NotificationResources& notification_resources) {
333 DCHECK_EQ(0u, notification_data.actions.size());
334 DCHECK_EQ(0u, notification_resources.action_icons.size());
335
309 int notification_id = 336 int notification_id =
310 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId()); 337 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId());
311 338
312 active_page_notifications_[notification_id] = delegate; 339 active_page_notifications_[notification_id] = delegate;
313 // TODO(mkwst): This is potentially doing the wrong thing with unique 340 // TODO(mkwst): This is potentially doing the wrong thing with unique
314 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See 341 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See
315 // https://crbug.com/490074 for detail. 342 // https://crbug.com/490074 for detail.
316 thread_safe_sender_->Send(new PlatformNotificationHostMsg_Show( 343 thread_safe_sender_->Send(new PlatformNotificationHostMsg_Show(
317 notification_id, blink::WebStringToGURL(origin.toString()), 344 notification_id, blink::WebStringToGURL(origin.toString()),
318 ToPlatformNotificationData(notification_data), notification_resources)); 345 ToPlatformNotificationData(notification_data), notification_resources));
319 } 346 }
320 347
321 void NotificationManager::DisplayPersistentNotification( 348 void NotificationManager::DisplayPersistentNotification(
322 const blink::WebSecurityOrigin& origin, 349 const blink::WebSecurityOrigin& origin,
323 const blink::WebNotificationData& notification_data, 350 const blink::WebNotificationData& notification_data,
324 int64_t service_worker_registration_id, 351 int64_t service_worker_registration_id,
325 scoped_ptr<blink::WebNotificationShowCallbacks> callbacks, 352 scoped_ptr<blink::WebNotificationShowCallbacks> callbacks,
326 const NotificationResources& notification_resources) { 353 const NotificationResources& notification_resources) {
354 DCHECK_EQ(notification_data.actions.size(),
355 notification_resources.action_icons.size());
356
327 // TODO(peter): GenerateNotificationId is more of a request id. Consider 357 // TODO(peter): GenerateNotificationId is more of a request id. Consider
328 // renaming the method in the NotificationDispatcher if this makes sense. 358 // renaming the method in the NotificationDispatcher if this makes sense.
329 int request_id = 359 int request_id =
330 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId()); 360 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId());
331 361
332 pending_show_notification_requests_.AddWithID(callbacks.release(), 362 pending_show_notification_requests_.AddWithID(callbacks.release(),
333 request_id); 363 request_id);
334 364
335 // TODO(mkwst): This is potentially doing the wrong thing with unique 365 // TODO(mkwst): This is potentially doing the wrong thing with unique
336 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See 366 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See
337 // https://crbug.com/490074 for detail. 367 // https://crbug.com/490074 for detail.
338 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ShowPersistent( 368 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ShowPersistent(
339 request_id, service_worker_registration_id, 369 request_id, service_worker_registration_id,
340 blink::WebStringToGURL(origin.toString()), 370 blink::WebStringToGURL(origin.toString()),
341 ToPlatformNotificationData(notification_data), notification_resources)); 371 ToPlatformNotificationData(notification_data), notification_resources));
342 } 372 }
343 373
344 } // namespace content 374 } // namespace content
OLDNEW
« no previous file with comments | « content/child/notifications/notification_image_loader.cc ('k') | content/child/notifications/pending_notification.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698