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

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: More init changes 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 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
285 } 285 }
286 286
287 void SyncManagerImpl::ThrowUnrecoverableError() { 287 void SyncManagerImpl::ThrowUnrecoverableError() {
288 DCHECK(thread_checker_.CalledOnValidThread()); 288 DCHECK(thread_checker_.CalledOnValidThread());
289 ReadTransaction trans(FROM_HERE, GetUserShare()); 289 ReadTransaction trans(FROM_HERE, GetUserShare());
290 trans.GetWrappedTrans()->OnUnrecoverableError( 290 trans.GetWrappedTrans()->OnUnrecoverableError(
291 FROM_HERE, "Simulating unrecoverable error for testing purposes."); 291 FROM_HERE, "Simulating unrecoverable error for testing purposes.");
292 } 292 }
293 293
294 ModelTypeSet SyncManagerImpl::InitialSyncEndedTypes() { 294 ModelTypeSet SyncManagerImpl::InitialSyncEndedTypes() {
295 DCHECK(initialized_);
tim (not reviewing) 2012/07/26 22:33:48 It still seems wrong from a client of SyncManager
rlarocque 2012/07/26 22:52:20 My first instinct was to downgrade this to a DCHEC
tim (not reviewing) 2012/07/27 01:54:32 True re: asserting on a pointer we're about to der
rlarocque 2012/07/27 17:47:19 Resolved offline.
296 return directory()->initial_sync_ended_types(); 295 return directory()->initial_sync_ended_types();
297 } 296 }
298 297
299 ModelTypeSet SyncManagerImpl::GetTypesWithEmptyProgressMarkerToken( 298 ModelTypeSet SyncManagerImpl::GetTypesWithEmptyProgressMarkerToken(
300 ModelTypeSet types) { 299 ModelTypeSet types) {
301 DCHECK(initialized_);
302 ModelTypeSet result; 300 ModelTypeSet result;
303 for (ModelTypeSet::Iterator i = types.First(); i.Good(); i.Inc()) { 301 for (ModelTypeSet::Iterator i = types.First(); i.Good(); i.Inc()) {
304 sync_pb::DataTypeProgressMarker marker; 302 sync_pb::DataTypeProgressMarker marker;
305 directory()->GetDownloadProgress(i.Get(), &marker); 303 directory()->GetDownloadProgress(i.Get(), &marker);
306 304
307 if (marker.token().empty()) 305 if (marker.token().empty())
308 result.Put(i.Get()); 306 result.Put(i.Get());
309 307
310 } 308 }
311 return result; 309 return result;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 } 360 }
363 361
364 bool SyncManagerImpl::Init( 362 bool SyncManagerImpl::Init(
365 const FilePath& database_location, 363 const FilePath& database_location,
366 const WeakHandle<JsEventHandler>& event_handler, 364 const WeakHandle<JsEventHandler>& event_handler,
367 const std::string& sync_server_and_path, 365 const std::string& sync_server_and_path,
368 int port, 366 int port,
369 bool use_ssl, 367 bool use_ssl,
370 const scoped_refptr<base::TaskRunner>& blocking_task_runner, 368 const scoped_refptr<base::TaskRunner>& blocking_task_runner,
371 scoped_ptr<HttpPostProviderFactory> post_factory, 369 scoped_ptr<HttpPostProviderFactory> post_factory,
372 const ModelSafeRoutingInfo& model_safe_routing_info,
373 const std::vector<ModelSafeWorker*>& workers, 370 const std::vector<ModelSafeWorker*>& workers,
374 ExtensionsActivityMonitor* extensions_activity_monitor, 371 ExtensionsActivityMonitor* extensions_activity_monitor,
375 SyncManager::ChangeDelegate* change_delegate, 372 SyncManager::ChangeDelegate* change_delegate,
376 const SyncCredentials& credentials, 373 const SyncCredentials& credentials,
377 scoped_ptr<SyncNotifier> sync_notifier, 374 scoped_ptr<SyncNotifier> sync_notifier,
378 const std::string& restored_key_for_bootstrapping, 375 const std::string& restored_key_for_bootstrapping,
379 scoped_ptr<InternalComponentsFactory> internal_components_factory, 376 scoped_ptr<InternalComponentsFactory> internal_components_factory,
380 Encryptor* encryptor, 377 Encryptor* encryptor,
381 UnrecoverableErrorHandler* unrecoverable_error_handler, 378 UnrecoverableErrorHandler* unrecoverable_error_handler,
382 ReportUnrecoverableErrorFunction report_unrecoverable_error_function) { 379 ReportUnrecoverableErrorFunction report_unrecoverable_error_function) {
383 CHECK(!initialized_); 380 CHECK(!initialized_);
384 DCHECK(thread_checker_.CalledOnValidThread()); 381 DCHECK(thread_checker_.CalledOnValidThread());
385 DCHECK(post_factory.get()); 382 DCHECK(post_factory.get());
383 DCHECK(!credentials.email.empty());
384 DCHECK(!credentials.sync_token.empty());
386 DVLOG(1) << "SyncManager starting Init..."; 385 DVLOG(1) << "SyncManager starting Init...";
387 386
388 weak_handle_this_ = MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()); 387 weak_handle_this_ = MakeWeakHandle(weak_ptr_factory_.GetWeakPtr());
389 388
390 blocking_task_runner_ = blocking_task_runner; 389 blocking_task_runner_ = blocking_task_runner;
391 390
392 change_delegate_ = change_delegate; 391 change_delegate_ = change_delegate;
393 392
394 sync_notifier_ = sync_notifier.Pass(); 393 sync_notifier_ = sync_notifier.Pass();
395 394
396 AddObserver(&js_sync_manager_observer_); 395 AddObserver(&js_sync_manager_observer_);
397 SetJsEventHandler(event_handler); 396 SetJsEventHandler(event_handler);
398 397
399 AddObserver(&debug_info_event_listener_); 398 AddObserver(&debug_info_event_listener_);
400 399
401 database_path_ = database_location.Append( 400 database_path_ = database_location.Append(
402 syncable::Directory::kSyncDatabaseFilename); 401 syncable::Directory::kSyncDatabaseFilename);
403 encryptor_ = encryptor; 402 encryptor_ = encryptor;
404 unrecoverable_error_handler_ = unrecoverable_error_handler; 403 unrecoverable_error_handler_ = unrecoverable_error_handler;
405 report_unrecoverable_error_function_ = report_unrecoverable_error_function; 404 report_unrecoverable_error_function_ = report_unrecoverable_error_function;
406 405
407 FilePath absolute_db_path(database_path_); 406 FilePath absolute_db_path(database_path_);
408 file_util::AbsolutePath(&absolute_db_path); 407 file_util::AbsolutePath(&absolute_db_path);
409 scoped_ptr<syncable::DirectoryBackingStore> backing_store = 408 scoped_ptr<syncable::DirectoryBackingStore> backing_store =
410 internal_components_factory->BuildDirectoryBackingStore( 409 internal_components_factory->BuildDirectoryBackingStore(
411 credentials.email, absolute_db_path).Pass(); 410 credentials.email, absolute_db_path).Pass();
412 411
413 DCHECK(backing_store.get()); 412 DCHECK(backing_store.get());
413 share_.name = credentials.email;
414 share_.directory.reset( 414 share_.directory.reset(
415 new syncable::Directory(encryptor_, 415 new syncable::Directory(encryptor_,
416 unrecoverable_error_handler_, 416 unrecoverable_error_handler_,
417 report_unrecoverable_error_function_, 417 report_unrecoverable_error_function_,
418 backing_store.release())); 418 backing_store.release()));
419 419
420 connection_manager_.reset(new SyncAPIServerConnectionManager( 420 connection_manager_.reset(new SyncAPIServerConnectionManager(
421 sync_server_and_path, port, use_ssl, post_factory.release())); 421 sync_server_and_path, port, use_ssl, post_factory.release()));
422 422
423 net::NetworkChangeNotifier::AddIPAddressObserver(this); 423 net::NetworkChangeNotifier::AddIPAddressObserver(this);
424 observing_ip_address_changes_ = true; 424 observing_ip_address_changes_ = true;
425 425
426 connection_manager_->AddListener(this); 426 connection_manager_->AddListener(this);
427 427
428 DVLOG(1) << "Username: " << username_for_share();
429 if (!OpenDirectory()) {
430 FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
431 OnInitializationComplete(
432 MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()),
433 false, syncer::ModelTypeSet()));
434 return false;
435 }
tim (not reviewing) 2012/07/26 22:33:48 Yay, this looks way nicer.
436
437 // Retrieve and set the sync notifier state.
438 std::string unique_id = directory()->cache_guid();
439 DVLOG(1) << "Read notification unique ID: " << unique_id;
440 allstatus_.SetUniqueId(unique_id);
441 sync_notifier_->SetUniqueId(unique_id);
442
443 std::string state = directory()->GetNotificationState();
444 if (VLOG_IS_ON(1)) {
445 std::string encoded_state;
446 base::Base64Encode(state, &encoded_state);
447 DVLOG(1) << "Read notification state: " << encoded_state;
448 }
449
450 // TODO(tim): Remove once invalidation state has been migrated to new
451 // InvalidationStateTracker store. Bug 124140.
452 sync_notifier_->SetStateDeprecated(state);
453
454 connection_manager_->set_auth_token(credentials.sync_token);
455 sync_notifier_->UpdateCredentials(credentials.email,
tim (not reviewing) 2012/07/26 22:33:48 If we can get rid of the initialized_ special logi
rlarocque 2012/07/26 22:52:20 The scheduler doesn't exist at this point, so the
tim (not reviewing) 2012/07/27 01:54:32 Oh, right, you mentioned that above too. Can we t
rlarocque 2012/07/27 17:47:19 Done. I also moved the IPAddressChangeObserver re
456 credentials.sync_token);
457
428 // Build a SyncSessionContext and store the worker in it. 458 // Build a SyncSessionContext and store the worker in it.
429 DVLOG(1) << "Sync is bringing up SyncSessionContext."; 459 DVLOG(1) << "Sync is bringing up SyncSessionContext.";
430 std::vector<SyncEngineEventListener*> listeners; 460 std::vector<SyncEngineEventListener*> listeners;
431 listeners.push_back(&allstatus_); 461 listeners.push_back(&allstatus_);
432 listeners.push_back(this); 462 listeners.push_back(this);
433 session_context_ = internal_components_factory->BuildContext( 463 session_context_ = internal_components_factory->BuildContext(
434 connection_manager_.get(), 464 connection_manager_.get(),
435 directory(), 465 directory(),
436 model_safe_routing_info,
437 workers, 466 workers,
438 extensions_activity_monitor, 467 extensions_activity_monitor,
439 &throttled_data_type_tracker_, 468 &throttled_data_type_tracker_,
440 listeners, 469 listeners,
441 &debug_info_event_listener_, 470 &debug_info_event_listener_,
442 &traffic_recorder_).Pass(); 471 &traffic_recorder_).Pass();
443 session_context_->set_account_name(credentials.email); 472 session_context_->set_account_name(credentials.email);
444 scheduler_ = internal_components_factory->BuildScheduler( 473 scheduler_ = internal_components_factory->BuildScheduler(
445 name_, session_context_.get()).Pass(); 474 name_, session_context_.get()).Pass();
446 475
447 bool success = SignIn(credentials); 476 scheduler_->Start(SyncScheduler::CONFIGURATION_MODE);
448 477
449 if (success) { 478 initialized_ = true;
450 scheduler_->Start(SyncScheduler::CONFIGURATION_MODE);
451 479
452 initialized_ = true; 480 // Cryptographer should only be accessed while holding a
481 // transaction. Grabbing the user share for the transaction
482 // checks the initialization state, so this must come after
483 // |initialized_| is set to true.
484 ReadTransaction trans(FROM_HERE, GetUserShare());
485 trans.GetCryptographer()->Bootstrap(restored_key_for_bootstrapping);
486 trans.GetCryptographer()->AddObserver(this);
453 487
454 // Unapplied datatypes (those that do not have initial sync ended set) get
455 // re-downloaded during any configuration. But, it's possible for a datatype
456 // to have a progress marker but not have initial sync ended yet, making
457 // it a candidate for migration. This is a problem, as the DataTypeManager
458 // does not support a migration while it's already in the middle of a
459 // configuration. As a result, any partially synced datatype can stall the
460 // DTM, waiting for the configuration to complete, which it never will due
461 // to the migration error. In addition, a partially synced nigori will
462 // trigger the migration logic before the backend is initialized, resulting
463 // in crashes. We therefore detect and purge any partially synced types as
464 // part of initialization.
465 if (!PurgePartiallySyncedTypes())
466 success = false;
467
468 // Cryptographer should only be accessed while holding a
469 // transaction. Grabbing the user share for the transaction
470 // checks the initialization state, so this must come after
471 // |initialized_| is set to true.
472 ReadTransaction trans(FROM_HERE, GetUserShare());
473 trans.GetCryptographer()->Bootstrap(restored_key_for_bootstrapping);
474 trans.GetCryptographer()->AddObserver(this);
475 }
476
477 // Notify that initialization is complete. Note: This should be the last to
478 // execute if |signed_in| is false. Reason being in that case we would
479 // post a task to shutdown sync. But if this function posts any other tasks
480 // on the UI thread and if shutdown wins then that tasks would execute on
481 // a freed pointer. This is because UI thread is not shut down.
482 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, 488 FOR_EACH_OBSERVER(SyncManager::Observer, observers_,
483 OnInitializationComplete( 489 OnInitializationComplete(
484 MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()), 490 MakeWeakHandle(weak_ptr_factory_.GetWeakPtr()),
485 success)); 491 true, InitialSyncEndedTypes()));
486 if (!success)
487 return false;
488 492
489 sync_notifier_->AddObserver(this); 493 sync_notifier_->AddObserver(this);
490 494 return true;
491 return success;
492 } 495 }
493 496
494 void SyncManagerImpl::RefreshNigori(const std::string& chrome_version, 497 void SyncManagerImpl::RefreshNigori(const std::string& chrome_version,
495 const base::Closure& done_callback) { 498 const base::Closure& done_callback) {
496 DCHECK(initialized_); 499 DCHECK(initialized_);
497 DCHECK(thread_checker_.CalledOnValidThread()); 500 DCHECK(thread_checker_.CalledOnValidThread());
498 GetSessionName( 501 GetSessionName(
499 blocking_task_runner_, 502 blocking_task_runner_,
500 base::Bind( 503 base::Bind(
501 &SyncManagerImpl::UpdateCryptographerAndNigoriCallback, 504 &SyncManagerImpl::UpdateCryptographerAndNigoriCallback,
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 MakeWeakHandle(js_mutation_event_observer_.AsWeakPtr())); 660 MakeWeakHandle(js_mutation_event_observer_.AsWeakPtr()));
658 661
659 syncable::DirOpenResult open_result = syncable::NOT_INITIALIZED; 662 syncable::DirOpenResult open_result = syncable::NOT_INITIALIZED;
660 open_result = directory()->Open(username_for_share(), this, 663 open_result = directory()->Open(username_for_share(), this,
661 transaction_observer); 664 transaction_observer);
662 if (open_result != syncable::OPENED) { 665 if (open_result != syncable::OPENED) {
663 LOG(ERROR) << "Could not open share for:" << username_for_share(); 666 LOG(ERROR) << "Could not open share for:" << username_for_share();
664 return false; 667 return false;
665 } 668 }
666 669
670 // Unapplied datatypes (those that do not have initial sync ended set) get
671 // re-downloaded during any configuration. But, it's possible for a datatype
672 // to have a progress marker but not have initial sync ended yet, making
673 // it a candidate for migration. This is a problem, as the DataTypeManager
674 // does not support a migration while it's already in the middle of a
675 // configuration. As a result, any partially synced datatype can stall the
676 // DTM, waiting for the configuration to complete, which it never will due
677 // to the migration error. In addition, a partially synced nigori will
678 // trigger the migration logic before the backend is initialized, resulting
679 // in crashes. We therefore detect and purge any partially synced types as
680 // part of initialization.
681 if (!PurgePartiallySyncedTypes())
682 return false;
683
667 connection_manager_->set_client_id(directory()->cache_guid()); 684 connection_manager_->set_client_id(directory()->cache_guid());
668 return true; 685 return true;
669 } 686 }
670 687
671 bool SyncManagerImpl::SignIn(const SyncCredentials& credentials) {
672 DCHECK(thread_checker_.CalledOnValidThread());
673 DCHECK(share_.name.empty());
674 share_.name = credentials.email;
675
676 DVLOG(1) << "Signing in user: " << username_for_share();
677 if (!OpenDirectory())
678 return false;
679
680 // Retrieve and set the sync notifier state. This should be done
681 // only after OpenDirectory is called.
682 std::string unique_id = directory()->cache_guid();
683 std::string state = directory()->GetNotificationState();
684 DVLOG(1) << "Read notification unique ID: " << unique_id;
685 if (VLOG_IS_ON(1)) {
686 std::string encoded_state;
687 base::Base64Encode(state, &encoded_state);
688 DVLOG(1) << "Read notification state: " << encoded_state;
689 }
690 allstatus_.SetUniqueId(unique_id);
691 sync_notifier_->SetUniqueId(unique_id);
692 // TODO(tim): Remove once invalidation state has been migrated to new
693 // InvalidationStateTracker store. Bug 124140.
694 sync_notifier_->SetStateDeprecated(state);
695
696 UpdateCredentials(credentials);
697 return true;
698 }
699
700 bool SyncManagerImpl::PurgePartiallySyncedTypes() { 688 bool SyncManagerImpl::PurgePartiallySyncedTypes() {
701 ModelTypeSet partially_synced_types = ModelTypeSet::All(); 689 ModelTypeSet partially_synced_types = ModelTypeSet::All();
702 partially_synced_types.RemoveAll(InitialSyncEndedTypes()); 690 partially_synced_types.RemoveAll(InitialSyncEndedTypes());
703 partially_synced_types.RemoveAll(GetTypesWithEmptyProgressMarkerToken( 691 partially_synced_types.RemoveAll(GetTypesWithEmptyProgressMarkerToken(
704 ModelTypeSet::All())); 692 ModelTypeSet::All()));
705 693
706 UMA_HISTOGRAM_COUNTS("Sync.PartiallySyncedTypes", 694 UMA_HISTOGRAM_COUNTS("Sync.PartiallySyncedTypes",
707 partially_synced_types.Size()); 695 partially_synced_types.Size());
708 if (partially_synced_types.Empty()) 696 if (partially_synced_types.Empty())
709 return true; 697 return true;
710 return directory()->PurgeEntriesWithTypeIn(partially_synced_types); 698 return directory()->PurgeEntriesWithTypeIn(partially_synced_types);
711 } 699 }
712 700
713 void SyncManagerImpl::UpdateCredentials( 701 void SyncManagerImpl::UpdateCredentials(
714 const SyncCredentials& credentials) { 702 const SyncCredentials& credentials) {
715 DCHECK(thread_checker_.CalledOnValidThread()); 703 DCHECK(thread_checker_.CalledOnValidThread());
716 DCHECK_EQ(credentials.email, share_.name); 704 DCHECK_EQ(credentials.email, share_.name);
717 DCHECK(!credentials.email.empty()); 705 DCHECK(!credentials.email.empty());
718 DCHECK(!credentials.sync_token.empty()); 706 DCHECK(!credentials.sync_token.empty());
719 707
720 observing_ip_address_changes_ = true; 708 observing_ip_address_changes_ = true;
721 if (connection_manager_->set_auth_token(credentials.sync_token)) { 709 if (connection_manager_->set_auth_token(credentials.sync_token)) {
722 sync_notifier_->UpdateCredentials( 710 sync_notifier_->UpdateCredentials(
723 credentials.email, credentials.sync_token); 711 credentials.email, credentials.sync_token);
724 if (initialized_) { 712 if (initialized_) {
tim (not reviewing) 2012/07/26 22:33:48 Do we actually need this if (initialized_) block a
rlarocque 2012/07/26 22:52:20 See comment above.
725 scheduler_->OnCredentialsUpdated(); 713 scheduler_->OnCredentialsUpdated();
726 } 714 }
727 } 715 }
728 } 716 }
729 717
730 void SyncManagerImpl::UpdateEnabledTypes( 718 void SyncManagerImpl::UpdateEnabledTypes(
731 const ModelTypeSet& enabled_types) { 719 const ModelTypeSet& enabled_types) {
732 DCHECK(thread_checker_.CalledOnValidThread()); 720 DCHECK(thread_checker_.CalledOnValidThread());
733 sync_notifier_->UpdateEnabledTypes(enabled_types); 721 sync_notifier_->UpdateEnabledTypes(enabled_types);
734 } 722 }
(...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after
1891 int SyncManagerImpl::GetDefaultNudgeDelay() { 1879 int SyncManagerImpl::GetDefaultNudgeDelay() {
1892 return kDefaultNudgeDelayMilliseconds; 1880 return kDefaultNudgeDelayMilliseconds;
1893 } 1881 }
1894 1882
1895 // static. 1883 // static.
1896 int SyncManagerImpl::GetPreferencesNudgeDelay() { 1884 int SyncManagerImpl::GetPreferencesNudgeDelay() {
1897 return kPreferencesNudgeDelayMilliseconds; 1885 return kPreferencesNudgeDelayMilliseconds;
1898 } 1886 }
1899 1887
1900 } // namespace syncer 1888 } // 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