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

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

Issue 1847863002: Move notification resource loading from content/child to blink (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: ImageFrame::getSkBitmap was removed. Created 4 years, 8 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 <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"
11 #include "base/strings/utf_string_conversions.h" 11 #include "base/strings/utf_string_conversions.h"
12 #include "base/thread_task_runner_handle.h"
13 #include "base/threading/thread_local.h" 12 #include "base/threading/thread_local.h"
14 #include "content/child/notifications/notification_data_conversions.h" 13 #include "content/child/notifications/notification_data_conversions.h"
15 #include "content/child/notifications/notification_dispatcher.h" 14 #include "content/child/notifications/notification_dispatcher.h"
16 #include "content/child/service_worker/web_service_worker_registration_impl.h" 15 #include "content/child/service_worker/web_service_worker_registration_impl.h"
17 #include "content/child/thread_safe_sender.h" 16 #include "content/child/thread_safe_sender.h"
18 #include "content/common/notification_constants.h" 17 #include "content/common/notification_constants.h"
19 #include "content/public/common/notification_resources.h" 18 #include "content/public/common/notification_resources.h"
20 #include "content/public/common/platform_notification_data.h" 19 #include "content/public/common/platform_notification_data.h"
21 #include "third_party/WebKit/public/platform/URLConversion.h" 20 #include "third_party/WebKit/public/platform/URLConversion.h"
22 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h" 21 #include "third_party/WebKit/public/platform/WebSecurityOrigin.h"
23 #include "third_party/WebKit/public/platform/modules/notifications/WebNotificati onDelegate.h" 22 #include "third_party/WebKit/public/platform/modules/notifications/WebNotificati onDelegate.h"
24 23
25 using blink::WebNotificationPermission; 24 using blink::WebNotificationPermission;
26 25
27 namespace content { 26 namespace content {
28 namespace { 27 namespace {
29 28
30 int CurrentWorkerId() { 29 int CurrentWorkerId() {
31 return WorkerThread::GetCurrentId(); 30 return WorkerThread::GetCurrentId();
32 } 31 }
33 32
34 // Checks whether |notification_data| specifies any non-empty resources that 33 NotificationResources ToNotificationResources(
35 // need to be fetched. 34 std::unique_ptr<blink::WebNotificationResources> web_resources) {
36 bool HasResourcesToFetch(const blink::WebNotificationData& notification_data) { 35 NotificationResources resources;
37 if (!notification_data.icon.isEmpty()) 36 resources.notification_icon = web_resources->icon;
38 return true; 37 resources.badge = web_resources->badge;
39 if (!notification_data.badge.isEmpty()) 38 for (const auto& action_icon : web_resources->actionIcons)
40 return true; 39 resources.action_icons.push_back(action_icon);
41 for (const auto& action : notification_data.actions) { 40 return resources;
42 if (!action.icon.isEmpty())
43 return true;
44 }
45 return false;
46 } 41 }
47 42
48 } // namespace 43 } // namespace
49 44
50 static base::LazyInstance<base::ThreadLocalPointer<NotificationManager>>::Leaky 45 static base::LazyInstance<base::ThreadLocalPointer<NotificationManager>>::Leaky
51 g_notification_manager_tls = LAZY_INSTANCE_INITIALIZER; 46 g_notification_manager_tls = LAZY_INSTANCE_INITIALIZER;
52 47
53 NotificationManager::NotificationManager( 48 NotificationManager::NotificationManager(
54 ThreadSafeSender* thread_safe_sender, 49 ThreadSafeSender* thread_safe_sender,
55 base::SingleThreadTaskRunner* main_thread_task_runner,
56 NotificationDispatcher* notification_dispatcher) 50 NotificationDispatcher* notification_dispatcher)
57 : thread_safe_sender_(thread_safe_sender), 51 : thread_safe_sender_(thread_safe_sender),
58 notification_dispatcher_(notification_dispatcher), 52 notification_dispatcher_(notification_dispatcher) {
59 notifications_tracker_(main_thread_task_runner) {
60 g_notification_manager_tls.Pointer()->Set(this); 53 g_notification_manager_tls.Pointer()->Set(this);
61 } 54 }
62 55
63 NotificationManager::~NotificationManager() { 56 NotificationManager::~NotificationManager() {
64 g_notification_manager_tls.Pointer()->Set(nullptr); 57 g_notification_manager_tls.Pointer()->Set(nullptr);
65 } 58 }
66 59
67 NotificationManager* NotificationManager::ThreadSpecificInstance( 60 NotificationManager* NotificationManager::ThreadSpecificInstance(
68 ThreadSafeSender* thread_safe_sender, 61 ThreadSafeSender* thread_safe_sender,
69 base::SingleThreadTaskRunner* main_thread_task_runner,
70 NotificationDispatcher* notification_dispatcher) { 62 NotificationDispatcher* notification_dispatcher) {
71 if (g_notification_manager_tls.Pointer()->Get()) 63 if (g_notification_manager_tls.Pointer()->Get())
72 return g_notification_manager_tls.Pointer()->Get(); 64 return g_notification_manager_tls.Pointer()->Get();
73 65
74 NotificationManager* manager = new NotificationManager( 66 NotificationManager* manager =
75 thread_safe_sender, main_thread_task_runner, notification_dispatcher); 67 new NotificationManager(thread_safe_sender, notification_dispatcher);
76 if (CurrentWorkerId()) 68 if (CurrentWorkerId())
77 WorkerThread::AddObserver(manager); 69 WorkerThread::AddObserver(manager);
78 return manager; 70 return manager;
79 } 71 }
80 72
81 void NotificationManager::WillStopCurrentWorkerThread() { 73 void NotificationManager::WillStopCurrentWorkerThread() {
82 delete this; 74 delete this;
83 } 75 }
84 76
85 void NotificationManager::show( 77 void NotificationManager::show(
86 const blink::WebSecurityOrigin& origin, 78 const blink::WebSecurityOrigin& origin,
87 const blink::WebNotificationData& notification_data, 79 const blink::WebNotificationData& notification_data,
80 std::unique_ptr<blink::WebNotificationResources> notification_resources,
88 blink::WebNotificationDelegate* delegate) { 81 blink::WebNotificationDelegate* delegate) {
89 DCHECK_EQ(0u, notification_data.actions.size()); 82 DCHECK_EQ(0u, notification_data.actions.size());
90 83
91 if (!HasResourcesToFetch(notification_data)) { 84 DisplayPageNotification(
Peter Beverloo 2016/04/13 18:32:27 Can we coalesce that method into this one now? Dit
Michael van Ouwerkerk 2016/04/14 13:42:11 Done.
92 DisplayPageNotification(origin, notification_data, delegate, 85 origin, notification_data, delegate,
93 NotificationResources()); 86 ToNotificationResources(std::move(notification_resources)));
94 return;
95 }
96
97 notifications_tracker_.FetchResources(
98 notification_data, delegate,
99 base::Bind(&NotificationManager::DisplayPageNotification,
100 base::Unretained(this), // this owns |notifications_tracker_|
101 origin, notification_data, delegate));
102 } 87 }
103 88
104 void NotificationManager::showPersistent( 89 void NotificationManager::showPersistent(
105 const blink::WebSecurityOrigin& origin, 90 const blink::WebSecurityOrigin& origin,
106 const blink::WebNotificationData& notification_data, 91 const blink::WebNotificationData& notification_data,
92 std::unique_ptr<blink::WebNotificationResources> notification_resources,
107 blink::WebServiceWorkerRegistration* service_worker_registration, 93 blink::WebServiceWorkerRegistration* service_worker_registration,
108 blink::WebNotificationShowCallbacks* callbacks) { 94 blink::WebNotificationShowCallbacks* callbacks) {
109 DCHECK(service_worker_registration); 95 DCHECK(service_worker_registration);
110 96
111 int64_t service_worker_registration_id = 97 int64_t service_worker_registration_id =
112 static_cast<WebServiceWorkerRegistrationImpl*>( 98 static_cast<WebServiceWorkerRegistrationImpl*>(
113 service_worker_registration) 99 service_worker_registration)
114 ->registration_id(); 100 ->registration_id();
115 101
116 std::unique_ptr<blink::WebNotificationShowCallbacks> owned_callbacks( 102 std::unique_ptr<blink::WebNotificationShowCallbacks> owned_callbacks(
117 callbacks); 103 callbacks);
118 104
119 // Verify that the author-provided payload size does not exceed our limit. 105 // Verify that the author-provided payload size does not exceed our limit.
120 // This is an implementation-defined limit to prevent abuse of notification 106 // This is an implementation-defined limit to prevent abuse of notification
121 // data as a storage mechanism. A UMA histogram records the requested sizes, 107 // data as a storage mechanism. A UMA histogram records the requested sizes,
122 // which enables us to track how much data authors are attempting to store. 108 // which enables us to track how much data authors are attempting to store.
123 // 109 //
124 // If the size exceeds this limit, reject the showNotification() promise. This 110 // If the size exceeds this limit, reject the showNotification() promise. This
125 // is outside of the boundaries set by the specification, but it gives authors 111 // is outside of the boundaries set by the specification, but it gives authors
126 // an indication that something has gone wrong. 112 // an indication that something has gone wrong.
127 size_t author_data_size = notification_data.data.size(); 113 size_t author_data_size = notification_data.data.size();
128 114
129 UMA_HISTOGRAM_COUNTS_1000("Notifications.AuthorDataSize", author_data_size); 115 UMA_HISTOGRAM_COUNTS_1000("Notifications.AuthorDataSize", author_data_size);
130 116
131 if (author_data_size > PlatformNotificationData::kMaximumDeveloperDataSize) { 117 if (author_data_size > PlatformNotificationData::kMaximumDeveloperDataSize) {
132 owned_callbacks->onError(); 118 owned_callbacks->onError();
133 return; 119 return;
134 } 120 }
135 121
136 if (!HasResourcesToFetch(notification_data)) { 122 DisplayPersistentNotification(
137 NotificationResources notification_resources; 123 origin, notification_data, service_worker_registration_id,
138 124 std::move(owned_callbacks),
139 // Action indices are expected to have a corresponding icon bitmap, which 125 ToNotificationResources(std::move(notification_resources)));
140 // may be empty when the developer provided no (or an invalid) icon.
141 if (!notification_data.actions.isEmpty()) {
142 notification_resources.action_icons.resize(
143 notification_data.actions.size());
144 }
145
146 DisplayPersistentNotification(
147 origin, notification_data, service_worker_registration_id,
148 std::move(owned_callbacks), notification_resources);
149 return;
150 }
151
152 notifications_tracker_.FetchResources(
153 notification_data, nullptr /* delegate */,
154 base::Bind(&NotificationManager::DisplayPersistentNotification,
155 base::Unretained(this), // this owns |notifications_tracker_|
156 origin, notification_data, service_worker_registration_id,
157 base::Passed(&owned_callbacks)));
158 } 126 }
159 127
160 void NotificationManager::getNotifications( 128 void NotificationManager::getNotifications(
161 const blink::WebString& filter_tag, 129 const blink::WebString& filter_tag,
162 blink::WebServiceWorkerRegistration* service_worker_registration, 130 blink::WebServiceWorkerRegistration* service_worker_registration,
163 blink::WebNotificationGetCallbacks* callbacks) { 131 blink::WebNotificationGetCallbacks* callbacks) {
164 DCHECK(service_worker_registration); 132 DCHECK(service_worker_registration);
165 DCHECK(callbacks); 133 DCHECK(callbacks);
166 134
167 WebServiceWorkerRegistrationImpl* service_worker_registration_impl = 135 WebServiceWorkerRegistrationImpl* service_worker_registration_impl =
(...skipping 10 matching lines...) Expand all
178 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId()); 146 notification_dispatcher_->GenerateNotificationId(CurrentWorkerId());
179 147
180 pending_get_notification_requests_.AddWithID(callbacks, request_id); 148 pending_get_notification_requests_.AddWithID(callbacks, request_id);
181 149
182 thread_safe_sender_->Send(new PlatformNotificationHostMsg_GetNotifications( 150 thread_safe_sender_->Send(new PlatformNotificationHostMsg_GetNotifications(
183 request_id, service_worker_registration_id, origin, 151 request_id, service_worker_registration_id, origin,
184 base::UTF16ToUTF8(base::StringPiece16(filter_tag)))); 152 base::UTF16ToUTF8(base::StringPiece16(filter_tag))));
185 } 153 }
186 154
187 void NotificationManager::close(blink::WebNotificationDelegate* delegate) { 155 void NotificationManager::close(blink::WebNotificationDelegate* delegate) {
188 if (notifications_tracker_.CancelResourceFetches(delegate))
189 return;
190
191 for (auto& iter : active_page_notifications_) { 156 for (auto& iter : active_page_notifications_) {
192 if (iter.second != delegate) 157 if (iter.second != delegate)
193 continue; 158 continue;
194 159
195 thread_safe_sender_->Send( 160 thread_safe_sender_->Send(
196 new PlatformNotificationHostMsg_Close(iter.first)); 161 new PlatformNotificationHostMsg_Close(iter.first));
197 active_page_notifications_.erase(iter.first); 162 active_page_notifications_.erase(iter.first);
198 return; 163 return;
199 } 164 }
200 165
201 // It should not be possible for Blink to call close() on a Notification which 166 // It should not be possible for Blink to call close() on a Notification which
202 // does not exist in either the pending or active notification lists. 167 // does not exist in either the pending or active notification lists.
203 NOTREACHED(); 168 NOTREACHED();
204 } 169 }
205 170
206 void NotificationManager::closePersistent( 171 void NotificationManager::closePersistent(
207 const blink::WebSecurityOrigin& origin, 172 const blink::WebSecurityOrigin& origin,
208 int64_t persistent_notification_id) { 173 int64_t persistent_notification_id) {
209 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ClosePersistent( 174 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ClosePersistent(
210 // TODO(mkwst): This is potentially doing the wrong thing with unique 175 // TODO(mkwst): This is potentially doing the wrong thing with unique
211 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See 176 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See
212 // https://crbug.com/490074 for detail. 177 // https://crbug.com/490074 for detail.
213 blink::WebStringToGURL(origin.toString()), persistent_notification_id)); 178 blink::WebStringToGURL(origin.toString()), persistent_notification_id));
214 } 179 }
215 180
216 void NotificationManager::notifyDelegateDestroyed( 181 void NotificationManager::notifyDelegateDestroyed(
217 blink::WebNotificationDelegate* delegate) { 182 blink::WebNotificationDelegate* delegate) {
218 if (notifications_tracker_.CancelResourceFetches(delegate))
219 return;
220
221 for (auto& iter : active_page_notifications_) { 183 for (auto& iter : active_page_notifications_) {
222 if (iter.second != delegate) 184 if (iter.second != delegate)
223 continue; 185 continue;
224 186
225 active_page_notifications_.erase(iter.first); 187 active_page_notifications_.erase(iter.first);
226 return; 188 return;
227 } 189 }
228 } 190 }
229 191
230 WebNotificationPermission NotificationManager::checkPermission( 192 WebNotificationPermission NotificationManager::checkPermission(
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 // TODO(mkwst): This is potentially doing the wrong thing with unique 329 // TODO(mkwst): This is potentially doing the wrong thing with unique
368 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See 330 // origins. Perhaps also 'file:', 'blob:' and 'filesystem:'. See
369 // https://crbug.com/490074 for detail. 331 // https://crbug.com/490074 for detail.
370 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ShowPersistent( 332 thread_safe_sender_->Send(new PlatformNotificationHostMsg_ShowPersistent(
371 request_id, service_worker_registration_id, 333 request_id, service_worker_registration_id,
372 blink::WebStringToGURL(origin.toString()), 334 blink::WebStringToGURL(origin.toString()),
373 ToPlatformNotificationData(notification_data), notification_resources)); 335 ToPlatformNotificationData(notification_data), notification_resources));
374 } 336 }
375 337
376 } // namespace content 338 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698