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

Side by Side Diff: content/browser/notifications/blink_notification_service_impl.cc

Issue 1904163002: Move Web Notifications to use Mojo Base URL: https://chromium.googlesource.com/chromium/src.git@skbitmap-blink
Patch Set: it works \o/ Created 4 years, 7 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
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/browser/notifications/blink_notification_service_impl.h"
6
7 #include "base/logging.h"
8 #include "base/strings/string_number_conversions.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "content/browser/notifications/notification_id_generator.h"
11 #include "content/browser/notifications/page_notification_delegate.h"
12 #include "content/browser/notifications/platform_notification_context_impl.h"
13 #include "content/browser/notifications/type_converters.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "content/public/browser/content_browser_client.h"
16 #include "content/public/browser/notification_database_data.h"
17 #include "content/public/browser/platform_notification_service.h"
18 #include "content/public/common/content_client.h"
19 #include "content/public/common/notification_resources.h"
20 #include "content/public/common/platform_notification_data.h"
21 #include "skia/public/type_converters.h"
22 #include "third_party/WebKit/public/platform/modules/permissions/permission_stat us.mojom.h"
23 #include "url/gurl.h"
24
25 namespace content {
26
27 namespace {
28
29 // Returns the implementation of the PlatformNotificationService. May be NULL.
30 PlatformNotificationService* service() {
31 return GetContentClient()->browser()->GetPlatformNotificationService();
32 }
33
34 // Displays a non-persistent notification with the given information on the UI
35 // thread. The close closure will be written to |*close_closure|.
36 void DisplayNonPersistentNotificationOnUI(
37 BrowserContext* browser_context,
38 const GURL& origin,
39 blink::mojom::NotificationPtr notification,
40 blink::mojom::NotificationResourcesPtr notification_resources,
41 blink::mojom::NotificationClientPtrInfo notification_client_info,
42 base::Closure* close_closure) {
43 DCHECK_CURRENTLY_ON(BrowserThread::UI);
44 blink::mojom::NotificationClientPtr notification_client =
45 mojo::MakeProxy(std::move(notification_client_info));
46
47 std::unique_ptr<PageNotificationDelegate> delegate(
48 new PageNotificationDelegate(std::move(notification_client)));
49
50 // TODO(peter): Use the |notification_id| when showing a notification.
51 service()->DisplayNotification(
52 browser_context, origin, notification.To<PlatformNotificationData>(),
53 notification_resources.To<NotificationResources>(), std::move(delegate),
54 close_closure);
55
56 DCHECK(!close_closure->is_null());
57 }
58
59 } // namespace
60
61 BlinkNotificationServiceImpl::BlinkNotificationServiceImpl(
62 PlatformNotificationContextImpl* notification_context,
63 BrowserContext* browser_context,
64 ResourceContext* resource_context,
65 int render_process_id,
66 mojo::InterfaceRequest<blink::mojom::NotificationService> request)
67 : notification_context_(notification_context),
68 browser_context_(browser_context),
69 resource_context_(resource_context),
70 render_process_id_(render_process_id),
71 binding_(this, std::move(request)),
72 weak_ptr_factory_(this) {
73 DCHECK_CURRENTLY_ON(BrowserThread::IO);
74 DCHECK(notification_context_);
75 DCHECK(browser_context_);
76
77 notification_id_generator_.reset(
78 new NotificationIdGenerator(browser_context_, render_process_id_));
79
80 binding_.set_connection_error_handler(
81 base::Bind(&BlinkNotificationServiceImpl::OnConnectionError,
82 base::Unretained(this) /* the channel is owned by this */));
83 }
84
85 BlinkNotificationServiceImpl::~BlinkNotificationServiceImpl() {
86 DCHECK_CURRENTLY_ON(BrowserThread::IO);
87 }
88
89 void BlinkNotificationServiceImpl::GetPermissionStatus(
90 const mojo::String& origin,
91 const GetPermissionStatusCallback& callback) {
92 DCHECK_CURRENTLY_ON(BrowserThread::IO);
93
94 if (!service()) {
95 callback.Run(blink::mojom::PermissionStatus::DENIED);
96 return;
97 }
98
99 blink::mojom::PermissionStatus permission_status =
100 service()->CheckPermissionOnIOThread(
101 resource_context_, GURL(origin.get()), render_process_id_);
102
103 callback.Run(permission_status);
104 }
105
106 void BlinkNotificationServiceImpl::Display(
107 const mojo::String& origin,
108 blink::mojom::NotificationPtr notification,
109 blink::mojom::NotificationResourcesPtr notification_resources,
110 blink::mojom::NotificationClientPtr notification_client,
111 const DisplayCallback& callback) {
112 DCHECK_CURRENTLY_ON(BrowserThread::IO);
113 DCHECK(service()); // TODO: This should be BadMessage?
114
115 // TODO(peter): Verify the notification's data and that permission has been
116 // granted for the given |origin|.
117
118 GURL origin_url(origin.get());
119
120 std::string notification_id =
121 notification_id_generator_->GenerateForNonPersistentNotification(
122 origin_url, notification->tag, ++non_persistent_notification_id_);
123
124 LOG(ERROR) << "Notification Id: " << notification_id;
125
126 std::unique_ptr<base::Closure> close_closure(new base::Closure());
127
128 BrowserThread::PostTaskAndReply(
129 BrowserThread::UI, FROM_HERE,
130 base::Bind(&DisplayNonPersistentNotificationOnUI, browser_context_,
131 origin_url, base::Passed(&notification),
132 base::Passed(&notification_resources),
133 base::Passed(notification_client.PassInterface()),
134 base::Unretained(close_closure.get())),
135 base::Bind(&BlinkNotificationServiceImpl::DidDisplay,
136 weak_ptr_factory_.GetWeakPtr(), notification_id,
137 base::Passed(std::move(close_closure)), callback));
138 }
139
140 void BlinkNotificationServiceImpl::DidDisplay(
141 const std::string& notification_id,
142 std::unique_ptr<base::Closure> close_closure,
143 const DisplayCallback& callback) {
144 DCHECK_CURRENTLY_ON(BrowserThread::IO);
145
146 close_closures_[notification_id] = *close_closure;
147
148 callback.Run(blink::mojom::NotificationDisplayResult::SUCCESS,
149 notification_id);
150 }
151
152 void BlinkNotificationServiceImpl::DisplayPersistent(
153 const mojo::String& origin,
154 int64_t service_worker_registration_id,
155 blink::mojom::NotificationPtr notification,
156 blink::mojom::NotificationResourcesPtr notification_resources,
157 const DisplayPersistentCallback& callback) {
158 DCHECK_CURRENTLY_ON(BrowserThread::IO);
159 DCHECK(service()); // TODO: This should be BadMessage?
160
161 // TODO(peter): Verify the notification's data and that permission has been
162 // granted for the given |origin|.
163
164 GURL origin_url(origin.get());
165
166 NotificationDatabaseData database_data;
167 database_data.origin = origin_url;
168 database_data.service_worker_registration_id = service_worker_registration_id;
169 database_data.notification_data = notification.To<PlatformNotificationData>();
170
171 notification_context_->WriteNotificationData(
172 origin_url, database_data,
173 base::Bind(&BlinkNotificationServiceImpl::DidStorePersistent,
174 weak_ptr_factory_.GetWeakPtr(), origin_url,
175 base::Passed(&notification),
176 base::Passed(&notification_resources), callback));
177 }
178
179 void BlinkNotificationServiceImpl::DidStorePersistent(
180 const GURL& origin,
181 blink::mojom::NotificationPtr notification,
182 blink::mojom::NotificationResourcesPtr notification_resources,
183 const DisplayPersistentCallback& callback,
184 bool success,
185 int64_t persistent_notification_id) {
186 DCHECK_CURRENTLY_ON(BrowserThread::IO);
187
188 if (!success) {
189 callback.Run(blink::mojom::NotificationDisplayResult::FAILED_STORAGE_ERROR);
190 return;
191 }
192
193 // TODO(peter): Send an Id generated by the NotificationIdGenerator to the
194 // service rather than the integral database id.
195 BrowserThread::PostTask(
196 BrowserThread::UI, FROM_HERE,
197 base::Bind(&PlatformNotificationService::DisplayPersistentNotification,
198 base::Unretained(service()), browser_context_,
199 persistent_notification_id, origin,
200 notification.To<PlatformNotificationData>(),
201 notification_resources.To<NotificationResources>()));
202
203 callback.Run(blink::mojom::NotificationDisplayResult::SUCCESS);
204 }
205
206 void BlinkNotificationServiceImpl::GetNotifications(
207 const mojo::String& origin,
208 int64_t service_worker_registration_id,
209 const mojo::String& tag,
210 const GetNotificationsCallback& callback) {
211 DCHECK_CURRENTLY_ON(BrowserThread::IO);
212
213 // TODO(peter): If no permission has been granted, invoke |callback| quickly
214 // with an empty Mojo array and avoid hitting the database.
215
216 GURL origin_url(origin.get());
217
218 notification_context_->ReadAllNotificationDataForServiceWorkerRegistration(
219 origin_url, service_worker_registration_id,
220 base::Bind(&BlinkNotificationServiceImpl::DidGetNotifications,
221 weak_ptr_factory_.GetWeakPtr(), tag.get(), callback));
222 }
223
224 void BlinkNotificationServiceImpl::DidGetNotifications(
225 const std::string& tag,
226 const GetNotificationsCallback& callback,
227 bool success,
228 const std::vector<NotificationDatabaseData>& notifications) {
229 DCHECK_CURRENTLY_ON(BrowserThread::IO);
230
231 if (!success) {
232 callback.Run(mojo::Array<blink::mojom::NotificationPtr>());
233 return;
234 }
235
236 mojo::Array<blink::mojom::NotificationPtr> mojo_notifications;
237
238 for (const auto& notification : notifications) {
239 if (!tag.empty() && notification.notification_data.tag != tag)
240 continue;
241
242 blink::mojom::NotificationPtr mojo_notification =
243 blink::mojom::Notification::From(notification.notification_data);
244
245 // TODO(peter): Use the NotificationIdGenerator when the database has been
246 // taught to work with these identifiers rather than the current numbers.
247 mojo_notification->id = base::Int64ToString(notification.notification_id);
248
249 mojo_notifications.push_back(std::move(mojo_notification));
250 }
251
252 callback.Run(std::move(mojo_notifications));
253 }
254
255 void BlinkNotificationServiceImpl::Close(const mojo::String& origin,
256 const mojo::String& notification_id,
257 const CloseCallback& callback) {
258 DCHECK_CURRENTLY_ON(BrowserThread::IO);
259 DCHECK(service()); // TODO: This should be BadMessage?
260
261 // TODO(peter): Do the necessary permission checks.
262
263 const std::string id = notification_id.get();
264
265 int64_t persistent_notification_id = 0;
266
267 // TODO(peter): Use NotificationIdGenerator::IsPersistentNotification when
268 // the notification system is in charge of generating its own ids.
269 if (base::StringToInt64(notification_id.get(), &persistent_notification_id)) {
270 // There's no point in waiting until the database has been updated before
271 // closing the notification presented to the user.
272 BrowserThread::PostTask(
273 BrowserThread::UI, FROM_HERE,
274 base::Bind(&PlatformNotificationService::ClosePersistentNotification,
275 base::Unretained(service()), // The service is a singleton.
276 browser_context_, persistent_notification_id));
277
278 notification_context_->DeleteNotificationData(
279 persistent_notification_id, GURL(origin.get()),
280 base::Bind(&BlinkNotificationServiceImpl::DidClosePersistent,
281 weak_ptr_factory_.GetWeakPtr(), callback));
282
283 return;
284 } else if (NotificationIdGenerator::IsNonPersistentNotification(id)) {
285 const auto& notification_iter = close_closures_.find(id);
286 if (notification_iter != close_closures_.end()) {
287 BrowserThread::PostTask(
288 BrowserThread::UI, FROM_HERE, notification_iter->second);
289
290 close_closures_.erase(notification_iter);
291
292 callback.Run(blink::mojom::NotificationCloseResult::CLOSED);
293 return;
294 }
295 } else {
296 // TODO: This should be BadMessage?
297 NOTREACHED() << "Unrecognized notification id";
298 }
299
300 callback.Run(blink::mojom::NotificationCloseResult::NOT_FOUND);
301 }
302
303 void BlinkNotificationServiceImpl::DidClosePersistent(
304 const CloseCallback& callback,
305 bool success) {
306 DCHECK_CURRENTLY_ON(BrowserThread::IO);
307
308 auto result = success ? blink::mojom::NotificationCloseResult::CLOSED
309 : blink::mojom::NotificationCloseResult::NOT_FOUND;
310
311 callback.Run(result);
312 }
313
314 void BlinkNotificationServiceImpl::OnConnectionError() {
315 notification_context_->RemoveService(this);
316 // |this| has now been deleted.
317 }
318
319 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698