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

Side by Side Diff: sync/internal_api/sync_manager_impl.cc

Issue 10804039: Make SyncBackendRegistrar aware of loaded data (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 8 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « sync/internal_api/sync_manager_impl.h ('k') | sync/internal_api/syncapi_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "sync/internal_api/sync_manager_impl.h" 5 #include "sync/internal_api/sync_manager_impl.h"
6 6
7 #include <string> 7 #include <string>
8 8
9 #include "base/base64.h" 9 #include "base/base64.h"
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
286 } 286 }
287 287
288 void SyncManagerImpl::ThrowUnrecoverableError() { 288 void SyncManagerImpl::ThrowUnrecoverableError() {
289 DCHECK(thread_checker_.CalledOnValidThread()); 289 DCHECK(thread_checker_.CalledOnValidThread());
290 ReadTransaction trans(FROM_HERE, GetUserShare()); 290 ReadTransaction trans(FROM_HERE, GetUserShare());
291 trans.GetWrappedTrans()->OnUnrecoverableError( 291 trans.GetWrappedTrans()->OnUnrecoverableError(
292 FROM_HERE, "Simulating unrecoverable error for testing purposes."); 292 FROM_HERE, "Simulating unrecoverable error for testing purposes.");
293 } 293 }
294 294
295 ModelTypeSet SyncManagerImpl::InitialSyncEndedTypes() { 295 ModelTypeSet SyncManagerImpl::InitialSyncEndedTypes() {
296 DCHECK(initialized_);
297 return directory()->initial_sync_ended_types(); 296 return directory()->initial_sync_ended_types();
298 } 297 }
299 298
300 ModelTypeSet SyncManagerImpl::GetTypesWithEmptyProgressMarkerToken( 299 ModelTypeSet SyncManagerImpl::GetTypesWithEmptyProgressMarkerToken(
301 ModelTypeSet types) { 300 ModelTypeSet types) {
302 DCHECK(initialized_);
303 ModelTypeSet result; 301 ModelTypeSet result;
304 for (ModelTypeSet::Iterator i = types.First(); i.Good(); i.Inc()) { 302 for (ModelTypeSet::Iterator i = types.First(); i.Good(); i.Inc()) {
305 sync_pb::DataTypeProgressMarker marker; 303 sync_pb::DataTypeProgressMarker marker;
306 directory()->GetDownloadProgress(i.Get(), &marker); 304 directory()->GetDownloadProgress(i.Get(), &marker);
307 305
308 if (marker.token().empty()) 306 if (marker.token().empty())
309 result.Put(i.Get()); 307 result.Put(i.Get());
310 308
311 } 309 }
312 return result; 310 return result;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
358 } 356 }
359 357
360 bool SyncManagerImpl::Init( 358 bool SyncManagerImpl::Init(
361 const FilePath& database_location, 359 const FilePath& database_location,
362 const WeakHandle<JsEventHandler>& event_handler, 360 const WeakHandle<JsEventHandler>& event_handler,
363 const std::string& sync_server_and_path, 361 const std::string& sync_server_and_path,
364 int port, 362 int port,
365 bool use_ssl, 363 bool use_ssl,
366 const scoped_refptr<base::TaskRunner>& blocking_task_runner, 364 const scoped_refptr<base::TaskRunner>& blocking_task_runner,
367 scoped_ptr<HttpPostProviderFactory> post_factory, 365 scoped_ptr<HttpPostProviderFactory> post_factory,
368 const ModelSafeRoutingInfo& model_safe_routing_info,
369 const std::vector<ModelSafeWorker*>& workers, 366 const std::vector<ModelSafeWorker*>& workers,
370 ExtensionsActivityMonitor* extensions_activity_monitor, 367 ExtensionsActivityMonitor* extensions_activity_monitor,
371 SyncManager::ChangeDelegate* change_delegate, 368 SyncManager::ChangeDelegate* change_delegate,
372 const SyncCredentials& credentials, 369 const SyncCredentials& credentials,
373 scoped_ptr<SyncNotifier> sync_notifier, 370 scoped_ptr<SyncNotifier> sync_notifier,
374 const std::string& restored_key_for_bootstrapping, 371 const std::string& restored_key_for_bootstrapping,
375 scoped_ptr<InternalComponentsFactory> internal_components_factory, 372 scoped_ptr<InternalComponentsFactory> internal_components_factory,
376 Encryptor* encryptor, 373 Encryptor* encryptor,
377 UnrecoverableErrorHandler* unrecoverable_error_handler, 374 UnrecoverableErrorHandler* unrecoverable_error_handler,
378 ReportUnrecoverableErrorFunction report_unrecoverable_error_function) { 375 ReportUnrecoverableErrorFunction report_unrecoverable_error_function) {
379 CHECK(!initialized_); 376 CHECK(!initialized_);
380 DCHECK(thread_checker_.CalledOnValidThread()); 377 DCHECK(thread_checker_.CalledOnValidThread());
381 DCHECK(post_factory.get()); 378 DCHECK(post_factory.get());
379 DCHECK(!credentials.email.empty());
380 DCHECK(!credentials.sync_token.empty());
382 DVLOG(1) << "SyncManager starting Init..."; 381 DVLOG(1) << "SyncManager starting Init...";
383 382
384 weak_handle_this_ = MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()); 383 weak_handle_this_ = MakeWeakHandle(weak_ptr_factory_.GetWeakPtr());
385 384
386 blocking_task_runner_ = blocking_task_runner; 385 blocking_task_runner_ = blocking_task_runner;
387 386
388 change_delegate_ = change_delegate; 387 change_delegate_ = change_delegate;
389 388
390 sync_notifier_ = sync_notifier.Pass(); 389 sync_notifier_ = sync_notifier.Pass();
391 390
392 AddObserver(&js_sync_manager_observer_); 391 AddObserver(&js_sync_manager_observer_);
393 SetJsEventHandler(event_handler); 392 SetJsEventHandler(event_handler);
394 393
395 AddObserver(&debug_info_event_listener_); 394 AddObserver(&debug_info_event_listener_);
396 395
397 database_path_ = database_location.Append( 396 database_path_ = database_location.Append(
398 syncable::Directory::kSyncDatabaseFilename); 397 syncable::Directory::kSyncDatabaseFilename);
399 encryptor_ = encryptor; 398 encryptor_ = encryptor;
400 unrecoverable_error_handler_ = unrecoverable_error_handler; 399 unrecoverable_error_handler_ = unrecoverable_error_handler;
401 report_unrecoverable_error_function_ = report_unrecoverable_error_function; 400 report_unrecoverable_error_function_ = report_unrecoverable_error_function;
402 401
403 FilePath absolute_db_path(database_path_); 402 FilePath absolute_db_path(database_path_);
404 file_util::AbsolutePath(&absolute_db_path); 403 file_util::AbsolutePath(&absolute_db_path);
405 scoped_ptr<syncable::DirectoryBackingStore> backing_store = 404 scoped_ptr<syncable::DirectoryBackingStore> backing_store =
406 internal_components_factory->BuildDirectoryBackingStore( 405 internal_components_factory->BuildDirectoryBackingStore(
407 credentials.email, absolute_db_path).Pass(); 406 credentials.email, absolute_db_path).Pass();
408 407
409 DCHECK(backing_store.get()); 408 DCHECK(backing_store.get());
409 share_.name = credentials.email;
410 share_.directory.reset( 410 share_.directory.reset(
411 new syncable::Directory(encryptor_, 411 new syncable::Directory(encryptor_,
412 unrecoverable_error_handler_, 412 unrecoverable_error_handler_,
413 report_unrecoverable_error_function_, 413 report_unrecoverable_error_function_,
414 backing_store.release())); 414 backing_store.release()));
415 415
416 connection_manager_.reset(new SyncAPIServerConnectionManager( 416 connection_manager_.reset(new SyncAPIServerConnectionManager(
417 sync_server_and_path, port, use_ssl, post_factory.release())); 417 sync_server_and_path, port, use_ssl, post_factory.release()));
418 connection_manager_->AddListener(this);
418 419
419 net::NetworkChangeNotifier::AddIPAddressObserver(this); 420 DVLOG(1) << "Username: " << username_for_share();
420 observing_ip_address_changes_ = true; 421 if (!OpenDirectory()) {
422 FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
423 OnInitializationComplete(
424 MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()),
425 false, syncer::ModelTypeSet()));
426 return false;
427 }
421 428
422 connection_manager_->AddListener(this); 429 // Retrieve and set the sync notifier state.
430 std::string unique_id = directory()->cache_guid();
431 DVLOG(1) << "Read notification unique ID: " << unique_id;
432 allstatus_.SetUniqueId(unique_id);
433 sync_notifier_->SetUniqueId(unique_id);
434
435 std::string state = directory()->GetNotificationState();
436 if (VLOG_IS_ON(1)) {
437 std::string encoded_state;
438 base::Base64Encode(state, &encoded_state);
439 DVLOG(1) << "Read notification state: " << encoded_state;
440 }
441
442 // TODO(tim): Remove once invalidation state has been migrated to new
443 // InvalidationStateTracker store. Bug 124140.
444 sync_notifier_->SetStateDeprecated(state);
423 445
424 // Build a SyncSessionContext and store the worker in it. 446 // Build a SyncSessionContext and store the worker in it.
425 DVLOG(1) << "Sync is bringing up SyncSessionContext."; 447 DVLOG(1) << "Sync is bringing up SyncSessionContext.";
426 std::vector<SyncEngineEventListener*> listeners; 448 std::vector<SyncEngineEventListener*> listeners;
427 listeners.push_back(&allstatus_); 449 listeners.push_back(&allstatus_);
428 listeners.push_back(this); 450 listeners.push_back(this);
429 session_context_ = internal_components_factory->BuildContext( 451 session_context_ = internal_components_factory->BuildContext(
430 connection_manager_.get(), 452 connection_manager_.get(),
431 directory(), 453 directory(),
432 model_safe_routing_info,
433 workers, 454 workers,
434 extensions_activity_monitor, 455 extensions_activity_monitor,
435 &throttled_data_type_tracker_, 456 &throttled_data_type_tracker_,
436 listeners, 457 listeners,
437 &debug_info_event_listener_, 458 &debug_info_event_listener_,
438 &traffic_recorder_).Pass(); 459 &traffic_recorder_).Pass();
439 session_context_->set_account_name(credentials.email); 460 session_context_->set_account_name(credentials.email);
440 scheduler_ = internal_components_factory->BuildScheduler( 461 scheduler_ = internal_components_factory->BuildScheduler(
441 name_, session_context_.get()).Pass(); 462 name_, session_context_.get()).Pass();
442 463
443 bool success = SignIn(credentials); 464 scheduler_->Start(SyncScheduler::CONFIGURATION_MODE);
444 465
445 if (success) { 466 initialized_ = true;
446 scheduler_->Start(SyncScheduler::CONFIGURATION_MODE);
447 467
448 initialized_ = true; 468 net::NetworkChangeNotifier::AddIPAddressObserver(this);
469 observing_ip_address_changes_ = true;
449 470
450 // Unapplied datatypes (those that do not have initial sync ended set) get 471 UpdateCredentials(credentials);
451 // re-downloaded during any configuration. But, it's possible for a datatype
452 // to have a progress marker but not have initial sync ended yet, making
453 // it a candidate for migration. This is a problem, as the DataTypeManager
454 // does not support a migration while it's already in the middle of a
455 // configuration. As a result, any partially synced datatype can stall the
456 // DTM, waiting for the configuration to complete, which it never will due
457 // to the migration error. In addition, a partially synced nigori will
458 // trigger the migration logic before the backend is initialized, resulting
459 // in crashes. We therefore detect and purge any partially synced types as
460 // part of initialization.
461 if (!PurgePartiallySyncedTypes())
462 success = false;
463 472
464 // Cryptographer should only be accessed while holding a 473 // Cryptographer should only be accessed while holding a
465 // transaction. Grabbing the user share for the transaction 474 // transaction. Grabbing the user share for the transaction
466 // checks the initialization state, so this must come after 475 // checks the initialization state, so this must come after
467 // |initialized_| is set to true. 476 // |initialized_| is set to true.
468 ReadTransaction trans(FROM_HERE, GetUserShare()); 477 ReadTransaction trans(FROM_HERE, GetUserShare());
469 trans.GetCryptographer()->Bootstrap(restored_key_for_bootstrapping); 478 trans.GetCryptographer()->Bootstrap(restored_key_for_bootstrapping);
470 trans.GetCryptographer()->AddObserver(this); 479 trans.GetCryptographer()->AddObserver(this);
471 }
472 480
473 // Notify that initialization is complete. Note: This should be the last to
474 // execute if |signed_in| is false. Reason being in that case we would
475 // post a task to shutdown sync. But if this function posts any other tasks
476 // on the UI thread and if shutdown wins then that tasks would execute on
477 // a freed pointer. This is because UI thread is not shut down.
478 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 481 FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
479 OnInitializationComplete( 482 OnInitializationComplete(
480 MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()), 483 MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()),
481 success)); 484 true, InitialSyncEndedTypes()));
482 if (!success) 485 return true;
483 return false;
484
485 return success;
486 } 486 }
487 487
488 void SyncManagerImpl::RefreshNigori(const std::string& chrome_version, 488 void SyncManagerImpl::RefreshNigori(const std::string& chrome_version,
489 const base::Closure& done_callback) { 489 const base::Closure& done_callback) {
490 DCHECK(initialized_); 490 DCHECK(initialized_);
491 DCHECK(thread_checker_.CalledOnValidThread()); 491 DCHECK(thread_checker_.CalledOnValidThread());
492 GetSessionName( 492 GetSessionName(
493 blocking_task_runner_, 493 blocking_task_runner_,
494 base::Bind( 494 base::Bind(
495 &SyncManagerImpl::UpdateCryptographerAndNigoriCallback, 495 &SyncManagerImpl::UpdateCryptographerAndNigoriCallback,
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
651 MakeWeakHandle(js_mutation_event_observer_.AsWeakPtr())); 651 MakeWeakHandle(js_mutation_event_observer_.AsWeakPtr()));
652 652
653 syncable::DirOpenResult open_result = syncable::NOT_INITIALIZED; 653 syncable::DirOpenResult open_result = syncable::NOT_INITIALIZED;
654 open_result = directory()->Open(username_for_share(), this, 654 open_result = directory()->Open(username_for_share(), this,
655 transaction_observer); 655 transaction_observer);
656 if (open_result != syncable::OPENED) { 656 if (open_result != syncable::OPENED) {
657 LOG(ERROR) << "Could not open share for:" << username_for_share(); 657 LOG(ERROR) << "Could not open share for:" << username_for_share();
658 return false; 658 return false;
659 } 659 }
660 660
661 // Unapplied datatypes (those that do not have initial sync ended set) get
662 // re-downloaded during any configuration. But, it's possible for a datatype
663 // to have a progress marker but not have initial sync ended yet, making
664 // it a candidate for migration. This is a problem, as the DataTypeManager
665 // does not support a migration while it's already in the middle of a
666 // configuration. As a result, any partially synced datatype can stall the
667 // DTM, waiting for the configuration to complete, which it never will due
668 // to the migration error. In addition, a partially synced nigori will
669 // trigger the migration logic before the backend is initialized, resulting
670 // in crashes. We therefore detect and purge any partially synced types as
671 // part of initialization.
672 if (!PurgePartiallySyncedTypes())
673 return false;
674
661 connection_manager_->set_client_id(directory()->cache_guid()); 675 connection_manager_->set_client_id(directory()->cache_guid());
662 return true; 676 return true;
663 } 677 }
664 678
665 bool SyncManagerImpl::SignIn(const SyncCredentials& credentials) {
666 DCHECK(thread_checker_.CalledOnValidThread());
667 DCHECK(share_.name.empty());
668 share_.name = credentials.email;
669
670 DVLOG(1) << "Signing in user: " << username_for_share();
671 if (!OpenDirectory())
672 return false;
673
674 // Retrieve and set the sync notifier state. This should be done
675 // only after OpenDirectory is called.
676 std::string unique_id = directory()->cache_guid();
677 std::string state = directory()->GetNotificationState();
678 DVLOG(1) << "Read notification unique ID: " << unique_id;
679 if (VLOG_IS_ON(1)) {
680 std::string encoded_state;
681 base::Base64Encode(state, &encoded_state);
682 DVLOG(1) << "Read notification state: " << encoded_state;
683 }
684 allstatus_.SetUniqueId(unique_id);
685 sync_notifier_->SetUniqueId(unique_id);
686 // TODO(tim): Remove once invalidation state has been migrated to new
687 // InvalidationStateTracker store. Bug 124140.
688 sync_notifier_->SetStateDeprecated(state);
689
690 UpdateCredentials(credentials);
691 return true;
692 }
693
694 bool SyncManagerImpl::PurgePartiallySyncedTypes() { 679 bool SyncManagerImpl::PurgePartiallySyncedTypes() {
695 ModelTypeSet partially_synced_types = ModelTypeSet::All(); 680 ModelTypeSet partially_synced_types = ModelTypeSet::All();
696 partially_synced_types.RemoveAll(InitialSyncEndedTypes()); 681 partially_synced_types.RemoveAll(InitialSyncEndedTypes());
697 partially_synced_types.RemoveAll(GetTypesWithEmptyProgressMarkerToken( 682 partially_synced_types.RemoveAll(GetTypesWithEmptyProgressMarkerToken(
698 ModelTypeSet::All())); 683 ModelTypeSet::All()));
699 684
700 UMA_HISTOGRAM_COUNTS("Sync.PartiallySyncedTypes", 685 UMA_HISTOGRAM_COUNTS("Sync.PartiallySyncedTypes",
701 partially_synced_types.Size()); 686 partially_synced_types.Size());
702 if (partially_synced_types.Empty()) 687 if (partially_synced_types.Empty())
703 return true; 688 return true;
704 return directory()->PurgeEntriesWithTypeIn(partially_synced_types); 689 return directory()->PurgeEntriesWithTypeIn(partially_synced_types);
705 } 690 }
706 691
707 void SyncManagerImpl::UpdateCredentials( 692 void SyncManagerImpl::UpdateCredentials(
708 const SyncCredentials& credentials) { 693 const SyncCredentials& credentials) {
709 DCHECK(thread_checker_.CalledOnValidThread()); 694 DCHECK(thread_checker_.CalledOnValidThread());
695 DCHECK(initialized_);
710 DCHECK_EQ(credentials.email, share_.name); 696 DCHECK_EQ(credentials.email, share_.name);
711 DCHECK(!credentials.email.empty()); 697 DCHECK(!credentials.email.empty());
712 DCHECK(!credentials.sync_token.empty()); 698 DCHECK(!credentials.sync_token.empty());
713 699
714 observing_ip_address_changes_ = true; 700 observing_ip_address_changes_ = true;
715 if (connection_manager_->set_auth_token(credentials.sync_token)) { 701 if (!connection_manager_->set_auth_token(credentials.sync_token))
716 sync_notifier_->UpdateCredentials( 702 return; // Auth token is known to be invalid, so exit early.
717 credentials.email, credentials.sync_token); 703
718 if (initialized_) { 704 sync_notifier_->UpdateCredentials(credentials.email, credentials.sync_token);
719 scheduler_->OnCredentialsUpdated(); 705 scheduler_->OnCredentialsUpdated();
720 }
721 }
722 } 706 }
723 707
724 void SyncManagerImpl::UpdateEnabledTypes( 708 void SyncManagerImpl::UpdateEnabledTypes(
725 const ModelTypeSet& enabled_types) { 709 const ModelTypeSet& enabled_types) {
726 DCHECK(thread_checker_.CalledOnValidThread()); 710 DCHECK(thread_checker_.CalledOnValidThread());
727 sync_notifier_->UpdateRegisteredIds(this, 711 sync_notifier_->UpdateRegisteredIds(this,
728 ModelTypeSetToObjectIdSet(enabled_types)); 712 ModelTypeSetToObjectIdSet(enabled_types));
729 } 713 }
730 714
731 void SyncManagerImpl::SetEncryptionPassphrase( 715 void SyncManagerImpl::SetEncryptionPassphrase(
(...skipping 1131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1863 int SyncManagerImpl::GetDefaultNudgeDelay() { 1847 int SyncManagerImpl::GetDefaultNudgeDelay() {
1864 return kDefaultNudgeDelayMilliseconds; 1848 return kDefaultNudgeDelayMilliseconds;
1865 } 1849 }
1866 1850
1867 // static. 1851 // static.
1868 int SyncManagerImpl::GetPreferencesNudgeDelay() { 1852 int SyncManagerImpl::GetPreferencesNudgeDelay() {
1869 return kPreferencesNudgeDelayMilliseconds; 1853 return kPreferencesNudgeDelayMilliseconds;
1870 } 1854 }
1871 1855
1872 } // namespace syncer 1856 } // namespace syncer
OLDNEW
« no previous file with comments | « sync/internal_api/sync_manager_impl.h ('k') | sync/internal_api/syncapi_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698