sync_manager_impl.cc 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511
  1. // Copyright (c) 2012 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "components/sync/engine/sync_manager_impl.h"
  5. #include <stddef.h>
  6. #include <utility>
  7. #include "base/bind.h"
  8. #include "base/callback.h"
  9. #include "base/compiler_specific.h"
  10. #include "base/feature_list.h"
  11. #include "base/metrics/histogram_macros.h"
  12. #include "base/observer_list.h"
  13. #include "base/threading/sequenced_task_runner_handle.h"
  14. #include "base/values.h"
  15. #include "components/sync/base/model_type.h"
  16. #include "components/sync/base/sync_invalidation.h"
  17. #include "components/sync/engine/cancelation_signal.h"
  18. #include "components/sync/engine/configure_reason.h"
  19. #include "components/sync/engine/engine_components_factory.h"
  20. #include "components/sync/engine/loopback_server/loopback_connection_manager.h"
  21. #include "components/sync/engine/model_type_connector_proxy.h"
  22. #include "components/sync/engine/net/http_post_provider_factory.h"
  23. #include "components/sync/engine/net/sync_server_connection_manager.h"
  24. #include "components/sync/engine/net/url_translator.h"
  25. #include "components/sync/engine/nigori/cryptographer.h"
  26. #include "components/sync/engine/nigori/key_derivation_params.h"
  27. #include "components/sync/engine/nigori/keystore_keys_handler.h"
  28. #include "components/sync/engine/polling_constants.h"
  29. #include "components/sync/engine/sync_scheduler.h"
  30. #include "components/sync/protocol/sync_enums.pb.h"
  31. namespace syncer {
  32. namespace {
  33. sync_pb::SyncEnums::GetUpdatesOrigin GetOriginFromReason(
  34. ConfigureReason reason) {
  35. switch (reason) {
  36. case CONFIGURE_REASON_RECONFIGURATION:
  37. return sync_pb::SyncEnums::RECONFIGURATION;
  38. case CONFIGURE_REASON_MIGRATION:
  39. return sync_pb::SyncEnums::MIGRATION;
  40. case CONFIGURE_REASON_NEW_CLIENT:
  41. return sync_pb::SyncEnums::NEW_CLIENT;
  42. case CONFIGURE_REASON_NEWLY_ENABLED_DATA_TYPE:
  43. case CONFIGURE_REASON_CRYPTO:
  44. return sync_pb::SyncEnums::NEWLY_SUPPORTED_DATATYPE;
  45. case CONFIGURE_REASON_PROGRAMMATIC:
  46. return sync_pb::SyncEnums::PROGRAMMATIC;
  47. case CONFIGURE_REASON_UNKNOWN:
  48. NOTREACHED();
  49. }
  50. return sync_pb::SyncEnums::UNKNOWN_ORIGIN;
  51. }
  52. const char kSyncServerSyncPath[] = "/command/";
  53. std::string StripTrailingSlash(const std::string& s) {
  54. int stripped_end_pos = s.size();
  55. if (s.at(stripped_end_pos - 1) == '/') {
  56. stripped_end_pos = stripped_end_pos - 1;
  57. }
  58. return s.substr(0, stripped_end_pos);
  59. }
  60. GURL MakeConnectionURL(const GURL& sync_server, const std::string& client_id) {
  61. DCHECK_EQ(kSyncServerSyncPath[0], '/');
  62. std::string full_path =
  63. StripTrailingSlash(sync_server.path()) + kSyncServerSyncPath;
  64. GURL::Replacements path_replacement;
  65. path_replacement.SetPathStr(full_path);
  66. return AppendSyncQueryString(sync_server.ReplaceComponents(path_replacement),
  67. client_id);
  68. }
  69. } // namespace
  70. SyncManagerImpl::SyncManagerImpl(
  71. const std::string& name,
  72. network::NetworkConnectionTracker* network_connection_tracker)
  73. : name_(name),
  74. network_connection_tracker_(network_connection_tracker),
  75. initialized_(false),
  76. observing_network_connectivity_changes_(false),
  77. sync_encryption_handler_(nullptr) {}
  78. SyncManagerImpl::~SyncManagerImpl() {
  79. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  80. DCHECK(!initialized_);
  81. }
  82. ModelTypeSet SyncManagerImpl::InitialSyncEndedTypes() {
  83. DCHECK(initialized_);
  84. return model_type_registry_->GetInitialSyncEndedTypes();
  85. }
  86. ModelTypeSet SyncManagerImpl::GetConnectedTypes() {
  87. DCHECK(initialized_);
  88. return model_type_registry_->GetConnectedTypes();
  89. }
  90. void SyncManagerImpl::ConfigureSyncer(ConfigureReason reason,
  91. ModelTypeSet to_download,
  92. SyncFeatureState sync_feature_state,
  93. base::OnceClosure ready_task) {
  94. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  95. DCHECK(!ready_task.is_null());
  96. DCHECK(initialized_);
  97. DVLOG(1) << "Configuring -"
  98. << "\n\t"
  99. << "types to download: " << ModelTypeSetToDebugString(to_download);
  100. scheduler_->Start(SyncScheduler::CONFIGURATION_MODE, base::Time());
  101. scheduler_->ScheduleConfiguration(GetOriginFromReason(reason), to_download,
  102. std::move(ready_task));
  103. if (sync_feature_state != SyncFeatureState::INITIALIZING) {
  104. cycle_context_->set_is_sync_feature_enabled(sync_feature_state ==
  105. SyncFeatureState::ON);
  106. }
  107. }
  108. void SyncManagerImpl::Init(InitArgs* args) {
  109. DCHECK(!initialized_);
  110. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  111. DCHECK(!args->cache_guid.empty());
  112. DCHECK(args->post_factory);
  113. DCHECK(!args->poll_interval.is_zero());
  114. DCHECK(args->cancelation_signal);
  115. DVLOG(1) << "SyncManager starting Init...";
  116. DCHECK(args->encryption_observer_proxy);
  117. encryption_observer_proxy_ = std::move(args->encryption_observer_proxy);
  118. AddObserver(&debug_info_event_listener_);
  119. DCHECK(args->encryption_handler);
  120. sync_encryption_handler_ = args->encryption_handler;
  121. // Register for encryption related changes now. We have to do this before
  122. // the initial download of control types or initializing the encryption
  123. // handler in order to receive notifications triggered during encryption
  124. // startup.
  125. sync_encryption_handler_->AddObserver(this);
  126. sync_encryption_handler_->AddObserver(encryption_observer_proxy_.get());
  127. sync_encryption_handler_->AddObserver(&debug_info_event_listener_);
  128. // base::Unretained() is safe here because SyncManagerImpl outlives
  129. // sync_status_tracker_.
  130. sync_status_tracker_ =
  131. std::make_unique<SyncStatusTracker>(base::BindRepeating(
  132. &SyncManagerImpl::NotifySyncStatusChanged, base::Unretained(this)));
  133. sync_status_tracker_->SetHasKeystoreKey(
  134. !sync_encryption_handler_->GetKeystoreKeysHandler()->NeedKeystoreKey());
  135. if (args->enable_local_sync_backend) {
  136. VLOG(1) << "Running against local sync backend.";
  137. sync_status_tracker_->SetLocalBackendFolder(
  138. args->local_sync_backend_folder.AsUTF8Unsafe());
  139. connection_manager_ = std::make_unique<LoopbackConnectionManager>(
  140. args->local_sync_backend_folder);
  141. } else {
  142. connection_manager_ = std::make_unique<SyncServerConnectionManager>(
  143. MakeConnectionURL(args->service_url, args->cache_guid),
  144. std::move(args->post_factory), args->cancelation_signal);
  145. }
  146. connection_manager_->AddListener(this);
  147. DVLOG(1) << "Setting sync client ID: " << args->cache_guid;
  148. sync_status_tracker_->SetCacheGuid(args->cache_guid);
  149. DVLOG(1) << "Setting invalidator client ID: " << args->invalidator_client_id;
  150. sync_status_tracker_->SetInvalidatorClientId(args->invalidator_client_id);
  151. model_type_registry_ = std::make_unique<ModelTypeRegistry>(
  152. this, args->cancelation_signal, sync_encryption_handler_);
  153. // Build a SyncCycleContext and store the worker in it.
  154. DVLOG(1) << "Sync is bringing up SyncCycleContext.";
  155. std::vector<SyncEngineEventListener*> listeners = {
  156. this, sync_status_tracker_.get()};
  157. cycle_context_ = args->engine_components_factory->BuildContext(
  158. connection_manager_.get(), args->extensions_activity, listeners,
  159. &debug_info_event_listener_, model_type_registry_.get(),
  160. args->invalidator_client_id, args->cache_guid, args->birthday,
  161. args->bag_of_chips, args->poll_interval);
  162. scheduler_ = args->engine_components_factory->BuildScheduler(
  163. name_, cycle_context_.get(), args->cancelation_signal,
  164. args->enable_local_sync_backend);
  165. scheduler_->Start(SyncScheduler::CONFIGURATION_MODE, base::Time());
  166. initialized_ = true;
  167. if (!args->enable_local_sync_backend) {
  168. network_connection_tracker_->AddNetworkConnectionObserver(this);
  169. } else {
  170. scheduler_->OnCredentialsUpdated();
  171. }
  172. debug_info_event_listener_.InitializationComplete();
  173. }
  174. void SyncManagerImpl::OnPassphraseRequired(
  175. const KeyDerivationParams& key_derivation_params,
  176. const sync_pb::EncryptedData& pending_keys) {
  177. // Does nothing.
  178. }
  179. void SyncManagerImpl::OnPassphraseAccepted() {
  180. // Does nothing.
  181. }
  182. void SyncManagerImpl::OnTrustedVaultKeyRequired() {
  183. // Does nothing.
  184. }
  185. void SyncManagerImpl::OnTrustedVaultKeyAccepted() {
  186. // Does nothing.
  187. }
  188. void SyncManagerImpl::OnEncryptedTypesChanged(ModelTypeSet encrypted_types,
  189. bool encrypt_everything) {
  190. sync_status_tracker_->SetEncryptedTypes(encrypted_types);
  191. }
  192. void SyncManagerImpl::OnCryptographerStateChanged(Cryptographer* cryptographer,
  193. bool has_pending_keys) {
  194. sync_status_tracker_->SetCryptographerCanEncrypt(cryptographer->CanEncrypt());
  195. sync_status_tracker_->SetCryptoHasPendingKeys(has_pending_keys);
  196. sync_status_tracker_->SetKeystoreMigrationTime(
  197. sync_encryption_handler_->GetKeystoreMigrationTime());
  198. sync_status_tracker_->SetTrustedVaultDebugInfo(
  199. sync_encryption_handler_->GetTrustedVaultDebugInfo());
  200. sync_status_tracker_->SetHasKeystoreKey(
  201. !sync_encryption_handler_->GetKeystoreKeysHandler()->NeedKeystoreKey());
  202. }
  203. void SyncManagerImpl::OnPassphraseTypeChanged(
  204. PassphraseType type,
  205. base::Time explicit_passphrase_time) {
  206. sync_status_tracker_->SetPassphraseType(type);
  207. sync_status_tracker_->SetKeystoreMigrationTime(
  208. sync_encryption_handler_->GetKeystoreMigrationTime());
  209. }
  210. void SyncManagerImpl::StartSyncingNormally(base::Time last_poll_time) {
  211. // Start the sync scheduler.
  212. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  213. scheduler_->Start(SyncScheduler::NORMAL_MODE, last_poll_time);
  214. }
  215. void SyncManagerImpl::StartConfiguration() {
  216. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  217. scheduler_->Start(SyncScheduler::CONFIGURATION_MODE, base::Time());
  218. }
  219. void SyncManagerImpl::UpdateCredentials(const SyncCredentials& credentials) {
  220. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  221. DCHECK(initialized_);
  222. cycle_context_->set_account_name(credentials.email);
  223. observing_network_connectivity_changes_ = true;
  224. if (!connection_manager_->SetAccessToken(credentials.access_token))
  225. return; // Auth token is known to be invalid, so exit early.
  226. scheduler_->OnCredentialsUpdated();
  227. // TODO(zea): pass the credential age to the debug info event listener.
  228. }
  229. void SyncManagerImpl::InvalidateCredentials() {
  230. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  231. connection_manager_->SetAccessToken(std::string());
  232. }
  233. void SyncManagerImpl::AddObserver(SyncManager::Observer* observer) {
  234. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  235. observers_.AddObserver(observer);
  236. }
  237. void SyncManagerImpl::RemoveObserver(SyncManager::Observer* observer) {
  238. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  239. observers_.RemoveObserver(observer);
  240. }
  241. void SyncManagerImpl::ShutdownOnSyncThread() {
  242. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  243. // Prevent any in-flight method calls from running.
  244. weak_ptr_factory_.InvalidateWeakPtrs();
  245. scheduler_.reset();
  246. cycle_context_.reset();
  247. model_type_registry_.reset();
  248. if (sync_encryption_handler_) {
  249. sync_encryption_handler_->RemoveObserver(&debug_info_event_listener_);
  250. sync_encryption_handler_->RemoveObserver(this);
  251. }
  252. RemoveObserver(&debug_info_event_listener_);
  253. // |connection_manager_| may end up being null here in tests (in synchronous
  254. // initialization mode).
  255. //
  256. // TODO(akalin): Fix this behavior.
  257. if (connection_manager_)
  258. connection_manager_->RemoveListener(this);
  259. connection_manager_.reset();
  260. network_connection_tracker_->RemoveNetworkConnectionObserver(this);
  261. observing_network_connectivity_changes_ = false;
  262. initialized_ = false;
  263. }
  264. void SyncManagerImpl::OnConnectionChanged(network::mojom::ConnectionType type) {
  265. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  266. if (!observing_network_connectivity_changes_) {
  267. DVLOG(1) << "Network change dropped.";
  268. return;
  269. }
  270. DVLOG(1) << "Network change detected.";
  271. scheduler_->OnConnectionStatusChange(type);
  272. }
  273. void SyncManagerImpl::OnServerConnectionEvent(
  274. const ServerConnectionEvent& event) {
  275. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  276. if (event.connection_code == HttpResponse::SERVER_CONNECTION_OK) {
  277. for (SyncManager::Observer& observer : observers_) {
  278. observer.OnConnectionStatusChange(CONNECTION_OK);
  279. }
  280. }
  281. if (event.connection_code == HttpResponse::SYNC_AUTH_ERROR) {
  282. observing_network_connectivity_changes_ = false;
  283. for (SyncManager::Observer& observer : observers_) {
  284. observer.OnConnectionStatusChange(CONNECTION_AUTH_ERROR);
  285. }
  286. }
  287. if (event.connection_code == HttpResponse::SYNC_SERVER_ERROR) {
  288. for (SyncManager::Observer& observer : observers_) {
  289. observer.OnConnectionStatusChange(CONNECTION_SERVER_ERROR);
  290. }
  291. }
  292. }
  293. void SyncManagerImpl::NudgeForInitialDownload(ModelType type) {
  294. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  295. scheduler_->ScheduleInitialSyncNudge(type);
  296. }
  297. void SyncManagerImpl::NudgeForCommit(ModelType type) {
  298. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  299. debug_info_event_listener_.OnNudgeFromDatatype(type);
  300. scheduler_->ScheduleLocalNudge(type);
  301. }
  302. void SyncManagerImpl::NotifySyncStatusChanged(const SyncStatus& status) {
  303. for (SyncManager::Observer& observer : observers_) {
  304. observer.OnSyncStatusChanged(status);
  305. }
  306. }
  307. void SyncManagerImpl::OnSyncCycleEvent(const SyncCycleEvent& event) {
  308. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  309. // Only send an event if this is due to a cycle ending and this cycle
  310. // concludes a canonical "sync" process; that is, based on what is known
  311. // locally we are "all happy" and up to date. There may be new changes on
  312. // the server, but we'll get them on a subsequent sync.
  313. //
  314. // Notifications are sent at the end of every sync cycle, regardless of
  315. // whether we should sync again.
  316. if (event.what_happened == SyncCycleEvent::SYNC_CYCLE_ENDED) {
  317. if (!initialized_) {
  318. DVLOG(1) << "OnSyncCycleCompleted not sent because sync api is not "
  319. << "initialized";
  320. return;
  321. }
  322. DVLOG(1) << "Sending OnSyncCycleCompleted";
  323. for (SyncManager::Observer& observer : observers_) {
  324. observer.OnSyncCycleCompleted(event.snapshot);
  325. }
  326. }
  327. }
  328. void SyncManagerImpl::OnActionableError(const SyncProtocolError& error) {
  329. for (SyncManager::Observer& observer : observers_) {
  330. observer.OnActionableError(error);
  331. }
  332. }
  333. void SyncManagerImpl::OnRetryTimeChanged(base::Time) {}
  334. void SyncManagerImpl::OnThrottledTypesChanged(ModelTypeSet) {}
  335. void SyncManagerImpl::OnBackedOffTypesChanged(ModelTypeSet) {}
  336. void SyncManagerImpl::OnMigrationRequested(ModelTypeSet types) {
  337. for (SyncManager::Observer& observer : observers_) {
  338. observer.OnMigrationRequested(types);
  339. }
  340. }
  341. void SyncManagerImpl::OnProtocolEvent(const ProtocolEvent& event) {
  342. protocol_event_buffer_.RecordProtocolEvent(event);
  343. for (SyncManager::Observer& observer : observers_) {
  344. observer.OnProtocolEvent(event);
  345. }
  346. }
  347. void SyncManagerImpl::SetInvalidatorEnabled(bool invalidator_enabled) {
  348. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  349. DVLOG(1) << "Invalidator enabled state is now: " << invalidator_enabled;
  350. sync_status_tracker_->SetNotificationsEnabled(invalidator_enabled);
  351. scheduler_->SetNotificationsEnabled(invalidator_enabled);
  352. }
  353. void SyncManagerImpl::OnIncomingInvalidation(
  354. ModelType type,
  355. std::unique_ptr<SyncInvalidation> invalidation) {
  356. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  357. sync_status_tracker_->IncrementNotificationsReceived();
  358. scheduler_->ScheduleInvalidationNudge(type, std::move(invalidation));
  359. }
  360. void SyncManagerImpl::RefreshTypes(ModelTypeSet types) {
  361. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  362. const ModelTypeSet types_to_refresh =
  363. Intersection(types, model_type_registry_->GetConnectedTypes());
  364. if (!types_to_refresh.Empty()) {
  365. scheduler_->ScheduleLocalRefreshRequest(types_to_refresh);
  366. }
  367. }
  368. ModelTypeConnector* SyncManagerImpl::GetModelTypeConnector() {
  369. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  370. return model_type_registry_.get();
  371. }
  372. std::unique_ptr<ModelTypeConnector>
  373. SyncManagerImpl::GetModelTypeConnectorProxy() {
  374. DCHECK(initialized_);
  375. return std::make_unique<ModelTypeConnectorProxy>(
  376. base::SequencedTaskRunnerHandle::Get(),
  377. model_type_registry_->AsWeakPtr());
  378. }
  379. std::string SyncManagerImpl::cache_guid() {
  380. DCHECK(initialized_);
  381. return cycle_context_->cache_guid();
  382. }
  383. std::string SyncManagerImpl::birthday() {
  384. DCHECK(initialized_);
  385. DCHECK(cycle_context_);
  386. return cycle_context_->birthday();
  387. }
  388. std::string SyncManagerImpl::bag_of_chips() {
  389. DCHECK(initialized_);
  390. DCHECK(cycle_context_);
  391. return cycle_context_->bag_of_chips();
  392. }
  393. bool SyncManagerImpl::HasUnsyncedItemsForTest() {
  394. return model_type_registry_->HasUnsyncedItems();
  395. }
  396. SyncEncryptionHandler* SyncManagerImpl::GetEncryptionHandler() {
  397. DCHECK(sync_encryption_handler_);
  398. return sync_encryption_handler_;
  399. }
  400. std::vector<std::unique_ptr<ProtocolEvent>>
  401. SyncManagerImpl::GetBufferedProtocolEvents() {
  402. return protocol_event_buffer_.GetBufferedProtocolEvents();
  403. }
  404. void SyncManagerImpl::OnCookieJarChanged(bool account_mismatch) {
  405. DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  406. cycle_context_->set_cookie_jar_mismatch(account_mismatch);
  407. }
  408. void SyncManagerImpl::UpdateInvalidationClientId(const std::string& client_id) {
  409. DVLOG(1) << "Setting invalidator client ID: " << client_id;
  410. sync_status_tracker_->SetInvalidatorClientId(client_id);
  411. cycle_context_->set_invalidator_client_id(client_id);
  412. }
  413. void SyncManagerImpl::UpdateActiveDevicesInvalidationInfo(
  414. ActiveDevicesInvalidationInfo active_devices_invalidation_info) {
  415. cycle_context_->set_active_devices_invalidation_info(
  416. std::move(active_devices_invalidation_info));
  417. }
  418. } // namespace syncer