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

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

Issue 1620203004: Notification action icons prototype. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Make it work on Android and clean up. 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"
11 #include "base/metrics/histogram_macros.h" 11 #include "base/metrics/histogram_macros.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "base/thread_task_runner_handle.h" 13 #include "base/thread_task_runner_handle.h"
14 #include "base/threading/thread_local.h" 14 #include "base/threading/thread_local.h"
15 #include "content/child/notifications/notification_data_conversions.h" 15 #include "content/child/notifications/notification_data_conversions.h"
16 #include "content/child/notifications/notification_dispatcher.h" 16 #include "content/child/notifications/notification_dispatcher.h"
17 #include "content/child/service_worker/web_service_worker_registration_impl.h" 17 #include "content/child/service_worker/web_service_worker_registration_impl.h"
18 #include "content/child/thread_safe_sender.h" 18 #include "content/child/thread_safe_sender.h"
19 #include "content/common/notification_constants.h" 19 #include "content/common/notification_constants.h"
20 #include "content/public/common/notification_resources.h"
20 #include "content/public/common/platform_notification_data.h" 21 #include "content/public/common/platform_notification_data.h"
21 #include "third_party/WebKit/public/platform/URLConversion.h" 22 #include "third_party/WebKit/public/platform/URLConversion.h"
22 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" 23 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
23 #include "third_party/WebKit/public/platform/modules/notifications/WebNotificati onDelegate.h" 24 #include "third_party/WebKit/public/platform/modules/notifications/WebNotificati onDelegate.h"
24 #include "third_party/skia/include/core/SkBitmap.h"
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),
45 notification_dispatcher_(notification_dispatcher), 57 notification_dispatcher_(notification_dispatcher),
46 pending_notifications_(main_thread_task_runner) { 58 notifications_tracker_(main_thread_task_runner) {
47 g_notification_manager_tls.Pointer()->Set(this); 59 g_notification_manager_tls.Pointer()->Set(this);
48 } 60 }
49 61
50 NotificationManager::~NotificationManager() { 62 NotificationManager::~NotificationManager() {
51 g_notification_manager_tls.Pointer()->Set(nullptr); 63 g_notification_manager_tls.Pointer()->Set(nullptr);
52 } 64 }
53 65
54 NotificationManager* NotificationManager::ThreadSpecificInstance( 66 NotificationManager* NotificationManager::ThreadSpecificInstance(
55 ThreadSafeSender* thread_safe_sender, 67 ThreadSafeSender* thread_safe_sender,
56 base::SingleThreadTaskRunner* main_thread_task_runner, 68 base::SingleThreadTaskRunner* main_thread_task_runner,
57 NotificationDispatcher* notification_dispatcher) { 69 NotificationDispatcher* notification_dispatcher) {
58 if (g_notification_manager_tls.Pointer()->Get()) 70 if (g_notification_manager_tls.Pointer()->Get())
59 return g_notification_manager_tls.Pointer()->Get(); 71 return g_notification_manager_tls.Pointer()->Get();
60 72
61 NotificationManager* manager = new NotificationManager( 73 NotificationManager* manager = new NotificationManager(
62 thread_safe_sender, main_thread_task_runner, notification_dispatcher); 74 thread_safe_sender, main_thread_task_runner, notification_dispatcher);
63 if (CurrentWorkerId()) 75 if (CurrentWorkerId())
64 WorkerThread::AddObserver(manager); 76 WorkerThread::AddObserver(manager);
65 return manager; 77 return manager;
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 if (!hasResourcesToFetch(notification_data)) {
77 DisplayPageNotification(origin, notification_data, delegate, SkBitmap()); 89 DisplayPageNotification(origin, notification_data, delegate,
90 NotificationResources());
78 return; 91 return;
79 } 92 }
80 93
81 pending_notifications_.FetchPageNotificationResources( 94 notifications_tracker_.FetchNotificationResources(
82 notification_data, delegate, 95 notification_data, delegate,
83 base::Bind(&NotificationManager::DisplayPageNotification, 96 base::Bind(&NotificationManager::DisplayPageNotification,
84 base::Unretained(this), // this owns |pending_notifications_| 97 base::Unretained(this), // this owns |notifications_tracker_|
85 origin, notification_data, delegate)); 98 origin, notification_data, delegate));
86 } 99 }
87 100
88 void NotificationManager::showPersistent( 101 void NotificationManager::showPersistent(
89 const blink::WebSecurityOrigin& origin, 102 const blink::WebSecurityOrigin& origin,
90 const blink::WebNotificationData& notification_data, 103 const blink::WebNotificationData& notification_data,
91 blink::WebServiceWorkerRegistration* service_worker_registration, 104 blink::WebServiceWorkerRegistration* service_worker_registration,
92 blink::WebNotificationShowCallbacks* callbacks) { 105 blink::WebNotificationShowCallbacks* callbacks) {
93 DCHECK(service_worker_registration); 106 DCHECK(service_worker_registration);
94 int64_t service_worker_registration_id = 107 int64_t service_worker_registration_id =
(...skipping 13 matching lines...) Expand all
108 // an indication that something has gone wrong. 121 // an indication that something has gone wrong.
109 size_t author_data_size = notification_data.data.size(); 122 size_t author_data_size = notification_data.data.size();
110 UMA_HISTOGRAM_MEMORY_KB("Notifications.AuthorDataSizeKB", 123 UMA_HISTOGRAM_MEMORY_KB("Notifications.AuthorDataSizeKB",
111 static_cast<int>(ceil(author_data_size / 1024.0))); 124 static_cast<int>(ceil(author_data_size / 1024.0)));
112 125
113 if (author_data_size > PlatformNotificationData::kMaximumDeveloperDataSize) { 126 if (author_data_size > PlatformNotificationData::kMaximumDeveloperDataSize) {
114 owned_callbacks->onError(); 127 owned_callbacks->onError();
115 return; 128 return;
116 } 129 }
117 130
118 if (notification_data.icon.isEmpty()) { 131 if (!hasResourcesToFetch(notification_data)) {
119 DisplayPersistentNotification(origin, notification_data, 132 NotificationResources notification_resources;
120 service_worker_registration_id, 133 if (!notification_data.actions.isEmpty()) {
121 std::move(owned_callbacks), SkBitmap()); 134 notification_resources.action_icons.resize(
135 notification_data.actions.size());
136 }
137 DisplayPersistentNotification(
138 origin, notification_data, service_worker_registration_id,
139 std::move(owned_callbacks), notification_resources);
122 return; 140 return;
123 } 141 }
124 142
125 pending_notifications_.FetchPersistentNotificationResources( 143 notifications_tracker_.FetchNotificationResources(
126 notification_data, 144 notification_data, nullptr /* delegate */,
127 base::Bind(&NotificationManager::DisplayPersistentNotification, 145 base::Bind(&NotificationManager::DisplayPersistentNotification,
128 base::Unretained(this), // this owns |pending_notifications_| 146 base::Unretained(this), // this owns |notifications_tracker_|
129 origin, notification_data, service_worker_registration_id, 147 origin, notification_data, service_worker_registration_id,
130 base::Passed(&owned_callbacks))); 148 base::Passed(&owned_callbacks)));
131 } 149 }
132 150
133 void NotificationManager::getNotifications( 151 void NotificationManager::getNotifications(
134 const blink::WebString& filter_tag, 152 const blink::WebString& filter_tag,
135 blink::WebServiceWorkerRegistration* service_worker_registration, 153 blink::WebServiceWorkerRegistration* service_worker_registration,
136 blink::WebNotificationGetCallbacks* callbacks) { 154 blink::WebNotificationGetCallbacks* callbacks) {
137 DCHECK(service_worker_registration); 155 DCHECK(service_worker_registration);
138 DCHECK(callbacks); 156 DCHECK(callbacks);
(...skipping 12 matching lines...) Expand all
151 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId()); 169 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId());
152 170
153 pending_get_notification_requests_.AddWithID(callbacks, request_id); 171 pending_get_notification_requests_.AddWithID(callbacks, request_id);
154 172
155 thread_safe_sender_->Send(new PlatformNotificationHostMsg_GetNotifications( 173 thread_safe_sender_->Send(new PlatformNotificationHostMsg_GetNotifications(
156 request_id, service_worker_registration_id, origin, 174 request_id, service_worker_registration_id, origin,
157 base::UTF16ToUTF8(base::StringPiece16(filter_tag)))); 175 base::UTF16ToUTF8(base::StringPiece16(filter_tag))));
158 } 176 }
159 177
160 void NotificationManager::close(blink::WebNotificationDelegate* delegate) { 178 void NotificationManager::close(blink::WebNotificationDelegate* delegate) {
161 if (pending_notifications_.CancelPageNotificationFetches(delegate)) 179 if (notifications_tracker_.CancelResourceFetches(delegate))
162 return; 180 return;
163 181
164 for (auto& iter : active_page_notifications_) { 182 for (auto& iter : active_page_notifications_) {
165 if (iter.second != delegate) 183 if (iter.second != delegate)
166 continue; 184 continue;
167 185
168 thread_safe_sender_->Send( 186 thread_safe_sender_->Send(
169 new PlatformNotificationHostMsg_Close(iter.first)); 187 new PlatformNotificationHostMsg_Close(iter.first));
170 active_page_notifications_.erase(iter.first); 188 active_page_notifications_.erase(iter.first);
171 return; 189 return;
172 } 190 }
173 191
174 // It should not be possible for Blink to call close() on a Notification which 192 // It should not be possible for Blink to call close() on a Notification which
175 // does not exist in either the pending or active notification lists. 193 // does not exist in either the pending or active notification lists.
176 NOTREACHED(); 194 NOTREACHED();
177 } 195 }
178 196
179 void NotificationManager::closePersistent( 197 void NotificationManager::closePersistent(
180 const blink::WebSecurityOrigin& origin, 198 const blink::WebSecurityOrigin& origin,
181 int64_t persistent_notification_id) { 199 int64_t persistent_notification_id) {
182 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ClosePersistent( 200 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ClosePersistent(
183 // TODO(mkwst): This is potentially doing the wrong thing with unique 201 // TODO(mkwst): This is potentially doing the wrong thing with unique
184 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See 202 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See
185 // https://crbug.com/490074 for detail. 203 // https://crbug.com/490074 for detail.
186 blink::WebStringToGURL(origin.toString()), persistent_notification_id)); 204 blink::WebStringToGURL(origin.toString()), persistent_notification_id));
187 } 205 }
188 206
189 void NotificationManager::notifyDelegateDestroyed( 207 void NotificationManager::notifyDelegateDestroyed(
190 blink::WebNotificationDelegate* delegate) { 208 blink::WebNotificationDelegate* delegate) {
191 if (pending_notifications_.CancelPageNotificationFetches(delegate)) 209 if (notifications_tracker_.CancelResourceFetches(delegate))
192 return; 210 return;
193 211
194 for (auto& iter : active_page_notifications_) { 212 for (auto& iter : active_page_notifications_) {
195 if (iter.second != delegate) 213 if (iter.second != delegate)
196 continue; 214 continue;
197 215
198 active_page_notifications_.erase(iter.first); 216 active_page_notifications_.erase(iter.first);
199 return; 217 return;
200 } 218 }
201 } 219 }
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 315
298 callbacks->onSuccess(notifications); 316 callbacks->onSuccess(notifications);
299 317
300 pending_get_notification_requests_.Remove(request_id); 318 pending_get_notification_requests_.Remove(request_id);
301 } 319 }
302 320
303 void NotificationManager::DisplayPageNotification( 321 void NotificationManager::DisplayPageNotification(
304 const blink::WebSecurityOrigin& origin, 322 const blink::WebSecurityOrigin& origin,
305 const blink::WebNotificationData& notification_data, 323 const blink::WebNotificationData& notification_data,
306 blink::WebNotificationDelegate* delegate, 324 blink::WebNotificationDelegate* delegate,
307 const SkBitmap& icon) { 325 const NotificationResources& notification_resources) {
326 DCHECK_EQ(notification_data.actions.size(), 0u);
327 DCHECK_EQ(notification_resources.action_icons.size(), 0u);
328
308 int notification_id = 329 int notification_id =
309 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId()); 330 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId());
310 331
311 active_page_notifications_[notification_id] = delegate; 332 active_page_notifications_[notification_id] = delegate;
312 // TODO(mkwst): This is potentially doing the wrong thing with unique 333 // TODO(mkwst): This is potentially doing the wrong thing with unique
313 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See 334 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See
314 // https://crbug.com/490074 for detail. 335 // https://crbug.com/490074 for detail.
315 thread_safe_sender_->Send(new PlatformNotificationHostMsg_Show( 336 thread_safe_sender_->Send(new PlatformNotificationHostMsg_Show(
316 notification_id, blink::WebStringToGURL(origin.toString()), icon, 337 notification_id, blink::WebStringToGURL(origin.toString()),
317 ToPlatformNotificationData(notification_data))); 338 ToPlatformNotificationData(notification_data), notification_resources));
318 } 339 }
319 340
320 void NotificationManager::DisplayPersistentNotification( 341 void NotificationManager::DisplayPersistentNotification(
321 const blink::WebSecurityOrigin& origin, 342 const blink::WebSecurityOrigin& origin,
322 const blink::WebNotificationData& notification_data, 343 const blink::WebNotificationData& notification_data,
323 int64_t service_worker_registration_id, 344 int64_t service_worker_registration_id,
324 scoped_ptr<blink::WebNotificationShowCallbacks> callbacks, 345 scoped_ptr<blink::WebNotificationShowCallbacks> callbacks,
325 const SkBitmap& icon) { 346 const NotificationResources& notification_resources) {
347 DCHECK_EQ(notification_data.actions.size(),
348 notification_resources.action_icons.size());
349
326 // TODO(peter): GenerateNotificationId is more of a request id. Consider 350 // TODO(peter): GenerateNotificationId is more of a request id. Consider
327 // renaming the method in the NotificationDispatcher if this makes sense. 351 // renaming the method in the NotificationDispatcher if this makes sense.
328 int request_id = 352 int request_id =
329 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId()); 353 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId());
330 354
331 pending_show_notification_requests_.AddWithID(callbacks.release(), 355 pending_show_notification_requests_.AddWithID(callbacks.release(),
332 request_id); 356 request_id);
333 357
334 // TODO(mkwst): This is potentially doing the wrong thing with unique 358 // TODO(mkwst): This is potentially doing the wrong thing with unique
335 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See 359 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See
336 // https://crbug.com/490074 for detail. 360 // https://crbug.com/490074 for detail.
337 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ShowPersistent( 361 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ShowPersistent(
338 request_id, service_worker_registration_id, 362 request_id, service_worker_registration_id,
339 blink::WebStringToGURL(origin.toString()), icon, 363 blink::WebStringToGURL(origin.toString()),
340 ToPlatformNotificationData(notification_data))); 364 ToPlatformNotificationData(notification_data), notification_resources));
341 } 365 }
342 366
343 } // namespace content 367 } // namespace content
OLDNEW
« no previous file with comments | « content/child/notifications/notification_manager.h ('k') | content/child/notifications/pending_notification.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698