| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "chrome/browser/sync/engine/syncapi.h" | 5 #include "chrome/browser/sync/engine/syncapi.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 #include <bitset> | 8 #include <bitset> |
| 9 #include <iomanip> | 9 #include <iomanip> |
| 10 #include <list> | 10 #include <list> |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 #include "chrome/browser/sync/engine/model_safe_worker.h" | 31 #include "chrome/browser/sync/engine/model_safe_worker.h" |
| 32 #include "chrome/browser/sync/engine/net/server_connection_manager.h" | 32 #include "chrome/browser/sync/engine/net/server_connection_manager.h" |
| 33 #include "chrome/browser/sync/engine/net/syncapi_server_connection_manager.h" | 33 #include "chrome/browser/sync/engine/net/syncapi_server_connection_manager.h" |
| 34 #include "chrome/browser/sync/engine/syncer.h" | 34 #include "chrome/browser/sync/engine/syncer.h" |
| 35 #include "chrome/browser/sync/engine/syncer_thread.h" | 35 #include "chrome/browser/sync/engine/syncer_thread.h" |
| 36 #include "chrome/browser/sync/engine/syncer_thread2.h" | 36 #include "chrome/browser/sync/engine/syncer_thread2.h" |
| 37 #include "chrome/browser/sync/engine/syncer_thread_adapter.h" | 37 #include "chrome/browser/sync/engine/syncer_thread_adapter.h" |
| 38 #include "chrome/browser/sync/js_arg_list.h" | 38 #include "chrome/browser/sync/js_arg_list.h" |
| 39 #include "chrome/browser/sync/js_backend.h" | 39 #include "chrome/browser/sync/js_backend.h" |
| 40 #include "chrome/browser/sync/js_event_router.h" | 40 #include "chrome/browser/sync/js_event_router.h" |
| 41 #include "chrome/browser/sync/notifier/server_notifier_thread.h" | 41 #include "chrome/browser/sync/notifier/sync_notifier.h" |
| 42 #include "chrome/browser/sync/notifier/state_writer.h" | 42 #include "chrome/browser/sync/notifier/sync_notifier_factory.h" |
| 43 #include "chrome/browser/sync/notifier/sync_notifier_observer.h" |
| 43 #include "chrome/browser/sync/protocol/app_specifics.pb.h" | 44 #include "chrome/browser/sync/protocol/app_specifics.pb.h" |
| 44 #include "chrome/browser/sync/protocol/autofill_specifics.pb.h" | 45 #include "chrome/browser/sync/protocol/autofill_specifics.pb.h" |
| 45 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h" | 46 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h" |
| 46 #include "chrome/browser/sync/protocol/extension_specifics.pb.h" | 47 #include "chrome/browser/sync/protocol/extension_specifics.pb.h" |
| 47 #include "chrome/browser/sync/protocol/nigori_specifics.pb.h" | 48 #include "chrome/browser/sync/protocol/nigori_specifics.pb.h" |
| 48 #include "chrome/browser/sync/protocol/preference_specifics.pb.h" | 49 #include "chrome/browser/sync/protocol/preference_specifics.pb.h" |
| 49 #include "chrome/browser/sync/protocol/proto_value_conversions.h" | 50 #include "chrome/browser/sync/protocol/proto_value_conversions.h" |
| 50 #include "chrome/browser/sync/protocol/service_constants.h" | 51 #include "chrome/browser/sync/protocol/service_constants.h" |
| 51 #include "chrome/browser/sync/protocol/session_specifics.pb.h" | 52 #include "chrome/browser/sync/protocol/session_specifics.pb.h" |
| 52 #include "chrome/browser/sync/protocol/sync.pb.h" | 53 #include "chrome/browser/sync/protocol/sync.pb.h" |
| 53 #include "chrome/browser/sync/protocol/theme_specifics.pb.h" | 54 #include "chrome/browser/sync/protocol/theme_specifics.pb.h" |
| 54 #include "chrome/browser/sync/protocol/typed_url_specifics.pb.h" | 55 #include "chrome/browser/sync/protocol/typed_url_specifics.pb.h" |
| 55 #include "chrome/browser/sync/sessions/sync_session.h" | 56 #include "chrome/browser/sync/sessions/sync_session.h" |
| 56 #include "chrome/browser/sync/sessions/sync_session_context.h" | 57 #include "chrome/browser/sync/sessions/sync_session_context.h" |
| 57 #include "chrome/browser/sync/syncable/autofill_migration.h" | 58 #include "chrome/browser/sync/syncable/autofill_migration.h" |
| 58 #include "chrome/browser/sync/syncable/directory_manager.h" | 59 #include "chrome/browser/sync/syncable/directory_manager.h" |
| 59 #include "chrome/browser/sync/syncable/nigori_util.h" | 60 #include "chrome/browser/sync/syncable/nigori_util.h" |
| 60 #include "chrome/browser/sync/syncable/syncable.h" | 61 #include "chrome/browser/sync/syncable/syncable.h" |
| 61 #include "chrome/browser/sync/util/crypto_helpers.h" | 62 #include "chrome/browser/sync/util/crypto_helpers.h" |
| 62 #include "chrome/common/chrome_switches.h" | 63 #include "chrome/common/chrome_switches.h" |
| 63 #include "chrome/common/deprecated/event_sys.h" | 64 #include "chrome/common/deprecated/event_sys.h" |
| 64 #include "chrome/common/net/gaia/gaia_authenticator.h" | 65 #include "chrome/common/net/gaia/gaia_authenticator.h" |
| 65 #include "content/browser/browser_thread.h" | 66 #include "content/browser/browser_thread.h" |
| 66 #include "jingle/notifier/listener/mediator_thread_impl.h" | |
| 67 #include "jingle/notifier/listener/notification_constants.h" | |
| 68 #include "jingle/notifier/listener/talk_mediator.h" | |
| 69 #include "jingle/notifier/listener/talk_mediator_impl.h" | |
| 70 #include "net/base/network_change_notifier.h" | 67 #include "net/base/network_change_notifier.h" |
| 71 | 68 |
| 72 using browser_sync::AllStatus; | 69 using browser_sync::AllStatus; |
| 73 using browser_sync::Cryptographer; | 70 using browser_sync::Cryptographer; |
| 74 using browser_sync::KeyParams; | 71 using browser_sync::KeyParams; |
| 75 using browser_sync::ModelSafeRoutingInfo; | 72 using browser_sync::ModelSafeRoutingInfo; |
| 76 using browser_sync::ModelSafeWorker; | 73 using browser_sync::ModelSafeWorker; |
| 77 using browser_sync::ModelSafeWorkerRegistrar; | 74 using browser_sync::ModelSafeWorkerRegistrar; |
| 78 using browser_sync::ServerConnectionEvent; | 75 using browser_sync::ServerConnectionEvent; |
| 79 using browser_sync::SyncEngineEvent; | 76 using browser_sync::SyncEngineEvent; |
| 80 using browser_sync::SyncEngineEventListener; | 77 using browser_sync::SyncEngineEventListener; |
| 81 using browser_sync::Syncer; | 78 using browser_sync::Syncer; |
| 82 using browser_sync::SyncerThread; | 79 using browser_sync::SyncerThread; |
| 83 using browser_sync::SyncerThreadAdapter; | 80 using browser_sync::SyncerThreadAdapter; |
| 84 using browser_sync::kNigoriTag; | 81 using browser_sync::kNigoriTag; |
| 85 using browser_sync::sessions::SyncSessionContext; | 82 using browser_sync::sessions::SyncSessionContext; |
| 86 using notifier::TalkMediator; | |
| 87 using notifier::TalkMediatorImpl; | |
| 88 using std::list; | 83 using std::list; |
| 89 using std::hex; | 84 using std::hex; |
| 90 using std::string; | 85 using std::string; |
| 91 using std::vector; | 86 using std::vector; |
| 92 using syncable::Directory; | 87 using syncable::Directory; |
| 93 using syncable::DirectoryManager; | 88 using syncable::DirectoryManager; |
| 94 using syncable::Entry; | 89 using syncable::Entry; |
| 95 using syncable::SPECIFICS; | 90 using syncable::SPECIFICS; |
| 91 using sync_notifier::SyncNotifierFactory; |
| 96 using sync_pb::AutofillProfileSpecifics; | 92 using sync_pb::AutofillProfileSpecifics; |
| 97 | 93 |
| 98 typedef GoogleServiceAuthError AuthError; | 94 typedef GoogleServiceAuthError AuthError; |
| 99 | 95 |
| 100 static const int kThreadExitTimeoutMsec = 60000; | 96 static const int kThreadExitTimeoutMsec = 60000; |
| 101 static const int kSSLPort = 443; | 97 static const int kSSLPort = 443; |
| 102 static const int kSyncerThreadDelayMsec = 250; | 98 static const int kSyncerThreadDelayMsec = 250; |
| 103 | 99 |
| 104 #if defined(OS_CHROMEOS) | 100 #if defined(OS_CHROMEOS) |
| 105 static const int kChromeOSNetworkChangeReactionDelayHackMsec = 5000; | 101 static const int kChromeOSNetworkChangeReactionDelayHackMsec = 5000; |
| (...skipping 1000 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1106 | 1102 |
| 1107 const sync_pb::PasswordSpecificsData& | 1103 const sync_pb::PasswordSpecificsData& |
| 1108 SyncManager::ExtraPasswordChangeRecordData::unencrypted() const { | 1104 SyncManager::ExtraPasswordChangeRecordData::unencrypted() const { |
| 1109 return unencrypted_; | 1105 return unencrypted_; |
| 1110 } | 1106 } |
| 1111 | 1107 |
| 1112 ////////////////////////////////////////////////////////////////////////// | 1108 ////////////////////////////////////////////////////////////////////////// |
| 1113 // SyncManager's implementation: SyncManager::SyncInternal | 1109 // SyncManager's implementation: SyncManager::SyncInternal |
| 1114 class SyncManager::SyncInternal | 1110 class SyncManager::SyncInternal |
| 1115 : public net::NetworkChangeNotifier::IPAddressObserver, | 1111 : public net::NetworkChangeNotifier::IPAddressObserver, |
| 1116 public TalkMediator::Delegate, | 1112 public sync_notifier::SyncNotifierObserver, |
| 1117 public sync_notifier::StateWriter, | |
| 1118 public browser_sync::ChannelEventHandler<syncable::DirectoryChangeEvent>, | 1113 public browser_sync::ChannelEventHandler<syncable::DirectoryChangeEvent>, |
| 1119 public browser_sync::JsBackend, | 1114 public browser_sync::JsBackend, |
| 1120 public SyncEngineEventListener { | 1115 public SyncEngineEventListener { |
| 1121 static const int kDefaultNudgeDelayMilliseconds; | 1116 static const int kDefaultNudgeDelayMilliseconds; |
| 1122 static const int kPreferencesNudgeDelayMilliseconds; | 1117 static const int kPreferencesNudgeDelayMilliseconds; |
| 1123 public: | 1118 public: |
| 1124 explicit SyncInternal(SyncManager* sync_manager) | 1119 explicit SyncInternal(SyncManager* sync_manager) |
| 1125 : core_message_loop_(NULL), | 1120 : core_message_loop_(NULL), |
| 1126 parent_router_(NULL), | 1121 parent_router_(NULL), |
| 1127 sync_manager_(sync_manager), | 1122 sync_manager_(sync_manager), |
| 1128 registrar_(NULL), | 1123 registrar_(NULL), |
| 1129 notification_pending_(false), | |
| 1130 initialized_(false), | 1124 initialized_(false), |
| 1131 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), | 1125 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { |
| 1132 server_notifier_thread_(NULL) { | |
| 1133 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1126 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1134 } | 1127 } |
| 1135 | 1128 |
| 1136 virtual ~SyncInternal() { | 1129 virtual ~SyncInternal() { |
| 1137 DCHECK(!core_message_loop_); | 1130 DCHECK(!core_message_loop_); |
| 1138 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 1131 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 1139 } | 1132 } |
| 1140 | 1133 |
| 1141 bool Init(const FilePath& database_location, | 1134 bool Init(const FilePath& database_location, |
| 1142 const std::string& sync_server_and_path, | 1135 const std::string& sync_server_and_path, |
| 1143 int port, | 1136 int port, |
| 1144 bool use_ssl, | 1137 bool use_ssl, |
| 1145 HttpPostProviderFactory* post_factory, | 1138 HttpPostProviderFactory* post_factory, |
| 1146 ModelSafeWorkerRegistrar* model_safe_worker_registrar, | 1139 ModelSafeWorkerRegistrar* model_safe_worker_registrar, |
| 1147 const char* user_agent, | 1140 const char* user_agent, |
| 1148 const SyncCredentials& credentials, | 1141 const SyncCredentials& credentials, |
| 1149 const notifier::NotifierOptions& notifier_options, | |
| 1150 const std::string& restored_key_for_bootstrapping, | 1142 const std::string& restored_key_for_bootstrapping, |
| 1151 bool setup_for_test_mode); | 1143 bool setup_for_test_mode); |
| 1152 | 1144 |
| 1153 // Sign into sync with given credentials. | 1145 // Sign into sync with given credentials. |
| 1154 // We do not verify the tokens given. After this call, the tokens are set | 1146 // We do not verify the tokens given. After this call, the tokens are set |
| 1155 // and the sync DB is open. True if successful, false if something | 1147 // and the sync DB is open. True if successful, false if something |
| 1156 // went wrong. | 1148 // went wrong. |
| 1157 bool SignIn(const SyncCredentials& credentials); | 1149 bool SignIn(const SyncCredentials& credentials); |
| 1158 | 1150 |
| 1159 // Update tokens that we're using in Sync. Email must stay the same. | 1151 // Update tokens that we're using in Sync. Email must stay the same. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1193 const syncable::DirectoryChangeEvent& event); | 1185 const syncable::DirectoryChangeEvent& event); |
| 1194 void HandleCalculateChangesChangeEventFromSyncer( | 1186 void HandleCalculateChangesChangeEventFromSyncer( |
| 1195 const syncable::DirectoryChangeEvent& event); | 1187 const syncable::DirectoryChangeEvent& event); |
| 1196 | 1188 |
| 1197 // Listens for notifications from the ServerConnectionManager | 1189 // Listens for notifications from the ServerConnectionManager |
| 1198 void HandleServerConnectionEvent(const ServerConnectionEvent& event); | 1190 void HandleServerConnectionEvent(const ServerConnectionEvent& event); |
| 1199 | 1191 |
| 1200 // Open the directory named with username_for_share | 1192 // Open the directory named with username_for_share |
| 1201 bool OpenDirectory(); | 1193 bool OpenDirectory(); |
| 1202 | 1194 |
| 1203 // Login to the talk mediator with the given credentials. | 1195 // SyncNotifierObserver implementation. |
| 1204 void TalkMediatorLogin( | |
| 1205 const std::string& email, const std::string& token); | |
| 1206 | |
| 1207 // TalkMediator::Delegate implementation. | |
| 1208 virtual void OnNotificationStateChange( | 1196 virtual void OnNotificationStateChange( |
| 1209 bool notifications_enabled); | 1197 bool notifications_enabled); |
| 1210 | 1198 |
| 1211 virtual void OnIncomingNotification( | 1199 virtual void OnIncomingNotification( |
| 1212 const IncomingNotificationData& notification_data); | 1200 const browser_sync::sessions::TypePayloadMap& type_payloads); |
| 1213 | 1201 |
| 1214 virtual void OnOutgoingNotification(); | 1202 virtual void StoreState(const std::string& cookie); |
| 1215 | |
| 1216 // sync_notifier::StateWriter implementation. | |
| 1217 virtual void WriteState(const std::string& state); | |
| 1218 | 1203 |
| 1219 void AddObserver(SyncManager::Observer* observer); | 1204 void AddObserver(SyncManager::Observer* observer); |
| 1220 | 1205 |
| 1221 void RemoveObserver(SyncManager::Observer* observer); | 1206 void RemoveObserver(SyncManager::Observer* observer); |
| 1222 | 1207 |
| 1223 // Accessors for the private members. | 1208 // Accessors for the private members. |
| 1224 DirectoryManager* dir_manager() { return share_.dir_manager.get(); } | 1209 DirectoryManager* dir_manager() { return share_.dir_manager.get(); } |
| 1225 SyncAPIServerConnectionManager* connection_manager() { | 1210 SyncAPIServerConnectionManager* connection_manager() { |
| 1226 return connection_manager_.get(); | 1211 return connection_manager_.get(); |
| 1227 } | 1212 } |
| 1228 SyncerThreadAdapter* syncer_thread() { return syncer_thread_.get(); } | 1213 SyncerThreadAdapter* syncer_thread() { return syncer_thread_.get(); } |
| 1229 TalkMediator* talk_mediator() { return talk_mediator_.get(); } | |
| 1230 UserShare* GetUserShare() { return &share_; } | 1214 UserShare* GetUserShare() { return &share_; } |
| 1231 | 1215 |
| 1232 // Return the currently active (validated) username for use with syncable | 1216 // Return the currently active (validated) username for use with syncable |
| 1233 // types. | 1217 // types. |
| 1234 const std::string& username_for_share() const { | 1218 const std::string& username_for_share() const { |
| 1235 return share_.name; | 1219 return share_.name; |
| 1236 } | 1220 } |
| 1237 | 1221 |
| 1238 Status GetStatus(); | 1222 Status GetStatus(); |
| 1239 | 1223 |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1327 | 1311 |
| 1328 // browser_sync::JsBackend implementation. | 1312 // browser_sync::JsBackend implementation. |
| 1329 virtual void SetParentJsEventRouter(browser_sync::JsEventRouter* router); | 1313 virtual void SetParentJsEventRouter(browser_sync::JsEventRouter* router); |
| 1330 virtual void RemoveParentJsEventRouter(); | 1314 virtual void RemoveParentJsEventRouter(); |
| 1331 virtual const browser_sync::JsEventRouter* GetParentJsEventRouter() const; | 1315 virtual const browser_sync::JsEventRouter* GetParentJsEventRouter() const; |
| 1332 virtual void ProcessMessage(const std::string& name, | 1316 virtual void ProcessMessage(const std::string& name, |
| 1333 const browser_sync::JsArgList& args, | 1317 const browser_sync::JsArgList& args, |
| 1334 const browser_sync::JsEventHandler* sender); | 1318 const browser_sync::JsEventHandler* sender); |
| 1335 | 1319 |
| 1336 private: | 1320 private: |
| 1337 // Helper to handle the details of initializing the TalkMediator. | |
| 1338 // Must be called only after OpenDirectory() is called. | |
| 1339 void InitializeTalkMediator(); | |
| 1340 | |
| 1341 // Helper to call OnAuthError when no authentication credentials are | 1321 // Helper to call OnAuthError when no authentication credentials are |
| 1342 // available. | 1322 // available. |
| 1343 void RaiseAuthNeededEvent(); | 1323 void RaiseAuthNeededEvent(); |
| 1344 | 1324 |
| 1345 // Helper to set initialized_ to true and raise an event to clients to notify | 1325 // Helper to set initialized_ to true and raise an event to clients to notify |
| 1346 // that initialization is complete and it is safe to send us changes. If | 1326 // that initialization is complete and it is safe to send us changes. If |
| 1347 // already initialized, this is a no-op. | 1327 // already initialized, this is a no-op. |
| 1348 void MarkAndNotifyInitializationComplete(); | 1328 void MarkAndNotifyInitializationComplete(); |
| 1349 | 1329 |
| 1350 // If there's a pending notification to be sent, either from the | 1330 // Sends notifications to peers. |
| 1351 // new_pending_notification flag or a previous unsuccessfully sent | 1331 void SendNotification(); |
| 1352 // notification, tries to send a notification. | |
| 1353 void SendPendingXMPPNotification(bool new_pending_notification); | |
| 1354 | 1332 |
| 1355 // Determine if the parents or predecessors differ between the old and new | 1333 // Determine if the parents or predecessors differ between the old and new |
| 1356 // versions of an entry stored in |a| and |b|. Note that a node's index may | 1334 // versions of an entry stored in |a| and |b|. Note that a node's index may |
| 1357 // change without its NEXT_ID changing if the node at NEXT_ID also moved (but | 1335 // change without its NEXT_ID changing if the node at NEXT_ID also moved (but |
| 1358 // the relative order is unchanged). To handle such cases, we rely on the | 1336 // the relative order is unchanged). To handle such cases, we rely on the |
| 1359 // caller to treat a position update on any sibling as updating the positions | 1337 // caller to treat a position update on any sibling as updating the positions |
| 1360 // of all siblings. | 1338 // of all siblings. |
| 1361 static bool VisiblePositionsDiffer(const syncable::EntryKernel& a, | 1339 static bool VisiblePositionsDiffer(const syncable::EntryKernel& a, |
| 1362 const syncable::Entry& b) { | 1340 const syncable::Entry& b) { |
| 1363 // If the datatype isn't one where the browser model cares about position, | 1341 // If the datatype isn't one where the browser model cares about position, |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1460 | 1438 |
| 1461 browser_sync::JsEventRouter* parent_router_; | 1439 browser_sync::JsEventRouter* parent_router_; |
| 1462 | 1440 |
| 1463 // The ServerConnectionManager used to abstract communication between the | 1441 // The ServerConnectionManager used to abstract communication between the |
| 1464 // client (the Syncer) and the sync server. | 1442 // client (the Syncer) and the sync server. |
| 1465 scoped_ptr<SyncAPIServerConnectionManager> connection_manager_; | 1443 scoped_ptr<SyncAPIServerConnectionManager> connection_manager_; |
| 1466 | 1444 |
| 1467 // The thread that runs the Syncer. Needs to be explicitly Start()ed. | 1445 // The thread that runs the Syncer. Needs to be explicitly Start()ed. |
| 1468 scoped_ptr<SyncerThreadAdapter> syncer_thread_; | 1446 scoped_ptr<SyncerThreadAdapter> syncer_thread_; |
| 1469 | 1447 |
| 1470 // Notification (xmpp) handler. | 1448 // The SyncNotifier which notifies us when updates need to be downloaded. |
| 1471 scoped_ptr<TalkMediator> talk_mediator_; | 1449 scoped_ptr<sync_notifier::SyncNotifier> sync_notifier_; |
| 1472 | 1450 |
| 1473 // A multi-purpose status watch object that aggregates stats from various | 1451 // A multi-purpose status watch object that aggregates stats from various |
| 1474 // sync components. | 1452 // sync components. |
| 1475 AllStatus allstatus_; | 1453 AllStatus allstatus_; |
| 1476 | 1454 |
| 1477 // Each element of this array is a store of change records produced by | 1455 // Each element of this array is a store of change records produced by |
| 1478 // HandleChangeEvent during the CALCULATE_CHANGES step. The changes are | 1456 // HandleChangeEvent during the CALCULATE_CHANGES step. The changes are |
| 1479 // segregated by model type, and are stored here to be processed and | 1457 // segregated by model type, and are stored here to be processed and |
| 1480 // forwarded to the observer slightly later, at the TRANSACTION_ENDING | 1458 // forwarded to the observer slightly later, at the TRANSACTION_ENDING |
| 1481 // step by HandleTransactionEndingChangeEvent. The list is cleared in the | 1459 // step by HandleTransactionEndingChangeEvent. The list is cleared in the |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1496 // Event listener hookup for the ServerConnectionManager. | 1474 // Event listener hookup for the ServerConnectionManager. |
| 1497 scoped_ptr<EventListenerHookup> connection_manager_hookup_; | 1475 scoped_ptr<EventListenerHookup> connection_manager_hookup_; |
| 1498 | 1476 |
| 1499 // The sync dir_manager to which we belong. | 1477 // The sync dir_manager to which we belong. |
| 1500 SyncManager* const sync_manager_; | 1478 SyncManager* const sync_manager_; |
| 1501 | 1479 |
| 1502 // The entity that provides us with information about which types to sync. | 1480 // The entity that provides us with information about which types to sync. |
| 1503 // The instance is shared between the SyncManager and the Syncer. | 1481 // The instance is shared between the SyncManager and the Syncer. |
| 1504 ModelSafeWorkerRegistrar* registrar_; | 1482 ModelSafeWorkerRegistrar* registrar_; |
| 1505 | 1483 |
| 1506 // True if the next SyncCycle should notify peers of an update. | |
| 1507 bool notification_pending_; | |
| 1508 | |
| 1509 // Set to true once Init has been called, and we know of an authenticated | 1484 // Set to true once Init has been called, and we know of an authenticated |
| 1510 // valid) username either from a fresh authentication attempt (as in | 1485 // valid) username either from a fresh authentication attempt (as in |
| 1511 // first-use case) or from a previous attempt stored in our UserSettings | 1486 // first-use case) or from a previous attempt stored in our UserSettings |
| 1512 // (as in the steady-state), and the syncable::Directory has been opened, | 1487 // (as in the steady-state), and the syncable::Directory has been opened, |
| 1513 // meaning we are ready to accept changes. Protected by initialized_mutex_ | 1488 // meaning we are ready to accept changes. Protected by initialized_mutex_ |
| 1514 // as it can get read/set by both the SyncerThread and the AuthWatcherThread. | 1489 // as it can get read/set by both the SyncerThread and the AuthWatcherThread. |
| 1515 bool initialized_; | 1490 bool initialized_; |
| 1516 mutable base::Lock initialized_mutex_; | 1491 mutable base::Lock initialized_mutex_; |
| 1517 | 1492 |
| 1518 notifier::NotifierOptions notifier_options_; | |
| 1519 | |
| 1520 // True if the SyncManager should be running in test mode (no syncer thread | 1493 // True if the SyncManager should be running in test mode (no syncer thread |
| 1521 // actually communicating with the server). | 1494 // actually communicating with the server). |
| 1522 bool setup_for_test_mode_; | 1495 bool setup_for_test_mode_; |
| 1523 | 1496 |
| 1524 syncable::ModelTypeSet enabled_types_; | |
| 1525 | |
| 1526 ScopedRunnableMethodFactory<SyncManager::SyncInternal> method_factory_; | 1497 ScopedRunnableMethodFactory<SyncManager::SyncInternal> method_factory_; |
| 1527 | |
| 1528 sync_notifier::ServerNotifierThread* server_notifier_thread_; | |
| 1529 }; | 1498 }; |
| 1530 const int SyncManager::SyncInternal::kDefaultNudgeDelayMilliseconds = 200; | 1499 const int SyncManager::SyncInternal::kDefaultNudgeDelayMilliseconds = 200; |
| 1531 const int SyncManager::SyncInternal::kPreferencesNudgeDelayMilliseconds = 2000; | 1500 const int SyncManager::SyncInternal::kPreferencesNudgeDelayMilliseconds = 2000; |
| 1532 | 1501 |
| 1533 SyncManager::Observer::~Observer() {} | 1502 SyncManager::Observer::~Observer() {} |
| 1534 | 1503 |
| 1535 SyncManager::SyncManager() { | 1504 SyncManager::SyncManager() { |
| 1536 data_ = new SyncInternal(this); | 1505 data_ = new SyncInternal(this); |
| 1537 } | 1506 } |
| 1538 | 1507 |
| 1539 bool SyncManager::Init(const FilePath& database_location, | 1508 bool SyncManager::Init(const FilePath& database_location, |
| 1540 const char* sync_server_and_path, | 1509 const char* sync_server_and_path, |
| 1541 int sync_server_port, | 1510 int sync_server_port, |
| 1542 bool use_ssl, | 1511 bool use_ssl, |
| 1543 HttpPostProviderFactory* post_factory, | 1512 HttpPostProviderFactory* post_factory, |
| 1544 ModelSafeWorkerRegistrar* registrar, | 1513 ModelSafeWorkerRegistrar* registrar, |
| 1545 const char* user_agent, | 1514 const char* user_agent, |
| 1546 const SyncCredentials& credentials, | 1515 const SyncCredentials& credentials, |
| 1547 const notifier::NotifierOptions& notifier_options, | |
| 1548 const std::string& restored_key_for_bootstrapping, | 1516 const std::string& restored_key_for_bootstrapping, |
| 1549 bool setup_for_test_mode) { | 1517 bool setup_for_test_mode) { |
| 1550 DCHECK(post_factory); | 1518 DCHECK(post_factory); |
| 1551 VLOG(1) << "SyncManager starting Init..."; | 1519 VLOG(1) << "SyncManager starting Init..."; |
| 1552 string server_string(sync_server_and_path); | 1520 string server_string(sync_server_and_path); |
| 1553 return data_->Init(database_location, | 1521 return data_->Init(database_location, |
| 1554 server_string, | 1522 server_string, |
| 1555 sync_server_port, | 1523 sync_server_port, |
| 1556 use_ssl, | 1524 use_ssl, |
| 1557 post_factory, | 1525 post_factory, |
| 1558 registrar, | 1526 registrar, |
| 1559 user_agent, | 1527 user_agent, |
| 1560 credentials, | 1528 credentials, |
| 1561 notifier_options, | |
| 1562 restored_key_for_bootstrapping, | 1529 restored_key_for_bootstrapping, |
| 1563 setup_for_test_mode); | 1530 setup_for_test_mode); |
| 1564 } | 1531 } |
| 1565 | 1532 |
| 1566 void SyncManager::UpdateCredentials(const SyncCredentials& credentials) { | 1533 void SyncManager::UpdateCredentials(const SyncCredentials& credentials) { |
| 1567 data_->UpdateCredentials(credentials); | 1534 data_->UpdateCredentials(credentials); |
| 1568 } | 1535 } |
| 1569 | 1536 |
| 1570 void SyncManager::UpdateEnabledTypes(const syncable::ModelTypeSet& types) { | 1537 void SyncManager::UpdateEnabledTypes(const syncable::ModelTypeSet& types) { |
| 1571 data_->UpdateEnabledTypes(types); | 1538 data_->UpdateEnabledTypes(types); |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1653 | 1620 |
| 1654 bool SyncManager::SyncInternal::Init( | 1621 bool SyncManager::SyncInternal::Init( |
| 1655 const FilePath& database_location, | 1622 const FilePath& database_location, |
| 1656 const std::string& sync_server_and_path, | 1623 const std::string& sync_server_and_path, |
| 1657 int port, | 1624 int port, |
| 1658 bool use_ssl, | 1625 bool use_ssl, |
| 1659 HttpPostProviderFactory* post_factory, | 1626 HttpPostProviderFactory* post_factory, |
| 1660 ModelSafeWorkerRegistrar* model_safe_worker_registrar, | 1627 ModelSafeWorkerRegistrar* model_safe_worker_registrar, |
| 1661 const char* user_agent, | 1628 const char* user_agent, |
| 1662 const SyncCredentials& credentials, | 1629 const SyncCredentials& credentials, |
| 1663 const notifier::NotifierOptions& notifier_options, | |
| 1664 const std::string& restored_key_for_bootstrapping, | 1630 const std::string& restored_key_for_bootstrapping, |
| 1665 bool setup_for_test_mode) { | 1631 bool setup_for_test_mode) { |
| 1666 | 1632 |
| 1667 VLOG(1) << "Starting SyncInternal initialization."; | 1633 VLOG(1) << "Starting SyncInternal initialization."; |
| 1668 | 1634 |
| 1669 core_message_loop_ = MessageLoop::current(); | 1635 core_message_loop_ = MessageLoop::current(); |
| 1670 DCHECK(core_message_loop_); | 1636 DCHECK(core_message_loop_); |
| 1671 notifier_options_ = notifier_options; | |
| 1672 registrar_ = model_safe_worker_registrar; | 1637 registrar_ = model_safe_worker_registrar; |
| 1673 setup_for_test_mode_ = setup_for_test_mode; | 1638 setup_for_test_mode_ = setup_for_test_mode; |
| 1674 | 1639 |
| 1675 share_.dir_manager.reset(new DirectoryManager(database_location)); | 1640 share_.dir_manager.reset(new DirectoryManager(database_location)); |
| 1676 | 1641 |
| 1677 connection_manager_.reset(new SyncAPIServerConnectionManager( | 1642 connection_manager_.reset(new SyncAPIServerConnectionManager( |
| 1678 sync_server_and_path, port, use_ssl, user_agent, post_factory)); | 1643 sync_server_and_path, port, use_ssl, user_agent, post_factory)); |
| 1679 | 1644 |
| 1680 connection_manager_hookup_.reset( | 1645 connection_manager_hookup_.reset( |
| 1681 NewEventListenerHookup(connection_manager()->channel(), this, | 1646 NewEventListenerHookup(connection_manager()->channel(), this, |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1775 if (initialized_) | 1740 if (initialized_) |
| 1776 return; | 1741 return; |
| 1777 initialized_ = true; | 1742 initialized_ = true; |
| 1778 } | 1743 } |
| 1779 | 1744 |
| 1780 // Notify that initialization is complete. | 1745 // Notify that initialization is complete. |
| 1781 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, | 1746 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, |
| 1782 OnInitializationComplete()); | 1747 OnInitializationComplete()); |
| 1783 } | 1748 } |
| 1784 | 1749 |
| 1785 void SyncManager::SyncInternal::SendPendingXMPPNotification( | 1750 void SyncManager::SyncInternal::SendNotification() { |
| 1786 bool new_pending_notification) { | |
| 1787 DCHECK_EQ(MessageLoop::current(), core_message_loop_); | 1751 DCHECK_EQ(MessageLoop::current(), core_message_loop_); |
| 1788 DCHECK_NE(notifier_options_.notification_method, | 1752 if (!sync_notifier_.get()) { |
| 1789 notifier::NOTIFICATION_SERVER); | 1753 VLOG(1) << "Not sending notification: sync_notifier_ is NULL"; |
| 1790 notification_pending_ = notification_pending_ || new_pending_notification; | |
| 1791 if (!notification_pending_) { | |
| 1792 VLOG(1) << "Not sending notification: no pending notification"; | |
| 1793 return; | 1754 return; |
| 1794 } | 1755 } |
| 1795 if (!talk_mediator()) { | 1756 allstatus_.IncrementNotificationsSent(); |
| 1796 VLOG(1) << "Not sending notification: shutting down (talk_mediator_ is " | 1757 sync_notifier_->SendNotification(); |
| 1797 "NULL)"; | |
| 1798 return; | |
| 1799 } | |
| 1800 VLOG(1) << "Sending XMPP notification..."; | |
| 1801 OutgoingNotificationData notification_data; | |
| 1802 notification_data.service_id = browser_sync::kSyncServiceId; | |
| 1803 notification_data.service_url = browser_sync::kSyncServiceUrl; | |
| 1804 notification_data.send_content = true; | |
| 1805 notification_data.priority = browser_sync::kSyncPriority; | |
| 1806 notification_data.write_to_cache_only = true; | |
| 1807 notification_data.service_specific_data = | |
| 1808 browser_sync::kSyncServiceSpecificData; | |
| 1809 notification_data.require_subscription = true; | |
| 1810 bool success = talk_mediator()->SendNotification(notification_data); | |
| 1811 if (success) { | |
| 1812 notification_pending_ = false; | |
| 1813 VLOG(1) << "Sent XMPP notification"; | |
| 1814 } else { | |
| 1815 VLOG(1) << "Could not send XMPP notification"; | |
| 1816 } | |
| 1817 } | 1758 } |
| 1818 | 1759 |
| 1819 bool SyncManager::SyncInternal::OpenDirectory() { | 1760 bool SyncManager::SyncInternal::OpenDirectory() { |
| 1820 DCHECK(!initialized()) << "Should only happen once"; | 1761 DCHECK(!initialized()) << "Should only happen once"; |
| 1821 | 1762 |
| 1822 bool share_opened = dir_manager()->Open(username_for_share()); | 1763 bool share_opened = dir_manager()->Open(username_for_share()); |
| 1823 DCHECK(share_opened); | 1764 DCHECK(share_opened); |
| 1824 if (!share_opened) { | 1765 if (!share_opened) { |
| 1825 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, | 1766 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, |
| 1826 OnStopSyncingPermanently()); | 1767 OnStopSyncingPermanently()); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1848 | 1789 |
| 1849 bool SyncManager::SyncInternal::SignIn(const SyncCredentials& credentials) { | 1790 bool SyncManager::SyncInternal::SignIn(const SyncCredentials& credentials) { |
| 1850 DCHECK_EQ(MessageLoop::current(), core_message_loop_); | 1791 DCHECK_EQ(MessageLoop::current(), core_message_loop_); |
| 1851 DCHECK(share_.name.empty()); | 1792 DCHECK(share_.name.empty()); |
| 1852 share_.name = credentials.email; | 1793 share_.name = credentials.email; |
| 1853 | 1794 |
| 1854 VLOG(1) << "Signing in user: " << username_for_share(); | 1795 VLOG(1) << "Signing in user: " << username_for_share(); |
| 1855 if (!OpenDirectory()) | 1796 if (!OpenDirectory()) |
| 1856 return false; | 1797 return false; |
| 1857 | 1798 |
| 1799 // Initialize the sync notifier. This should be done only after OpenDirectory |
| 1800 // is called, as we also need to set the state. |
| 1801 // TODO(nileshagrawal): Pass SyncNotifierFactory as an argument to Init |
| 1802 // to improve testability. |
| 1803 SyncNotifierFactory sync_notifier_factory; |
| 1804 sync_notifier_.reset(sync_notifier_factory.CreateSyncNotifier( |
| 1805 *CommandLine::ForCurrentProcess())); |
| 1806 sync_notifier_->AddObserver(this); |
| 1807 |
| 1808 syncable::ScopedDirLookup lookup(dir_manager(), username_for_share()); |
| 1809 std::string state; |
| 1810 if (lookup.good()) { |
| 1811 state = lookup->GetAndClearNotificationState(); |
| 1812 } else { |
| 1813 LOG(ERROR) << "Could not read notification state"; |
| 1814 } |
| 1815 if (VLOG_IS_ON(1)) { |
| 1816 std::string encoded_state; |
| 1817 base::Base64Encode(state, &encoded_state); |
| 1818 VLOG(1) << "Read notification state: " << encoded_state; |
| 1819 } |
| 1820 sync_notifier_->SetState(state); |
| 1821 |
| 1858 if (!setup_for_test_mode_) { | 1822 if (!setup_for_test_mode_) { |
| 1859 UpdateCredentials(credentials); | 1823 UpdateCredentials(credentials); |
| 1860 } | 1824 } |
| 1861 return true; | 1825 return true; |
| 1862 } | 1826 } |
| 1863 | 1827 |
| 1864 void SyncManager::SyncInternal::UpdateCredentials( | 1828 void SyncManager::SyncInternal::UpdateCredentials( |
| 1865 const SyncCredentials& credentials) { | 1829 const SyncCredentials& credentials) { |
| 1866 DCHECK_EQ(MessageLoop::current(), core_message_loop_); | 1830 DCHECK_EQ(MessageLoop::current(), core_message_loop_); |
| 1867 DCHECK_EQ(credentials.email, share_.name); | 1831 DCHECK_EQ(credentials.email, share_.name); |
| 1832 DCHECK(!credentials.email.empty()); |
| 1833 DCHECK(!credentials.sync_token.empty()); |
| 1868 connection_manager()->set_auth_token(credentials.sync_token); | 1834 connection_manager()->set_auth_token(credentials.sync_token); |
| 1869 TalkMediatorLogin(credentials.email, credentials.sync_token); | 1835 sync_notifier_->UpdateCredentials( |
| 1836 credentials.email, credentials.sync_token); |
| 1870 CheckServerReachable(); | 1837 CheckServerReachable(); |
| 1871 } | 1838 } |
| 1872 | 1839 |
| 1873 void SyncManager::SyncInternal::UpdateEnabledTypes( | 1840 void SyncManager::SyncInternal::UpdateEnabledTypes( |
| 1874 const syncable::ModelTypeSet& types) { | 1841 const syncable::ModelTypeSet& types) { |
| 1875 DCHECK_EQ(MessageLoop::current(), core_message_loop_); | 1842 DCHECK_EQ(MessageLoop::current(), core_message_loop_); |
| 1876 | 1843 |
| 1877 enabled_types_ = types; | 1844 sync_notifier_->UpdateEnabledTypes(types); |
| 1878 if (server_notifier_thread_ != NULL) { | |
| 1879 server_notifier_thread_->UpdateEnabledTypes(types); | |
| 1880 } | |
| 1881 } | |
| 1882 | |
| 1883 void SyncManager::SyncInternal::InitializeTalkMediator() { | |
| 1884 if (notifier_options_.notification_method == | |
| 1885 notifier::NOTIFICATION_SERVER) { | |
| 1886 syncable::ScopedDirLookup lookup(dir_manager(), username_for_share()); | |
| 1887 std::string state; | |
| 1888 if (lookup.good()) | |
| 1889 state = lookup->GetAndClearNotificationState(); | |
| 1890 else | |
| 1891 LOG(ERROR) << "Could not read notification state"; | |
| 1892 if (VLOG_IS_ON(1)) { | |
| 1893 std::string encoded_state; | |
| 1894 base::Base64Encode(state, &encoded_state); | |
| 1895 VLOG(1) << "Read notification state: " << encoded_state; | |
| 1896 } | |
| 1897 | |
| 1898 // |talk_mediator_| takes ownership of |sync_notifier_thread_| | |
| 1899 // but it is. guaranteed that |sync_notifier_thread_| is destroyed only | |
| 1900 // when |talk_mediator_| is (see the comments in talk_mediator.h). | |
| 1901 server_notifier_thread_ = new sync_notifier::ServerNotifierThread( | |
| 1902 notifier_options_, state, this); | |
| 1903 talk_mediator_.reset( | |
| 1904 new TalkMediatorImpl(server_notifier_thread_, | |
| 1905 notifier_options_.invalidate_xmpp_login, | |
| 1906 notifier_options_.allow_insecure_connection)); | |
| 1907 | |
| 1908 // Since we may be initialized more than once, make sure that any | |
| 1909 // newly created server notifier thread has the latest enabled types. | |
| 1910 server_notifier_thread_->UpdateEnabledTypes(enabled_types_); | |
| 1911 } else { | |
| 1912 notifier::MediatorThread* mediator_thread = | |
| 1913 new notifier::MediatorThreadImpl(notifier_options_); | |
| 1914 talk_mediator_.reset( | |
| 1915 new TalkMediatorImpl(mediator_thread, | |
| 1916 notifier_options_.invalidate_xmpp_login, | |
| 1917 notifier_options_.allow_insecure_connection)); | |
| 1918 talk_mediator_->AddSubscribedServiceUrl(browser_sync::kSyncServiceUrl); | |
| 1919 server_notifier_thread_ = NULL; | |
| 1920 } | |
| 1921 talk_mediator()->SetDelegate(this); | |
| 1922 } | 1845 } |
| 1923 | 1846 |
| 1924 void SyncManager::SyncInternal::RaiseAuthNeededEvent() { | 1847 void SyncManager::SyncInternal::RaiseAuthNeededEvent() { |
| 1925 FOR_EACH_OBSERVER( | 1848 FOR_EACH_OBSERVER( |
| 1926 SyncManager::Observer, observers_, | 1849 SyncManager::Observer, observers_, |
| 1927 OnAuthError(AuthError(AuthError::INVALID_GAIA_CREDENTIALS))); | 1850 OnAuthError(AuthError(AuthError::INVALID_GAIA_CREDENTIALS))); |
| 1928 } | 1851 } |
| 1929 | 1852 |
| 1930 void SyncManager::SyncInternal::SetUsingExplicitPassphrasePrefForMigration() { | 1853 void SyncManager::SyncInternal::SetUsingExplicitPassphrasePrefForMigration() { |
| 1931 WriteTransaction trans(&share_); | 1854 WriteTransaction trans(&share_); |
| (...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2129 return data_; | 2052 return data_; |
| 2130 } | 2053 } |
| 2131 | 2054 |
| 2132 void SyncManager::Shutdown() { | 2055 void SyncManager::Shutdown() { |
| 2133 data_->Shutdown(); | 2056 data_->Shutdown(); |
| 2134 } | 2057 } |
| 2135 | 2058 |
| 2136 void SyncManager::SyncInternal::Shutdown() { | 2059 void SyncManager::SyncInternal::Shutdown() { |
| 2137 method_factory_.RevokeAll(); | 2060 method_factory_.RevokeAll(); |
| 2138 | 2061 |
| 2139 // We NULL out talk_mediator_ so that any tasks pumped below do not | |
| 2140 // trigger further XMPP actions. | |
| 2141 // | |
| 2142 // TODO(akalin): NULL the other member variables defensively, too. | |
| 2143 scoped_ptr<TalkMediator> talk_mediator(talk_mediator_.release()); | |
| 2144 | |
| 2145 if (syncer_thread()) { | 2062 if (syncer_thread()) { |
| 2146 if (!syncer_thread()->Stop(kThreadExitTimeoutMsec)) { | 2063 if (!syncer_thread()->Stop(kThreadExitTimeoutMsec)) { |
| 2147 LOG(FATAL) << "Unable to stop the syncer, it won't be happy..."; | 2064 LOG(FATAL) << "Unable to stop the syncer, it won't be happy..."; |
| 2148 } | 2065 } |
| 2149 syncer_thread_.reset(); | 2066 syncer_thread_.reset(); |
| 2150 } | 2067 } |
| 2151 | 2068 |
| 2152 // Shutdown the xmpp buzz connection. | 2069 // We NULL out sync_notifer_ so that any pending tasks do not |
| 2153 if (talk_mediator.get()) { | 2070 // trigger further notifications. |
| 2154 VLOG(1) << "P2P: Mediator logout started."; | 2071 // TODO(akalin): NULL the other member variables defensively, too. |
| 2155 talk_mediator->Logout(); | 2072 if (sync_notifier_.get()) { |
| 2156 VLOG(1) << "P2P: Mediator logout completed."; | 2073 sync_notifier_->RemoveObserver(this); |
| 2157 talk_mediator.reset(); | 2074 sync_notifier_.reset(); |
| 2158 | |
| 2159 // |server_notifier_thread_| is owned by |talk_mediator|. We NULL | |
| 2160 // it out here so as to not have a dangling pointer. | |
| 2161 server_notifier_thread_= NULL; | |
| 2162 VLOG(1) << "P2P: Mediator destroyed."; | |
| 2163 } | 2075 } |
| 2164 | 2076 |
| 2165 // Pump any messages the auth watcher, syncer thread, or talk | 2077 // Pump any messages the auth watcher, syncer thread, or talk |
| 2166 // mediator posted before they shut down. (See OnSyncEngineEvent(), | 2078 // mediator posted before they shut down. (See OnSyncEngineEvent(), |
| 2167 // and HandleTalkMediatorEvent() for the | 2079 // and HandleTalkMediatorEvent() for the |
| 2168 // events that may be posted.) | 2080 // events that may be posted.) |
| 2169 { | 2081 { |
| 2170 CHECK(core_message_loop_); | 2082 CHECK(core_message_loop_); |
| 2171 bool old_state = core_message_loop_->NestableTasksAllowed(); | 2083 bool old_state = core_message_loop_->NestableTasksAllowed(); |
| 2172 core_message_loop_->SetNestableTasksAllowed(true); | 2084 core_message_loop_->SetNestableTasksAllowed(true); |
| (...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2480 } | 2392 } |
| 2481 | 2393 |
| 2482 if (!initialized()) | 2394 if (!initialized()) |
| 2483 return; | 2395 return; |
| 2484 | 2396 |
| 2485 if (!event.snapshot->has_more_to_sync) { | 2397 if (!event.snapshot->has_more_to_sync) { |
| 2486 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, | 2398 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, |
| 2487 OnSyncCycleCompleted(event.snapshot)); | 2399 OnSyncCycleCompleted(event.snapshot)); |
| 2488 } | 2400 } |
| 2489 | 2401 |
| 2490 if (notifier_options_.notification_method != | 2402 // This is here for tests, which are still using p2p notifications. |
| 2491 notifier::NOTIFICATION_SERVER) { | 2403 // SendNotification does not do anything if we are using server based |
| 2492 // TODO(chron): Consider changing this back to track has_more_to_sync | 2404 // notifications. |
| 2493 // only notify peers if a successful commit has occurred. | 2405 // TODO(chron): Consider changing this back to track has_more_to_sync |
| 2494 bool new_pending_notification = | 2406 // only notify peers if a successful commit has occurred. |
| 2495 (event.snapshot->syncer_status.num_successful_commits > 0); | 2407 bool new_notification = |
| 2408 (event.snapshot->syncer_status.num_successful_commits > 0); |
| 2409 if (new_notification) { |
| 2496 core_message_loop_->PostTask( | 2410 core_message_loop_->PostTask( |
| 2497 FROM_HERE, | 2411 FROM_HERE, |
| 2498 NewRunnableMethod( | 2412 NewRunnableMethod( |
| 2499 this, | 2413 this, |
| 2500 &SyncManager::SyncInternal::SendPendingXMPPNotification, | 2414 &SyncManager::SyncInternal::SendNotification)); |
| 2501 new_pending_notification)); | |
| 2502 } | 2415 } |
| 2503 } | 2416 } |
| 2504 | 2417 |
| 2505 if (event.what_happened == SyncEngineEvent::SYNCER_THREAD_PAUSED) { | 2418 if (event.what_happened == SyncEngineEvent::SYNCER_THREAD_PAUSED) { |
| 2506 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, | 2419 FOR_EACH_OBSERVER(SyncManager::Observer, observers_, |
| 2507 OnPaused()); | 2420 OnPaused()); |
| 2508 return; | 2421 return; |
| 2509 } | 2422 } |
| 2510 | 2423 |
| 2511 if (event.what_happened == SyncEngineEvent::SYNCER_THREAD_RESUMED) { | 2424 if (event.what_happened == SyncEngineEvent::SYNCER_THREAD_RESUMED) { |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2639 if (syncer_thread()) { | 2552 if (syncer_thread()) { |
| 2640 syncer_thread()->SetNotificationsEnabled(notifications_enabled); | 2553 syncer_thread()->SetNotificationsEnabled(notifications_enabled); |
| 2641 } | 2554 } |
| 2642 if (parent_router_) { | 2555 if (parent_router_) { |
| 2643 ListValue args; | 2556 ListValue args; |
| 2644 args.Append(Value::CreateBooleanValue(notifications_enabled)); | 2557 args.Append(Value::CreateBooleanValue(notifications_enabled)); |
| 2645 // TODO(akalin): Tidy up grammar in event names. | 2558 // TODO(akalin): Tidy up grammar in event names. |
| 2646 parent_router_->RouteJsEvent("onSyncNotificationStateChange", | 2559 parent_router_->RouteJsEvent("onSyncNotificationStateChange", |
| 2647 browser_sync::JsArgList(args), NULL); | 2560 browser_sync::JsArgList(args), NULL); |
| 2648 } | 2561 } |
| 2649 if ((notifier_options_.notification_method != | |
| 2650 notifier::NOTIFICATION_SERVER) && notifications_enabled) { | |
| 2651 // Nudge the syncer thread when notifications are enabled, in case there is | |
| 2652 // any data that has not yet been synced. If we are listening to | |
| 2653 // server-issued notifications, we are already guaranteed to receive a | |
| 2654 // notification on a successful connection. | |
| 2655 if (syncer_thread()) { | |
| 2656 syncer_thread()->NudgeSyncer(0, SyncerThread::kLocal); | |
| 2657 } | |
| 2658 | |
| 2659 // Send a notification as soon as subscriptions are on | |
| 2660 // (see http://code.google.com/p/chromium/issues/detail?id=38563 ). | |
| 2661 core_message_loop_->PostTask( | |
| 2662 FROM_HERE, | |
| 2663 NewRunnableMethod( | |
| 2664 this, | |
| 2665 &SyncManager::SyncInternal::SendPendingXMPPNotification, | |
| 2666 true)); | |
| 2667 } | |
| 2668 } | |
| 2669 | |
| 2670 void SyncManager::SyncInternal::TalkMediatorLogin( | |
| 2671 const std::string& email, const std::string& token) { | |
| 2672 DCHECK_EQ(MessageLoop::current(), core_message_loop_); | |
| 2673 DCHECK(!email.empty()); | |
| 2674 DCHECK(!token.empty()); | |
| 2675 InitializeTalkMediator(); | |
| 2676 talk_mediator()->SetAuthToken(email, token, SYNC_SERVICE_NAME); | |
| 2677 talk_mediator()->Login(); | |
| 2678 } | 2562 } |
| 2679 | 2563 |
| 2680 void SyncManager::SyncInternal::OnIncomingNotification( | 2564 void SyncManager::SyncInternal::OnIncomingNotification( |
| 2681 const IncomingNotificationData& notification_data) { | 2565 const browser_sync::sessions::TypePayloadMap& type_payloads) { |
| 2682 browser_sync::sessions::TypePayloadMap model_types_with_payloads; | 2566 if (!type_payloads.empty()) { |
| 2683 | |
| 2684 // Check if the service url is a sync URL. An empty service URL is | |
| 2685 // treated as a legacy sync notification. If we're listening to | |
| 2686 // server-issued notifications, no need to check the service_url. | |
| 2687 if (notifier_options_.notification_method == | |
| 2688 notifier::NOTIFICATION_SERVER) { | |
| 2689 VLOG(1) << "Sync received server notification from " << | |
| 2690 notification_data.service_url << ": " << | |
| 2691 notification_data.service_specific_data; | |
| 2692 syncable::ModelTypeBitSet model_types; | |
| 2693 const std::string& model_type_list = notification_data.service_url; | |
| 2694 const std::string& notification_payload = | |
| 2695 notification_data.service_specific_data; | |
| 2696 | |
| 2697 if (!syncable::ModelTypeBitSetFromString(model_type_list, &model_types)) { | |
| 2698 LOG(DFATAL) << "Could not extract model types from server data."; | |
| 2699 model_types.set(); | |
| 2700 } | |
| 2701 | |
| 2702 model_types_with_payloads = | |
| 2703 browser_sync::sessions::MakeTypePayloadMapFromBitSet(model_types, | |
| 2704 notification_payload); | |
| 2705 } else if (notification_data.service_url.empty() || | |
| 2706 (notification_data.service_url == | |
| 2707 browser_sync::kSyncLegacyServiceUrl) || | |
| 2708 (notification_data.service_url == | |
| 2709 browser_sync::kSyncServiceUrl)) { | |
| 2710 VLOG(1) << "Sync received P2P notification."; | |
| 2711 | |
| 2712 // Catch for sync integration tests (uses p2p). Just set all enabled | |
| 2713 // datatypes. | |
| 2714 ModelSafeRoutingInfo routes; | |
| 2715 registrar_->GetModelSafeRoutingInfo(&routes); | |
| 2716 model_types_with_payloads = | |
| 2717 browser_sync::sessions::MakeTypePayloadMapFromRoutingInfo(routes, | |
| 2718 std::string()); | |
| 2719 } else { | |
| 2720 LOG(WARNING) << "Notification fron unexpected source: " | |
| 2721 << notification_data.service_url; | |
| 2722 } | |
| 2723 | |
| 2724 if (!model_types_with_payloads.empty()) { | |
| 2725 if (syncer_thread()) { | 2567 if (syncer_thread()) { |
| 2726 syncer_thread()->NudgeSyncerWithPayloads( | 2568 syncer_thread()->NudgeSyncerWithPayloads( |
| 2727 kSyncerThreadDelayMsec, | 2569 kSyncerThreadDelayMsec, |
| 2728 SyncerThread::kNotification, | 2570 SyncerThread::kNotification, |
| 2729 model_types_with_payloads); | 2571 type_payloads); |
| 2730 } | 2572 } |
| 2731 allstatus_.IncrementNotificationsReceived(); | 2573 allstatus_.IncrementNotificationsReceived(); |
| 2732 } else { | 2574 } else { |
| 2733 LOG(WARNING) << "Sync received notification without any type information."; | 2575 LOG(WARNING) << "Sync received notification without any type information."; |
| 2734 } | 2576 } |
| 2735 | 2577 |
| 2736 if (parent_router_) { | 2578 if (parent_router_) { |
| 2737 ListValue args; | 2579 ListValue args; |
| 2738 ListValue* changed_types = new ListValue(); | 2580 ListValue* changed_types = new ListValue(); |
| 2739 args.Append(changed_types); | 2581 args.Append(changed_types); |
| 2740 for (browser_sync::sessions::TypePayloadMap::const_iterator | 2582 for (browser_sync::sessions::TypePayloadMap::const_iterator |
| 2741 it = model_types_with_payloads.begin(); | 2583 it = type_payloads.begin(); |
| 2742 it != model_types_with_payloads.end(); ++it) { | 2584 it != type_payloads.end(); ++it) { |
| 2743 const std::string& model_type_str = | 2585 const std::string& model_type_str = |
| 2744 syncable::ModelTypeToString(it->first); | 2586 syncable::ModelTypeToString(it->first); |
| 2745 changed_types->Append(Value::CreateStringValue(model_type_str)); | 2587 changed_types->Append(Value::CreateStringValue(model_type_str)); |
| 2746 } | 2588 } |
| 2747 parent_router_->RouteJsEvent("onSyncIncomingNotification", | 2589 parent_router_->RouteJsEvent("onSyncIncomingNotification", |
| 2748 browser_sync::JsArgList(args), NULL); | 2590 browser_sync::JsArgList(args), NULL); |
| 2749 } | 2591 } |
| 2750 } | 2592 } |
| 2751 | 2593 |
| 2752 void SyncManager::SyncInternal::OnOutgoingNotification() { | 2594 void SyncManager::SyncInternal::StoreState( |
| 2753 DCHECK_NE(notifier_options_.notification_method, | 2595 const std::string& state) { |
| 2754 notifier::NOTIFICATION_SERVER); | |
| 2755 allstatus_.IncrementNotificationsSent(); | |
| 2756 } | |
| 2757 | |
| 2758 void SyncManager::SyncInternal::WriteState(const std::string& state) { | |
| 2759 syncable::ScopedDirLookup lookup(dir_manager(), username_for_share()); | 2596 syncable::ScopedDirLookup lookup(dir_manager(), username_for_share()); |
| 2760 if (!lookup.good()) { | 2597 if (!lookup.good()) { |
| 2761 LOG(ERROR) << "Could not write notification state"; | 2598 LOG(ERROR) << "Could not write notification state"; |
| 2762 // TODO(akalin): Propagate result callback all the way to this | 2599 // TODO(akalin): Propagate result callback all the way to this |
| 2763 // function and call it with "false" to signal failure. | 2600 // function and call it with "false" to signal failure. |
| 2764 return; | 2601 return; |
| 2765 } | 2602 } |
| 2766 if (VLOG_IS_ON(1)) { | 2603 if (VLOG_IS_ON(1)) { |
| 2767 std::string encoded_state; | 2604 std::string encoded_state; |
| 2768 base::Base64Encode(state, &encoded_state); | 2605 base::Base64Encode(state, &encoded_state); |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2830 return (trans.GetWrappedTrans()->directory()->unsynced_entity_count() != 0); | 2667 return (trans.GetWrappedTrans()->directory()->unsynced_entity_count() != 0); |
| 2831 } | 2668 } |
| 2832 | 2669 |
| 2833 void SyncManager::TriggerOnNotificationStateChangeForTest( | 2670 void SyncManager::TriggerOnNotificationStateChangeForTest( |
| 2834 bool notifications_enabled) { | 2671 bool notifications_enabled) { |
| 2835 data_->OnNotificationStateChange(notifications_enabled); | 2672 data_->OnNotificationStateChange(notifications_enabled); |
| 2836 } | 2673 } |
| 2837 | 2674 |
| 2838 void SyncManager::TriggerOnIncomingNotificationForTest( | 2675 void SyncManager::TriggerOnIncomingNotificationForTest( |
| 2839 const syncable::ModelTypeBitSet& model_types) { | 2676 const syncable::ModelTypeBitSet& model_types) { |
| 2840 IncomingNotificationData notification_data; | 2677 browser_sync::sessions::TypePayloadMap model_types_with_payloads = |
| 2841 notification_data.service_url = model_types.to_string(); | 2678 browser_sync::sessions::MakeTypePayloadMapFromBitSet(model_types, |
| 2842 // Here we rely on the default notification method being SERVER. | 2679 std::string()); |
| 2843 data_->OnIncomingNotification(notification_data); | 2680 |
| 2681 data_->OnIncomingNotification(model_types_with_payloads); |
| 2844 } | 2682 } |
| 2845 | 2683 |
| 2846 } // namespace sync_api | 2684 } // namespace sync_api |
| OLD | NEW |