OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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/browser/notifications/platform_notification_context_impl.h" | 5 #include "content/browser/notifications/platform_notification_context_impl.h" |
6 | 6 |
7 #include "base/bind_helpers.h" | 7 #include "base/bind_helpers.h" |
8 #include "base/files/file_util.h" | 8 #include "base/files/file_util.h" |
9 #include "base/memory/ptr_util.h" | 9 #include "base/memory/ptr_util.h" |
10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
53 } | 53 } |
54 | 54 |
55 void PlatformNotificationContextImpl::Initialize() { | 55 void PlatformNotificationContextImpl::Initialize() { |
56 DCHECK_CURRENTLY_ON(BrowserThread::UI); | 56 DCHECK_CURRENTLY_ON(BrowserThread::UI); |
57 PlatformNotificationService* service = | 57 PlatformNotificationService* service = |
58 GetContentClient()->browser()->GetPlatformNotificationService(); | 58 GetContentClient()->browser()->GetPlatformNotificationService(); |
59 if (service) { | 59 if (service) { |
60 std::set<std::string> displayed_notifications; | 60 std::set<std::string> displayed_notifications; |
61 | 61 |
62 bool notification_synchronization_supported = | 62 bool notification_synchronization_supported = |
63 service->GetDisplayedPersistentNotifications(browser_context_, | 63 service->GetDisplayedNotifications(browser_context_, |
64 &displayed_notifications); | 64 &displayed_notifications); |
65 | 65 |
66 // Synchronize the notifications stored in the database with the set of | 66 // Synchronize the notifications stored in the database with the set of |
67 // displaying notifications in |displayed_notifications|. This is necessary | 67 // displaying notifications in |displayed_notifications|. This is necessary |
68 // because flakiness may cause a platform to inform Chrome of a notification | 68 // because flakiness may cause a platform to inform Chrome of a notification |
69 // that has since been closed, or because the platform does not support | 69 // that has since been closed, or because the platform does not support |
70 // notifications that exceed the lifetime of the browser process. | 70 // notifications that exceed the lifetime of the browser process. |
71 | 71 |
72 // TODO(peter): Synchronizing the actual notifications will be done when the | 72 // TODO(peter): Synchronizing the actual notifications will be done when the |
73 // persistent notification ids are stable. For M44 we need to support the | 73 // persistent notification ids are stable. For M44 we need to support the |
74 // case where there may be no notifications after a Chrome restart. | 74 // case where there may be no notifications after a Chrome restart. |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
175 // Blow away the database if reading data failed due to corruption. | 175 // Blow away the database if reading data failed due to corruption. |
176 if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED) | 176 if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED) |
177 DestroyDatabase(); | 177 DestroyDatabase(); |
178 | 178 |
179 BrowserThread::PostTask( | 179 BrowserThread::PostTask( |
180 BrowserThread::IO, FROM_HERE, | 180 BrowserThread::IO, FROM_HERE, |
181 base::Bind(callback, false /* success */, NotificationDatabaseData())); | 181 base::Bind(callback, false /* success */, NotificationDatabaseData())); |
182 } | 182 } |
183 | 183 |
184 void PlatformNotificationContextImpl:: | 184 void PlatformNotificationContextImpl:: |
185 SynchronizeDisplayedNotificationsForServiceWorkerRegistration( | |
186 const GURL& origin, | |
187 int64_t service_worker_registration_id, | |
188 const ReadAllResultCallback& callback, | |
189 std::set<std::string>* notification_ids, | |
190 bool sync_supported) { | |
191 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
192 LazyInitialize( | |
193 base::Bind(&PlatformNotificationContextImpl:: | |
194 DoReadAllNotificationDataForServiceWorkerRegistration, | |
195 this, origin, service_worker_registration_id, callback, | |
196 base::Unretained(notification_ids), sync_supported), | |
197 base::Bind(callback, false /* success */, | |
198 std::vector<NotificationDatabaseData>())); | |
199 } | |
200 | |
201 void PlatformNotificationContextImpl:: | |
185 ReadAllNotificationDataForServiceWorkerRegistration( | 202 ReadAllNotificationDataForServiceWorkerRegistration( |
186 const GURL& origin, | 203 const GURL& origin, |
187 int64_t service_worker_registration_id, | 204 int64_t service_worker_registration_id, |
188 const ReadAllResultCallback& callback) { | 205 const ReadAllResultCallback& callback) { |
189 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 206 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
190 LazyInitialize( | 207 |
191 base::Bind(&PlatformNotificationContextImpl:: | 208 // notification_ids becomes owned by |
192 DoReadAllNotificationDataForServiceWorkerRegistration, | 209 // DoReadAllNotificationDataForServiceWorkerRegistration |
193 this, origin, service_worker_registration_id, callback), | 210 std::set<std::string>* notification_ids = new std::set<std::string>(); |
194 base::Bind(callback, false /* success */, | 211 PlatformNotificationService* service = |
195 std::vector<NotificationDatabaseData>())); | 212 GetContentClient()->browser()->GetPlatformNotificationService(); |
213 | |
214 if (!service) { | |
215 // Rely on the database only | |
216 SynchronizeDisplayedNotificationsForServiceWorkerRegistration( | |
217 origin, service_worker_registration_id, callback, notification_ids, | |
218 false /* sync_supported */); | |
219 return; | |
220 } | |
221 | |
222 BrowserThread::PostTaskAndReplyWithResult( | |
223 BrowserThread::UI, FROM_HERE, | |
224 base::Bind(&PlatformNotificationService::GetDisplayedNotifications, | |
225 base::Unretained(service), browser_context_, | |
226 base::Unretained(notification_ids)), | |
227 base::Bind( | |
228 &PlatformNotificationContextImpl:: | |
229 SynchronizeDisplayedNotificationsForServiceWorkerRegistration, | |
230 this, origin, service_worker_registration_id, callback, | |
231 base::Unretained(notification_ids))); | |
196 } | 232 } |
197 | 233 |
198 void PlatformNotificationContextImpl:: | 234 void PlatformNotificationContextImpl:: |
199 DoReadAllNotificationDataForServiceWorkerRegistration( | 235 DoReadAllNotificationDataForServiceWorkerRegistration( |
200 const GURL& origin, | 236 const GURL& origin, |
201 int64_t service_worker_registration_id, | 237 int64_t service_worker_registration_id, |
202 const ReadAllResultCallback& callback) { | 238 const ReadAllResultCallback& callback, |
239 std::set<std::string>* displayed_notifications, | |
240 bool synchronization_supported) { | |
203 DCHECK(task_runner_->RunsTasksOnCurrentThread()); | 241 DCHECK(task_runner_->RunsTasksOnCurrentThread()); |
242 std::unique_ptr<std::set<std::string>> displayed_ids = | |
243 base::WrapUnique(displayed_notifications); | |
204 | 244 |
205 std::vector<NotificationDatabaseData> notification_datas; | 245 std::vector<NotificationDatabaseData> notification_datas; |
206 | 246 |
207 NotificationDatabase::Status status = | 247 NotificationDatabase::Status status = |
208 database_->ReadAllNotificationDataForServiceWorkerRegistration( | 248 database_->ReadAllNotificationDataForServiceWorkerRegistration( |
209 origin, service_worker_registration_id, ¬ification_datas); | 249 origin, service_worker_registration_id, ¬ification_datas); |
210 | 250 |
211 UMA_HISTOGRAM_ENUMERATION("Notifications.Database.ReadForServiceWorkerResult", | 251 UMA_HISTOGRAM_ENUMERATION("Notifications.Database.ReadForServiceWorkerResult", |
212 status, NotificationDatabase::STATUS_COUNT); | 252 status, NotificationDatabase::STATUS_COUNT); |
213 | 253 |
214 if (status == NotificationDatabase::STATUS_OK) { | 254 if (status == NotificationDatabase::STATUS_OK) { |
255 if (synchronization_supported) { | |
256 DCHECK(displayed_ids); | |
257 // Filter out notifications that are not actually on display anymore. | |
258 // TODO(miguelg) synchronize the database if there are inconsistencies. | |
259 for (auto it = notification_datas.begin(); | |
260 it != notification_datas.end();) { | |
261 if (NotificationIdGenerator::IsPersistentNotification( | |
262 it->notification_id) && | |
263 displayed_ids->count(it->notification_id)) { | |
Peter Beverloo
2016/12/13 11:41:12
Mm. std::set<> makes this O(n log n). Could be O(n
Miguel Garcia
2016/12/13 16:43:10
Yeah, and it makes the test more predictable (sinc
| |
264 ++it; | |
265 } else { | |
266 it = notification_datas.erase(it); | |
Peter Beverloo
2016/12/13 11:41:12
nit: drop this. Maybe DCHECK on NotificationIdGene
Miguel Garcia
2016/12/13 16:43:10
Done.
| |
267 } | |
268 } | |
269 } | |
270 | |
215 BrowserThread::PostTask( | 271 BrowserThread::PostTask( |
216 BrowserThread::IO, FROM_HERE, | 272 BrowserThread::IO, FROM_HERE, |
217 base::Bind(callback, true /* success */, notification_datas)); | 273 base::Bind(callback, true /* success */, notification_datas)); |
218 return; | 274 return; |
219 } | 275 } |
220 | 276 |
221 // Blow away the database if reading data failed due to corruption. | 277 // Blow away the database if reading data failed due to corruption. |
222 if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED) | 278 if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED) |
223 DestroyDatabase(); | 279 DestroyDatabase(); |
224 | 280 |
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
477 | 533 |
478 return path_.Append(kPlatformNotificationsDirectory); | 534 return path_.Append(kPlatformNotificationsDirectory); |
479 } | 535 } |
480 | 536 |
481 void PlatformNotificationContextImpl::SetTaskRunnerForTesting( | 537 void PlatformNotificationContextImpl::SetTaskRunnerForTesting( |
482 const scoped_refptr<base::SequencedTaskRunner>& task_runner) { | 538 const scoped_refptr<base::SequencedTaskRunner>& task_runner) { |
483 task_runner_ = task_runner; | 539 task_runner_ = task_runner; |
484 } | 540 } |
485 | 541 |
486 } // namespace content | 542 } // namespace content |
OLD | NEW |