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 |