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