OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
71 | 71 |
72 // Helper macros to log with the syncer thread name; useful when there | 72 // Helper macros to log with the syncer thread name; useful when there |
73 // are multiple syncers involved. | 73 // are multiple syncers involved. |
74 | 74 |
75 #define SLOG(severity) LOG(severity) << name_ << ": " | 75 #define SLOG(severity) LOG(severity) << name_ << ": " |
76 | 76 |
77 #define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " | 77 #define SDVLOG(verbose_level) DVLOG(verbose_level) << name_ << ": " |
78 | 78 |
79 class SyncBackendHost::Core | 79 class SyncBackendHost::Core |
80 : public base::RefCountedThreadSafe<SyncBackendHost::Core>, | 80 : public base::RefCountedThreadSafe<SyncBackendHost::Core>, |
81 public syncer::SyncEncryptionHandler::Observer, | |
81 public syncer::SyncManager::Observer, | 82 public syncer::SyncManager::Observer, |
82 public syncer::SyncNotifierObserver { | 83 public syncer::SyncNotifierObserver { |
83 public: | 84 public: |
84 Core(const std::string& name, | 85 Core(const std::string& name, |
85 const FilePath& sync_data_folder_path, | 86 const FilePath& sync_data_folder_path, |
86 const base::WeakPtr<SyncBackendHost>& backend); | 87 const base::WeakPtr<SyncBackendHost>& backend); |
87 | 88 |
88 // SyncManager::Observer implementation. The Core just acts like an air | 89 // SyncManager::Observer implementation. The Core just acts like an air |
89 // traffic controller here, forwarding incoming messages to appropriate | 90 // traffic controller here, forwarding incoming messages to appropriate |
90 // landing threads. | 91 // landing threads. |
91 virtual void OnSyncCycleCompleted( | 92 virtual void OnSyncCycleCompleted( |
92 const syncer::sessions::SyncSessionSnapshot& snapshot) OVERRIDE; | 93 const syncer::sessions::SyncSessionSnapshot& snapshot) OVERRIDE; |
93 virtual void OnInitializationComplete( | 94 virtual void OnInitializationComplete( |
94 const syncer::WeakHandle<syncer::JsBackend>& js_backend, | 95 const syncer::WeakHandle<syncer::JsBackend>& js_backend, |
95 bool success, | 96 bool success, |
96 syncer::ModelTypeSet restored_types) OVERRIDE; | 97 syncer::ModelTypeSet restored_types) OVERRIDE; |
97 virtual void OnConnectionStatusChange( | 98 virtual void OnConnectionStatusChange( |
98 syncer::ConnectionStatus status) OVERRIDE; | 99 syncer::ConnectionStatus status) OVERRIDE; |
100 virtual void OnStopSyncingPermanently() OVERRIDE; | |
101 virtual void OnUpdatedToken(const std::string& token) OVERRIDE; | |
102 virtual void OnActionableError( | |
103 const syncer::SyncProtocolError& sync_error) OVERRIDE; | |
104 | |
105 // SyncEncryptionHandler::Observer implementation. | |
99 virtual void OnPassphraseRequired( | 106 virtual void OnPassphraseRequired( |
100 syncer::PassphraseRequiredReason reason, | 107 syncer::PassphraseRequiredReason reason, |
101 const sync_pb::EncryptedData& pending_keys) OVERRIDE; | 108 const sync_pb::EncryptedData& pending_keys) OVERRIDE; |
102 virtual void OnPassphraseAccepted() OVERRIDE; | 109 virtual void OnPassphraseAccepted() OVERRIDE; |
103 virtual void OnBootstrapTokenUpdated( | 110 virtual void OnBootstrapTokenUpdated( |
104 const std::string& bootstrap_token) OVERRIDE; | 111 const std::string& bootstrap_token) OVERRIDE; |
105 virtual void OnStopSyncingPermanently() OVERRIDE; | |
106 virtual void OnUpdatedToken(const std::string& token) OVERRIDE; | |
107 virtual void OnEncryptedTypesChanged( | 112 virtual void OnEncryptedTypesChanged( |
108 syncer::ModelTypeSet encrypted_types, | 113 syncer::ModelTypeSet encrypted_types, |
109 bool encrypt_everything) OVERRIDE; | 114 bool encrypt_everything) OVERRIDE; |
110 virtual void OnEncryptionComplete() OVERRIDE; | 115 virtual void OnEncryptionComplete() OVERRIDE; |
111 virtual void OnActionableError( | 116 virtual void OnCryptographerStateChanged( |
112 const syncer::SyncProtocolError& sync_error) OVERRIDE; | 117 syncer::Cryptographer* cryptographer) OVERRIDE; |
113 | 118 |
114 // syncer::SyncNotifierObserver implementation. | 119 // syncer::SyncNotifierObserver implementation. |
115 virtual void OnNotificationsEnabled() OVERRIDE; | 120 virtual void OnNotificationsEnabled() OVERRIDE; |
116 virtual void OnNotificationsDisabled( | 121 virtual void OnNotificationsDisabled( |
117 syncer::NotificationsDisabledReason reason) OVERRIDE; | 122 syncer::NotificationsDisabledReason reason) OVERRIDE; |
118 virtual void OnIncomingNotification( | 123 virtual void OnIncomingNotification( |
119 const syncer::ObjectIdPayloadMap& id_payloads, | 124 const syncer::ObjectIdPayloadMap& id_payloads, |
120 syncer::IncomingNotificationSource source) OVERRIDE; | 125 syncer::IncomingNotificationSource source) OVERRIDE; |
121 | 126 |
122 // Note: | 127 // Note: |
(...skipping 23 matching lines...) Expand all Loading... | |
146 void DoSetEncryptionPassphrase(const std::string& passphrase, | 151 void DoSetEncryptionPassphrase(const std::string& passphrase, |
147 bool is_explicit); | 152 bool is_explicit); |
148 | 153 |
149 // Called to decrypt the pending keys. | 154 // Called to decrypt the pending keys. |
150 void DoSetDecryptionPassphrase(const std::string& passphrase); | 155 void DoSetDecryptionPassphrase(const std::string& passphrase); |
151 | 156 |
152 // Called to turn on encryption of all sync data as well as | 157 // Called to turn on encryption of all sync data as well as |
153 // reencrypt everything. | 158 // reencrypt everything. |
154 void DoEnableEncryptEverything(); | 159 void DoEnableEncryptEverything(); |
155 | 160 |
156 // Called to refresh encryption with the most recent passphrase | 161 // Called to load sync encryption state and re-encrypt any types |
157 // and set of encrypted types. Also adds device information to the nigori | 162 // needing encryption as necessary. |
158 // node. |done_callback| is called on the sync thread. | 163 void DoAssociateNigori( |
159 void DoRefreshNigori(const base::Closure& done_callback); | 164 const syncer::WeakHandle<syncer::JsBackend>& js_backend); |
160 | 165 |
161 // The shutdown order is a bit complicated: | 166 // The shutdown order is a bit complicated: |
162 // 1) From |sync_thread_|, invoke the syncapi Shutdown call to do | 167 // 1) From |sync_thread_|, invoke the syncapi Shutdown call to do |
163 // a final SaveChanges, and close sqlite handles. | 168 // a final SaveChanges, and close sqlite handles. |
164 // 2) Then, from |frontend_loop_|, halt the sync_thread_ (which is | 169 // 2) Then, from |frontend_loop_|, halt the sync_thread_ (which is |
165 // a blocking call). This causes syncapi thread-exit handlers | 170 // a blocking call). This causes syncapi thread-exit handlers |
166 // to run and make use of cached pointers to various components | 171 // to run and make use of cached pointers to various components |
167 // owned implicitly by us. | 172 // owned implicitly by us. |
168 // 3) Destroy this Core. That will delete syncapi components in a | 173 // 3) Destroy this Core. That will delete syncapi components in a |
169 // safe order because the thread that was using them has exited | 174 // safe order because the thread that was using them has exited |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
730 | 735 |
731 bool SyncBackendHost::IsNigoriEnabled() const { | 736 bool SyncBackendHost::IsNigoriEnabled() const { |
732 return registrar_.get() && registrar_->IsNigoriEnabled(); | 737 return registrar_.get() && registrar_->IsNigoriEnabled(); |
733 } | 738 } |
734 | 739 |
735 bool SyncBackendHost::IsUsingExplicitPassphrase() { | 740 bool SyncBackendHost::IsUsingExplicitPassphrase() { |
736 // This should only be called once the nigori node has been downloaded, as | 741 // This should only be called once the nigori node has been downloaded, as |
737 // otherwise we have no idea what kind of passphrase we are using. This will | 742 // otherwise we have no idea what kind of passphrase we are using. This will |
738 // NOTREACH in sync_manager and return false if we fail to load the nigori | 743 // NOTREACH in sync_manager and return false if we fail to load the nigori |
739 // node. | 744 // node. |
745 // TODO(zea): cache this value here, then make the encryption handler | |
746 // NonThreadSafe and only accessible from the sync thread. | |
740 return IsNigoriEnabled() && | 747 return IsNigoriEnabled() && |
741 core_->sync_manager()->IsUsingExplicitPassphrase(); | 748 core_->sync_manager()->GetEncryptionHandler()-> |
749 IsUsingExplicitPassphrase(); | |
742 } | 750 } |
743 | 751 |
744 bool SyncBackendHost::IsCryptographerReady( | 752 bool SyncBackendHost::IsCryptographerReady( |
745 const syncer::BaseTransaction* trans) const { | 753 const syncer::BaseTransaction* trans) const { |
746 return initialized() && trans->GetCryptographer()->is_ready(); | 754 return initialized() && trans->GetCryptographer()->is_ready(); |
747 } | 755 } |
748 | 756 |
749 void SyncBackendHost::GetModelSafeRoutingInfo( | 757 void SyncBackendHost::GetModelSafeRoutingInfo( |
750 syncer::ModelSafeRoutingInfo* out) const { | 758 syncer::ModelSafeRoutingInfo* out) const { |
751 if (initialized()) { | 759 if (initialized()) { |
(...skipping 234 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
986 void SyncBackendHost::Core::OnEncryptionComplete() { | 994 void SyncBackendHost::Core::OnEncryptionComplete() { |
987 if (!sync_loop_) | 995 if (!sync_loop_) |
988 return; | 996 return; |
989 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 997 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
990 // NOTE: We're in a transaction. | 998 // NOTE: We're in a transaction. |
991 host_.Call( | 999 host_.Call( |
992 FROM_HERE, | 1000 FROM_HERE, |
993 &SyncBackendHost::NotifyEncryptionComplete); | 1001 &SyncBackendHost::NotifyEncryptionComplete); |
994 } | 1002 } |
995 | 1003 |
1004 void SyncBackendHost::Core::OnCryptographerStateChanged( | |
1005 syncer::Cryptographer* cryptographer) { | |
1006 // Do nothing. | |
1007 } | |
1008 | |
996 void SyncBackendHost::Core::OnActionableError( | 1009 void SyncBackendHost::Core::OnActionableError( |
997 const syncer::SyncProtocolError& sync_error) { | 1010 const syncer::SyncProtocolError& sync_error) { |
998 if (!sync_loop_) | 1011 if (!sync_loop_) |
999 return; | 1012 return; |
1000 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1013 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1001 host_.Call( | 1014 host_.Call( |
1002 FROM_HERE, | 1015 FROM_HERE, |
1003 &SyncBackendHost::HandleActionableErrorEventOnFrontendLoop, | 1016 &SyncBackendHost::HandleActionableErrorEventOnFrontendLoop, |
1004 sync_error); | 1017 sync_error); |
1005 } | 1018 } |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1115 sync_manager_->UpdateRegisteredInvalidationIds(this, ids); | 1128 sync_manager_->UpdateRegisteredInvalidationIds(this, ids); |
1116 } | 1129 } |
1117 } | 1130 } |
1118 | 1131 |
1119 void SyncBackendHost::Core::DoStartSyncing( | 1132 void SyncBackendHost::Core::DoStartSyncing( |
1120 const syncer::ModelSafeRoutingInfo& routing_info) { | 1133 const syncer::ModelSafeRoutingInfo& routing_info) { |
1121 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1134 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1122 sync_manager_->StartSyncingNormally(routing_info); | 1135 sync_manager_->StartSyncingNormally(routing_info); |
1123 } | 1136 } |
1124 | 1137 |
1138 void SyncBackendHost::Core::DoAssociateNigori( | |
1139 const syncer::WeakHandle<syncer::JsBackend>& js_backend) { | |
1140 DCHECK_EQ(MessageLoop::current(), sync_loop_); | |
1141 sync_manager_->GetEncryptionHandler()->AddObserver(this); | |
1142 sync_manager_->GetEncryptionHandler()->Init(); | |
1143 host_.Call(FROM_HERE, | |
1144 &SyncBackendHost::HandleInitializationCompletedOnFrontendLoop, | |
1145 js_backend, | |
1146 true); | |
1147 } | |
1148 | |
1125 void SyncBackendHost::Core::DoSetEncryptionPassphrase( | 1149 void SyncBackendHost::Core::DoSetEncryptionPassphrase( |
1126 const std::string& passphrase, | 1150 const std::string& passphrase, |
1127 bool is_explicit) { | 1151 bool is_explicit) { |
1128 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1152 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1129 sync_manager_->SetEncryptionPassphrase(passphrase, is_explicit); | 1153 sync_manager_->GetEncryptionHandler()->SetEncryptionPassphrase( |
1154 passphrase, is_explicit); | |
1130 } | 1155 } |
1131 | 1156 |
1132 void SyncBackendHost::Core::DoSetDecryptionPassphrase( | 1157 void SyncBackendHost::Core::DoSetDecryptionPassphrase( |
1133 const std::string& passphrase) { | 1158 const std::string& passphrase) { |
1134 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1159 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1135 sync_manager_->SetDecryptionPassphrase(passphrase); | 1160 sync_manager_->GetEncryptionHandler()->SetDecryptionPassphrase( |
1161 passphrase); | |
1136 } | 1162 } |
1137 | 1163 |
1138 void SyncBackendHost::Core::DoEnableEncryptEverything() { | 1164 void SyncBackendHost::Core::DoEnableEncryptEverything() { |
1139 DCHECK_EQ(MessageLoop::current(), sync_loop_); | 1165 DCHECK_EQ(MessageLoop::current(), sync_loop_); |
1140 sync_manager_->EnableEncryptEverything(); | 1166 sync_manager_->GetEncryptionHandler()->EnableEncryptEverything(); |
1141 } | |
1142 | |
1143 void SyncBackendHost::Core::DoRefreshNigori( | |
1144 const base::Closure& done_callback) { | |
1145 DCHECK_EQ(MessageLoop::current(), sync_loop_); | |
1146 chrome::VersionInfo version_info; | |
1147 sync_manager_->RefreshNigori(version_info.CreateVersionString(), | |
1148 done_callback); | |
1149 } | 1167 } |
1150 | 1168 |
1151 void SyncBackendHost::Core::DoStopSyncManagerForShutdown( | 1169 void SyncBackendHost::Core::DoStopSyncManagerForShutdown( |
1152 const base::Closure& closure) { | 1170 const base::Closure& closure) { |
1153 if (sync_manager_.get()) { | 1171 if (sync_manager_.get()) { |
1154 sync_manager_->StopSyncingForShutdown(closure); | 1172 sync_manager_->StopSyncingForShutdown(closure); |
1155 } else { | 1173 } else { |
1156 sync_loop_->PostTask(FROM_HERE, closure); | 1174 sync_loop_->PostTask(FROM_HERE, closure); |
1157 } | 1175 } |
1158 } | 1176 } |
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1303 WITH_NIGORI, | 1321 WITH_NIGORI, |
1304 // Calls back into this function. | 1322 // Calls back into this function. |
1305 base::Bind( | 1323 base::Bind( |
1306 &SyncBackendHost:: | 1324 &SyncBackendHost:: |
1307 HandleNigoriConfigurationCompletedOnFrontendLoop, | 1325 HandleNigoriConfigurationCompletedOnFrontendLoop, |
1308 weak_ptr_factory_.GetWeakPtr(), js_backend), | 1326 weak_ptr_factory_.GetWeakPtr(), js_backend), |
1309 base::Bind(&SyncBackendHost::OnNigoriDownloadRetry, | 1327 base::Bind(&SyncBackendHost::OnNigoriDownloadRetry, |
1310 weak_ptr_factory_.GetWeakPtr())); | 1328 weak_ptr_factory_.GetWeakPtr())); |
1311 break; | 1329 break; |
1312 case DOWNLOADING_NIGORI: | 1330 case DOWNLOADING_NIGORI: |
1313 initialization_state_ = REFRESHING_NIGORI; | 1331 initialization_state_ = ASSOCIATING_NIGORI; |
1314 // Triggers OnEncryptedTypesChanged() and OnEncryptionComplete() | 1332 // Triggers OnEncryptedTypesChanged() and OnEncryptionComplete() |
1315 // if necessary. | 1333 // if necessary. |
1316 RefreshNigori( | 1334 AssociateNigori(js_backend); |
tim (not reviewing)
2012/08/15 00:23:30
Can we cache js_backend somewhere in this class to
Nicolas Zea
2012/08/15 01:08:29
Done.
| |
1317 base::Bind( | |
1318 &SyncBackendHost:: | |
1319 HandleInitializationCompletedOnFrontendLoop, | |
1320 weak_ptr_factory_.GetWeakPtr(), js_backend, true)); | |
1321 break; | 1335 break; |
1322 case REFRESHING_NIGORI: | 1336 case ASSOCIATING_NIGORI: |
1323 initialization_state_ = INITIALIZED; | 1337 initialization_state_ = INITIALIZED; |
1324 // Now that we've downloaded the nigori node, we can see if there are any | 1338 // Now that we've downloaded the nigori node, we can see if there are any |
1325 // experimental types to enable. This should be done before we inform | 1339 // experimental types to enable. This should be done before we inform |
1326 // the frontend to ensure they're visible in the customize screen. | 1340 // the frontend to ensure they're visible in the customize screen. |
1327 AddExperimentalTypes(); | 1341 AddExperimentalTypes(); |
1328 frontend_->OnBackendInitialized(js_backend, true); | 1342 frontend_->OnBackendInitialized(js_backend, true); |
1329 break; | 1343 break; |
1330 default: | 1344 default: |
1331 NOTREACHED(); | 1345 NOTREACHED(); |
1332 } | 1346 } |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1406 } | 1420 } |
1407 | 1421 |
1408 bool SyncBackendHost::CheckPassphraseAgainstCachedPendingKeys( | 1422 bool SyncBackendHost::CheckPassphraseAgainstCachedPendingKeys( |
1409 const std::string& passphrase) const { | 1423 const std::string& passphrase) const { |
1410 DCHECK(cached_pending_keys_.has_blob()); | 1424 DCHECK(cached_pending_keys_.has_blob()); |
1411 DCHECK(!passphrase.empty()); | 1425 DCHECK(!passphrase.empty()); |
1412 syncer::Nigori nigori; | 1426 syncer::Nigori nigori; |
1413 nigori.InitByDerivation("localhost", "dummy", passphrase); | 1427 nigori.InitByDerivation("localhost", "dummy", passphrase); |
1414 std::string plaintext; | 1428 std::string plaintext; |
1415 bool result = nigori.Decrypt(cached_pending_keys_.blob(), &plaintext); | 1429 bool result = nigori.Decrypt(cached_pending_keys_.blob(), &plaintext); |
1430 DVLOG_IF(1, result) << "Passphrase failed to decrypt pending keys."; | |
1416 return result; | 1431 return result; |
1417 } | 1432 } |
1418 | 1433 |
1419 void SyncBackendHost::NotifyPassphraseRequired( | 1434 void SyncBackendHost::NotifyPassphraseRequired( |
1420 syncer::PassphraseRequiredReason reason, | 1435 syncer::PassphraseRequiredReason reason, |
1421 sync_pb::EncryptedData pending_keys) { | 1436 sync_pb::EncryptedData pending_keys) { |
1422 if (!frontend_) | 1437 if (!frontend_) |
1423 return; | 1438 return; |
1424 | 1439 |
1425 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 1440 DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1488 void SyncBackendHost::HandleNigoriConfigurationCompletedOnFrontendLoop( | 1503 void SyncBackendHost::HandleNigoriConfigurationCompletedOnFrontendLoop( |
1489 const syncer::WeakHandle<syncer::JsBackend>& js_backend, | 1504 const syncer::WeakHandle<syncer::JsBackend>& js_backend, |
1490 const syncer::ModelTypeSet failed_configuration_types) { | 1505 const syncer::ModelTypeSet failed_configuration_types) { |
1491 HandleInitializationCompletedOnFrontendLoop( | 1506 HandleInitializationCompletedOnFrontendLoop( |
1492 js_backend, failed_configuration_types.Empty()); | 1507 js_backend, failed_configuration_types.Empty()); |
1493 } | 1508 } |
1494 | 1509 |
1495 namespace { | 1510 namespace { |
1496 | 1511 |
1497 // Needed because MessageLoop::PostTask is overloaded. | 1512 // Needed because MessageLoop::PostTask is overloaded. |
1498 void PostClosure(MessageLoop* message_loop, | 1513 void PostClosure(MessageLoop* message_loop, |
tim (not reviewing)
2012/08/15 00:23:30
This can go too, I think!
Nicolas Zea
2012/08/15 01:08:29
Done.
| |
1499 const tracked_objects::Location& from_here, | 1514 const tracked_objects::Location& from_here, |
1500 const base::Closure& callback) { | 1515 const base::Closure& callback) { |
1501 message_loop->PostTask(from_here, callback); | 1516 message_loop->PostTask(from_here, callback); |
1502 } | 1517 } |
1503 | 1518 |
1504 } // namespace | 1519 } // namespace |
1505 | 1520 |
1506 void SyncBackendHost::RefreshNigori(const base::Closure& done_callback) { | 1521 void SyncBackendHost::AssociateNigori( |
1522 const syncer::WeakHandle<syncer::JsBackend>& js_backend) { | |
1507 DCHECK_EQ(MessageLoop::current(), frontend_loop_); | 1523 DCHECK_EQ(MessageLoop::current(), frontend_loop_); |
1508 base::Closure sync_thread_done_callback = | |
1509 base::Bind(&PostClosure, | |
1510 MessageLoop::current(), FROM_HERE, done_callback); | |
1511 sync_thread_.message_loop()->PostTask( | 1524 sync_thread_.message_loop()->PostTask( |
1512 FROM_HERE, | 1525 FROM_HERE, |
1513 base::Bind(&SyncBackendHost::Core::DoRefreshNigori, | 1526 base::Bind(&SyncBackendHost::Core::DoAssociateNigori, |
1514 core_.get(), sync_thread_done_callback)); | 1527 js_backend, |
1528 core_.get())); | |
1515 } | 1529 } |
1516 | 1530 |
1517 #undef SDVLOG | 1531 #undef SDVLOG |
1518 | 1532 |
1519 #undef SLOG | 1533 #undef SLOG |
1520 | 1534 |
1521 } // namespace browser_sync | 1535 } // namespace browser_sync |
OLD | NEW |