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

Side by Side Diff: chrome/browser/sync/glue/sync_backend_host.cc

Issue 8938013: [Sync] Make SyncBackendHost::Core use a WeakHandle to its host (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Sync to head Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « chrome/browser/sync/glue/sync_backend_host.h ('k') | chrome/browser/sync/test_profile_sync_service.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698