Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "build/build_config.h" | 5 #include "build/build_config.h" |
| 6 | 6 |
| 7 #include "chrome/browser/sync/glue/sync_backend_host.h" | 7 #include "chrome/browser/sync/glue/sync_backend_host.h" |
| 8 | 8 |
| 9 #include <algorithm> | 9 #include <algorithm> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 53 // Helper macros to log with the syncer thread name; useful when there | 53 // Helper macros to log with the syncer thread name; useful when there |
| 54 // are multiple syncers involved. | 54 // are multiple syncers involved. |
| 55 | 55 |
| 56 #define SLOG(severity) LOG(severity) << name_ << ": " | 56 #define SLOG(severity) LOG(severity) << name_ << ": " |
| 57 | 57 |
| 58 #define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " | 58 #define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " |
| 59 | 59 |
| 60 SyncBackendHost::SyncBackendHost(const std::string& name, | 60 SyncBackendHost::SyncBackendHost(const std::string& name, |
| 61 Profile* profile, | 61 Profile* profile, |
| 62 const base::WeakPtr<SyncPrefs>& sync_prefs) | 62 const base::WeakPtr<SyncPrefs>& sync_prefs) |
| 63 : core_(new Core(name, ALLOW_THIS_IN_INITIALIZER_LIST(this))), | 63 : initialization_state_(NOT_ATTEMPTED), |
| 64 initialization_state_(NOT_ATTEMPTED), | 64 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), |
| 65 sync_thread_("Chrome_SyncThread"), | 65 sync_thread_("Chrome_SyncThread"), |
| 66 frontend_loop_(MessageLoop::current()), | 66 frontend_loop_(MessageLoop::current()), |
| 67 profile_(profile), | 67 profile_(profile), |
| 68 name_(name), | |
| 69 core_(new Core(name, profile_->GetPath().Append(kSyncDataFolderName), | |
| 70 weak_ptr_factory_.GetWeakPtr())), | |
| 68 sync_prefs_(sync_prefs), | 71 sync_prefs_(sync_prefs), |
| 69 name_(name), | |
| 70 sync_notifier_factory_( | 72 sync_notifier_factory_( |
| 71 content::GetUserAgent(GURL()), | 73 content::GetUserAgent(GURL()), |
| 72 profile_->GetRequestContext(), | 74 profile_->GetRequestContext(), |
| 73 sync_prefs, | 75 sync_prefs, |
| 74 *CommandLine::ForCurrentProcess()), | 76 *CommandLine::ForCurrentProcess()), |
| 75 frontend_(NULL), | 77 frontend_(NULL), |
| 76 sync_data_folder_path_( | |
| 77 profile_->GetPath().Append(kSyncDataFolderName)), | |
| 78 last_auth_error_(AuthError::None()) { | 78 last_auth_error_(AuthError::None()) { |
| 79 } | 79 } |
| 80 | 80 |
| 81 SyncBackendHost::SyncBackendHost() | 81 SyncBackendHost::SyncBackendHost() |
| 82 : initialization_state_(NOT_ATTEMPTED), | 82 : initialization_state_(NOT_ATTEMPTED), |
| 83 weak_ptr_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)), | |
| 83 sync_thread_("Chrome_SyncThread"), | 84 sync_thread_("Chrome_SyncThread"), |
| 84 frontend_loop_(MessageLoop::current()), | 85 frontend_loop_(MessageLoop::current()), |
| 85 profile_(NULL), | 86 profile_(NULL), |
| 86 name_("Unknown"), | 87 name_("Unknown"), |
| 87 sync_notifier_factory_( | 88 sync_notifier_factory_( |
| 88 content::GetUserAgent(GURL()), | 89 content::GetUserAgent(GURL()), |
| 89 NULL, | 90 NULL, |
| 90 base::WeakPtr<sync_notifier::InvalidationVersionTracker>(), | 91 base::WeakPtr<sync_notifier::InvalidationVersionTracker>(), |
| 91 *CommandLine::ForCurrentProcess()), | 92 *CommandLine::ForCurrentProcess()), |
| 92 frontend_(NULL), | 93 frontend_(NULL), |
| 93 last_auth_error_(AuthError::None()) { | 94 last_auth_error_(AuthError::None()) { |
| 94 } | 95 } |
| 95 | 96 |
| 96 SyncBackendHost::~SyncBackendHost() { | 97 SyncBackendHost::~SyncBackendHost() { |
| 97 DCHECK(!core_ && !frontend_) << "Must call Shutdown before destructor."; | 98 DCHECK(!core_ && !frontend_) << "Must call Shutdown before destructor."; |
| 98 DCHECK(!registrar_.get()); | 99 DCHECK(!registrar_.get()); |
| 99 } | 100 } |
| 100 | 101 |
| 102 namespace { | |
| 103 | |
| 104 sync_api::HttpPostProviderFactory* MakeHttpBridgeFactory( | |
| 105 const scoped_refptr<net::URLRequestContextGetter>& getter) { | |
| 106 return new HttpBridgeFactory(getter); | |
| 107 } | |
| 108 | |
| 109 } // namespace | |
| 110 | |
| 101 void SyncBackendHost::Initialize( | 111 void SyncBackendHost::Initialize( |
| 102 SyncFrontend* frontend, | 112 SyncFrontend* frontend, |
| 103 const WeakHandle<JsEventHandler>& event_handler, | 113 const WeakHandle<JsEventHandler>& event_handler, |
| 104 const GURL& sync_service_url, | 114 const GURL& sync_service_url, |
| 105 syncable::ModelTypeSet initial_types, | 115 syncable::ModelTypeSet initial_types, |
| 106 const SyncCredentials& credentials, | 116 const SyncCredentials& credentials, |
| 107 bool delete_sync_data_folder) { | 117 bool delete_sync_data_folder) { |
| 108 if (!sync_thread_.Start()) | 118 if (!sync_thread_.Start()) |
| 109 return; | 119 return; |
| 110 | 120 |
| 111 frontend_ = frontend; | 121 frontend_ = frontend; |
| 112 DCHECK(frontend); | 122 DCHECK(frontend); |
| 113 | 123 |
| 114 syncable::ModelTypeSet initial_types_with_nigori(initial_types); | 124 syncable::ModelTypeSet initial_types_with_nigori(initial_types); |
| 115 CHECK(sync_prefs_.get()); | 125 CHECK(sync_prefs_.get()); |
| 116 if (sync_prefs_->HasSyncSetupCompleted()) { | 126 if (sync_prefs_->HasSyncSetupCompleted()) { |
| 117 initial_types_with_nigori.Put(syncable::NIGORI); | 127 initial_types_with_nigori.Put(syncable::NIGORI); |
| 118 } | 128 } |
| 119 | 129 |
| 120 registrar_.reset(new SyncBackendRegistrar(initial_types_with_nigori, | 130 registrar_.reset(new SyncBackendRegistrar(initial_types_with_nigori, |
| 121 name_, | 131 name_, |
| 122 profile_, | 132 profile_, |
| 123 sync_thread_.message_loop())); | 133 sync_thread_.message_loop())); |
| 124 initialization_state_ = CREATING_SYNC_MANAGER; | 134 initialization_state_ = CREATING_SYNC_MANAGER; |
| 125 InitCore(Core::DoInitializeOptions( | 135 InitCore(DoInitializeOptions( |
| 126 sync_thread_.message_loop(), | 136 sync_thread_.message_loop(), |
| 127 registrar_.get(), | 137 registrar_.get(), |
| 128 event_handler, | 138 event_handler, |
| 129 sync_service_url, | 139 sync_service_url, |
| 130 profile_->GetRequestContext(), | 140 base::Bind(&MakeHttpBridgeFactory, |
|
Nicolas Zea
2011/12/14 20:37:25
Since MakeHttpBridgeFactory is now an anon functio
akalin
2011/12/15 01:21:05
Yeah. Added comment in header file saying the clo
| |
| 141 make_scoped_refptr(profile_->GetRequestContext())), | |
| 131 credentials, | 142 credentials, |
| 143 &sync_notifier_factory_, | |
| 132 delete_sync_data_folder, | 144 delete_sync_data_folder, |
| 133 sync_prefs_->GetEncryptionBootstrapToken(), | 145 sync_prefs_->GetEncryptionBootstrapToken(), |
| 134 false)); | 146 false)); |
| 135 } | 147 } |
| 136 | 148 |
| 137 void SyncBackendHost::InitCore(const Core::DoInitializeOptions& options) { | |
| 138 sync_thread_.message_loop()->PostTask(FROM_HERE, | |
| 139 base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(),options)); | |
| 140 } | |
| 141 | |
| 142 void SyncBackendHost::UpdateCredentials(const SyncCredentials& credentials) { | 149 void SyncBackendHost::UpdateCredentials(const SyncCredentials& credentials) { |
| 143 sync_thread_.message_loop()->PostTask(FROM_HERE, | 150 sync_thread_.message_loop()->PostTask(FROM_HERE, |
| 144 base::Bind(&SyncBackendHost::Core::DoUpdateCredentials, core_.get(), | 151 base::Bind(&SyncBackendHost::Core::DoUpdateCredentials, core_.get(), |
| 145 credentials)); | 152 credentials)); |
| 146 } | 153 } |
| 147 | 154 |
| 148 void SyncBackendHost::StartSyncingWithServer() { | 155 void SyncBackendHost::StartSyncingWithServer() { |
| 149 SDVLOG(1) << "SyncBackendHost::StartSyncingWithServer called."; | 156 SDVLOG(1) << "SyncBackendHost::StartSyncingWithServer called."; |
| 150 sync_thread_.message_loop()->PostTask(FROM_HERE, | 157 sync_thread_.message_loop()->PostTask(FROM_HERE, |
| 151 base::Bind(&SyncBackendHost::Core::DoStartSyncing, core_.get())); | 158 base::Bind(&SyncBackendHost::Core::DoStartSyncing, core_.get())); |
| (...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 373 void SyncBackendHost::GetModelSafeRoutingInfo( | 380 void SyncBackendHost::GetModelSafeRoutingInfo( |
| 374 ModelSafeRoutingInfo* out) const { | 381 ModelSafeRoutingInfo* out) const { |
| 375 if (initialized()) { | 382 if (initialized()) { |
| 376 CHECK(registrar_.get()); | 383 CHECK(registrar_.get()); |
| 377 registrar_->GetModelSafeRoutingInfo(out); | 384 registrar_->GetModelSafeRoutingInfo(out); |
| 378 } else { | 385 } else { |
| 379 NOTREACHED(); | 386 NOTREACHED(); |
| 380 } | 387 } |
| 381 } | 388 } |
| 382 | 389 |
| 390 void SyncBackendHost::InitCore(const DoInitializeOptions& options) { | |
| 391 sync_thread_.message_loop()->PostTask(FROM_HERE, | |
| 392 base::Bind(&SyncBackendHost::Core::DoInitialize, core_.get(),options)); | |
| 393 } | |
| 394 | |
| 395 void SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop( | |
| 396 SyncSessionSnapshot* snapshot) { | |
| 397 if (!frontend_) | |
| 398 return; | |
| 399 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
| 400 | |
| 401 last_snapshot_.reset(snapshot); | |
| 402 | |
| 403 SDVLOG(1) << "Got snapshot " << snapshot->ToString(); | |
| 404 | |
| 405 const syncable::ModelTypeSet to_migrate = | |
| 406 snapshot->syncer_status.types_needing_local_migration; | |
| 407 if (!to_migrate.Empty()) | |
| 408 frontend_->OnMigrationNeededForTypes(to_migrate); | |
| 409 | |
| 410 // Process any changes to the datatypes we're syncing. | |
| 411 // TODO(sync): add support for removing types. | |
| 412 if (initialized()) | |
| 413 AddExperimentalTypes(); | |
| 414 | |
| 415 // If we are waiting for a configuration change, check here to see | |
| 416 // if this sync cycle has initialized all of the types we've been | |
| 417 // waiting for. | |
| 418 if (pending_download_state_.get()) { | |
| 419 scoped_ptr<PendingConfigureDataTypesState> state( | |
| 420 pending_download_state_.release()); | |
| 421 const syncable::ModelTypeSet types_to_add = state->types_to_add; | |
| 422 const syncable::ModelTypeSet added_types = state->added_types; | |
| 423 DCHECK(types_to_add.HasAll(added_types)); | |
| 424 const syncable::ModelTypeSet initial_sync_ended = | |
| 425 snapshot->initial_sync_ended; | |
| 426 const syncable::ModelTypeSet failed_configuration_types = | |
| 427 Difference(added_types, initial_sync_ended); | |
| 428 SDVLOG(1) | |
| 429 << "Added types: " | |
| 430 << syncable::ModelTypeSetToString(added_types) | |
| 431 << ", configured types: " | |
| 432 << syncable::ModelTypeSetToString(initial_sync_ended) | |
| 433 << ", failed configuration types: " | |
| 434 << syncable::ModelTypeSetToString(failed_configuration_types); | |
| 435 state->ready_task.Run(failed_configuration_types); | |
| 436 if (!failed_configuration_types.Empty()) | |
| 437 return; | |
| 438 } | |
| 439 | |
| 440 if (initialized()) | |
| 441 frontend_->OnSyncCycleCompleted(); | |
| 442 } | |
| 443 | |
| 444 void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop() { | |
| 445 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
| 446 // Nudge the syncer. This is necessary for both datatype addition/deletion. | |
| 447 // | |
| 448 // Deletions need a nudge in order to ensure the deletion occurs in a timely | |
| 449 // manner (see issue 56416). | |
| 450 // | |
| 451 // In the case of additions, on the next sync cycle, the syncer should | |
| 452 // notice that the routing info has changed and start the process of | |
| 453 // downloading updates for newly added data types. Once this is | |
| 454 // complete, the configure_state_.ready_task_ is run via an | |
| 455 // OnInitializationComplete notification. | |
| 456 | |
| 457 SDVLOG(1) << "Syncer in config mode. SBH executing " | |
| 458 << "FinishConfigureDataTypesOnFrontendLoop"; | |
| 459 | |
| 460 if (pending_config_mode_state_->added_types.Empty() && | |
| 461 !core_->sync_manager()->InitialSyncEndedForAllEnabledTypes()) { | |
| 462 | |
| 463 syncable::ModelTypeSet enabled_types; | |
| 464 ModelSafeRoutingInfo routing_info; | |
| 465 registrar_->GetModelSafeRoutingInfo(&routing_info); | |
| 466 for (ModelSafeRoutingInfo::const_iterator i = routing_info.begin(); | |
| 467 i != routing_info.end(); ++i) { | |
| 468 enabled_types.Put(i->first); | |
| 469 } | |
| 470 | |
| 471 // TODO(tim): Log / UMA / count this somehow? | |
| 472 // Add only the types with empty progress markers. Note: it is possible | |
| 473 // that some types have their initial_sync_ended be false but with non | |
| 474 // empty progress marker. Which is ok as the rest of the changes would | |
| 475 // be downloaded on a regular nudge and initial_sync_ended should be set | |
| 476 // to true. However this is a very corner case. So it is not explicitly | |
| 477 // handled. | |
| 478 pending_config_mode_state_->added_types = | |
| 479 sync_api::GetTypesWithEmptyProgressMarkerToken(enabled_types, | |
| 480 GetUserShare()); | |
| 481 } | |
| 482 | |
| 483 // If we've added types, we always want to request a nudge/config (even if | |
| 484 // the initial sync is ended), in case we could not decrypt the data. | |
| 485 if (pending_config_mode_state_->added_types.Empty()) { | |
| 486 SDVLOG(1) << "No new types added; calling ready_task directly"; | |
| 487 // No new types - just notify the caller that the types are available. | |
| 488 const syncable::ModelTypeSet failed_configuration_types; | |
| 489 pending_config_mode_state_->ready_task.Run(failed_configuration_types); | |
| 490 } else { | |
| 491 pending_download_state_.reset(pending_config_mode_state_.release()); | |
| 492 | |
| 493 // Always configure nigori if it's enabled. | |
| 494 syncable::ModelTypeSet types_to_config = | |
| 495 pending_download_state_->added_types; | |
| 496 if (IsNigoriEnabled()) { | |
| 497 // Note: Nigori is the only type that gets added with a nonempty | |
| 498 // progress marker during config. If the server returns a migration | |
| 499 // error then we will go into unrecoverable error. We dont handle it | |
| 500 // explicitly because server might help us out here by not sending a | |
| 501 // migraiton error for nigori during config. | |
| 502 types_to_config.Put(syncable::NIGORI); | |
| 503 } | |
| 504 SDVLOG(1) << "Types " | |
| 505 << syncable::ModelTypeSetToString(types_to_config) | |
| 506 << " added; calling DoRequestConfig"; | |
| 507 sync_thread_.message_loop()->PostTask(FROM_HERE, | |
| 508 base::Bind(&SyncBackendHost::Core::DoRequestConfig, | |
| 509 core_.get(), | |
| 510 types_to_config, | |
| 511 pending_download_state_->reason)); | |
| 512 } | |
| 513 | |
| 514 pending_config_mode_state_.reset(); | |
| 515 | |
| 516 // Notify the SyncManager about the new types. | |
| 517 sync_thread_.message_loop()->PostTask(FROM_HERE, | |
| 518 base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get())); | |
| 519 } | |
| 520 | |
| 521 SyncBackendHost::DoInitializeOptions::DoInitializeOptions( | |
| 522 MessageLoop* sync_loop, | |
| 523 SyncBackendRegistrar* registrar, | |
| 524 const WeakHandle<JsEventHandler>& event_handler, | |
| 525 const GURL& service_url, | |
| 526 MakeHttpBridgeFactoryFn make_http_bridge_factory_fn, | |
| 527 const sync_api::SyncCredentials& credentials, | |
| 528 sync_notifier::SyncNotifierFactory* sync_notifier_factory, | |
| 529 bool delete_sync_data_folder, | |
| 530 const std::string& restored_key_for_bootstrapping, | |
| 531 bool setup_for_test_mode) | |
| 532 : sync_loop(sync_loop), | |
| 533 registrar(registrar), | |
| 534 event_handler(event_handler), | |
| 535 service_url(service_url), | |
| 536 make_http_bridge_factory_fn(make_http_bridge_factory_fn), | |
| 537 credentials(credentials), | |
| 538 sync_notifier_factory(sync_notifier_factory), | |
| 539 delete_sync_data_folder(delete_sync_data_folder), | |
| 540 restored_key_for_bootstrapping(restored_key_for_bootstrapping), | |
| 541 setup_for_test_mode(setup_for_test_mode) { | |
| 542 } | |
| 543 | |
| 544 SyncBackendHost::DoInitializeOptions::~DoInitializeOptions() {} | |
| 545 | |
| 383 SyncBackendHost::Core::Core(const std::string& name, | 546 SyncBackendHost::Core::Core(const std::string& name, |
| 384 SyncBackendHost* backend) | 547 const FilePath& sync_data_folder_path, |
| 548 const base::WeakPtr<SyncBackendHost>& backend) | |
| 385 : name_(name), | 549 : name_(name), |
| 550 sync_data_folder_path_(sync_data_folder_path), | |
| 386 host_(backend), | 551 host_(backend), |
| 387 sync_loop_(NULL), | 552 sync_loop_(NULL), |
| 388 registrar_(NULL) { | 553 registrar_(NULL) { |
| 389 DCHECK(host_); | 554 DCHECK(backend.get()); |
| 390 } | 555 } |
| 391 | 556 |
| 392 SyncBackendHost::Core::~Core() { | 557 SyncBackendHost::Core::~Core() { |
| 393 DCHECK(!sync_manager_.get()); | 558 DCHECK(!sync_manager_.get()); |
| 394 DCHECK(!sync_loop_); | 559 DCHECK(!sync_loop_); |
| 395 } | 560 } |
| 396 | 561 |
| 562 SyncBackendHost::PendingConfigureDataTypesState:: | |
| 563 PendingConfigureDataTypesState() | |
| 564 : reason(sync_api::CONFIGURE_REASON_UNKNOWN) {} | |
| 565 | |
| 566 SyncBackendHost::PendingConfigureDataTypesState:: | |
| 567 ~PendingConfigureDataTypesState() {} | |
| 568 | |
| 397 void SyncBackendHost::Core::OnSyncCycleCompleted( | 569 void SyncBackendHost::Core::OnSyncCycleCompleted( |
| 398 const SyncSessionSnapshot* snapshot) { | 570 const SyncSessionSnapshot* snapshot) { |
| 399 if (!sync_loop_) | 571 if (!sync_loop_) |
| 400 return; | 572 return; |
| 401 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 573 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 402 host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( | 574 host_.Call( |
| 403 &Core::HandleSyncCycleCompletedOnFrontendLoop, | 575 FROM_HERE, |
| 404 this, | 576 &SyncBackendHost::HandleSyncCycleCompletedOnFrontendLoop, |
| 405 new SyncSessionSnapshot(*snapshot))); | 577 new SyncSessionSnapshot(*snapshot)); |
| 406 } | 578 } |
| 407 | 579 |
| 408 | 580 |
| 409 void SyncBackendHost::Core::OnInitializationComplete( | 581 void SyncBackendHost::Core::OnInitializationComplete( |
| 410 const WeakHandle<JsBackend>& js_backend, | 582 const WeakHandle<JsBackend>& js_backend, |
| 411 bool success) { | 583 bool success) { |
| 412 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 584 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 413 | 585 host_.Call( |
| 414 host_->frontend_loop_->PostTask(FROM_HERE, | 586 FROM_HERE, |
| 415 base::Bind(&Core::HandleInitializationCompletedOnFrontendLoop, this, | 587 &SyncBackendHost::HandleInitializationCompletedOnFrontendLoop, |
| 416 js_backend, success)); | 588 js_backend, success); |
| 417 | 589 |
| 418 if (success) { | 590 if (success) { |
| 419 // Initialization is complete, so we can schedule recurring SaveChanges. | 591 // Initialization is complete, so we can schedule recurring SaveChanges. |
| 420 sync_loop_->PostTask(FROM_HERE, | 592 sync_loop_->PostTask(FROM_HERE, |
| 421 base::Bind(&Core::StartSavingChanges, this)); | 593 base::Bind(&Core::StartSavingChanges, this)); |
| 422 } | 594 } |
| 423 } | 595 } |
| 424 | 596 |
| 425 void SyncBackendHost::Core::OnAuthError(const AuthError& auth_error) { | 597 void SyncBackendHost::Core::OnAuthError(const AuthError& auth_error) { |
| 426 if (!sync_loop_) | 598 if (!sync_loop_) |
| 427 return; | 599 return; |
| 428 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 600 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 429 // Post to our core loop so we can modify state. Could be on another thread. | 601 host_.Call( |
| 430 host_->frontend_loop_->PostTask(FROM_HERE, | 602 FROM_HERE, |
| 431 base::Bind(&Core::HandleAuthErrorEventOnFrontendLoop, this, auth_error)); | 603 &SyncBackendHost::HandleAuthErrorEventOnFrontendLoop, auth_error); |
| 432 } | 604 } |
| 433 | 605 |
| 434 void SyncBackendHost::Core::OnPassphraseRequired( | 606 void SyncBackendHost::Core::OnPassphraseRequired( |
| 435 sync_api::PassphraseRequiredReason reason) { | 607 sync_api::PassphraseRequiredReason reason) { |
| 436 if (!sync_loop_) | 608 if (!sync_loop_) |
| 437 return; | 609 return; |
| 438 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 610 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 439 host_->frontend_loop_->PostTask(FROM_HERE, | 611 host_.Call( |
| 440 base::Bind(&Core::NotifyPassphraseRequired, this, reason)); | 612 FROM_HERE, |
| 613 &SyncBackendHost::NotifyPassphraseRequired, reason); | |
| 441 } | 614 } |
| 442 | 615 |
| 443 void SyncBackendHost::Core::OnPassphraseAccepted( | 616 void SyncBackendHost::Core::OnPassphraseAccepted( |
| 444 const std::string& bootstrap_token) { | 617 const std::string& bootstrap_token) { |
| 445 if (!sync_loop_) | 618 if (!sync_loop_) |
| 446 return; | 619 return; |
| 447 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 620 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 448 host_->frontend_loop_->PostTask(FROM_HERE, | 621 host_.Call( |
| 449 base::Bind(&Core::NotifyPassphraseAccepted, this, bootstrap_token)); | 622 FROM_HERE, |
| 623 &SyncBackendHost::NotifyPassphraseAccepted, bootstrap_token); | |
| 450 } | 624 } |
| 451 | 625 |
| 452 void SyncBackendHost::Core::OnStopSyncingPermanently() { | 626 void SyncBackendHost::Core::OnStopSyncingPermanently() { |
| 453 if (!sync_loop_) | 627 if (!sync_loop_) |
| 454 return; | 628 return; |
| 455 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 629 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 456 host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( | 630 host_.Call( |
| 457 &Core::HandleStopSyncingPermanentlyOnFrontendLoop, this)); | 631 FROM_HERE, |
| 632 &SyncBackendHost::HandleStopSyncingPermanentlyOnFrontendLoop); | |
| 458 } | 633 } |
| 459 | 634 |
| 460 void SyncBackendHost::Core::OnUpdatedToken(const std::string& token) { | 635 void SyncBackendHost::Core::OnUpdatedToken(const std::string& token) { |
| 461 if (!sync_loop_) | 636 if (!sync_loop_) |
| 462 return; | 637 return; |
| 463 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 638 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 464 host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( | 639 host_.Call( |
| 465 &Core::NotifyUpdatedToken, this, token)); | 640 FROM_HERE, |
| 641 &SyncBackendHost::NotifyUpdatedToken, token); | |
| 466 } | 642 } |
| 467 | 643 |
| 468 void SyncBackendHost::Core::OnClearServerDataFailed() { | 644 void SyncBackendHost::Core::OnClearServerDataFailed() { |
| 469 if (!sync_loop_) | 645 if (!sync_loop_) |
| 470 return; | 646 return; |
| 471 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 647 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 472 host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( | 648 host_.Call( |
| 473 &Core::HandleClearServerDataFailedOnFrontendLoop, this)); | 649 FROM_HERE, |
| 650 &SyncBackendHost::HandleClearServerDataFailedOnFrontendLoop); | |
| 474 } | 651 } |
| 475 | 652 |
| 476 void SyncBackendHost::Core::OnClearServerDataSucceeded() { | 653 void SyncBackendHost::Core::OnClearServerDataSucceeded() { |
| 477 if (!sync_loop_) | 654 if (!sync_loop_) |
| 478 return; | 655 return; |
| 479 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 656 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 480 host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( | 657 host_.Call( |
| 481 &Core::HandleClearServerDataSucceededOnFrontendLoop, this)); | 658 FROM_HERE, |
| 659 &SyncBackendHost::HandleClearServerDataSucceededOnFrontendLoop); | |
| 482 } | 660 } |
| 483 | 661 |
| 484 void SyncBackendHost::Core::OnEncryptedTypesChanged( | 662 void SyncBackendHost::Core::OnEncryptedTypesChanged( |
| 485 syncable::ModelTypeSet encrypted_types, | 663 syncable::ModelTypeSet encrypted_types, |
| 486 bool encrypt_everything) { | 664 bool encrypt_everything) { |
| 487 if (!sync_loop_) | 665 if (!sync_loop_) |
| 488 return; | 666 return; |
| 489 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 667 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 490 // NOTE: We're in a transaction. | 668 // NOTE: We're in a transaction. |
| 491 host_->frontend_loop_->PostTask( | 669 host_.Call( |
| 492 FROM_HERE, | 670 FROM_HERE, |
| 493 base::Bind(&Core::NotifyEncryptedTypesChanged, this, | 671 &SyncBackendHost::NotifyEncryptedTypesChanged, |
| 494 encrypted_types, encrypt_everything)); | 672 encrypted_types, encrypt_everything); |
| 495 } | 673 } |
| 496 | 674 |
| 497 void SyncBackendHost::Core::OnEncryptionComplete() { | 675 void SyncBackendHost::Core::OnEncryptionComplete() { |
| 498 if (!sync_loop_) | 676 if (!sync_loop_) |
| 499 return; | 677 return; |
| 500 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 678 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 501 // NOTE: We're in a transaction. | 679 // NOTE: We're in a transaction. |
| 502 host_->frontend_loop_->PostTask( | 680 host_.Call( |
| 503 FROM_HERE, | 681 FROM_HERE, |
| 504 base::Bind(&Core::NotifyEncryptionComplete, this)); | 682 &SyncBackendHost::NotifyEncryptionComplete); |
| 505 } | 683 } |
| 506 | 684 |
| 507 void SyncBackendHost::Core::OnActionableError( | 685 void SyncBackendHost::Core::OnActionableError( |
| 508 const browser_sync::SyncProtocolError& sync_error) { | 686 const browser_sync::SyncProtocolError& sync_error) { |
| 509 if (!sync_loop_) | 687 if (!sync_loop_) |
| 510 return; | 688 return; |
| 511 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 689 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 512 host_->frontend_loop_->PostTask( | 690 host_.Call( |
| 513 FROM_HERE, | 691 FROM_HERE, |
| 514 base::Bind(&Core::HandleActionableErrorEventOnFrontendLoop, this, | 692 &SyncBackendHost::HandleActionableErrorEventOnFrontendLoop, |
| 515 sync_error)); | 693 sync_error); |
| 516 } | 694 } |
| 517 | 695 |
| 518 SyncBackendHost::Core::DoInitializeOptions::DoInitializeOptions( | |
| 519 MessageLoop* sync_loop, | |
| 520 SyncBackendRegistrar* registrar, | |
| 521 const WeakHandle<JsEventHandler>& event_handler, | |
| 522 const GURL& service_url, | |
| 523 const scoped_refptr<net::URLRequestContextGetter>& | |
| 524 request_context_getter, | |
| 525 const sync_api::SyncCredentials& credentials, | |
| 526 bool delete_sync_data_folder, | |
| 527 const std::string& restored_key_for_bootstrapping, | |
| 528 bool setup_for_test_mode) | |
| 529 : sync_loop(sync_loop), | |
| 530 registrar(registrar), | |
| 531 event_handler(event_handler), | |
| 532 service_url(service_url), | |
| 533 request_context_getter(request_context_getter), | |
| 534 credentials(credentials), | |
| 535 delete_sync_data_folder(delete_sync_data_folder), | |
| 536 restored_key_for_bootstrapping(restored_key_for_bootstrapping), | |
| 537 setup_for_test_mode(setup_for_test_mode) { | |
| 538 } | |
| 539 | |
| 540 SyncBackendHost::Core::DoInitializeOptions::~DoInitializeOptions() {} | |
| 541 | |
| 542 // Helper to construct a user agent string (ASCII) suitable for use by | 696 // Helper to construct a user agent string (ASCII) suitable for use by |
| 543 // the syncapi for any HTTP communication. This string is used by the sync | 697 // the syncapi for any HTTP communication. This string is used by the sync |
| 544 // backend for classifying client types when calculating statistics. | 698 // backend for classifying client types when calculating statistics. |
| 545 std::string MakeUserAgentForSyncApi() { | 699 std::string MakeUserAgentForSyncApi() { |
| 546 std::string user_agent; | 700 std::string user_agent; |
| 547 user_agent = "Chrome "; | 701 user_agent = "Chrome "; |
| 548 #if defined(OS_WIN) | 702 #if defined(OS_WIN) |
| 549 user_agent += "WIN "; | 703 user_agent += "WIN "; |
| 550 #elif defined(OS_LINUX) | 704 #elif defined(OS_LINUX) |
| 551 user_agent += "LINUX "; | 705 user_agent += "LINUX "; |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 575 DCHECK(sync_loop_); | 729 DCHECK(sync_loop_); |
| 576 | 730 |
| 577 // Blow away the partial or corrupt sync data folder before doing any more | 731 // Blow away the partial or corrupt sync data folder before doing any more |
| 578 // initialization, if necessary. | 732 // initialization, if necessary. |
| 579 if (options.delete_sync_data_folder) { | 733 if (options.delete_sync_data_folder) { |
| 580 DeleteSyncDataFolder(); | 734 DeleteSyncDataFolder(); |
| 581 } | 735 } |
| 582 | 736 |
| 583 // Make sure that the directory exists before initializing the backend. | 737 // Make sure that the directory exists before initializing the backend. |
| 584 // If it already exists, this will do no harm. | 738 // If it already exists, this will do no harm. |
| 585 bool success = file_util::CreateDirectory(host_->sync_data_folder_path()); | 739 bool success = file_util::CreateDirectory(sync_data_folder_path_); |
| 586 DCHECK(success); | 740 DCHECK(success); |
| 587 | 741 |
| 588 DCHECK(!registrar_); | 742 DCHECK(!registrar_); |
| 589 registrar_ = options.registrar; | 743 registrar_ = options.registrar; |
| 590 DCHECK(registrar_); | 744 DCHECK(registrar_); |
| 591 | 745 |
| 592 sync_manager_.reset(new sync_api::SyncManager(name_)); | 746 sync_manager_.reset(new sync_api::SyncManager(name_)); |
| 593 sync_manager_->AddObserver(this); | 747 sync_manager_->AddObserver(this); |
| 594 const FilePath& path_str = host_->sync_data_folder_path(); | |
| 595 success = sync_manager_->Init( | 748 success = sync_manager_->Init( |
| 596 path_str, | 749 sync_data_folder_path_, |
| 597 options.event_handler, | 750 options.event_handler, |
| 598 options.service_url.host() + options.service_url.path(), | 751 options.service_url.host() + options.service_url.path(), |
| 599 options.service_url.EffectiveIntPort(), | 752 options.service_url.EffectiveIntPort(), |
| 600 options.service_url.SchemeIsSecure(), | 753 options.service_url.SchemeIsSecure(), |
| 601 host_->MakeHttpBridgeFactory(options.request_context_getter), | 754 options.make_http_bridge_factory_fn.Run(), |
| 602 options.registrar /* as ModelSafeWorkerRegistrar */, | 755 options.registrar /* as ModelSafeWorkerRegistrar */, |
| 603 options.registrar /* as SyncManager::ChangeDelegate */, | 756 options.registrar /* as SyncManager::ChangeDelegate */, |
| 604 MakeUserAgentForSyncApi(), | 757 MakeUserAgentForSyncApi(), |
| 605 options.credentials, | 758 options.credentials, |
| 606 host_->sync_notifier_factory_.CreateSyncNotifier(), | 759 options.sync_notifier_factory->CreateSyncNotifier(), |
| 607 options.restored_key_for_bootstrapping, | 760 options.restored_key_for_bootstrapping, |
| 608 options.setup_for_test_mode); | 761 options.setup_for_test_mode); |
| 609 LOG_IF(ERROR, !success) << "Syncapi initialization failed!"; | 762 LOG_IF(ERROR, !success) << "Syncapi initialization failed!"; |
| 610 } | 763 } |
| 611 | 764 |
| 612 void SyncBackendHost::Core::DoCheckServerReachable() { | 765 void SyncBackendHost::Core::DoCheckServerReachable() { |
| 613 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 766 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 614 sync_manager_->CheckServerReachable(); | 767 sync_manager_->CheckServerReachable(); |
| 615 } | 768 } |
| 616 | 769 |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 673 sync_manager_->ShutdownOnSyncThread(); | 826 sync_manager_->ShutdownOnSyncThread(); |
| 674 sync_manager_->RemoveObserver(this); | 827 sync_manager_->RemoveObserver(this); |
| 675 sync_manager_.reset(); | 828 sync_manager_.reset(); |
| 676 registrar_ = NULL; | 829 registrar_ = NULL; |
| 677 | 830 |
| 678 if (sync_disabled) | 831 if (sync_disabled) |
| 679 DeleteSyncDataFolder(); | 832 DeleteSyncDataFolder(); |
| 680 | 833 |
| 681 sync_loop_ = NULL; | 834 sync_loop_ = NULL; |
| 682 | 835 |
| 683 host_ = NULL; | 836 host_.Reset(); |
| 684 } | 837 } |
| 685 | 838 |
| 686 void SyncBackendHost::Core::DoRequestConfig( | 839 void SyncBackendHost::Core::DoRequestConfig( |
| 687 syncable::ModelTypeSet types_to_config, | 840 syncable::ModelTypeSet types_to_config, |
| 688 sync_api::ConfigureReason reason) { | 841 sync_api::ConfigureReason reason) { |
| 689 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 842 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 690 sync_manager_->RequestConfig(types_to_config, reason); | 843 sync_manager_->RequestConfig(types_to_config, reason); |
| 691 } | 844 } |
| 692 | 845 |
| 693 void SyncBackendHost::Core::DoStartConfiguration( | 846 void SyncBackendHost::Core::DoStartConfiguration( |
| 694 const base::Closure& callback) { | 847 const base::Closure& callback) { |
| 695 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 848 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 696 sync_manager_->StartConfigurationMode(callback); | 849 sync_manager_->StartConfigurationMode(callback); |
| 697 } | 850 } |
| 698 | 851 |
| 699 void SyncBackendHost::Core::DeleteSyncDataFolder() { | 852 void SyncBackendHost::Core::DeleteSyncDataFolder() { |
| 700 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 853 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 701 if (file_util::DirectoryExists(host_->sync_data_folder_path())) { | 854 if (file_util::DirectoryExists(sync_data_folder_path_)) { |
| 702 if (!file_util::Delete(host_->sync_data_folder_path(), true)) | 855 if (!file_util::Delete(sync_data_folder_path_, true)) |
| 703 SLOG(DFATAL) << "Could not delete the Sync Data folder."; | 856 SLOG(DFATAL) << "Could not delete the Sync Data folder."; |
| 704 } | 857 } |
| 705 } | 858 } |
| 706 | 859 |
| 707 void SyncBackendHost::Core::FinishConfigureDataTypes() { | 860 void SyncBackendHost::Core::FinishConfigureDataTypes() { |
| 708 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 861 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 709 host_->frontend_loop_->PostTask(FROM_HERE, base::Bind( | 862 host_.Call( |
| 710 &SyncBackendHost::Core::FinishConfigureDataTypesOnFrontendLoop, this)); | 863 FROM_HERE, |
| 711 } | 864 &SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop); |
| 712 | |
| 713 void SyncBackendHost::Core::HandleInitializationCompletedOnFrontendLoop( | |
| 714 const WeakHandle<JsBackend>& js_backend, | |
| 715 bool success) { | |
| 716 if (!host_) | |
| 717 return; | |
| 718 host_->HandleInitializationCompletedOnFrontendLoop(js_backend, success); | |
| 719 } | |
| 720 | |
| 721 void SyncBackendHost::Core::HandleNigoriConfigurationCompletedOnFrontendLoop( | |
| 722 const WeakHandle<JsBackend>& js_backend, | |
| 723 const syncable::ModelTypeSet failed_configuration_types) { | |
| 724 if (!host_) | |
| 725 return; | |
| 726 host_->HandleInitializationCompletedOnFrontendLoop( | |
| 727 js_backend, failed_configuration_types.Empty()); | |
| 728 } | 865 } |
| 729 | 866 |
| 730 void SyncBackendHost::Core::StartSavingChanges() { | 867 void SyncBackendHost::Core::StartSavingChanges() { |
| 731 // We may already be shut down. | 868 // We may already be shut down. |
| 732 if (!sync_loop_) | 869 if (!sync_loop_) |
| 733 return; | 870 return; |
| 734 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 871 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 735 save_changes_timer_.Start(FROM_HERE, | 872 save_changes_timer_.Start(FROM_HERE, |
| 736 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), | 873 base::TimeDelta::FromSeconds(kSaveChangesIntervalSeconds), |
| 737 this, &Core::SaveChanges); | 874 this, &Core::SaveChanges); |
| 738 } | 875 } |
| 739 | 876 |
| 740 void SyncBackendHost::Core::SaveChanges() { | 877 void SyncBackendHost::Core::SaveChanges() { |
| 741 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 878 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
| 742 sync_manager_->SaveChanges(); | 879 sync_manager_->SaveChanges(); |
| 743 } | 880 } |
| 744 | 881 |
| 745 void SyncBackendHost::Core::HandleActionableErrorEventOnFrontendLoop( | |
| 746 const browser_sync::SyncProtocolError& sync_error) { | |
| 747 if (!host_ || !host_->frontend_) | |
| 748 return; | |
| 749 DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); | |
| 750 host_->frontend_->OnActionableError(sync_error); | |
| 751 } | |
| 752 | |
| 753 void SyncBackendHost::Core::HandleAuthErrorEventOnFrontendLoop( | |
| 754 const GoogleServiceAuthError& new_auth_error) { | |
| 755 if (!host_ || !host_->frontend_) | |
| 756 return; | |
| 757 | |
| 758 DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); | |
| 759 | |
| 760 host_->last_auth_error_ = new_auth_error; | |
| 761 host_->frontend_->OnAuthError(); | |
| 762 } | |
| 763 | |
| 764 void SyncBackendHost::Core::NotifyPassphraseRequired( | |
| 765 sync_api::PassphraseRequiredReason reason) { | |
| 766 if (!host_ || !host_->frontend_) | |
| 767 return; | |
| 768 | |
| 769 DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); | |
| 770 | |
| 771 host_->frontend_->OnPassphraseRequired(reason); | |
| 772 } | |
| 773 | |
| 774 void SyncBackendHost::Core::NotifyPassphraseAccepted( | |
| 775 const std::string& bootstrap_token) { | |
| 776 if (!host_ || !host_->frontend_) | |
| 777 return; | |
| 778 | |
| 779 DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); | |
| 780 | |
| 781 host_->PersistEncryptionBootstrapToken(bootstrap_token); | |
| 782 host_->frontend_->OnPassphraseAccepted(); | |
| 783 } | |
| 784 | |
| 785 void SyncBackendHost::Core::NotifyUpdatedToken(const std::string& token) { | |
| 786 if (!host_) | |
| 787 return; | |
| 788 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 789 TokenAvailableDetails details(GaiaConstants::kSyncService, token); | |
| 790 content::NotificationService::current()->Notify( | |
| 791 chrome::NOTIFICATION_TOKEN_UPDATED, | |
| 792 content::Source<Profile>(host_->profile_), | |
| 793 content::Details<const TokenAvailableDetails>(&details)); | |
| 794 } | |
| 795 | |
| 796 void SyncBackendHost::Core::NotifyEncryptedTypesChanged( | |
| 797 syncable::ModelTypeSet encrypted_types, | |
| 798 bool encrypt_everything) { | |
| 799 if (!host_) | |
| 800 return; | |
| 801 DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); | |
| 802 host_->frontend_->OnEncryptedTypesChanged( | |
| 803 encrypted_types, encrypt_everything); | |
| 804 } | |
| 805 | |
| 806 void SyncBackendHost::Core::NotifyEncryptionComplete() { | |
| 807 if (!host_) | |
| 808 return; | |
| 809 DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); | |
| 810 host_->frontend_->OnEncryptionComplete(); | |
| 811 } | |
| 812 | |
| 813 void SyncBackendHost::Core::HandleSyncCycleCompletedOnFrontendLoop( | |
| 814 SyncSessionSnapshot* snapshot) { | |
| 815 if (!host_ || !host_->frontend_) | |
| 816 return; | |
| 817 DCHECK_EQ(MessageLoop::current(), host_->frontend_loop_); | |
| 818 | |
| 819 host_->last_snapshot_.reset(snapshot); | |
| 820 | |
| 821 SDVLOG(1) << "Got snapshot " << snapshot->ToString(); | |
| 822 | |
| 823 const syncable::ModelTypeSet to_migrate = | |
| 824 snapshot->syncer_status.types_needing_local_migration; | |
| 825 if (!to_migrate.Empty()) | |
| 826 host_->frontend_->OnMigrationNeededForTypes(to_migrate); | |
| 827 | |
| 828 // Process any changes to the datatypes we're syncing. | |
| 829 // TODO(sync): add support for removing types. | |
| 830 if (host_->initialized()) | |
| 831 host_->AddExperimentalTypes(); | |
| 832 | |
| 833 // If we are waiting for a configuration change, check here to see | |
| 834 // if this sync cycle has initialized all of the types we've been | |
| 835 // waiting for. | |
| 836 if (host_->pending_download_state_.get()) { | |
| 837 scoped_ptr<PendingConfigureDataTypesState> state( | |
| 838 host_->pending_download_state_.release()); | |
| 839 const syncable::ModelTypeSet types_to_add = state->types_to_add; | |
| 840 const syncable::ModelTypeSet added_types = state->added_types; | |
| 841 DCHECK(types_to_add.HasAll(added_types)); | |
| 842 const syncable::ModelTypeSet initial_sync_ended = | |
| 843 snapshot->initial_sync_ended; | |
| 844 const syncable::ModelTypeSet failed_configuration_types = | |
| 845 Difference(added_types, initial_sync_ended); | |
| 846 SDVLOG(1) | |
| 847 << "Added types: " | |
| 848 << syncable::ModelTypeSetToString(added_types) | |
| 849 << ", configured types: " | |
| 850 << syncable::ModelTypeSetToString(initial_sync_ended) | |
| 851 << ", failed configuration types: " | |
| 852 << syncable::ModelTypeSetToString(failed_configuration_types); | |
| 853 state->ready_task.Run(failed_configuration_types); | |
| 854 if (!failed_configuration_types.Empty()) | |
| 855 return; | |
| 856 } | |
| 857 | |
| 858 if (host_->initialized()) | |
| 859 host_->frontend_->OnSyncCycleCompleted(); | |
| 860 } | |
| 861 | |
| 862 void SyncBackendHost::Core::HandleStopSyncingPermanentlyOnFrontendLoop() { | |
| 863 if (!host_ || !host_->frontend_) | |
| 864 return; | |
| 865 host_->frontend_->OnStopSyncingPermanently(); | |
| 866 } | |
| 867 | |
| 868 void SyncBackendHost::Core::HandleClearServerDataSucceededOnFrontendLoop() { | |
| 869 if (!host_ || !host_->frontend_) | |
| 870 return; | |
| 871 host_->frontend_->OnClearServerDataSucceeded(); | |
| 872 } | |
| 873 | |
| 874 void SyncBackendHost::Core::HandleClearServerDataFailedOnFrontendLoop() { | |
| 875 if (!host_ || !host_->frontend_) | |
| 876 return; | |
| 877 host_->frontend_->OnClearServerDataFailed(); | |
| 878 } | |
| 879 | |
| 880 void SyncBackendHost::Core::FinishConfigureDataTypesOnFrontendLoop() { | |
| 881 host_->FinishConfigureDataTypesOnFrontendLoop(); | |
| 882 } | |
| 883 | |
| 884 void SyncBackendHost::AddExperimentalTypes() { | 882 void SyncBackendHost::AddExperimentalTypes() { |
| 885 CHECK(initialized()); | 883 CHECK(initialized()); |
| 886 syncable::ModelTypeSet to_add; | 884 syncable::ModelTypeSet to_add; |
| 887 if (core_->sync_manager()->ReceivedExperimentalTypes(&to_add)) | 885 if (core_->sync_manager()->ReceivedExperimentalTypes(&to_add)) |
| 888 frontend_->OnDataTypesChanged(to_add); | 886 frontend_->OnDataTypesChanged(to_add); |
| 889 } | 887 } |
| 890 | 888 |
| 891 void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop( | 889 void SyncBackendHost::HandleInitializationCompletedOnFrontendLoop( |
| 892 const WeakHandle<JsBackend>& js_backend, bool success) { | 890 const WeakHandle<JsBackend>& js_backend, bool success) { |
| 893 DCHECK_NE(NOT_ATTEMPTED, initialization_state_); | 891 DCHECK_NE(NOT_ATTEMPTED, initialization_state_); |
| (...skipping 23 matching lines...) Expand all Loading... | |
| 917 // Run initialization state machine. | 915 // Run initialization state machine. |
| 918 switch (initialization_state_) { | 916 switch (initialization_state_) { |
| 919 case NOT_INITIALIZED: | 917 case NOT_INITIALIZED: |
| 920 initialization_state_ = DOWNLOADING_NIGORI; | 918 initialization_state_ = DOWNLOADING_NIGORI; |
| 921 ConfigureDataTypes( | 919 ConfigureDataTypes( |
| 922 syncable::ModelTypeSet(), | 920 syncable::ModelTypeSet(), |
| 923 syncable::ModelTypeSet(), | 921 syncable::ModelTypeSet(), |
| 924 sync_api::CONFIGURE_REASON_NEW_CLIENT, | 922 sync_api::CONFIGURE_REASON_NEW_CLIENT, |
| 925 // Calls back into this function. | 923 // Calls back into this function. |
| 926 base::Bind( | 924 base::Bind( |
| 927 &SyncBackendHost::Core:: | 925 &SyncBackendHost:: |
| 928 HandleNigoriConfigurationCompletedOnFrontendLoop, | 926 HandleNigoriConfigurationCompletedOnFrontendLoop, |
| 929 core_.get(), js_backend), | 927 weak_ptr_factory_.GetWeakPtr(), js_backend), |
| 930 true); | 928 true); |
| 931 break; | 929 break; |
| 932 case DOWNLOADING_NIGORI: | 930 case DOWNLOADING_NIGORI: |
| 933 initialization_state_ = REFRESHING_ENCRYPTION; | 931 initialization_state_ = REFRESHING_ENCRYPTION; |
| 934 // Triggers OnEncryptedTypesChanged() and OnEncryptionComplete() | 932 // Triggers OnEncryptedTypesChanged() and OnEncryptionComplete() |
| 935 // if necessary. | 933 // if necessary. |
| 936 RefreshEncryption( | 934 RefreshEncryption( |
| 937 base::Bind( | 935 base::Bind( |
| 938 &SyncBackendHost::Core:: | 936 &SyncBackendHost:: |
| 939 HandleInitializationCompletedOnFrontendLoop, | 937 HandleInitializationCompletedOnFrontendLoop, |
| 940 core_.get(), js_backend, true)); | 938 weak_ptr_factory_.GetWeakPtr(), js_backend, true)); |
| 941 break; | 939 break; |
| 942 case REFRESHING_ENCRYPTION: | 940 case REFRESHING_ENCRYPTION: |
| 943 initialization_state_ = INITIALIZED; | 941 initialization_state_ = INITIALIZED; |
| 944 // Now that we've downloaded the nigori node, we can see if there are any | 942 // Now that we've downloaded the nigori node, we can see if there are any |
| 945 // experimental types to enable. This should be done before we inform | 943 // experimental types to enable. This should be done before we inform |
| 946 // the frontend to ensure they're visible in the customize screen. | 944 // the frontend to ensure they're visible in the customize screen. |
| 947 AddExperimentalTypes(); | 945 AddExperimentalTypes(); |
| 948 frontend_->OnBackendInitialized(js_backend, true); | 946 frontend_->OnBackendInitialized(js_backend, true); |
| 949 // Now that we're fully initialized, kick off a server | 947 // Now that we're fully initialized, kick off a server |
| 950 // reachability check. | 948 // reachability check. |
| 951 sync_thread_.message_loop()->PostTask( | 949 sync_thread_.message_loop()->PostTask( |
| 952 FROM_HERE, | 950 FROM_HERE, |
| 953 base::Bind(&SyncBackendHost::Core::DoCheckServerReachable, | 951 base::Bind(&SyncBackendHost::Core::DoCheckServerReachable, |
| 954 core_.get())); | 952 core_.get())); |
| 955 break; | 953 break; |
| 956 default: | 954 default: |
| 957 NOTREACHED(); | 955 NOTREACHED(); |
| 958 } | 956 } |
| 959 } | 957 } |
| 960 | 958 |
| 961 void SyncBackendHost::FinishConfigureDataTypesOnFrontendLoop() { | |
| 962 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
| 963 // Nudge the syncer. This is necessary for both datatype addition/deletion. | |
| 964 // | |
| 965 // Deletions need a nudge in order to ensure the deletion occurs in a timely | |
| 966 // manner (see issue 56416). | |
| 967 // | |
| 968 // In the case of additions, on the next sync cycle, the syncer should | |
| 969 // notice that the routing info has changed and start the process of | |
| 970 // downloading updates for newly added data types. Once this is | |
| 971 // complete, the configure_state_.ready_task_ is run via an | |
| 972 // OnInitializationComplete notification. | |
| 973 | |
| 974 SDVLOG(1) << "Syncer in config mode. SBH executing " | |
| 975 << "FinishConfigureDataTypesOnFrontendLoop"; | |
| 976 | |
| 977 if (pending_config_mode_state_->added_types.Empty() && | |
| 978 !core_->sync_manager()->InitialSyncEndedForAllEnabledTypes()) { | |
| 979 | |
| 980 syncable::ModelTypeSet enabled_types; | |
| 981 ModelSafeRoutingInfo routing_info; | |
| 982 registrar_->GetModelSafeRoutingInfo(&routing_info); | |
| 983 for (ModelSafeRoutingInfo::const_iterator i = routing_info.begin(); | |
| 984 i != routing_info.end(); ++i) { | |
| 985 enabled_types.Put(i->first); | |
| 986 } | |
| 987 | |
| 988 // TODO(tim): Log / UMA / count this somehow? | |
| 989 // Add only the types with empty progress markers. Note: it is possible | |
| 990 // that some types have their initial_sync_ended be false but with non | |
| 991 // empty progress marker. Which is ok as the rest of the changes would | |
| 992 // be downloaded on a regular nudge and initial_sync_ended should be set | |
| 993 // to true. However this is a very corner case. So it is not explicitly | |
| 994 // handled. | |
| 995 pending_config_mode_state_->added_types = | |
| 996 sync_api::GetTypesWithEmptyProgressMarkerToken(enabled_types, | |
| 997 GetUserShare()); | |
| 998 } | |
| 999 | |
| 1000 // If we've added types, we always want to request a nudge/config (even if | |
| 1001 // the initial sync is ended), in case we could not decrypt the data. | |
| 1002 if (pending_config_mode_state_->added_types.Empty()) { | |
| 1003 SDVLOG(1) << "No new types added; calling ready_task directly"; | |
| 1004 // No new types - just notify the caller that the types are available. | |
| 1005 const syncable::ModelTypeSet failed_configuration_types; | |
| 1006 pending_config_mode_state_->ready_task.Run(failed_configuration_types); | |
| 1007 } else { | |
| 1008 pending_download_state_.reset(pending_config_mode_state_.release()); | |
| 1009 | |
| 1010 // Always configure nigori if it's enabled. | |
| 1011 syncable::ModelTypeSet types_to_config = | |
| 1012 pending_download_state_->added_types; | |
| 1013 if (IsNigoriEnabled()) { | |
| 1014 // Note: Nigori is the only type that gets added with a nonempty | |
| 1015 // progress marker during config. If the server returns a migration | |
| 1016 // error then we will go into unrecoverable error. We dont handle it | |
| 1017 // explicitly because server might help us out here by not sending a | |
| 1018 // migraiton error for nigori during config. | |
| 1019 types_to_config.Put(syncable::NIGORI); | |
| 1020 } | |
| 1021 SDVLOG(1) << "Types " << syncable::ModelTypeSetToString(types_to_config) | |
| 1022 << " added; calling DoRequestConfig"; | |
| 1023 sync_thread_.message_loop()->PostTask(FROM_HERE, | |
| 1024 base::Bind(&SyncBackendHost::Core::DoRequestConfig, | |
| 1025 core_.get(), | |
| 1026 types_to_config, | |
| 1027 pending_download_state_->reason)); | |
| 1028 } | |
| 1029 | |
| 1030 pending_config_mode_state_.reset(); | |
| 1031 | |
| 1032 // Notify the SyncManager about the new types. | |
| 1033 sync_thread_.message_loop()->PostTask(FROM_HERE, | |
| 1034 base::Bind(&SyncBackendHost::Core::DoUpdateEnabledTypes, core_.get())); | |
| 1035 } | |
| 1036 | |
| 1037 sync_api::HttpPostProviderFactory* SyncBackendHost::MakeHttpBridgeFactory( | |
| 1038 const scoped_refptr<net::URLRequestContextGetter>& getter) { | |
| 1039 return new HttpBridgeFactory(getter); | |
| 1040 } | |
| 1041 | |
| 1042 void SyncBackendHost::PersistEncryptionBootstrapToken( | 959 void SyncBackendHost::PersistEncryptionBootstrapToken( |
| 1043 const std::string& token) { | 960 const std::string& token) { |
| 1044 CHECK(sync_prefs_.get()); | 961 CHECK(sync_prefs_.get()); |
| 1045 sync_prefs_->SetEncryptionBootstrapToken(token); | 962 sync_prefs_->SetEncryptionBootstrapToken(token); |
| 1046 } | 963 } |
| 1047 | 964 |
| 1048 SyncBackendHost::PendingConfigureDataTypesState:: | 965 void SyncBackendHost::HandleActionableErrorEventOnFrontendLoop( |
| 1049 PendingConfigureDataTypesState() | 966 const browser_sync::SyncProtocolError& sync_error) { |
| 1050 : reason(sync_api::CONFIGURE_REASON_UNKNOWN) {} | 967 if (!frontend_) |
| 968 return; | |
| 969 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
| 970 frontend_->OnActionableError(sync_error); | |
| 971 } | |
| 1051 | 972 |
| 1052 SyncBackendHost::PendingConfigureDataTypesState:: | 973 void SyncBackendHost::NotifyPassphraseRequired( |
| 1053 ~PendingConfigureDataTypesState() {} | 974 sync_api::PassphraseRequiredReason reason) { |
| 975 if (!frontend_) | |
| 976 return; | |
| 977 | |
| 978 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
| 979 | |
| 980 frontend_->OnPassphraseRequired(reason); | |
| 981 } | |
| 982 | |
| 983 void SyncBackendHost::NotifyPassphraseAccepted( | |
| 984 const std::string& bootstrap_token) { | |
| 985 if (!frontend_) | |
| 986 return; | |
| 987 | |
| 988 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
| 989 | |
| 990 PersistEncryptionBootstrapToken(bootstrap_token); | |
| 991 frontend_->OnPassphraseAccepted(); | |
| 992 } | |
| 993 | |
| 994 void SyncBackendHost::NotifyUpdatedToken(const std::string& token) { | |
| 995 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | |
| 996 TokenAvailableDetails details(GaiaConstants::kSyncService, token); | |
| 997 content::NotificationService::current()->Notify( | |
| 998 chrome::NOTIFICATION_TOKEN_UPDATED, | |
| 999 content::Source<Profile>(profile_), | |
| 1000 content::Details<const TokenAvailableDetails>(&details)); | |
| 1001 } | |
| 1002 | |
| 1003 void SyncBackendHost::NotifyEncryptedTypesChanged( | |
| 1004 syncable::ModelTypeSet encrypted_types, | |
| 1005 bool encrypt_everything) { | |
| 1006 if (!frontend_) | |
| 1007 return; | |
| 1008 | |
| 1009 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
| 1010 frontend_->OnEncryptedTypesChanged( | |
| 1011 encrypted_types, encrypt_everything); | |
| 1012 } | |
| 1013 | |
| 1014 void SyncBackendHost::NotifyEncryptionComplete() { | |
| 1015 if (!frontend_) | |
| 1016 return; | |
| 1017 | |
| 1018 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
| 1019 frontend_->OnEncryptionComplete(); | |
| 1020 } | |
| 1021 | |
| 1022 void SyncBackendHost::HandleStopSyncingPermanentlyOnFrontendLoop() { | |
| 1023 if (!frontend_) | |
| 1024 return; | |
| 1025 frontend_->OnStopSyncingPermanently(); | |
| 1026 } | |
| 1027 | |
| 1028 void SyncBackendHost::HandleClearServerDataSucceededOnFrontendLoop() { | |
| 1029 if (!frontend_) | |
| 1030 return; | |
| 1031 frontend_->OnClearServerDataSucceeded(); | |
| 1032 } | |
| 1033 | |
| 1034 void SyncBackendHost::HandleClearServerDataFailedOnFrontendLoop() { | |
| 1035 if (!frontend_) | |
| 1036 return; | |
| 1037 frontend_->OnClearServerDataFailed(); | |
| 1038 } | |
| 1039 | |
| 1040 void SyncBackendHost::HandleAuthErrorEventOnFrontendLoop( | |
| 1041 const GoogleServiceAuthError& new_auth_error) { | |
| 1042 if (!frontend_) | |
| 1043 return; | |
| 1044 | |
| 1045 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | |
| 1046 | |
| 1047 last_auth_error_ = new_auth_error; | |
| 1048 frontend_->OnAuthError(); | |
| 1049 } | |
| 1050 | |
| 1051 void SyncBackendHost::HandleNigoriConfigurationCompletedOnFrontendLoop( | |
| 1052 const WeakHandle<JsBackend>& js_backend, | |
| 1053 const syncable::ModelTypeSet failed_configuration_types) { | |
| 1054 HandleInitializationCompletedOnFrontendLoop( | |
| 1055 js_backend, failed_configuration_types.Empty()); | |
| 1056 } | |
| 1054 | 1057 |
| 1055 namespace { | 1058 namespace { |
| 1056 | 1059 |
| 1057 // Needed because MessageLoop::PostTask is overloaded. | 1060 // Needed because MessageLoop::PostTask is overloaded. |
| 1058 void PostClosure(MessageLoop* message_loop, | 1061 void PostClosure(MessageLoop* message_loop, |
| 1059 const tracked_objects::Location& from_here, | 1062 const tracked_objects::Location& from_here, |
| 1060 const base::Closure& callback) { | 1063 const base::Closure& callback) { |
| 1061 message_loop->PostTask(from_here, callback); | 1064 message_loop->PostTask(from_here, callback); |
| 1062 } | 1065 } |
| 1063 | 1066 |
| 1064 } // namespace | 1067 } // namespace |
| 1065 | 1068 |
| 1066 void SyncBackendHost::RefreshEncryption(const base::Closure& done_callback) { | 1069 void SyncBackendHost::RefreshEncryption(const base::Closure& done_callback) { |
| 1067 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 1070 DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
| 1068 base::Closure sync_thread_done_callback = | 1071 base::Closure sync_thread_done_callback = |
| 1069 base::Bind(&PostClosure, | 1072 base::Bind(&PostClosure, |
| 1070 MessageLoop::current(), FROM_HERE, done_callback); | 1073 MessageLoop::current(), FROM_HERE, done_callback); |
| 1071 sync_thread_.message_loop()->PostTask( | 1074 sync_thread_.message_loop()->PostTask( |
| 1072 FROM_HERE, | 1075 FROM_HERE, |
| 1073 base::Bind(&SyncBackendHost::Core::DoRefreshEncryption, | 1076 base::Bind(&SyncBackendHost::Core::DoRefreshEncryption, |
| 1074 core_.get(), sync_thread_done_callback)); | 1077 core_.get(), sync_thread_done_callback)); |
| 1075 } | 1078 } |
| 1076 | 1079 |
| 1077 #undef SDVLOG | 1080 #undef SDVLOG |
| 1078 | 1081 |
| 1079 #undef SLOG | 1082 #undef SLOG |
| 1080 | 1083 |
| 1081 } // namespace browser_sync | 1084 } // namespace browser_sync |
| OLD | NEW |