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

Side by Side Diff: content/browser/background_sync/background_sync_manager.cc

Issue 1106523002: [BackgroundSync] Fire one-shot sync events (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@store_origin
Patch Set: Rebase fix Created 5 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
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/background_sync/background_sync_manager.h" 5 #include "content/browser/background_sync/background_sync_manager.h"
6 6
7 #include "base/barrier_closure.h" 7 #include "base/barrier_closure.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "content/browser/background_sync/background_sync_network_observer.h" 9 #include "content/browser/background_sync/background_sync_network_observer.h"
10 #include "content/browser/service_worker/service_worker_context_wrapper.h" 10 #include "content/browser/service_worker/service_worker_context_wrapper.h"
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
133 // Operations already in the queue will either fail when they write to storage 133 // Operations already in the queue will either fail when they write to storage
134 // or return stale results based on registrations loaded in memory. This is 134 // or return stale results based on registrations loaded in memory. This is
135 // inconsequential since the service worker is gone. 135 // inconsequential since the service worker is gone.
136 op_scheduler_.ScheduleOperation(base::Bind( 136 op_scheduler_.ScheduleOperation(base::Bind(
137 &BackgroundSyncManager::OnRegistrationDeletedImpl, 137 &BackgroundSyncManager::OnRegistrationDeletedImpl,
138 weak_ptr_factory_.GetWeakPtr(), registration_id, MakeEmptyCompletion())); 138 weak_ptr_factory_.GetWeakPtr(), registration_id, MakeEmptyCompletion()));
139 } 139 }
140 140
141 void BackgroundSyncManager::OnStorageWiped() { 141 void BackgroundSyncManager::OnStorageWiped() {
142 DCHECK_CURRENTLY_ON(BrowserThread::IO); 142 DCHECK_CURRENTLY_ON(BrowserThread::IO);
143
143 // Operations already in the queue will either fail when they write to storage 144 // Operations already in the queue will either fail when they write to storage
144 // or return stale results based on registrations loaded in memory. This is 145 // or return stale results based on registrations loaded in memory. This is
145 // inconsequential since the service workers are gone. 146 // inconsequential since the service workers are gone.
146 op_scheduler_.ScheduleOperation( 147 op_scheduler_.ScheduleOperation(
147 base::Bind(&BackgroundSyncManager::OnStorageWipedImpl, 148 base::Bind(&BackgroundSyncManager::OnStorageWipedImpl,
148 weak_ptr_factory_.GetWeakPtr(), MakeEmptyCompletion())); 149 weak_ptr_factory_.GetWeakPtr(), MakeEmptyCompletion()));
149 } 150 }
150 151
151 BackgroundSyncManager::BackgroundSyncManager( 152 BackgroundSyncManager::BackgroundSyncManager(
152 const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context) 153 const scoped_refptr<ServiceWorkerContextWrapper>& service_worker_context)
(...skipping 30 matching lines...) Expand all
183 GetDataFromBackend( 184 GetDataFromBackend(
184 kBackgroundSyncUserDataKey, 185 kBackgroundSyncUserDataKey,
185 base::Bind(&BackgroundSyncManager::InitDidGetDataFromBackend, 186 base::Bind(&BackgroundSyncManager::InitDidGetDataFromBackend,
186 weak_ptr_factory_.GetWeakPtr(), callback)); 187 weak_ptr_factory_.GetWeakPtr(), callback));
187 } 188 }
188 189
189 void BackgroundSyncManager::InitDidGetDataFromBackend( 190 void BackgroundSyncManager::InitDidGetDataFromBackend(
190 const base::Closure& callback, 191 const base::Closure& callback,
191 const std::vector<std::pair<int64, std::string>>& user_data, 192 const std::vector<std::pair<int64, std::string>>& user_data,
192 ServiceWorkerStatusCode status) { 193 ServiceWorkerStatusCode status) {
194 DCHECK_CURRENTLY_ON(BrowserThread::IO);
195
193 if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND) { 196 if (status != SERVICE_WORKER_OK && status != SERVICE_WORKER_ERROR_NOT_FOUND) {
194 LOG(ERROR) << "BackgroundSync failed to init due to backend failure."; 197 LOG(ERROR) << "BackgroundSync failed to init due to backend failure.";
195 DisableAndClearManager(base::Bind(callback)); 198 DisableAndClearManager(base::Bind(callback));
196 return; 199 return;
197 } 200 }
198 201
199 bool corruption_detected = false; 202 bool corruption_detected = false;
200 for (const std::pair<int64, std::string>& data : user_data) { 203 for (const std::pair<int64, std::string>& data : user_data) {
201 BackgroundSyncRegistrationsProto registrations_proto; 204 BackgroundSyncRegistrationsProto registrations_proto;
202 if (registrations_proto.ParseFromString(data.second)) { 205 if (registrations_proto.ParseFromString(data.second)) {
(...skipping 16 matching lines...) Expand all
219 registration_proto.periodicity()); 222 registration_proto.periodicity());
220 BackgroundSyncRegistration* registration = 223 BackgroundSyncRegistration* registration =
221 &registrations->registration_map[registration_key]; 224 &registrations->registration_map[registration_key];
222 225
223 registration->id = registration_proto.id(); 226 registration->id = registration_proto.id();
224 registration->tag = registration_proto.tag(); 227 registration->tag = registration_proto.tag();
225 registration->periodicity = registration_proto.periodicity(); 228 registration->periodicity = registration_proto.periodicity();
226 registration->min_period = registration_proto.min_period(); 229 registration->min_period = registration_proto.min_period();
227 registration->network_state = registration_proto.network_state(); 230 registration->network_state = registration_proto.network_state();
228 registration->power_state = registration_proto.power_state(); 231 registration->power_state = registration_proto.power_state();
232 registration->sync_state = registration_proto.sync_state();
233 if (registration->sync_state == SYNC_STATE_FIRING) {
234 // If the browser (or worker) closed while firing the event, consider
235 // it pending again>
236 registration->sync_state = SYNC_STATE_PENDING;
237 }
229 } 238 }
230 } 239 }
231 240
232 if (corruption_detected) 241 if (corruption_detected)
233 break; 242 break;
234 } 243 }
235 244
236 if (corruption_detected) { 245 if (corruption_detected) {
237 LOG(ERROR) << "Corruption detected in background sync backend"; 246 LOG(ERROR) << "Corruption detected in background sync backend";
238 DisableAndClearManager(base::Bind(callback)); 247 DisableAndClearManager(base::Bind(callback));
239 return; 248 return;
240 } 249 }
241 250
242 // TODO(jkarlin): Call the scheduling algorithm here. 251 FireReadyEvents();
243 252
244 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback)); 253 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
245 } 254 }
246 255
247 void BackgroundSyncManager::RegisterImpl( 256 void BackgroundSyncManager::RegisterImpl(
248 int64 sw_registration_id, 257 int64 sw_registration_id,
249 const BackgroundSyncRegistration& sync_registration, 258 const BackgroundSyncRegistration& sync_registration,
250 const StatusAndRegistrationCallback& callback) { 259 const StatusAndRegistrationCallback& callback) {
260 DCHECK_CURRENTLY_ON(BrowserThread::IO);
261
251 if (disabled_) { 262 if (disabled_) {
252 base::MessageLoop::current()->PostTask( 263 base::MessageLoop::current()->PostTask(
253 FROM_HERE, 264 FROM_HERE,
254 base::Bind(callback, ERROR_TYPE_STORAGE, BackgroundSyncRegistration())); 265 base::Bind(callback, ERROR_TYPE_STORAGE, BackgroundSyncRegistration()));
255 return; 266 return;
256 } 267 }
257 268
258 const BackgroundSyncRegistration* existing_registration = LookupRegistration( 269 const BackgroundSyncRegistration* existing_registration = LookupRegistration(
259 sw_registration_id, RegistrationKey(sync_registration)); 270 sw_registration_id, RegistrationKey(sync_registration));
260 if (existing_registration && 271 if (existing_registration &&
(...skipping 23 matching lines...) Expand all
284 295
285 StoreRegistrations( 296 StoreRegistrations(
286 sw_registration_id, 297 sw_registration_id,
287 base::Bind(&BackgroundSyncManager::RegisterDidStore, 298 base::Bind(&BackgroundSyncManager::RegisterDidStore,
288 weak_ptr_factory_.GetWeakPtr(), sw_registration_id, 299 weak_ptr_factory_.GetWeakPtr(), sw_registration_id,
289 new_registration, callback)); 300 new_registration, callback));
290 } 301 }
291 302
292 void BackgroundSyncManager::DisableAndClearManager( 303 void BackgroundSyncManager::DisableAndClearManager(
293 const base::Closure& callback) { 304 const base::Closure& callback) {
305 DCHECK_CURRENTLY_ON(BrowserThread::IO);
306
294 if (disabled_) { 307 if (disabled_) {
295 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback)); 308 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
296 return; 309 return;
297 } 310 }
298 311
299 disabled_ = true; 312 disabled_ = true;
300 sw_to_registrations_map_.clear(); 313 sw_to_registrations_map_.clear();
301 314
302 // Delete all backend entries. The memory representation of registered syncs 315 // Delete all backend entries. The memory representation of registered syncs
303 // may be out of sync with storage (e.g., due to corruption detection on 316 // may be out of sync with storage (e.g., due to corruption detection on
304 // loading from storage), so reload the registrations from storage again. 317 // loading from storage), so reload the registrations from storage again.
305 GetDataFromBackend( 318 GetDataFromBackend(
306 kBackgroundSyncUserDataKey, 319 kBackgroundSyncUserDataKey,
307 base::Bind(&BackgroundSyncManager::DisableAndClearDidGetRegistrations, 320 base::Bind(&BackgroundSyncManager::DisableAndClearDidGetRegistrations,
308 weak_ptr_factory_.GetWeakPtr(), callback)); 321 weak_ptr_factory_.GetWeakPtr(), callback));
309 } 322 }
310 323
311 void BackgroundSyncManager::DisableAndClearDidGetRegistrations( 324 void BackgroundSyncManager::DisableAndClearDidGetRegistrations(
312 const base::Closure& callback, 325 const base::Closure& callback,
313 const std::vector<std::pair<int64, std::string>>& user_data, 326 const std::vector<std::pair<int64, std::string>>& user_data,
314 ServiceWorkerStatusCode status) { 327 ServiceWorkerStatusCode status) {
328 DCHECK_CURRENTLY_ON(BrowserThread::IO);
329
315 if (status != SERVICE_WORKER_OK || user_data.empty()) { 330 if (status != SERVICE_WORKER_OK || user_data.empty()) {
316 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback)); 331 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
317 return; 332 return;
318 } 333 }
319 334
320 base::Closure barrier_closure = 335 base::Closure barrier_closure =
321 base::BarrierClosure(user_data.size(), base::Bind(callback)); 336 base::BarrierClosure(user_data.size(), base::Bind(callback));
322 337
323 for (const auto& sw_id_and_regs : user_data) { 338 for (const auto& sw_id_and_regs : user_data) {
324 service_worker_context_->ClearRegistrationUserData( 339 service_worker_context_->ClearRegistrationUserData(
325 sw_id_and_regs.first, kBackgroundSyncUserDataKey, 340 sw_id_and_regs.first, kBackgroundSyncUserDataKey,
326 base::Bind(&BackgroundSyncManager::DisableAndClearManagerClearedOne, 341 base::Bind(&BackgroundSyncManager::DisableAndClearManagerClearedOne,
327 weak_ptr_factory_.GetWeakPtr(), barrier_closure)); 342 weak_ptr_factory_.GetWeakPtr(), barrier_closure));
328 } 343 }
329 } 344 }
330 345
331 void BackgroundSyncManager::DisableAndClearManagerClearedOne( 346 void BackgroundSyncManager::DisableAndClearManagerClearedOne(
332 const base::Closure& barrier_closure, 347 const base::Closure& barrier_closure,
333 ServiceWorkerStatusCode status) { 348 ServiceWorkerStatusCode status) {
349 DCHECK_CURRENTLY_ON(BrowserThread::IO);
350
334 // The status doesn't matter at this point, there is nothing else to be done. 351 // The status doesn't matter at this point, there is nothing else to be done.
335 base::MessageLoop::current()->PostTask(FROM_HERE, 352 base::MessageLoop::current()->PostTask(FROM_HERE,
336 base::Bind(barrier_closure)); 353 base::Bind(barrier_closure));
337 } 354 }
338 355
339 BackgroundSyncManager::BackgroundSyncRegistration* 356 BackgroundSyncManager::BackgroundSyncRegistration*
340 BackgroundSyncManager::LookupRegistration( 357 BackgroundSyncManager::LookupRegistration(
341 int64 sw_registration_id, 358 int64 sw_registration_id,
342 const RegistrationKey& registration_key) { 359 const RegistrationKey& registration_key) {
360 DCHECK_CURRENTLY_ON(BrowserThread::IO);
361
343 SWIdToRegistrationsMap::iterator it = 362 SWIdToRegistrationsMap::iterator it =
344 sw_to_registrations_map_.find(sw_registration_id); 363 sw_to_registrations_map_.find(sw_registration_id);
345 if (it == sw_to_registrations_map_.end()) 364 if (it == sw_to_registrations_map_.end())
346 return nullptr; 365 return nullptr;
347 366
348 BackgroundSyncRegistrations& registrations = it->second; 367 BackgroundSyncRegistrations& registrations = it->second;
349 DCHECK_LE(BackgroundSyncRegistration::kInitialId, registrations.next_id); 368 DCHECK_LE(BackgroundSyncRegistration::kInitialId, registrations.next_id);
350 DCHECK(!registrations.origin.is_empty()); 369 DCHECK(!registrations.origin.is_empty());
351 370
352 auto key_and_registration_iter = 371 auto key_and_registration_iter =
353 registrations.registration_map.find(registration_key); 372 registrations.registration_map.find(registration_key);
354 if (key_and_registration_iter == registrations.registration_map.end()) 373 if (key_and_registration_iter == registrations.registration_map.end())
355 return nullptr; 374 return nullptr;
356 375
357 return &key_and_registration_iter->second; 376 return &key_and_registration_iter->second;
358 } 377 }
359 378
360 void BackgroundSyncManager::StoreRegistrations( 379 void BackgroundSyncManager::StoreRegistrations(
361 int64 sw_registration_id, 380 int64 sw_registration_id,
362 const ServiceWorkerStorage::StatusCallback& callback) { 381 const ServiceWorkerStorage::StatusCallback& callback) {
382 DCHECK_CURRENTLY_ON(BrowserThread::IO);
383
363 // Serialize the data. 384 // Serialize the data.
364 const BackgroundSyncRegistrations& registrations = 385 const BackgroundSyncRegistrations& registrations =
365 sw_to_registrations_map_[sw_registration_id]; 386 sw_to_registrations_map_[sw_registration_id];
366 BackgroundSyncRegistrationsProto registrations_proto; 387 BackgroundSyncRegistrationsProto registrations_proto;
367 registrations_proto.set_next_registration_id(registrations.next_id); 388 registrations_proto.set_next_registration_id(registrations.next_id);
368 registrations_proto.set_origin(registrations.origin.spec()); 389 registrations_proto.set_origin(registrations.origin.spec());
369 390
370 for (const auto& key_and_registration : registrations.registration_map) { 391 for (const auto& key_and_registration : registrations.registration_map) {
371 const BackgroundSyncRegistration& registration = 392 const BackgroundSyncRegistration& registration =
372 key_and_registration.second; 393 key_and_registration.second;
373 BackgroundSyncRegistrationProto* registration_proto = 394 BackgroundSyncRegistrationProto* registration_proto =
374 registrations_proto.add_registration(); 395 registrations_proto.add_registration();
375 registration_proto->set_id(registration.id); 396 registration_proto->set_id(registration.id);
376 registration_proto->set_tag(registration.tag); 397 registration_proto->set_tag(registration.tag);
377 registration_proto->set_periodicity(registration.periodicity); 398 registration_proto->set_periodicity(registration.periodicity);
378 registration_proto->set_min_period(registration.min_period); 399 registration_proto->set_min_period(registration.min_period);
379 registration_proto->set_network_state(registration.network_state); 400 registration_proto->set_network_state(registration.network_state);
380 registration_proto->set_power_state(registration.power_state); 401 registration_proto->set_power_state(registration.power_state);
402 registration_proto->set_sync_state(registration.sync_state);
381 } 403 }
382 std::string serialized; 404 std::string serialized;
383 bool success = registrations_proto.SerializeToString(&serialized); 405 bool success = registrations_proto.SerializeToString(&serialized);
384 DCHECK(success); 406 DCHECK(success);
385 407
386 StoreDataInBackend(sw_registration_id, registrations.origin, 408 StoreDataInBackend(sw_registration_id, registrations.origin,
387 kBackgroundSyncUserDataKey, serialized, callback); 409 kBackgroundSyncUserDataKey, serialized, callback);
388 } 410 }
389 411
390 void BackgroundSyncManager::RegisterDidStore( 412 void BackgroundSyncManager::RegisterDidStore(
391 int64 sw_registration_id, 413 int64 sw_registration_id,
392 const BackgroundSyncRegistration& new_registration, 414 const BackgroundSyncRegistration& new_registration,
393 const StatusAndRegistrationCallback& callback, 415 const StatusAndRegistrationCallback& callback,
394 ServiceWorkerStatusCode status) { 416 ServiceWorkerStatusCode status) {
417 DCHECK_CURRENTLY_ON(BrowserThread::IO);
418
395 if (status == SERVICE_WORKER_ERROR_NOT_FOUND) { 419 if (status == SERVICE_WORKER_ERROR_NOT_FOUND) {
396 // The registration is gone. 420 // The registration is gone.
397 sw_to_registrations_map_.erase(sw_registration_id); 421 sw_to_registrations_map_.erase(sw_registration_id);
398 base::MessageLoop::current()->PostTask( 422 base::MessageLoop::current()->PostTask(
399 FROM_HERE, 423 FROM_HERE,
400 base::Bind(callback, ERROR_TYPE_STORAGE, BackgroundSyncRegistration())); 424 base::Bind(callback, ERROR_TYPE_STORAGE, BackgroundSyncRegistration()));
401 return; 425 return;
402 } 426 }
403 427
404 if (status != SERVICE_WORKER_OK) { 428 if (status != SERVICE_WORKER_OK) {
405 LOG(ERROR) << "BackgroundSync failed to store registration due to backend " 429 LOG(ERROR) << "BackgroundSync failed to store registration due to backend "
406 "failure."; 430 "failure.";
407 DisableAndClearManager( 431 DisableAndClearManager(
408 base::Bind(callback, ERROR_TYPE_STORAGE, BackgroundSyncRegistration())); 432 base::Bind(callback, ERROR_TYPE_STORAGE, BackgroundSyncRegistration()));
409 return; 433 return;
410 } 434 }
411 435
412 // TODO(jkarlin): Run the registration algorithm. 436 FireReadyEvents();
413 base::MessageLoop::current()->PostTask( 437 base::MessageLoop::current()->PostTask(
414 FROM_HERE, base::Bind(callback, ERROR_TYPE_OK, new_registration)); 438 FROM_HERE, base::Bind(callback, ERROR_TYPE_OK, new_registration));
415 } 439 }
416 440
417 void BackgroundSyncManager::RemoveRegistrationFromMap( 441 void BackgroundSyncManager::RemoveRegistrationFromMap(
418 int64 sw_registration_id, 442 int64 sw_registration_id,
419 const RegistrationKey& registration_key) { 443 const RegistrationKey& registration_key) {
444 DCHECK_CURRENTLY_ON(BrowserThread::IO);
420 DCHECK(LookupRegistration(sw_registration_id, registration_key)); 445 DCHECK(LookupRegistration(sw_registration_id, registration_key));
421 446
422 BackgroundSyncRegistrations* registrations = 447 BackgroundSyncRegistrations* registrations =
423 &sw_to_registrations_map_[sw_registration_id]; 448 &sw_to_registrations_map_[sw_registration_id];
424 449
425 registrations->registration_map.erase(registration_key); 450 registrations->registration_map.erase(registration_key);
426 } 451 }
427 452
428 void BackgroundSyncManager::AddRegistrationToMap( 453 void BackgroundSyncManager::AddRegistrationToMap(
429 int64 sw_registration_id, 454 int64 sw_registration_id,
430 const GURL& origin, 455 const GURL& origin,
431 const BackgroundSyncRegistration& sync_registration) { 456 const BackgroundSyncRegistration& sync_registration) {
457 DCHECK_CURRENTLY_ON(BrowserThread::IO);
432 DCHECK_NE(BackgroundSyncRegistration::kInvalidRegistrationId, 458 DCHECK_NE(BackgroundSyncRegistration::kInvalidRegistrationId,
433 sw_registration_id); 459 sw_registration_id);
434 460
435 BackgroundSyncRegistrations* registrations = 461 BackgroundSyncRegistrations* registrations =
436 &sw_to_registrations_map_[sw_registration_id]; 462 &sw_to_registrations_map_[sw_registration_id];
437 registrations->origin = origin; 463 registrations->origin = origin;
438 464
439 RegistrationKey registration_key(sync_registration); 465 RegistrationKey registration_key(sync_registration);
440 registrations->registration_map[registration_key] = sync_registration; 466 registrations->registration_map[registration_key] = sync_registration;
441 } 467 }
442 468
443 void BackgroundSyncManager::StoreDataInBackend( 469 void BackgroundSyncManager::StoreDataInBackend(
444 int64 sw_registration_id, 470 int64 sw_registration_id,
445 const GURL& origin, 471 const GURL& origin,
446 const std::string& backend_key, 472 const std::string& backend_key,
447 const std::string& data, 473 const std::string& data,
448 const ServiceWorkerStorage::StatusCallback& callback) { 474 const ServiceWorkerStorage::StatusCallback& callback) {
475 DCHECK_CURRENTLY_ON(BrowserThread::IO);
476
449 service_worker_context_->StoreRegistrationUserData( 477 service_worker_context_->StoreRegistrationUserData(
450 sw_registration_id, origin, backend_key, data, callback); 478 sw_registration_id, origin, backend_key, data, callback);
451 } 479 }
452 480
453 void BackgroundSyncManager::GetDataFromBackend( 481 void BackgroundSyncManager::GetDataFromBackend(
454 const std::string& backend_key, 482 const std::string& backend_key,
455 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback& 483 const ServiceWorkerStorage::GetUserDataForAllRegistrationsCallback&
456 callback) { 484 callback) {
457 DCHECK_CURRENTLY_ON(BrowserThread::IO); 485 DCHECK_CURRENTLY_ON(BrowserThread::IO);
458 486
459 service_worker_context_->GetUserDataForAllRegistrations(backend_key, 487 service_worker_context_->GetUserDataForAllRegistrations(backend_key,
460 callback); 488 callback);
461 } 489 }
462 490
491 void BackgroundSyncManager::FireOneShotSync(
492 const scoped_refptr<ServiceWorkerVersion>& active_version,
493 const ServiceWorkerVersion::StatusCallback& callback) {
494 DCHECK_CURRENTLY_ON(BrowserThread::IO);
495
496 active_version->DispatchSyncEvent(callback);
497 }
498
463 void BackgroundSyncManager::UnregisterImpl( 499 void BackgroundSyncManager::UnregisterImpl(
464 int64 sw_registration_id, 500 int64 sw_registration_id,
465 const RegistrationKey& registration_key, 501 const RegistrationKey& registration_key,
466 BackgroundSyncRegistration::RegistrationId sync_registration_id, 502 BackgroundSyncRegistration::RegistrationId sync_registration_id,
467 const StatusCallback& callback) { 503 const StatusCallback& callback) {
504 DCHECK_CURRENTLY_ON(BrowserThread::IO);
505
468 if (disabled_) { 506 if (disabled_) {
469 base::MessageLoop::current()->PostTask( 507 base::MessageLoop::current()->PostTask(
470 FROM_HERE, base::Bind(callback, ERROR_TYPE_STORAGE)); 508 FROM_HERE, base::Bind(callback, ERROR_TYPE_STORAGE));
471 return; 509 return;
472 } 510 }
473 511
474 const BackgroundSyncRegistration* existing_registration = 512 const BackgroundSyncRegistration* existing_registration =
475 LookupRegistration(sw_registration_id, registration_key); 513 LookupRegistration(sw_registration_id, registration_key);
476 if (!existing_registration || 514 if (!existing_registration ||
477 existing_registration->id != sync_registration_id) { 515 existing_registration->id != sync_registration_id) {
478 base::MessageLoop::current()->PostTask( 516 base::MessageLoop::current()->PostTask(
479 FROM_HERE, base::Bind(callback, ERROR_TYPE_NOT_FOUND)); 517 FROM_HERE, base::Bind(callback, ERROR_TYPE_NOT_FOUND));
480 return; 518 return;
481 } 519 }
482 520
483 RemoveRegistrationFromMap(sw_registration_id, registration_key); 521 RemoveRegistrationFromMap(sw_registration_id, registration_key);
484 522
485 StoreRegistrations( 523 StoreRegistrations(
486 sw_registration_id, 524 sw_registration_id,
487 base::Bind(&BackgroundSyncManager::UnregisterDidStore, 525 base::Bind(&BackgroundSyncManager::UnregisterDidStore,
488 weak_ptr_factory_.GetWeakPtr(), sw_registration_id, callback)); 526 weak_ptr_factory_.GetWeakPtr(), sw_registration_id, callback));
489 } 527 }
490 528
491 void BackgroundSyncManager::UnregisterDidStore( 529 void BackgroundSyncManager::UnregisterDidStore(
492 int64 sw_registration_id, 530 int64 sw_registration_id,
493 const StatusCallback& callback, 531 const StatusCallback& callback,
494 ServiceWorkerStatusCode status) { 532 ServiceWorkerStatusCode status) {
533 DCHECK_CURRENTLY_ON(BrowserThread::IO);
534
495 if (status == SERVICE_WORKER_ERROR_NOT_FOUND) { 535 if (status == SERVICE_WORKER_ERROR_NOT_FOUND) {
496 // ServiceWorker was unregistered. 536 // ServiceWorker was unregistered.
497 sw_to_registrations_map_.erase(sw_registration_id); 537 sw_to_registrations_map_.erase(sw_registration_id);
498 base::MessageLoop::current()->PostTask( 538 base::MessageLoop::current()->PostTask(
499 FROM_HERE, base::Bind(callback, ERROR_TYPE_STORAGE)); 539 FROM_HERE, base::Bind(callback, ERROR_TYPE_STORAGE));
500 return; 540 return;
501 } 541 }
502 542
503 if (status != SERVICE_WORKER_OK) { 543 if (status != SERVICE_WORKER_OK) {
504 LOG(ERROR) << "BackgroundSync failed to unregister due to backend failure."; 544 LOG(ERROR) << "BackgroundSync failed to unregister due to backend failure.";
505 DisableAndClearManager(base::Bind(callback, ERROR_TYPE_STORAGE)); 545 DisableAndClearManager(base::Bind(callback, ERROR_TYPE_STORAGE));
506 return; 546 return;
507 } 547 }
508 548
509 // TODO(jkarlin): Run the registration algorithm.
510 base::MessageLoop::current()->PostTask(FROM_HERE, 549 base::MessageLoop::current()->PostTask(FROM_HERE,
511 base::Bind(callback, ERROR_TYPE_OK)); 550 base::Bind(callback, ERROR_TYPE_OK));
512 } 551 }
513 552
514 void BackgroundSyncManager::GetRegistrationImpl( 553 void BackgroundSyncManager::GetRegistrationImpl(
515 int64 sw_registration_id, 554 int64 sw_registration_id,
516 const RegistrationKey& registration_key, 555 const RegistrationKey& registration_key,
517 const StatusAndRegistrationCallback& callback) { 556 const StatusAndRegistrationCallback& callback) {
557 DCHECK_CURRENTLY_ON(BrowserThread::IO);
558
518 if (disabled_) { 559 if (disabled_) {
519 base::MessageLoop::current()->PostTask( 560 base::MessageLoop::current()->PostTask(
520 FROM_HERE, 561 FROM_HERE,
521 base::Bind(callback, ERROR_TYPE_STORAGE, BackgroundSyncRegistration())); 562 base::Bind(callback, ERROR_TYPE_STORAGE, BackgroundSyncRegistration()));
522 return; 563 return;
523 } 564 }
524 565
525 const BackgroundSyncRegistration* out_registration = 566 const BackgroundSyncRegistration* out_registration =
526 LookupRegistration(sw_registration_id, registration_key); 567 LookupRegistration(sw_registration_id, registration_key);
527 if (!out_registration) { 568 if (!out_registration) {
528 base::MessageLoop::current()->PostTask( 569 base::MessageLoop::current()->PostTask(
529 FROM_HERE, base::Bind(callback, ERROR_TYPE_NOT_FOUND, 570 FROM_HERE, base::Bind(callback, ERROR_TYPE_NOT_FOUND,
530 BackgroundSyncRegistration())); 571 BackgroundSyncRegistration()));
531 return; 572 return;
532 } 573 }
533 574
534 base::MessageLoop::current()->PostTask( 575 base::MessageLoop::current()->PostTask(
535 FROM_HERE, base::Bind(callback, ERROR_TYPE_OK, *out_registration)); 576 FROM_HERE, base::Bind(callback, ERROR_TYPE_OK, *out_registration));
536 } 577 }
537 578
579 bool BackgroundSyncManager::IsRegistrationReadyToFire(
580 const BackgroundSyncRegistration& registration) {
581 DCHECK_CURRENTLY_ON(BrowserThread::IO);
582
583 // TODO(jkarlin): Add support for firing periodic registrations.
584 if (registration.periodicity == SYNC_PERIODIC)
585 return false;
586
587 if (registration.sync_state != SYNC_STATE_PENDING)
588 return false;
589
590 DCHECK_EQ(SYNC_ONE_SHOT, registration.periodicity);
591
592 return network_observer_->NetworkSufficient(registration.network_state);
593 }
594
595 void BackgroundSyncManager::FireReadyEvents() {
596 DCHECK_CURRENTLY_ON(BrowserThread::IO);
597
598 if (disabled_)
599 return;
600
601 op_scheduler_.ScheduleOperation(
602 base::Bind(&BackgroundSyncManager::FireReadyEventsImpl,
603 weak_ptr_factory_.GetWeakPtr(), MakeEmptyCompletion()));
604 }
605
606 void BackgroundSyncManager::FireReadyEventsImpl(const base::Closure& callback) {
607 DCHECK_CURRENTLY_ON(BrowserThread::IO);
608
609 if (disabled_) {
610 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
611 return;
612 }
613
614 // Find the registrations that are ready to run.
615 std::vector<std::pair<int64, RegistrationKey>> sw_id_and_keys_to_fire;
616
617 for (auto& sw_id_and_registrations : sw_to_registrations_map_) {
618 const int64 service_worker_id = sw_id_and_registrations.first;
619 for (auto& key_and_registration :
620 sw_id_and_registrations.second.registration_map) {
621 BackgroundSyncRegistration* registration = &key_and_registration.second;
622 if (IsRegistrationReadyToFire(*registration)) {
623 sw_id_and_keys_to_fire.push_back(
624 std::make_pair(service_worker_id, key_and_registration.first));
625 // The state change is not saved to persistent storage because
626 // if the sync event is killed mid-sync then it should return to
627 // SYNC_STATE_PENDING.
628 registration->sync_state = SYNC_STATE_FIRING;
629 }
630 }
631 }
632
633 // Fire the sync event of the ready registrations and run |callback| once
634 // they're all done.
635 base::Closure barrier_closure =
636 base::BarrierClosure(sw_id_and_keys_to_fire.size(), base::Bind(callback));
637
638 for (const auto& sw_id_and_key : sw_id_and_keys_to_fire) {
639 int64 service_worker_id = sw_id_and_key.first;
640 const BackgroundSyncRegistration* registration =
641 LookupRegistration(service_worker_id, sw_id_and_key.second);
642
643 service_worker_context_->FindRegistrationForId(
644 service_worker_id, sw_to_registrations_map_[service_worker_id].origin,
645 base::Bind(&BackgroundSyncManager::FireReadyEventsDidFindRegistration,
646 weak_ptr_factory_.GetWeakPtr(), sw_id_and_key.second,
647 registration->id, barrier_closure));
648 }
649 }
650
651 void BackgroundSyncManager::FireReadyEventsDidFindRegistration(
652 const RegistrationKey& registration_key,
653 BackgroundSyncRegistration::RegistrationId registration_id,
654 const base::Closure& callback,
655 ServiceWorkerStatusCode service_worker_status,
656 const scoped_refptr<ServiceWorkerRegistration>&
657 service_worker_registration) {
658 DCHECK_CURRENTLY_ON(BrowserThread::IO);
659
660 if (service_worker_status != SERVICE_WORKER_OK) {
661 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
662 return;
663 }
664
665 FireOneShotSync(
666 service_worker_registration->active_version(),
667 base::Bind(&BackgroundSyncManager::EventComplete,
668 weak_ptr_factory_.GetWeakPtr(), service_worker_registration,
669 service_worker_registration->id(), registration_key,
670 registration_id));
671
672 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
673 }
674
675 // |service_worker_registration| is just to keep the registration alive
676 // while the event is firing.
677 void BackgroundSyncManager::EventComplete(
678 const scoped_refptr<ServiceWorkerRegistration>& service_worker_registration,
679 int64 service_worker_id,
680 const RegistrationKey& key,
681 BackgroundSyncRegistration::RegistrationId sync_registration_id,
682 ServiceWorkerStatusCode status_code) {
683 DCHECK_CURRENTLY_ON(BrowserThread::IO);
684
685 if (disabled_)
686 return;
687
688 op_scheduler_.ScheduleOperation(
689 base::Bind(&BackgroundSyncManager::EventCompleteImpl,
690 weak_ptr_factory_.GetWeakPtr(), service_worker_id, key,
691 sync_registration_id, status_code, MakeEmptyCompletion()));
692 }
693
694 void BackgroundSyncManager::EventCompleteImpl(
695 int64 service_worker_id,
696 const RegistrationKey& key,
697 BackgroundSyncRegistration::RegistrationId sync_registration_id,
698 ServiceWorkerStatusCode status_code,
699 const base::Closure& callback) {
700 DCHECK_CURRENTLY_ON(BrowserThread::IO);
701
702 if (disabled_) {
703 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
704 return;
705 }
706
707 BackgroundSyncRegistration* registration =
708 LookupRegistration(service_worker_id, key);
709 if (!registration || registration->id != sync_registration_id) {
710 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
711 return;
712 }
713
714 if (registration->periodicity == SYNC_ONE_SHOT) {
715 if (status_code != SERVICE_WORKER_OK) {
716 // TODO(jkarlin) Fire the sync event on the next page load controlled by
717 // this registration. (crbug.com/479665)
718 registration->sync_state = SYNC_STATE_FAILED;
719 } else {
720 registration = nullptr;
721 RemoveRegistrationFromMap(service_worker_id, key);
722 }
723 } else {
724 // TODO(jkarlin): Add support for running periodic syncs. (crbug.com/479674)
725 NOTREACHED();
726 }
727
728 StoreRegistrations(
729 service_worker_id,
730 base::Bind(&BackgroundSyncManager::EventCompleteDidStore,
731 weak_ptr_factory_.GetWeakPtr(), service_worker_id, callback));
732 }
733
734 void BackgroundSyncManager::EventCompleteDidStore(
735 int64 service_worker_id,
736 const base::Closure& callback,
737 ServiceWorkerStatusCode status_code) {
738 DCHECK_CURRENTLY_ON(BrowserThread::IO);
739
740 if (status_code == SERVICE_WORKER_ERROR_NOT_FOUND) {
741 // The registration is gone.
742 sw_to_registrations_map_.erase(service_worker_id);
743 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
744 return;
745 }
746
747 if (status_code != SERVICE_WORKER_OK) {
748 LOG(ERROR) << "BackgroundSync failed to store registration due to backend "
749 "failure.";
750 DisableAndClearManager(base::Bind(callback));
751 return;
752 }
753
754 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
755 }
756
538 void BackgroundSyncManager::OnRegistrationDeletedImpl( 757 void BackgroundSyncManager::OnRegistrationDeletedImpl(
539 int64 registration_id, 758 int64 registration_id,
540 const base::Closure& callback) { 759 const base::Closure& callback) {
760 DCHECK_CURRENTLY_ON(BrowserThread::IO);
761
541 // The backend (ServiceWorkerStorage) will delete the data, so just delete the 762 // The backend (ServiceWorkerStorage) will delete the data, so just delete the
542 // memory representation here. 763 // memory representation here.
543 sw_to_registrations_map_.erase(registration_id); 764 sw_to_registrations_map_.erase(registration_id);
544 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback)); 765 base::MessageLoop::current()->PostTask(FROM_HERE, base::Bind(callback));
545 } 766 }
546 767
547 void BackgroundSyncManager::OnStorageWipedImpl(const base::Closure& callback) { 768 void BackgroundSyncManager::OnStorageWipedImpl(const base::Closure& callback) {
769 DCHECK_CURRENTLY_ON(BrowserThread::IO);
770
548 sw_to_registrations_map_.clear(); 771 sw_to_registrations_map_.clear();
549 disabled_ = false; 772 disabled_ = false;
550 InitImpl(callback); 773 InitImpl(callback);
551 } 774 }
552 775
553 void BackgroundSyncManager::OnNetworkChanged() { 776 void BackgroundSyncManager::OnNetworkChanged() {
554 // TODO(jkarlin): Run the scheduling algorithm here if initialized and not 777 DCHECK_CURRENTLY_ON(BrowserThread::IO);
555 // disabled. 778
779 FireReadyEvents();
556 } 780 }
557 781
558 void BackgroundSyncManager::PendingStatusAndRegistrationCallback( 782 void BackgroundSyncManager::PendingStatusAndRegistrationCallback(
559 const StatusAndRegistrationCallback& callback, 783 const StatusAndRegistrationCallback& callback,
560 ErrorType error, 784 ErrorType error,
561 const BackgroundSyncRegistration& sync_registration) { 785 const BackgroundSyncRegistration& sync_registration) {
786 DCHECK_CURRENTLY_ON(BrowserThread::IO);
787
562 // The callback might delete this object, so hang onto a weak ptr to find out. 788 // The callback might delete this object, so hang onto a weak ptr to find out.
563 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr(); 789 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr();
564 callback.Run(error, sync_registration); 790 callback.Run(error, sync_registration);
565 if (manager) 791 if (manager)
566 op_scheduler_.CompleteOperationAndRunNext(); 792 op_scheduler_.CompleteOperationAndRunNext();
567 } 793 }
568 794
569 void BackgroundSyncManager::PendingStatusCallback( 795 void BackgroundSyncManager::PendingStatusCallback(
570 const StatusCallback& callback, 796 const StatusCallback& callback,
571 ErrorType error) { 797 ErrorType error) {
798 DCHECK_CURRENTLY_ON(BrowserThread::IO);
799
572 // The callback might delete this object, so hang onto a weak ptr to find out. 800 // The callback might delete this object, so hang onto a weak ptr to find out.
573 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr(); 801 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr();
574 callback.Run(error); 802 callback.Run(error);
575 if (manager) 803 if (manager)
576 op_scheduler_.CompleteOperationAndRunNext(); 804 op_scheduler_.CompleteOperationAndRunNext();
577 } 805 }
578 806
579 void BackgroundSyncManager::PendingClosure(const base::Closure& callback) { 807 void BackgroundSyncManager::PendingClosure(const base::Closure& callback) {
808 DCHECK_CURRENTLY_ON(BrowserThread::IO);
809
580 // The callback might delete this object, so hang onto a weak ptr to find out. 810 // The callback might delete this object, so hang onto a weak ptr to find out.
581 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr(); 811 base::WeakPtr<BackgroundSyncManager> manager = weak_ptr_factory_.GetWeakPtr();
582 callback.Run(); 812 callback.Run();
583 if (manager) 813 if (manager)
584 op_scheduler_.CompleteOperationAndRunNext(); 814 op_scheduler_.CompleteOperationAndRunNext();
585 } 815 }
586 816
587 base::Closure BackgroundSyncManager::MakeEmptyCompletion() { 817 base::Closure BackgroundSyncManager::MakeEmptyCompletion() {
818 DCHECK_CURRENTLY_ON(BrowserThread::IO);
819
588 return base::Bind(&BackgroundSyncManager::PendingClosure, 820 return base::Bind(&BackgroundSyncManager::PendingClosure,
589 weak_ptr_factory_.GetWeakPtr(), 821 weak_ptr_factory_.GetWeakPtr(),
590 base::Bind(base::DoNothing)); 822 base::Bind(base::DoNothing));
591 } 823 }
592 824
593 BackgroundSyncManager::StatusAndRegistrationCallback 825 BackgroundSyncManager::StatusAndRegistrationCallback
594 BackgroundSyncManager::MakeStatusAndRegistrationCompletion( 826 BackgroundSyncManager::MakeStatusAndRegistrationCompletion(
595 const StatusAndRegistrationCallback& callback) { 827 const StatusAndRegistrationCallback& callback) {
828 DCHECK_CURRENTLY_ON(BrowserThread::IO);
829
596 return base::Bind( 830 return base::Bind(
597 &BackgroundSyncManager::PendingStatusAndRegistrationCallback, 831 &BackgroundSyncManager::PendingStatusAndRegistrationCallback,
598 weak_ptr_factory_.GetWeakPtr(), callback); 832 weak_ptr_factory_.GetWeakPtr(), callback);
599 } 833 }
600 834
601 BackgroundSyncManager::StatusCallback 835 BackgroundSyncManager::StatusCallback
602 BackgroundSyncManager::MakeStatusCompletion(const StatusCallback& callback) { 836 BackgroundSyncManager::MakeStatusCompletion(const StatusCallback& callback) {
837 DCHECK_CURRENTLY_ON(BrowserThread::IO);
838
603 return base::Bind(&BackgroundSyncManager::PendingStatusCallback, 839 return base::Bind(&BackgroundSyncManager::PendingStatusCallback,
604 weak_ptr_factory_.GetWeakPtr(), callback); 840 weak_ptr_factory_.GetWeakPtr(), callback);
605 } 841 }
606 842
607 } // namespace content 843 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698