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

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

Issue 2749453002: Make GetDisplayedNotifications asynchronous. (Closed)
Patch Set: review Created 3 years, 9 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 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
50 if (database_) { 50 if (database_) {
51 DCHECK(task_runner_); 51 DCHECK(task_runner_);
52 task_runner_->DeleteSoon(FROM_HERE, database_.release()); 52 task_runner_->DeleteSoon(FROM_HERE, database_.release());
53 } 53 }
54 } 54 }
55 55
56 void PlatformNotificationContextImpl::Initialize() { 56 void PlatformNotificationContextImpl::Initialize() {
57 DCHECK_CURRENTLY_ON(BrowserThread::UI); 57 DCHECK_CURRENTLY_ON(BrowserThread::UI);
58 PlatformNotificationService* service = 58 PlatformNotificationService* service =
59 GetContentClient()->browser()->GetPlatformNotificationService(); 59 GetContentClient()->browser()->GetPlatformNotificationService();
60 if (service) { 60 if (!service) {
61 std::set<std::string> displayed_notifications; 61 auto displayed_notifications = base::MakeUnique<std::set<std::string>>();
62 62 BrowserThread::PostTask(
63 bool notification_synchronization_supported = 63 BrowserThread::IO, FROM_HERE,
64 service->GetDisplayedNotifications(browser_context_, 64 base::Bind(&PlatformNotificationContextImpl::InitializeOnIO, this,
65 &displayed_notifications); 65 base::Passed(&displayed_notifications), false));
66 66 return;
67 // Synchronize the notifications stored in the database with the set of
68 // displaying notifications in |displayed_notifications|. This is necessary
69 // because flakiness may cause a platform to inform Chrome of a notification
70 // that has since been closed, or because the platform does not support
71 // notifications that exceed the lifetime of the browser process.
72
73 // TODO(peter): Synchronizing the actual notifications will be done when the
74 // persistent notification ids are stable. For M44 we need to support the
75 // case where there may be no notifications after a Chrome restart.
76 if (notification_synchronization_supported &&
77 displayed_notifications.empty()) {
78 prune_database_on_open_ = true;
79 }
80 } 67 }
81 68
69 service->GetDisplayedNotifications(
70 browser_context_,
71 base::Bind(&PlatformNotificationContextImpl::DidGetNotificationsOnUI,
72 this));
73 }
74
75 void PlatformNotificationContextImpl::DidGetNotificationsOnUI(
76 std::unique_ptr<std::set<std::string>> displayed_notifications,
77 bool supports_synchronization) {
78 DCHECK_CURRENTLY_ON(BrowserThread::UI);
82 BrowserThread::PostTask( 79 BrowserThread::PostTask(
83 BrowserThread::IO, FROM_HERE, 80 BrowserThread::IO, FROM_HERE,
84 base::Bind(&PlatformNotificationContextImpl::InitializeOnIO, this)); 81 base::Bind(&PlatformNotificationContextImpl::InitializeOnIO, this,
82 base::Passed(&displayed_notifications),
83 supports_synchronization));
85 } 84 }
86 85
87 void PlatformNotificationContextImpl::InitializeOnIO() { 86 void PlatformNotificationContextImpl::InitializeOnIO(
87 std::unique_ptr<std::set<std::string>> displayed_notifications,
88 bool supports_synchronization) {
88 DCHECK_CURRENTLY_ON(BrowserThread::IO); 89 DCHECK_CURRENTLY_ON(BrowserThread::IO);
89 90
91 // Synchronize the notifications stored in the database with the set of
92 // displaying notifications in |displayed_notifications|. This is necessary
93 // because flakiness may cause a platform to inform Chrome of a notification
94 // that has since been closed, or because the platform does not support
95 // notifications that exceed the lifetime of the browser process.
96
97 // TODO(peter): Synchronizing the actual notifications will be done when the
98 // persistent notification ids are stable. For M44 we need to support the
99 // case where there may be no notifications after a Chrome restart.
100
101 if (supports_synchronization && displayed_notifications->empty()) {
102 prune_database_on_open_ = true;
103 }
104
90 // |service_worker_context_| may be NULL in tests. 105 // |service_worker_context_| may be NULL in tests.
91 if (service_worker_context_) 106 if (service_worker_context_)
92 service_worker_context_->AddObserver(this); 107 service_worker_context_->AddObserver(this);
93 } 108 }
94 109
95 void PlatformNotificationContextImpl::Shutdown() { 110 void PlatformNotificationContextImpl::Shutdown() {
96 DCHECK_CURRENTLY_ON(BrowserThread::UI); 111 DCHECK_CURRENTLY_ON(BrowserThread::UI);
97 BrowserThread::PostTask( 112 BrowserThread::PostTask(
98 BrowserThread::IO, FROM_HERE, 113 BrowserThread::IO, FROM_HERE,
99 base::Bind(&PlatformNotificationContextImpl::ShutdownOnIO, this)); 114 base::Bind(&PlatformNotificationContextImpl::ShutdownOnIO, this));
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
174 // Blow away the database if reading data failed due to corruption. 189 // Blow away the database if reading data failed due to corruption.
175 if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED) 190 if (status == NotificationDatabase::STATUS_ERROR_CORRUPTED)
176 DestroyDatabase(); 191 DestroyDatabase();
177 192
178 BrowserThread::PostTask( 193 BrowserThread::PostTask(
179 BrowserThread::IO, FROM_HERE, 194 BrowserThread::IO, FROM_HERE,
180 base::Bind(callback, false /* success */, NotificationDatabaseData())); 195 base::Bind(callback, false /* success */, NotificationDatabaseData()));
181 } 196 }
182 197
183 void PlatformNotificationContextImpl:: 198 void PlatformNotificationContextImpl::
184 SynchronizeDisplayedNotificationsForServiceWorkerRegistration( 199 SynchronizeDisplayedNotificationsForServiceWorkerRegistrationOnUI(
185 const GURL& origin, 200 const GURL& origin,
186 int64_t service_worker_registration_id, 201 int64_t service_worker_registration_id,
187 const ReadAllResultCallback& callback, 202 const ReadAllResultCallback& callback,
188 std::unique_ptr<std::set<std::string>> notification_ids, 203 std::unique_ptr<std::set<std::string>> notification_ids,
189 bool sync_supported) { 204 bool supports_synchronization) {
205 DCHECK_CURRENTLY_ON(BrowserThread::UI);
206
207 BrowserThread::PostTask(
208 BrowserThread::IO, FROM_HERE,
209 base::Bind(
210 &PlatformNotificationContextImpl::
211 SynchronizeDisplayedNotificationsForServiceWorkerRegistrationOnIO,
212 this, origin, service_worker_registration_id, callback,
213 base::Passed(&notification_ids), supports_synchronization));
214 }
215
216 void PlatformNotificationContextImpl::
217 SynchronizeDisplayedNotificationsForServiceWorkerRegistrationOnIO(
218 const GURL& origin,
219 int64_t service_worker_registration_id,
220 const ReadAllResultCallback& callback,
221 std::unique_ptr<std::set<std::string>> notification_ids,
222 bool supports_synchronization) {
190 DCHECK_CURRENTLY_ON(BrowserThread::IO); 223 DCHECK_CURRENTLY_ON(BrowserThread::IO);
191 LazyInitialize( 224 LazyInitialize(
192 base::Bind(&PlatformNotificationContextImpl:: 225 base::Bind(&PlatformNotificationContextImpl::
193 DoReadAllNotificationDataForServiceWorkerRegistration, 226 DoReadAllNotificationDataForServiceWorkerRegistration,
194 this, origin, service_worker_registration_id, callback, 227 this, origin, service_worker_registration_id, callback,
195 base::Passed(&notification_ids), sync_supported), 228 base::Passed(&notification_ids), supports_synchronization),
196 base::Bind(callback, false /* success */, 229 base::Bind(callback, false /* success */,
197 std::vector<NotificationDatabaseData>())); 230 std::vector<NotificationDatabaseData>()));
198 } 231 }
199 232
200 void PlatformNotificationContextImpl:: 233 void PlatformNotificationContextImpl::
201 ReadAllNotificationDataForServiceWorkerRegistration( 234 ReadAllNotificationDataForServiceWorkerRegistration(
202 const GURL& origin, 235 const GURL& origin,
203 int64_t service_worker_registration_id, 236 int64_t service_worker_registration_id,
204 const ReadAllResultCallback& callback) { 237 const ReadAllResultCallback& callback) {
205 DCHECK_CURRENTLY_ON(BrowserThread::IO); 238 DCHECK_CURRENTLY_ON(BrowserThread::IO);
206 239
207 std::unique_ptr<std::set<std::string>> notification_ids = 240 auto notification_ids = base::MakeUnique<std::set<std::string>>();
208 base::MakeUnique<std::set<std::string>>();
209 241
210 PlatformNotificationService* service = 242 PlatformNotificationService* service =
211 GetContentClient()->browser()->GetPlatformNotificationService(); 243 GetContentClient()->browser()->GetPlatformNotificationService();
212 244
213 if (!service) { 245 if (!service) {
214 // Rely on the database only 246 // Rely on the database only
215 SynchronizeDisplayedNotificationsForServiceWorkerRegistration( 247 SynchronizeDisplayedNotificationsForServiceWorkerRegistrationOnIO(
216 origin, service_worker_registration_id, callback, 248 origin, service_worker_registration_id, callback,
217 std::move(notification_ids), false /* sync_supported */); 249 std::move(notification_ids), false /* supports_synchronization */);
218 return; 250 return;
219 } 251 }
220 252
221 std::set<std::string>* notification_ids_ptr = notification_ids.get(); 253 BrowserThread::PostTask(
222
223 BrowserThread::PostTaskAndReplyWithResult(
224 BrowserThread::UI, FROM_HERE, 254 BrowserThread::UI, FROM_HERE,
225 base::Bind(&PlatformNotificationService::GetDisplayedNotifications,
226 base::Unretained(service), browser_context_,
227 notification_ids_ptr),
228 base::Bind( 255 base::Bind(
229 &PlatformNotificationContextImpl:: 256 &PlatformNotificationService::GetDisplayedNotifications,
230 SynchronizeDisplayedNotificationsForServiceWorkerRegistration, 257 base::Unretained(service), browser_context_,
231 this, origin, service_worker_registration_id, callback, 258 base::Bind(
232 base::Passed(&notification_ids))); 259 &PlatformNotificationContextImpl::
260 SynchronizeDisplayedNotificationsForServiceWorkerRegistrationO nUI,
261 this, origin, service_worker_registration_id, callback)));
233 } 262 }
234 263
235 void PlatformNotificationContextImpl:: 264 void PlatformNotificationContextImpl::
236 DoReadAllNotificationDataForServiceWorkerRegistration( 265 DoReadAllNotificationDataForServiceWorkerRegistration(
237 const GURL& origin, 266 const GURL& origin,
238 int64_t service_worker_registration_id, 267 int64_t service_worker_registration_id,
239 const ReadAllResultCallback& callback, 268 const ReadAllResultCallback& callback,
240 std::unique_ptr<std::set<std::string>> displayed_notifications, 269 std::unique_ptr<std::set<std::string>> displayed_notifications,
241 bool synchronization_supported) { 270 bool supports_synchronization) {
242 DCHECK(task_runner_->RunsTasksOnCurrentThread()); 271 DCHECK(task_runner_->RunsTasksOnCurrentThread());
243 DCHECK(displayed_notifications); 272 DCHECK(displayed_notifications);
244 273
245 std::vector<NotificationDatabaseData> notification_datas; 274 std::vector<NotificationDatabaseData> notification_datas;
246 275
247 NotificationDatabase::Status status = 276 NotificationDatabase::Status status =
248 database_->ReadAllNotificationDataForServiceWorkerRegistration( 277 database_->ReadAllNotificationDataForServiceWorkerRegistration(
249 origin, service_worker_registration_id, &notification_datas); 278 origin, service_worker_registration_id, &notification_datas);
250 279
251 UMA_HISTOGRAM_ENUMERATION("Notifications.Database.ReadForServiceWorkerResult", 280 UMA_HISTOGRAM_ENUMERATION("Notifications.Database.ReadForServiceWorkerResult",
252 status, NotificationDatabase::STATUS_COUNT); 281 status, NotificationDatabase::STATUS_COUNT);
253 282
254 if (status == NotificationDatabase::STATUS_OK) { 283 if (status == NotificationDatabase::STATUS_OK) {
255 if (synchronization_supported) { 284 if (supports_synchronization) {
256 // Filter out notifications that are not actually on display anymore. 285 // Filter out notifications that are not actually on display anymore.
257 // TODO(miguelg) synchronize the database if there are inconsistencies. 286 // TODO(miguelg) synchronize the database if there are inconsistencies.
258 for (auto it = notification_datas.begin(); 287 for (auto it = notification_datas.begin();
259 it != notification_datas.end();) { 288 it != notification_datas.end();) {
260 // The database is only used for persistent notifications. 289 // The database is only used for persistent notifications.
261 DCHECK(NotificationIdGenerator::IsPersistentNotification( 290 DCHECK(NotificationIdGenerator::IsPersistentNotification(
262 it->notification_id)); 291 it->notification_id));
263 if (displayed_notifications->count(it->notification_id)) { 292 if (displayed_notifications->count(it->notification_id)) {
264 ++it; 293 ++it;
265 } else { 294 } else {
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 562
534 return path_.Append(kPlatformNotificationsDirectory); 563 return path_.Append(kPlatformNotificationsDirectory);
535 } 564 }
536 565
537 void PlatformNotificationContextImpl::SetTaskRunnerForTesting( 566 void PlatformNotificationContextImpl::SetTaskRunnerForTesting(
538 const scoped_refptr<base::SequencedTaskRunner>& task_runner) { 567 const scoped_refptr<base::SequencedTaskRunner>& task_runner) {
539 task_runner_ = task_runner; 568 task_runner_ = task_runner;
540 } 569 }
541 570
542 } // namespace content 571 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698