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

Side by Side Diff: chrome/browser/sync/engine/syncapi.cc

Issue 3305003: New authorization framework for sync. ... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: '' Created 10 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 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 "build/build_config.h" 7 #include "build/build_config.h"
8 8
9 #include <iomanip> 9 #include <iomanip>
10 #include <list> 10 #include <list>
11 #include <string> 11 #include <string>
12 #include <vector> 12 #include <vector>
13 13
14 #include "base/basictypes.h" 14 #include "base/basictypes.h"
15 #include "base/base64.h" 15 #include "base/base64.h"
16 #include "base/lock.h" 16 #include "base/lock.h"
17 #include "base/logging.h" 17 #include "base/logging.h"
18 #include "base/message_loop.h" 18 #include "base/message_loop.h"
19 #include "base/platform_thread.h" 19 #include "base/platform_thread.h"
20 #include "base/scoped_ptr.h" 20 #include "base/scoped_ptr.h"
21 #include "base/sha1.h" 21 #include "base/sha1.h"
22 #include "base/string_util.h" 22 #include "base/string_util.h"
23 #include "base/task.h" 23 #include "base/task.h"
24 #include "base/utf_string_conversions.h" 24 #include "base/utf_string_conversions.h"
25 #include "chrome/browser/browser_process.h" 25 #include "chrome/browser/browser_process.h"
26 #include "chrome/browser/sync/sync_constants.h" 26 #include "chrome/browser/sync/sync_constants.h"
27 #include "chrome/browser/sync/engine/all_status.h" 27 #include "chrome/browser/sync/engine/all_status.h"
28 #include "chrome/browser/sync/engine/auth_watcher.h"
29 #include "chrome/browser/sync/engine/change_reorder_buffer.h" 28 #include "chrome/browser/sync/engine/change_reorder_buffer.h"
30 #include "chrome/browser/sync/engine/model_safe_worker.h" 29 #include "chrome/browser/sync/engine/model_safe_worker.h"
31 #include "chrome/browser/sync/engine/net/server_connection_manager.h" 30 #include "chrome/browser/sync/engine/net/server_connection_manager.h"
32 #include "chrome/browser/sync/engine/net/syncapi_server_connection_manager.h" 31 #include "chrome/browser/sync/engine/net/syncapi_server_connection_manager.h"
33 #include "chrome/browser/sync/engine/syncer.h" 32 #include "chrome/browser/sync/engine/syncer.h"
34 #include "chrome/browser/sync/engine/syncer_thread.h" 33 #include "chrome/browser/sync/engine/syncer_thread.h"
35 #include "chrome/browser/sync/notifier/server_notifier_thread.h" 34 #include "chrome/browser/sync/notifier/server_notifier_thread.h"
36 #include "chrome/browser/sync/protocol/app_specifics.pb.h" 35 #include "chrome/browser/sync/protocol/app_specifics.pb.h"
37 #include "chrome/browser/sync/protocol/autofill_specifics.pb.h" 36 #include "chrome/browser/sync/protocol/autofill_specifics.pb.h"
38 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h" 37 #include "chrome/browser/sync/protocol/bookmark_specifics.pb.h"
39 #include "chrome/browser/sync/protocol/extension_specifics.pb.h" 38 #include "chrome/browser/sync/protocol/extension_specifics.pb.h"
40 #include "chrome/browser/sync/protocol/nigori_specifics.pb.h" 39 #include "chrome/browser/sync/protocol/nigori_specifics.pb.h"
41 #include "chrome/browser/sync/protocol/password_specifics.pb.h" 40 #include "chrome/browser/sync/protocol/password_specifics.pb.h"
42 #include "chrome/browser/sync/protocol/preference_specifics.pb.h" 41 #include "chrome/browser/sync/protocol/preference_specifics.pb.h"
43 #include "chrome/browser/sync/protocol/session_specifics.pb.h" 42 #include "chrome/browser/sync/protocol/session_specifics.pb.h"
44 #include "chrome/browser/sync/protocol/service_constants.h" 43 #include "chrome/browser/sync/protocol/service_constants.h"
45 #include "chrome/browser/sync/protocol/sync.pb.h" 44 #include "chrome/browser/sync/protocol/sync.pb.h"
46 #include "chrome/browser/sync/protocol/theme_specifics.pb.h" 45 #include "chrome/browser/sync/protocol/theme_specifics.pb.h"
47 #include "chrome/browser/sync/protocol/typed_url_specifics.pb.h" 46 #include "chrome/browser/sync/protocol/typed_url_specifics.pb.h"
48 #include "chrome/browser/sync/sessions/sync_session_context.h" 47 #include "chrome/browser/sync/sessions/sync_session_context.h"
49 #include "chrome/browser/sync/syncable/directory_manager.h" 48 #include "chrome/browser/sync/syncable/directory_manager.h"
50 #include "chrome/browser/sync/syncable/syncable.h" 49 #include "chrome/browser/sync/syncable/syncable.h"
51 #include "chrome/browser/sync/util/crypto_helpers.h" 50 #include "chrome/browser/sync/util/crypto_helpers.h"
52 #include "chrome/browser/sync/util/user_settings.h"
53 #include "chrome/common/chrome_switches.h" 51 #include "chrome/common/chrome_switches.h"
54 #include "chrome/common/deprecated/event_sys.h" 52 #include "chrome/common/deprecated/event_sys.h"
55 #include "chrome/common/net/gaia/gaia_authenticator.h" 53 #include "chrome/common/net/gaia/gaia_authenticator.h"
56 #include "jingle/notifier/listener/mediator_thread_impl.h" 54 #include "jingle/notifier/listener/mediator_thread_impl.h"
57 #include "jingle/notifier/listener/notification_constants.h" 55 #include "jingle/notifier/listener/notification_constants.h"
58 #include "jingle/notifier/listener/talk_mediator.h" 56 #include "jingle/notifier/listener/talk_mediator.h"
59 #include "jingle/notifier/listener/talk_mediator_impl.h" 57 #include "jingle/notifier/listener/talk_mediator_impl.h"
60 #include "net/base/network_change_notifier.h" 58 #include "net/base/network_change_notifier.h"
61 59
62 using browser_sync::AllStatus; 60 using browser_sync::AllStatus;
63 using browser_sync::AllStatusEvent; 61 using browser_sync::AllStatusEvent;
64 using browser_sync::AuthWatcher;
65 using browser_sync::AuthWatcherEvent;
66 using browser_sync::Cryptographer; 62 using browser_sync::Cryptographer;
67 using browser_sync::KeyParams; 63 using browser_sync::KeyParams;
68 using browser_sync::ModelSafeRoutingInfo; 64 using browser_sync::ModelSafeRoutingInfo;
69 using browser_sync::ModelSafeWorker; 65 using browser_sync::ModelSafeWorker;
70 using browser_sync::ModelSafeWorkerRegistrar; 66 using browser_sync::ModelSafeWorkerRegistrar;
67 using browser_sync::ServerConnectionEvent;
71 using browser_sync::Syncer; 68 using browser_sync::Syncer;
72 using browser_sync::SyncerEvent; 69 using browser_sync::SyncerEvent;
73 using browser_sync::SyncerThread; 70 using browser_sync::SyncerThread;
74 using browser_sync::UserSettings;
75 using browser_sync::kNigoriTag; 71 using browser_sync::kNigoriTag;
76 using browser_sync::sessions::SyncSessionContext; 72 using browser_sync::sessions::SyncSessionContext;
77 using notifier::TalkMediator; 73 using notifier::TalkMediator;
78 using notifier::TalkMediatorImpl; 74 using notifier::TalkMediatorImpl;
79 using std::list; 75 using std::list;
80 using std::hex; 76 using std::hex;
81 using std::string; 77 using std::string;
82 using std::vector; 78 using std::vector;
83 using syncable::Directory; 79 using syncable::Directory;
84 using syncable::DirectoryManager; 80 using syncable::DirectoryManager;
(...skipping 818 matching lines...) Expand 10 before | Expand all | Expand 10 after
903 : public net::NetworkChangeNotifier::Observer, 899 : public net::NetworkChangeNotifier::Observer,
904 public TalkMediator::Delegate, 900 public TalkMediator::Delegate,
905 public browser_sync::ChannelEventHandler<syncable::DirectoryChangeEvent>, 901 public browser_sync::ChannelEventHandler<syncable::DirectoryChangeEvent>,
906 public browser_sync::ChannelEventHandler<SyncerEvent>{ 902 public browser_sync::ChannelEventHandler<SyncerEvent>{
907 static const int kDefaultNudgeDelayMilliseconds; 903 static const int kDefaultNudgeDelayMilliseconds;
908 static const int kPreferencesNudgeDelayMilliseconds; 904 static const int kPreferencesNudgeDelayMilliseconds;
909 public: 905 public:
910 explicit SyncInternal(SyncManager* sync_manager) 906 explicit SyncInternal(SyncManager* sync_manager)
911 : core_message_loop_(NULL), 907 : core_message_loop_(NULL),
912 observer_(NULL), 908 observer_(NULL),
913 auth_problem_(AuthError::NONE),
914 sync_manager_(sync_manager), 909 sync_manager_(sync_manager),
915 registrar_(NULL), 910 registrar_(NULL),
916 notification_pending_(false), 911 notification_pending_(false),
917 initialized_(false), 912 initialized_(false),
918 use_chrome_async_socket_(false), 913 use_chrome_async_socket_(false),
919 notification_method_(browser_sync::kDefaultNotificationMethod), 914 notification_method_(browser_sync::kDefaultNotificationMethod),
920 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) { 915 ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
921 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 916 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
922 } 917 }
923 918
924 ~SyncInternal() { 919 ~SyncInternal() {
925 DCHECK(!core_message_loop_); 920 DCHECK(!core_message_loop_);
926 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI)); 921 DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
927 } 922 }
928 923
929 bool Init(const FilePath& database_location, 924 bool Init(const FilePath& database_location,
930 const std::string& sync_server_and_path, 925 const std::string& sync_server_and_path,
931 int port, 926 int port,
932 const char* gaia_service_id,
933 const char* gaia_source,
934 bool use_ssl, 927 bool use_ssl,
935 HttpPostProviderFactory* post_factory, 928 HttpPostProviderFactory* post_factory,
936 HttpPostProviderFactory* auth_post_factory,
937 ModelSafeWorkerRegistrar* model_safe_worker_registrar, 929 ModelSafeWorkerRegistrar* model_safe_worker_registrar,
938 bool attempt_last_user_authentication,
939 bool invalidate_last_user_auth_token,
940 bool invalidate_xmpp_auth_token,
941 const char* user_agent, 930 const char* user_agent,
942 const std::string& lsid, 931 const SyncCredentials& credentials,
943 const bool use_chrome_async_socket, 932 const bool use_chrome_async_socket,
944 const bool try_ssltcp_first, 933 const bool try_ssltcp_first,
945 browser_sync::NotificationMethod notification_method, 934 browser_sync::NotificationMethod notification_method,
946 const std::string& restored_key_for_bootstrapping); 935 const std::string& restored_key_for_bootstrapping);
947 936
948 // Tell sync engine to submit credentials to GAIA for verification. 937
949 // Successful GAIA authentication will kick off the following chain of events: 938 // Sign into sync with given credentials.
950 // 1. Cause sync engine to open the syncer database. 939 // We do not verify the tokens given. After this call, the tokens are set
951 // 2. Trigger the AuthWatcher to create a Syncer for the directory and call 940 // and the sync DB is open. True if successful, false if something
952 // SyncerThread::SyncDirectory; the SyncerThread will block until (4). 941 // went wrong.
953 // 3. Tell the ServerConnectionManager to pass the newly received GAIA auth 942 bool SignIn(const SyncCredentials& credentials);
954 // token to a sync server to obtain a sync token. 943
955 // 4. On receipt of this token, the ServerConnectionManager broadcasts 944 // Update tokens that we're using in Sync. Email must stay the same.
956 // a server-reachable event, which will unblock the SyncerThread. 945 void UpdateCredentials(const SyncCredentials& credentials);
957 // 5. When StartSyncing is called, the Syncer will begin the sync process, by
958 // downloading from or uploading to the server.
959 //
960 // If authentication fails, an event will be broadcast all the way up to
961 // the SyncManager::Observer. It may, in turn, decide to try again with new
962 // credentials. Calling this method again is the appropriate course of action
963 // to "retry".
964 void Authenticate(const std::string& username, const std::string& password,
965 const std::string& captcha);
966 946
967 // Tell the sync engine to start the syncing process. 947 // Tell the sync engine to start the syncing process.
968 void StartSyncing(); 948 void StartSyncing();
969 949
970 void SetPassphrase(const std::string& passphrase); 950 void SetPassphrase(const std::string& passphrase);
971 951
972 // Call periodically from a database-safe thread to persist recent changes 952 // Call periodically from a database-safe thread to persist recent changes
973 // to the syncapi model. 953 // to the syncapi model.
974 void SaveChanges(); 954 void SaveChanges();
975 955
976 // This listener is called upon completion of a syncable transaction, and 956 // This listener is called upon completion of a syncable transaction, and
977 // builds the list of sync-engine initiated changes that will be forwarded to 957 // builds the list of sync-engine initiated changes that will be forwarded to
978 // the SyncManager's Observers. 958 // the SyncManager's Observers.
979 virtual void HandleChannelEvent(const syncable::DirectoryChangeEvent& event); 959 virtual void HandleChannelEvent(const syncable::DirectoryChangeEvent& event);
980 void HandleTransactionEndingChangeEvent( 960 void HandleTransactionEndingChangeEvent(
981 const syncable::DirectoryChangeEvent& event); 961 const syncable::DirectoryChangeEvent& event);
982 void HandleCalculateChangesChangeEventFromSyncApi( 962 void HandleCalculateChangesChangeEventFromSyncApi(
983 const syncable::DirectoryChangeEvent& event); 963 const syncable::DirectoryChangeEvent& event);
984 void HandleCalculateChangesChangeEventFromSyncer( 964 void HandleCalculateChangesChangeEventFromSyncer(
985 const syncable::DirectoryChangeEvent& event); 965 const syncable::DirectoryChangeEvent& event);
986 966
987 // This listener is called by the syncer channel for all syncer events. 967 // This listener is called by the syncer channel for all syncer events.
988 virtual void HandleChannelEvent(const SyncerEvent& event); 968 virtual void HandleChannelEvent(const SyncerEvent& event);
989 969
990 // We have a direct hookup to the authwatcher to be notified for auth failures 970 // Listens for notifications from the ServerConnectionManager
991 // on startup, to serve our UI needs. 971 void HandleServerConnectionEvent(const ServerConnectionEvent& event);
992 void HandleAuthWatcherEvent(const AuthWatcherEvent& event);
993 972
994 // Listen here for directory opened events. 973 // Open the directory named with username_for_share
995 void HandleDirectoryManagerEvent( 974 bool OpenDirectory();
996 const syncable::DirectoryManagerEvent& event);
997 975
998 // Login to the talk mediator with the given credentials. 976 // Login to the talk mediator with the given credentials.
999 void TalkMediatorLogin( 977 void TalkMediatorLogin(
1000 const std::string& email, const std::string& token); 978 const std::string& email, const std::string& token);
1001 979
1002 // TalkMediator::Delegate implementation. 980 // TalkMediator::Delegate implementation.
1003
1004 virtual void OnNotificationStateChange( 981 virtual void OnNotificationStateChange(
1005 bool notifications_enabled); 982 bool notifications_enabled);
1006 983
1007 virtual void OnIncomingNotification( 984 virtual void OnIncomingNotification(
1008 const IncomingNotificationData& notification_data); 985 const IncomingNotificationData& notification_data);
1009 986
1010 virtual void OnOutgoingNotification(); 987 virtual void OnOutgoingNotification();
1011 988
1012 // Accessors for the private members. 989 // Accessors for the private members.
1013 DirectoryManager* dir_manager() { return share_.dir_manager.get(); } 990 DirectoryManager* dir_manager() { return share_.dir_manager.get(); }
1014 SyncAPIServerConnectionManager* connection_manager() { 991 SyncAPIServerConnectionManager* connection_manager() {
1015 return connection_manager_.get(); 992 return connection_manager_.get();
1016 } 993 }
1017 SyncerThread* syncer_thread() { return syncer_thread_.get(); } 994 SyncerThread* syncer_thread() { return syncer_thread_.get(); }
1018 TalkMediator* talk_mediator() { return talk_mediator_.get(); } 995 TalkMediator* talk_mediator() { return talk_mediator_.get(); }
1019 AuthWatcher* auth_watcher() { return auth_watcher_.get(); }
1020 void set_observer(SyncManager::Observer* observer) { observer_ = observer; } 996 void set_observer(SyncManager::Observer* observer) { observer_ = observer; }
1021 UserShare* GetUserShare() { return &share_; } 997 UserShare* GetUserShare() { return &share_; }
1022 998
1023 // Return the currently active (validated) username for use with syncable 999 // Return the currently active (validated) username for use with syncable
1024 // types. 1000 // types.
1025 const std::string& username_for_share() const { 1001 const std::string& username_for_share() const {
1026 return share_.authenticated_name; 1002 return share_.name;
1027 } 1003 }
1028 1004
1029 // Note about SyncManager::Status implementation: Status is a trimmed 1005 // Note about SyncManager::Status implementation: Status is a trimmed
1030 // down AllStatus::Status, augmented with authentication failure information 1006 // down AllStatus::Status, augmented with authentication failure information
1031 // gathered from the internal AuthWatcher. The sync UI itself hooks up to 1007 // gathered from the internal AuthWatcher. The sync UI itself hooks up to
1032 // various sources like the AuthWatcher individually, but with syncapi we try 1008 // various sources like the AuthWatcher individually, but with syncapi we try
1033 // to keep everything status-related in one place. This means we have to 1009 // to keep everything status-related in one place. This means we have to
1034 // privately manage state about authentication failures, and whenever the 1010 // privately manage state about authentication failures, and whenever the
1035 // status or status summary is requested we aggregate this state with 1011 // status or status summary is requested we aggregate this state with
1036 // AllStatus::Status information. 1012 // AllStatus::Status information.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 registrar_->GetModelSafeRoutingInfo(&enabled_types); 1047 registrar_->GetModelSafeRoutingInfo(&enabled_types);
1072 for (ModelSafeRoutingInfo::const_iterator i = enabled_types.begin(); 1048 for (ModelSafeRoutingInfo::const_iterator i = enabled_types.begin();
1073 i != enabled_types.end(); ++i) { 1049 i != enabled_types.end(); ++i) {
1074 if (!lookup->initial_sync_ended_for_type(i->first)) 1050 if (!lookup->initial_sync_ended_for_type(i->first))
1075 return false; 1051 return false;
1076 } 1052 }
1077 return true; 1053 return true;
1078 } 1054 }
1079 1055
1080 private: 1056 private:
1081 // Try to authenticate using a LSID cookie.
1082 void AuthenticateWithLsid(const std::string& lsid);
1083
1084 // Try to authenticate using persisted credentials from a previous successful
1085 // authentication. If no such credentials exist, calls OnAuthError on the
1086 // client to collect credentials. Otherwise, there exist local credentials
1087 // that were once used for a successful auth, so we'll try to re-use these.
1088 // Failure of that attempt will be communicated as normal using OnAuthError.
1089 // Since this entry point will bypass normal GAIA authentication and try to
1090 // authenticate directly with the sync service using a cached token,
1091 // authentication failure will generally occur due to expired credentials, or
1092 // possibly because of a password change.
1093 bool AuthenticateForUser(const std::string& username,
1094 const std::string& auth_token);
1095
1096 // Helper to call OnAuthError when no authentication credentials are 1057 // Helper to call OnAuthError when no authentication credentials are
1097 // available. 1058 // available.
1098 void RaiseAuthNeededEvent(); 1059 void RaiseAuthNeededEvent();
1099 1060
1100 // Helper to set initialized_ to true and raise an event to clients to notify 1061 // Helper to set initialized_ to true and raise an event to clients to notify
1101 // that initialization is complete and it is safe to send us changes. If 1062 // that initialization is complete and it is safe to send us changes. If
1102 // already initialized, this is a no-op. 1063 // already initialized, this is a no-op.
1103 void MarkAndNotifyInitializationComplete(); 1064 void MarkAndNotifyInitializationComplete();
1104 1065
1105 // If there's a pending notification to be sent, either from the 1066 // If there's a pending notification to be sent, either from the
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 } else { 1125 } else {
1165 NOTREACHED() << "Should be valid connection manager!"; 1126 NOTREACHED() << "Should be valid connection manager!";
1166 } 1127 }
1167 } 1128 }
1168 1129
1169 // We couple the DirectoryManager and username together in a UserShare member 1130 // We couple the DirectoryManager and username together in a UserShare member
1170 // so we can return a handle to share_ to clients of the API for use when 1131 // so we can return a handle to share_ to clients of the API for use when
1171 // constructing any transaction type. 1132 // constructing any transaction type.
1172 UserShare share_; 1133 UserShare share_;
1173 1134
1174 // A wrapper around a sqlite store used for caching authentication data,
1175 // last user information, current sync-related URLs, and more.
1176 scoped_ptr<UserSettings> user_settings_;
1177
1178 MessageLoop* core_message_loop_; 1135 MessageLoop* core_message_loop_;
1179 1136
1180 // Observer registered via SetObserver/RemoveObserver. 1137 // Observer registered via SetObserver/RemoveObserver.
1181 // WARNING: This can be NULL! 1138 // WARNING: This can be NULL!
1182 SyncManager::Observer* observer_; 1139 SyncManager::Observer* observer_;
1183 1140
1184 // The ServerConnectionManager used to abstract communication between the 1141 // The ServerConnectionManager used to abstract communication between the
1185 // client (the Syncer) and the sync server. 1142 // client (the Syncer) and the sync server.
1186 scoped_ptr<SyncAPIServerConnectionManager> connection_manager_; 1143 scoped_ptr<SyncAPIServerConnectionManager> connection_manager_;
1187 1144
1188 // The thread that runs the Syncer. Needs to be explicitly Start()ed. 1145 // The thread that runs the Syncer. Needs to be explicitly Start()ed.
1189 scoped_refptr<SyncerThread> syncer_thread_; 1146 scoped_refptr<SyncerThread> syncer_thread_;
1190 1147
1191 // Notification (xmpp) handler. 1148 // Notification (xmpp) handler.
1192 scoped_ptr<TalkMediator> talk_mediator_; 1149 scoped_ptr<TalkMediator> talk_mediator_;
1193 1150
1194 // A multi-purpose status watch object that aggregates stats from various 1151 // A multi-purpose status watch object that aggregates stats from various
1195 // sync components. 1152 // sync components.
1196 AllStatus allstatus_; 1153 AllStatus allstatus_;
1197 1154
1198 // AuthWatcher kicks off the authentication process and follows it through
1199 // phase 1 (GAIA) to phase 2 (sync engine). As part of this work it determines
1200 // the initial connectivity and causes the server connection event to be
1201 // broadcast, which signals the syncer thread to start syncing.
1202 // It has a heavy duty constructor requiring boilerplate so we heap allocate.
1203 scoped_refptr<AuthWatcher> auth_watcher_;
1204
1205 // Each element of this array is a store of change records produced by 1155 // Each element of this array is a store of change records produced by
1206 // HandleChangeEvent during the CALCULATE_CHANGES step. The changes are 1156 // HandleChangeEvent during the CALCULATE_CHANGES step. The changes are
1207 // segregated by model type, and are stored here to be processed and 1157 // segregated by model type, and are stored here to be processed and
1208 // forwarded to the observer slightly later, at the TRANSACTION_ENDING 1158 // forwarded to the observer slightly later, at the TRANSACTION_ENDING
1209 // step by HandleTransactionEndingChangeEvent. 1159 // step by HandleTransactionEndingChangeEvent.
1210 ChangeReorderBuffer change_buffers_[syncable::MODEL_TYPE_COUNT]; 1160 ChangeReorderBuffer change_buffers_[syncable::MODEL_TYPE_COUNT];
1211 1161
1212 // The event listener hookup that is registered for HandleChangeEvent. 1162 // The event listener hookup that is registered for HandleChangeEvent.
1213 scoped_ptr<browser_sync::ChannelHookup<syncable::DirectoryChangeEvent> > 1163 scoped_ptr<browser_sync::ChannelHookup<syncable::DirectoryChangeEvent> >
1214 dir_change_hookup_; 1164 dir_change_hookup_;
1215 1165
1166 // Event listener hookup for the ServerConnectionManager.
1167 scoped_ptr<EventListenerHookup> connection_manager_hookup_;
1168
1216 // The event listener hookup registered for HandleSyncerEvent. 1169 // The event listener hookup registered for HandleSyncerEvent.
1217 scoped_ptr<browser_sync::ChannelHookup<SyncerEvent> > syncer_event_; 1170 scoped_ptr<browser_sync::ChannelHookup<SyncerEvent> > syncer_event_;
1218 1171
1219 // The event listener hookup registered for HandleAuthWatcherEvent.
1220 scoped_ptr<EventListenerHookup> authwatcher_hookup_;
1221
1222 // The event listener hookup registered for the DirectoryManager (OPENED).
1223 scoped_ptr<EventListenerHookup> directory_manager_hookup_;
1224
1225 // Our cache of a recent authentication problem. If no authentication problem
1226 // occurred, or if the last problem encountered has been cleared (by a
1227 // subsequent AuthWatcherEvent), this is set to NONE.
1228 AuthError::State auth_problem_;
1229
1230 // The sync dir_manager to which we belong. 1172 // The sync dir_manager to which we belong.
1231 SyncManager* const sync_manager_; 1173 SyncManager* const sync_manager_;
1232 1174
1233 // The entity that provides us with information about which types to sync. 1175 // The entity that provides us with information about which types to sync.
1234 // The instance is shared between the SyncManager and the Syncer. 1176 // The instance is shared between the SyncManager and the Syncer.
1235 ModelSafeWorkerRegistrar* registrar_; 1177 ModelSafeWorkerRegistrar* registrar_;
1236 1178
1237 // True if the next SyncCycle should notify peers of an update. 1179 // True if the next SyncCycle should notify peers of an update.
1238 bool notification_pending_; 1180 bool notification_pending_;
1239 1181
(...skipping 14 matching lines...) Expand all
1254 const int SyncManager::SyncInternal::kDefaultNudgeDelayMilliseconds = 200; 1196 const int SyncManager::SyncInternal::kDefaultNudgeDelayMilliseconds = 200;
1255 const int SyncManager::SyncInternal::kPreferencesNudgeDelayMilliseconds = 2000; 1197 const int SyncManager::SyncInternal::kPreferencesNudgeDelayMilliseconds = 2000;
1256 1198
1257 SyncManager::SyncManager() { 1199 SyncManager::SyncManager() {
1258 data_ = new SyncInternal(this); 1200 data_ = new SyncInternal(this);
1259 } 1201 }
1260 1202
1261 bool SyncManager::Init(const FilePath& database_location, 1203 bool SyncManager::Init(const FilePath& database_location,
1262 const char* sync_server_and_path, 1204 const char* sync_server_and_path,
1263 int sync_server_port, 1205 int sync_server_port,
1264 const char* gaia_service_id,
1265 const char* gaia_source,
1266 bool use_ssl, 1206 bool use_ssl,
1267 HttpPostProviderFactory* post_factory, 1207 HttpPostProviderFactory* post_factory,
1268 HttpPostProviderFactory* auth_post_factory,
1269 ModelSafeWorkerRegistrar* registrar, 1208 ModelSafeWorkerRegistrar* registrar,
1270 bool attempt_last_user_authentication,
1271 bool invalidate_last_user_auth_token,
1272 bool invalidate_xmpp_auth_token,
1273 const char* user_agent, 1209 const char* user_agent,
1274 const char* lsid, 1210 const SyncCredentials& credentials,
1275 bool use_chrome_async_socket, 1211 bool use_chrome_async_socket,
1276 bool try_ssltcp_first, 1212 bool try_ssltcp_first,
1277 browser_sync::NotificationMethod notification_method, 1213 browser_sync::NotificationMethod notification_method,
1278 const std::string& restored_key_for_bootstrapping) { 1214 const std::string& restored_key_for_bootstrapping) {
1279 DCHECK(post_factory); 1215 DCHECK(post_factory);
1280 LOG(INFO) << "SyncManager starting Init..."; 1216 LOG(INFO) << "SyncManager starting Init...";
1281 string server_string(sync_server_and_path); 1217 string server_string(sync_server_and_path);
1282 return data_->Init(database_location, 1218 return data_->Init(database_location,
1283 server_string, 1219 server_string,
1284 sync_server_port, 1220 sync_server_port,
1285 gaia_service_id,
1286 gaia_source,
1287 use_ssl, 1221 use_ssl,
1288 post_factory, 1222 post_factory,
1289 auth_post_factory,
1290 registrar, 1223 registrar,
1291 attempt_last_user_authentication,
1292 invalidate_last_user_auth_token,
1293 invalidate_xmpp_auth_token,
1294 user_agent, 1224 user_agent,
1295 lsid, 1225 credentials,
1296 use_chrome_async_socket, 1226 use_chrome_async_socket,
1297 try_ssltcp_first, 1227 try_ssltcp_first,
1298 notification_method, 1228 notification_method,
1299 restored_key_for_bootstrapping); 1229 restored_key_for_bootstrapping);
1300 } 1230 }
1301 1231
1302 void SyncManager::Authenticate(const char* username, const char* password, 1232 void SyncManager::UpdateCredentials(const SyncCredentials& credentials) {
1303 const char* captcha) { 1233 data_->UpdateCredentials(credentials);
1304 data_->Authenticate(std::string(username), std::string(password),
1305 std::string(captcha));
1306 } 1234 }
1307 1235
1236
1308 bool SyncManager::InitialSyncEndedForAllEnabledTypes() { 1237 bool SyncManager::InitialSyncEndedForAllEnabledTypes() {
1309 return data_->InitialSyncEndedForAllEnabledTypes(); 1238 return data_->InitialSyncEndedForAllEnabledTypes();
1310 } 1239 }
1311 1240
1312 void SyncManager::StartSyncing() { 1241 void SyncManager::StartSyncing() {
1313 data_->StartSyncing(); 1242 data_->StartSyncing();
1314 } 1243 }
1315 1244
1316 void SyncManager::SetPassphrase(const std::string& passphrase) { 1245 void SyncManager::SetPassphrase(const std::string& passphrase) {
1317 data_->SetPassphrase(passphrase); 1246 data_->SetPassphrase(passphrase);
1318 } 1247 }
1319 1248
1320 bool SyncManager::RequestPause() { 1249 bool SyncManager::RequestPause() {
1321 return data_->syncer_thread()->RequestPause(); 1250 return data_->syncer_thread()->RequestPause();
1322 } 1251 }
1323 1252
1324 bool SyncManager::RequestResume() { 1253 bool SyncManager::RequestResume() {
1325 return data_->syncer_thread()->RequestResume(); 1254 return data_->syncer_thread()->RequestResume();
1326 } 1255 }
1327 1256
1328 void SyncManager::RequestNudge() { 1257 void SyncManager::RequestNudge() {
1329 data_->syncer_thread()->NudgeSyncer(0, SyncerThread::kLocal); 1258 data_->syncer_thread()->NudgeSyncer(0, SyncerThread::kLocal);
1330 } 1259 }
1331 1260
1261 // TODO(chron): Don't need to plumb this so deep.
1332 const std::string& SyncManager::GetAuthenticatedUsername() { 1262 const std::string& SyncManager::GetAuthenticatedUsername() {
1333 DCHECK(data_); 1263 DCHECK(data_);
1334 return data_->username_for_share(); 1264 return data_->username_for_share();
1335 } 1265 }
1336 1266
1337 bool SyncManager::SyncInternal::Init( 1267 bool SyncManager::SyncInternal::Init(
1338 const FilePath& database_location, 1268 const FilePath& database_location,
1339 const std::string& sync_server_and_path, 1269 const std::string& sync_server_and_path,
1340 int port, 1270 int port,
1341 const char* gaia_service_id,
1342 const char* gaia_source,
1343 bool use_ssl, 1271 bool use_ssl,
1344 HttpPostProviderFactory* post_factory, 1272 HttpPostProviderFactory* post_factory,
1345 HttpPostProviderFactory* auth_post_factory,
1346 ModelSafeWorkerRegistrar* model_safe_worker_registrar, 1273 ModelSafeWorkerRegistrar* model_safe_worker_registrar,
1347 bool attempt_last_user_authentication,
1348 bool invalidate_last_user_auth_token,
1349 bool invalidate_xmpp_auth_token,
1350 const char* user_agent, 1274 const char* user_agent,
1351 const std::string& lsid, 1275 const SyncCredentials& credentials,
1352 bool use_chrome_async_socket, 1276 bool use_chrome_async_socket,
1353 bool try_ssltcp_first, 1277 bool try_ssltcp_first,
1354 browser_sync::NotificationMethod notification_method, 1278 browser_sync::NotificationMethod notification_method,
1355 const std::string& restored_key_for_bootstrapping) { 1279 const std::string& restored_key_for_bootstrapping) {
1356 1280
1357 LOG(INFO) << "Starting SyncInternal initialization."; 1281 LOG(INFO) << "Starting SyncInternal initialization.";
1358 1282
1359 core_message_loop_ = MessageLoop::current(); 1283 core_message_loop_ = MessageLoop::current();
1360 DCHECK(core_message_loop_); 1284 DCHECK(core_message_loop_);
1361 notification_method_ = notification_method; 1285 notification_method_ = notification_method;
1362 // Set up UserSettings, creating the db if necessary. We need this to
1363 // instantiate a URLFactory to give to the Syncer.
1364 FilePath settings_db_file =
1365 database_location.Append(FilePath(kBookmarkSyncUserSettingsDatabase));
1366 user_settings_.reset(new UserSettings());
1367 if (!user_settings_->Init(settings_db_file))
1368 return false;
1369
1370 registrar_ = model_safe_worker_registrar; 1286 registrar_ = model_safe_worker_registrar;
1371 1287
1372 LOG(INFO) << "Initialized sync user settings. Starting DirectoryManager."; 1288 share_.dir_manager.reset(new DirectoryManager(database_location));
1373 1289
1374 share_.dir_manager.reset(new DirectoryManager(database_location)); 1290 connection_manager_.reset(new SyncAPIServerConnectionManager(
1375 directory_manager_hookup_.reset(NewEventListenerHookup( 1291 sync_server_and_path, port, use_ssl, user_agent, post_factory));
1376 share_.dir_manager->channel(), this,
1377 &SyncInternal::HandleDirectoryManagerEvent));
1378 share_.dir_manager->cryptographer()->Bootstrap(
1379 restored_key_for_bootstrapping);
1380 1292
1381 string client_id = user_settings_->GetClientId(); 1293 connection_manager_hookup_.reset(
1382 connection_manager_.reset(new SyncAPIServerConnectionManager( 1294 NewEventListenerHookup(connection_manager()->channel(), this,
1383 sync_server_and_path, port, use_ssl, user_agent, client_id, 1295 &SyncManager::SyncInternal::HandleServerConnectionEvent));
1384 post_factory));
1385
1386 // Watch various objects for aggregated status.
1387 allstatus_.WatchConnectionManager(connection_manager());
1388 1296
1389 net::NetworkChangeNotifier::AddObserver(this); 1297 net::NetworkChangeNotifier::AddObserver(this);
1390 // TODO(akalin): CheckServerReachable() can block, which may cause jank if we 1298 // TODO(akalin): CheckServerReachable() can block, which may cause jank if we
1391 // try to shut down sync. Fix this. 1299 // try to shut down sync. Fix this.
1392 core_message_loop_->PostTask(FROM_HERE, 1300 core_message_loop_->PostTask(FROM_HERE,
1393 method_factory_.NewRunnableMethod(&SyncInternal::CheckServerReachable)); 1301 method_factory_.NewRunnableMethod(&SyncInternal::CheckServerReachable));
1394 1302
1395 // NOTIFICATION_SERVER uses a substantially different notification method, so 1303 // NOTIFICATION_SERVER uses a substantially different notification method, so
1396 // it has its own MediatorThread implementation. Everything else just uses 1304 // it has its own MediatorThread implementation. Everything else just uses
1397 // MediatorThreadImpl. 1305 // MediatorThreadImpl.
1398 notifier::MediatorThread* mediator_thread = 1306 notifier::MediatorThread* mediator_thread =
1399 (notification_method == browser_sync::NOTIFICATION_SERVER) ? 1307 (notification_method == browser_sync::NOTIFICATION_SERVER) ?
1400 new sync_notifier::ServerNotifierThread(use_chrome_async_socket, 1308 new sync_notifier::ServerNotifierThread(use_chrome_async_socket,
1401 try_ssltcp_first) : 1309 try_ssltcp_first) :
1402 new notifier::MediatorThreadImpl(use_chrome_async_socket, 1310 new notifier::MediatorThreadImpl(use_chrome_async_socket,
1403 try_ssltcp_first); 1311 try_ssltcp_first);
1404 const bool kInitializeSsl = true; 1312 const bool kInitializeSsl = true;
1405 const bool kConnectImmediately = false; 1313 const bool kConnectImmediately = false;
1406 talk_mediator_.reset(new TalkMediatorImpl(mediator_thread, kInitializeSsl, 1314 talk_mediator_.reset(new TalkMediatorImpl(mediator_thread, kInitializeSsl,
1407 kConnectImmediately, invalidate_xmpp_auth_token)); 1315 kConnectImmediately, false));
1408 if (notification_method != browser_sync::NOTIFICATION_LEGACY && 1316 if (notification_method != browser_sync::NOTIFICATION_LEGACY &&
1409 notification_method != browser_sync::NOTIFICATION_SERVER) { 1317 notification_method != browser_sync::NOTIFICATION_SERVER) {
1410 if (notification_method == browser_sync::NOTIFICATION_TRANSITIONAL) { 1318 if (notification_method == browser_sync::NOTIFICATION_TRANSITIONAL) {
1411 talk_mediator_->AddSubscribedServiceUrl( 1319 talk_mediator_->AddSubscribedServiceUrl(
1412 browser_sync::kSyncLegacyServiceUrl); 1320 browser_sync::kSyncLegacyServiceUrl);
1413 } 1321 }
1414 talk_mediator_->AddSubscribedServiceUrl(browser_sync::kSyncServiceUrl); 1322 talk_mediator_->AddSubscribedServiceUrl(browser_sync::kSyncServiceUrl);
1415 } 1323 }
1416 1324
1417 // Listen to TalkMediator events ourselves 1325 // Listen to TalkMediator events ourselves
1418 talk_mediator_->SetDelegate(this); 1326 talk_mediator_->SetDelegate(this);
1419 1327
1420 std::string gaia_url = gaia::kGaiaUrl; 1328 LOG(INFO) << "Sync is bringing up SyncSessionContext.";
1421 const char* service_id = gaia_service_id ?
1422 gaia_service_id : SYNC_SERVICE_NAME;
1423
1424 BridgedGaiaAuthenticator* gaia_auth = new BridgedGaiaAuthenticator(
1425 gaia_source, service_id, gaia_url, auth_post_factory);
1426
1427 LOG(INFO) << "Sync is bringing up authwatcher and SyncSessionContext.";
1428
1429 auth_watcher_ = new AuthWatcher(dir_manager(),
1430 connection_manager(),
1431 gaia_source,
1432 service_id,
1433 gaia_url,
1434 user_settings_.get(),
1435 gaia_auth);
1436
1437 authwatcher_hookup_.reset(NewEventListenerHookup(auth_watcher_->channel(),
1438 this, &SyncInternal::HandleAuthWatcherEvent));
1439 1329
1440 // Build a SyncSessionContext and store the worker in it. 1330 // Build a SyncSessionContext and store the worker in it.
1441 SyncSessionContext* context = new SyncSessionContext( 1331 SyncSessionContext* context = new SyncSessionContext(
1442 connection_manager_.get(), auth_watcher(), 1332 connection_manager_.get(), dir_manager(), model_safe_worker_registrar);
1443 dir_manager(), model_safe_worker_registrar);
1444 1333
1445 // The SyncerThread takes ownership of |context|. 1334 // The SyncerThread takes ownership of |context|.
1446 syncer_thread_ = new SyncerThread(context); 1335 syncer_thread_ = new SyncerThread(context);
1447 allstatus_.WatchSyncerThread(syncer_thread()); 1336 allstatus_.WatchSyncerThread(syncer_thread());
1448 1337
1449 // Subscribe to the syncer thread's channel. 1338 // Subscribe to the syncer thread's channel.
1450 syncer_event_.reset(syncer_thread()->relay_channel()->AddObserver(this)); 1339 syncer_event_.reset(syncer_thread()->relay_channel()->AddObserver(this));
1451 1340
1452 bool attempting_auth = false; 1341 return SignIn(credentials);
1453 std::string username, auth_token;
1454 if (attempt_last_user_authentication &&
1455 auth_watcher()->settings()->GetLastUserAndServiceToken(
1456 SYNC_SERVICE_NAME, &username, &auth_token)) {
1457 if (invalidate_last_user_auth_token) {
1458 auth_token += "bogus";
1459 }
1460 attempting_auth = AuthenticateForUser(username, auth_token);
1461 } else if (!lsid.empty()) {
1462 attempting_auth = true;
1463 AuthenticateWithLsid(lsid);
1464 }
1465 if (attempt_last_user_authentication && !attempting_auth)
1466 RaiseAuthNeededEvent();
1467 return true;
1468 } 1342 }
1469 1343
1470 void SyncManager::SyncInternal::StartSyncing() { 1344 void SyncManager::SyncInternal::StartSyncing() {
1471 if (syncer_thread()) // NULL during certain unittests. 1345 if (syncer_thread()) // NULL during certain unittests.
1472 syncer_thread()->Start(); // Start the syncer thread. This won't actually 1346 syncer_thread()->Start(); // Start the syncer thread. This won't actually
1473 // result in any syncing until at least the 1347 // result in any syncing until at least the
1474 // DirectoryManager broadcasts the OPENED event, 1348 // DirectoryManager broadcasts the OPENED event,
1475 // and a valid server connection is detected. 1349 // and a valid server connection is detected.
1476 } 1350 }
1477 1351
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1529 } 1403 }
1530 bool success = talk_mediator_->SendNotification(notification_data); 1404 bool success = talk_mediator_->SendNotification(notification_data);
1531 if (success) { 1405 if (success) {
1532 notification_pending_ = false; 1406 notification_pending_ = false;
1533 LOG(INFO) << "Sent XMPP notification"; 1407 LOG(INFO) << "Sent XMPP notification";
1534 } else { 1408 } else {
1535 LOG(INFO) << "Could not send XMPP notification"; 1409 LOG(INFO) << "Could not send XMPP notification";
1536 } 1410 }
1537 } 1411 }
1538 1412
1539 void SyncManager::SyncInternal::Authenticate(const std::string& username, 1413 bool SyncManager::SyncInternal::OpenDirectory() {
1540 const std::string& password, 1414 DCHECK(!initialized()) << "Should only happen once";
1541 const std::string& captcha) {
1542 DCHECK(username_for_share().empty() || username == username_for_share())
1543 << "Username change from valid username detected";
1544 if (allstatus_.status().authenticated)
1545 return;
1546 if (password.empty()) {
1547 // TODO(timsteele): Seems like this shouldn't be needed, but auth_watcher
1548 // currently drops blank password attempts on the floor and doesn't update
1549 // state; it only LOGs an error in this case. We want to make sure we set
1550 // our GoogleServiceAuthError state to denote an error.
1551 RaiseAuthNeededEvent();
1552 }
1553 auth_watcher()->Authenticate(username, password, std::string(),
1554 captcha);
1555 }
1556 1415
1557 void SyncManager::SyncInternal::AuthenticateWithLsid(const string& lsid) { 1416 bool share_opened = dir_manager()->Open(username_for_share());
1558 DCHECK(!lsid.empty()); 1417 DCHECK(share_opened);
1559 auth_watcher()->AuthenticateWithLsid(lsid); 1418 if (!share_opened) {
1560 } 1419 if (observer_) {
1420 observer_->OnStopSyncingPermanently();
1421 }
1561 1422
1562 bool SyncManager::SyncInternal::AuthenticateForUser( 1423 LOG(ERROR) << "Could not open share for:" << username_for_share();
1563 const std::string& username, const std::string& auth_token) {
1564 share_.authenticated_name = username;
1565
1566 // We optimize by opening the directory before the "fresh" authentication
1567 // attempt completes so that we can immediately begin processing changes.
1568 if (!dir_manager()->Open(username_for_share())) {
1569 if (observer_)
1570 observer_->OnStopSyncingPermanently();
1571 return false; 1424 return false;
1572 } 1425 }
1573 1426
1574 // Load the last-known good auth token into the connection manager and send 1427 // Database has to be initialized for the guid to be available.
1575 // it off to the AuthWatcher for validation. The result of the validation 1428 syncable::ScopedDirLookup lookup(dir_manager(), username_for_share());
1576 // will update the connection manager if necessary. 1429 if (!lookup.good()) {
1577 connection_manager()->set_auth_token(auth_token); 1430 NOTREACHED();
1578 auth_watcher()->AuthenticateWithToken(username, auth_token); 1431 return false;
1432 }
1433
1434 connection_manager()->set_client_id(lookup->cache_guid());
1435 syncer_thread()->CreateSyncer(username_for_share());
1436 MarkAndNotifyInitializationComplete();
1437 dir_change_hookup_.reset(lookup->AddChangeObserver(this));
1579 return true; 1438 return true;
1580 } 1439 }
1581 1440
1441 bool SyncManager::SyncInternal::SignIn(const SyncCredentials& credentials) {
1442 DCHECK_EQ(MessageLoop::current(), core_message_loop_);
1443 DCHECK(share_.name.empty());
1444 share_.name = credentials.email;
1445
1446 LOG(INFO) << "Signing in user: " << username_for_share();
1447 if (!OpenDirectory()) {
1448 return false;
1449 }
1450
1451 UpdateCredentials(credentials);
1452 return true;
1453 }
1454
1455 void SyncManager::SyncInternal::UpdateCredentials(
1456 const SyncCredentials& credentials) {
1457 DCHECK_EQ(MessageLoop::current(), core_message_loop_);
1458 DCHECK(share_.name == credentials.email);
1459 connection_manager()->set_auth_token(credentials.sync_token);
1460 TalkMediatorLogin(credentials.email, credentials.sync_token);
1461 CheckServerReachable();
1462 sync_manager_->RequestNudge();
1463 }
1464
1582 void SyncManager::SyncInternal::RaiseAuthNeededEvent() { 1465 void SyncManager::SyncInternal::RaiseAuthNeededEvent() {
1583 auth_problem_ = AuthError::INVALID_GAIA_CREDENTIALS; 1466 if (observer_) {
1584 if (observer_) 1467 observer_->OnAuthError(AuthError(AuthError::INVALID_GAIA_CREDENTIALS));
1585 observer_->OnAuthError(AuthError(auth_problem_)); 1468 }
1586 } 1469 }
1587 1470
1588 void SyncManager::SyncInternal::SetPassphrase( 1471 void SyncManager::SyncInternal::SetPassphrase(
1589 const std::string& passphrase) { 1472 const std::string& passphrase) {
1590 Cryptographer* cryptographer = dir_manager()->cryptographer(); 1473 Cryptographer* cryptographer = dir_manager()->cryptographer();
1591 KeyParams params = {"localhost", "dummy", passphrase}; 1474 KeyParams params = {"localhost", "dummy", passphrase};
1592 if (cryptographer->has_pending_keys()) { 1475 if (cryptographer->has_pending_keys()) {
1593 if (!cryptographer->DecryptPendingKeys(params)) { 1476 if (!cryptographer->DecryptPendingKeys(params)) {
1594 observer_->OnPassphraseRequired(); 1477 observer_->OnPassphraseRequired();
1595 return; 1478 return;
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
1635 1518
1636 void SyncManager::SyncInternal::Shutdown() { 1519 void SyncManager::SyncInternal::Shutdown() {
1637 method_factory_.RevokeAll(); 1520 method_factory_.RevokeAll();
1638 1521
1639 // We NULL out talk_mediator_ so that any tasks pumped below do not 1522 // We NULL out talk_mediator_ so that any tasks pumped below do not
1640 // trigger further XMPP actions. 1523 // trigger further XMPP actions.
1641 // 1524 //
1642 // TODO(akalin): NULL the other member variables defensively, too. 1525 // TODO(akalin): NULL the other member variables defensively, too.
1643 scoped_ptr<TalkMediator> talk_mediator(talk_mediator_.release()); 1526 scoped_ptr<TalkMediator> talk_mediator(talk_mediator_.release());
1644 1527
1645 // First reset the AuthWatcher in case an auth attempt is in progress so that
1646 // it terminates gracefully before we shutdown and close other components.
1647 // Otherwise the attempt can complete after we've closed the directory, for
1648 // example, and cause initialization to continue, which is bad.
1649 if (auth_watcher_) {
1650 auth_watcher_->Shutdown();
1651 authwatcher_hookup_.reset();
1652 }
1653
1654 if (syncer_thread()) { 1528 if (syncer_thread()) {
1655 if (!syncer_thread()->Stop(kThreadExitTimeoutMsec)) { 1529 if (!syncer_thread()->Stop(kThreadExitTimeoutMsec)) {
1656 LOG(FATAL) << "Unable to stop the syncer, it won't be happy..."; 1530 LOG(FATAL) << "Unable to stop the syncer, it won't be happy...";
1657 } 1531 }
1658 syncer_event_.reset(); 1532 syncer_event_.reset();
1659 syncer_thread_ = NULL; 1533 syncer_thread_ = NULL;
1660 } 1534 }
1661 1535
1662 // TODO(chron): Since the auth_watcher_ is held by the sync session state,
1663 // we release the ref here after the syncer is deallocated.
1664 // In reality the SyncerSessionState's pointer to the
1665 // authwatcher should be ref counted, but for M6 we use this
1666 // lower risk fix so it's deallocated on the original thread.
1667 if (auth_watcher_) {
1668 auth_watcher_ = NULL;
1669 }
1670
1671 // Shutdown the xmpp buzz connection. 1536 // Shutdown the xmpp buzz connection.
1672 if (talk_mediator.get()) { 1537 if (talk_mediator.get()) {
1673 LOG(INFO) << "P2P: Mediator logout started."; 1538 LOG(INFO) << "P2P: Mediator logout started.";
1674 talk_mediator->Logout(); 1539 talk_mediator->Logout();
1675 LOG(INFO) << "P2P: Mediator logout completed."; 1540 LOG(INFO) << "P2P: Mediator logout completed.";
1676 talk_mediator.reset(); 1541 talk_mediator.reset();
1677 LOG(INFO) << "P2P: Mediator destroyed."; 1542 LOG(INFO) << "P2P: Mediator destroyed.";
1678 } 1543 }
1679 1544
1680 // Pump any messages the auth watcher, syncer thread, or talk 1545 // Pump any messages the auth watcher, syncer thread, or talk
1681 // mediator posted before they shut down. (See HandleSyncerEvent(), 1546 // mediator posted before they shut down. (See HandleSyncerEvent(),
1682 // HandleAuthWatcherEvent(), and HandleTalkMediatorEvent() for the 1547 // and HandleTalkMediatorEvent() for the
1683 // events that may be posted.) 1548 // events that may be posted.)
1684 { 1549 {
1685 CHECK(core_message_loop_); 1550 CHECK(core_message_loop_);
1686 bool old_state = core_message_loop_->NestableTasksAllowed(); 1551 bool old_state = core_message_loop_->NestableTasksAllowed();
1687 core_message_loop_->SetNestableTasksAllowed(true); 1552 core_message_loop_->SetNestableTasksAllowed(true);
1688 core_message_loop_->RunAllPending(); 1553 core_message_loop_->RunAllPending();
1689 core_message_loop_->SetNestableTasksAllowed(old_state); 1554 core_message_loop_->SetNestableTasksAllowed(old_state);
1690 } 1555 }
1691 1556
1692 net::NetworkChangeNotifier::RemoveObserver(this); 1557 net::NetworkChangeNotifier::RemoveObserver(this);
1693 1558
1559 connection_manager_hookup_.reset();
1560
1694 if (dir_manager()) { 1561 if (dir_manager()) {
1695 dir_manager()->FinalSaveChangesForAll(); 1562 dir_manager()->FinalSaveChangesForAll();
1696 dir_manager()->Close(username_for_share()); 1563 dir_manager()->Close(username_for_share());
1697 } 1564 }
1698 1565
1699 // Reset the DirectoryManager and UserSettings so they relinquish sqlite 1566 // Reset the DirectoryManager and UserSettings so they relinquish sqlite
1700 // handles to backing files. 1567 // handles to backing files.
1701 share_.dir_manager.reset(); 1568 share_.dir_manager.reset();
1702 user_settings_.reset();
1703 1569
1704 // We don't want to process any more events. 1570 // We don't want to process any more events.
1705 dir_change_hookup_.reset(); 1571 dir_change_hookup_.reset();
1706 1572
1707 core_message_loop_ = NULL; 1573 core_message_loop_ = NULL;
1708 } 1574 }
1709 1575
1710 void SyncManager::SyncInternal::OnIPAddressChanged() { 1576 void SyncManager::SyncInternal::OnIPAddressChanged() {
1711 LOG(INFO) << "IP address change detected"; 1577 LOG(INFO) << "IP address change detected";
1712 // TODO(akalin): CheckServerReachable() can block, which may cause 1578 // TODO(akalin): CheckServerReachable() can block, which may cause
1713 // jank if we try to shut down sync. Fix this. 1579 // jank if we try to shut down sync. Fix this.
1714 connection_manager()->CheckServerReachable(); 1580 connection_manager()->CheckServerReachable();
1715 } 1581 sync_manager_->RequestNudge();
1716
1717 void SyncManager::SyncInternal::HandleDirectoryManagerEvent(
1718 const syncable::DirectoryManagerEvent& event) {
1719 LOG(INFO) << "Sync internal handling a directory manager event";
1720 if (syncable::DirectoryManagerEvent::OPENED == event.what_happened) {
1721 DCHECK(!initialized()) << "Should only happen once";
1722 if (username_for_share().empty()) {
1723 share_.authenticated_name = event.dirname;
1724 }
1725 DCHECK(LowerCaseEqualsASCII(username_for_share(),
1726 StringToLowerASCII(event.dirname).c_str()))
1727 << "username_for_share= " << username_for_share()
1728 << ", event.dirname= " << event.dirname;
1729 MarkAndNotifyInitializationComplete();
1730 }
1731 } 1582 }
1732 1583
1733 // Listen to model changes, filter out ones initiated by the sync API, and 1584 // Listen to model changes, filter out ones initiated by the sync API, and
1734 // saves the rest (hopefully just backend Syncer changes resulting from 1585 // saves the rest (hopefully just backend Syncer changes resulting from
1735 // ApplyUpdates) to data_->changelist. 1586 // ApplyUpdates) to data_->changelist.
1736 void SyncManager::SyncInternal::HandleChannelEvent( 1587 void SyncManager::SyncInternal::HandleChannelEvent(
1737 const syncable::DirectoryChangeEvent& event) { 1588 const syncable::DirectoryChangeEvent& event) {
1738 if (event.todo == syncable::DirectoryChangeEvent::TRANSACTION_ENDING) { 1589 if (event.todo == syncable::DirectoryChangeEvent::TRANSACTION_ENDING) {
1739 HandleTransactionEndingChangeEvent(event); 1590 HandleTransactionEndingChangeEvent(event);
1740 return; 1591 return;
1741 } else if (event.todo == syncable::DirectoryChangeEvent::CALCULATE_CHANGES) { 1592 } else if (event.todo == syncable::DirectoryChangeEvent::CALCULATE_CHANGES) {
1742 if (event.writer == syncable::SYNCAPI) { 1593 if (event.writer == syncable::SYNCAPI) {
1743 HandleCalculateChangesChangeEventFromSyncApi(event); 1594 HandleCalculateChangesChangeEventFromSyncApi(event);
1744 return; 1595 return;
1745 } 1596 }
1746 HandleCalculateChangesChangeEventFromSyncer(event); 1597 HandleCalculateChangesChangeEventFromSyncer(event);
1747 return; 1598 return;
1748 } else if (event.todo == syncable::DirectoryChangeEvent::SHUTDOWN) { 1599 } else if (event.todo == syncable::DirectoryChangeEvent::SHUTDOWN) {
1749 dir_change_hookup_.reset(); 1600 dir_change_hookup_.reset();
1750 } 1601 }
1751 } 1602 }
1752 1603
1604 void SyncManager::SyncInternal::HandleServerConnectionEvent(
1605 const ServerConnectionEvent& event) {
1606 allstatus_.HandleServerConnectionEvent(event);
1607 if (event.what_happened == ServerConnectionEvent::STATUS_CHANGED) {
1608 if (event.connection_code ==
1609 browser_sync::HttpResponse::SERVER_CONNECTION_OK) {
1610 if (observer_) {
1611 observer_->OnAuthError(AuthError(AuthError::None()));
1612 }
1613 }
1614
1615 if (event.connection_code == browser_sync::HttpResponse::SYNC_AUTH_ERROR) {
1616 if (observer_) {
1617 observer_->OnAuthError(AuthError(AuthError::INVALID_GAIA_CREDENTIALS));
1618 }
1619 }
1620 }
1621 }
1622
1753 void SyncManager::SyncInternal::HandleTransactionEndingChangeEvent( 1623 void SyncManager::SyncInternal::HandleTransactionEndingChangeEvent(
1754 const syncable::DirectoryChangeEvent& event) { 1624 const syncable::DirectoryChangeEvent& event) {
1755 // This notification happens immediately before a syncable WriteTransaction 1625 // This notification happens immediately before a syncable WriteTransaction
1756 // falls out of scope. It happens while the channel mutex is still held, 1626 // falls out of scope. It happens while the channel mutex is still held,
1757 // and while the transaction mutex is held, so it cannot be re-entrant. 1627 // and while the transaction mutex is held, so it cannot be re-entrant.
1758 DCHECK_EQ(event.todo, syncable::DirectoryChangeEvent::TRANSACTION_ENDING); 1628 DCHECK_EQ(event.todo, syncable::DirectoryChangeEvent::TRANSACTION_ENDING);
1759 if (!observer_ || ChangeBuffersAreEmpty()) 1629 if (!observer_ || ChangeBuffersAreEmpty())
1760 return; 1630 return;
1761 1631
1762 // This will continue the WriteTransaction using a read only wrapper. 1632 // This will continue the WriteTransaction using a read only wrapper.
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1974 1844
1975 if (event.what_happened == SyncerEvent::RESUMED) { 1845 if (event.what_happened == SyncerEvent::RESUMED) {
1976 observer_->OnResumed(); 1846 observer_->OnResumed();
1977 return; 1847 return;
1978 } 1848 }
1979 1849
1980 if (event.what_happened == SyncerEvent::STOP_SYNCING_PERMANENTLY) { 1850 if (event.what_happened == SyncerEvent::STOP_SYNCING_PERMANENTLY) {
1981 observer_->OnStopSyncingPermanently(); 1851 observer_->OnStopSyncingPermanently();
1982 return; 1852 return;
1983 } 1853 }
1854
1855 if (event.what_happened == SyncerEvent::UPDATED_TOKEN) {
1856 observer_->OnUpdatedToken(event.updated_token);
1857 return;
1858 }
1984 } 1859 }
1985 1860
1986 void SyncManager::SyncInternal::HandleAuthWatcherEvent(
1987 const AuthWatcherEvent& event) {
1988 allstatus_.HandleAuthWatcherEvent(event);
1989 // We don't care about an authentication attempt starting event, and we
1990 // don't want to reset our state to GoogleServiceAuthError::NONE because the
1991 // fact that an _attempt_ is starting doesn't change the fact that we have an
1992 // auth problem.
1993 if (event.what_happened == AuthWatcherEvent::AUTHENTICATION_ATTEMPT_START)
1994 return;
1995 // We clear our last auth problem cache on new auth watcher events, and only
1996 // set it to indicate a problem state for certain AuthWatcherEvent types.
1997 auth_problem_ = AuthError::NONE;
1998 switch (event.what_happened) {
1999 case AuthWatcherEvent::AUTH_SUCCEEDED:
2000 DCHECK(!event.user_email.empty());
2001 // We now know the supplied username and password were valid. If this
2002 // wasn't the first sync, authenticated_name should already be assigned.
2003 if (username_for_share().empty()) {
2004 share_.authenticated_name = event.user_email;
2005 }
2006
2007 DCHECK(LowerCaseEqualsASCII(username_for_share(),
2008 StringToLowerASCII(event.user_email).c_str()))
2009 << "username_for_share= " << username_for_share()
2010 << ", event.user_email= " << event.user_email;
2011
2012 if (observer_)
2013 observer_->OnAuthError(AuthError::None());
2014
2015 // Hook up the DirectoryChangeEvent listener, HandleChangeEvent.
2016 {
2017 syncable::ScopedDirLookup lookup(dir_manager(), username_for_share());
2018 if (!lookup.good()) {
2019 DCHECK(false) << "ScopedDirLookup creation failed; unable to hook "
2020 << "up directory change event listener!";
2021 return;
2022 }
2023
2024 // Note that we can end up here multiple times, for example if the
2025 // user had to re-login and we got a second AUTH_SUCCEEDED event. Take
2026 // care not to add ourselves as an observer a second time.
2027 if (!dir_change_hookup_.get())
2028 dir_change_hookup_.reset(lookup->AddChangeObserver(this));
2029 }
2030
2031 if (!event.auth_token.empty()) {
2032 core_message_loop_->PostTask(
2033 FROM_HERE,
2034 NewRunnableMethod(
2035 this, &SyncManager::SyncInternal::TalkMediatorLogin,
2036 event.user_email, event.auth_token));
2037 }
2038 return;
2039 case AuthWatcherEvent::AUTH_RENEWED:
2040 DCHECK(!event.user_email.empty());
2041 DCHECK(!event.auth_token.empty());
2042 core_message_loop_->PostTask(
2043 FROM_HERE,
2044 NewRunnableMethod(
2045 this, &SyncManager::SyncInternal::TalkMediatorLogin,
2046 event.user_email, event.auth_token));
2047 return;
2048 // Authentication failures translate to GoogleServiceAuthError events.
2049 case AuthWatcherEvent::GAIA_AUTH_FAILED: // Invalid GAIA credentials.
2050 if (event.auth_results->auth_error == gaia::CaptchaRequired) {
2051 auth_problem_ = AuthError::CAPTCHA_REQUIRED;
2052 std::string url_string("https://www.google.com/accounts/");
2053 url_string += event.auth_results->captcha_url;
2054 GURL captcha(url_string);
2055 observer_->OnAuthError(AuthError::FromCaptchaChallenge(
2056 event.auth_results->captcha_token, captcha,
2057 GURL(event.auth_results->auth_error_url)));
2058 return;
2059 } else if (event.auth_results->auth_error ==
2060 gaia::ConnectionUnavailable) {
2061 auth_problem_ = AuthError::CONNECTION_FAILED;
2062 } else {
2063 auth_problem_ = AuthError::INVALID_GAIA_CREDENTIALS;
2064 }
2065 break;
2066 case AuthWatcherEvent::SERVICE_AUTH_FAILED: // Expired GAIA credentials.
2067 auth_problem_ = AuthError::INVALID_GAIA_CREDENTIALS;
2068 break;
2069 case AuthWatcherEvent::SERVICE_USER_NOT_SIGNED_UP:
2070 auth_problem_ = AuthError::USER_NOT_SIGNED_UP;
2071 break;
2072 case AuthWatcherEvent::SERVICE_CONNECTION_FAILED:
2073 auth_problem_ = AuthError::CONNECTION_FAILED;
2074 break;
2075 default: // We don't care about the many other AuthWatcherEvent types.
2076 return;
2077 }
2078
2079
2080 // Fire notification that the status changed due to an authentication error.
2081 if (observer_)
2082 observer_->OnAuthError(AuthError(auth_problem_));
2083 }
2084
2085 void SyncManager::SyncInternal::OnNotificationStateChange( 1861 void SyncManager::SyncInternal::OnNotificationStateChange(
2086 bool notifications_enabled) { 1862 bool notifications_enabled) {
2087 LOG(INFO) << "P2P: Notifications enabled = " 1863 LOG(INFO) << "P2P: Notifications enabled = "
2088 << (notifications_enabled ? "true" : "false"); 1864 << (notifications_enabled ? "true" : "false");
2089 allstatus_.SetNotificationsEnabled(notifications_enabled); 1865 allstatus_.SetNotificationsEnabled(notifications_enabled);
2090 if (syncer_thread()) { 1866 if (syncer_thread()) {
2091 syncer_thread()->SetNotificationsEnabled(notifications_enabled); 1867 syncer_thread()->SetNotificationsEnabled(notifications_enabled);
2092 } 1868 }
2093 if ((notification_method_ != browser_sync::NOTIFICATION_SERVER) && 1869 if ((notification_method_ != browser_sync::NOTIFICATION_SERVER) &&
2094 notifications_enabled) { 1870 notifications_enabled) {
(...skipping 19 matching lines...) Expand all
2114 void SyncManager::SyncInternal::TalkMediatorLogin( 1890 void SyncManager::SyncInternal::TalkMediatorLogin(
2115 const std::string& email, const std::string& token) { 1891 const std::string& email, const std::string& token) {
2116 DCHECK_EQ(MessageLoop::current(), core_message_loop_); 1892 DCHECK_EQ(MessageLoop::current(), core_message_loop_);
2117 DCHECK(!email.empty()); 1893 DCHECK(!email.empty());
2118 DCHECK(!token.empty()); 1894 DCHECK(!token.empty());
2119 if (!talk_mediator_.get()) { 1895 if (!talk_mediator_.get()) {
2120 LOG(INFO) << "Not logging in: shutting down " 1896 LOG(INFO) << "Not logging in: shutting down "
2121 << "(talk_mediator_ is NULL)"; 1897 << "(talk_mediator_ is NULL)";
2122 return; 1898 return;
2123 } 1899 }
2124 // TODO(akalin): Make talk_mediator automatically login on 1900 LOG(INFO) << "P2P: Trying talk mediator login.";
2125 // auth token change. 1901
2126 talk_mediator_->SetAuthToken(email, token, SYNC_SERVICE_NAME); 1902 talk_mediator_->SetAuthToken(email, token, SYNC_SERVICE_NAME);
2127 talk_mediator_->Login(); 1903 talk_mediator_->Login();
2128 } 1904 }
2129 1905
2130 void SyncManager::SyncInternal::OnIncomingNotification( 1906 void SyncManager::SyncInternal::OnIncomingNotification(
2131 const IncomingNotificationData& notification_data) { 1907 const IncomingNotificationData& notification_data) {
2132 // Check if the service url is a sync URL. An empty service URL is 1908 // Check if the service url is a sync URL. An empty service URL is
2133 // treated as a legacy sync notification. If we're listening to 1909 // treated as a legacy sync notification. If we're listening to
2134 // server-issued notifications, no need to check the service_url. 1910 // server-issued notifications, no need to check the service_url.
2135 if ((notification_method_ == browser_sync::NOTIFICATION_SERVER) || 1911 if ((notification_method_ == browser_sync::NOTIFICATION_SERVER) ||
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2177 lookup->SaveChanges(); 1953 lookup->SaveChanges();
2178 } 1954 }
2179 1955
2180 void SyncManager::SetupForTestMode(const std::wstring& test_username) { 1956 void SyncManager::SetupForTestMode(const std::wstring& test_username) {
2181 DCHECK(data_) << "SetupForTestMode requires initialization"; 1957 DCHECK(data_) << "SetupForTestMode requires initialization";
2182 data_->SetupForTestMode(test_username); 1958 data_->SetupForTestMode(test_username);
2183 } 1959 }
2184 1960
2185 void SyncManager::SyncInternal::SetupForTestMode( 1961 void SyncManager::SyncInternal::SetupForTestMode(
2186 const std::wstring& test_username) { 1962 const std::wstring& test_username) {
2187 share_.authenticated_name = WideToUTF8(test_username); 1963 share_.name = WideToUTF8(test_username);
2188 1964
2189 // Some tests are targeting only local db operations & integrity, and don't 1965 // Some tests are targeting only local db operations & integrity, and don't
2190 // want syncer thread interference. 1966 // want syncer thread interference.
2191 syncer_event_.reset(); 1967 syncer_event_.reset();
2192 allstatus_.WatchSyncerThread(NULL); 1968 allstatus_.WatchSyncerThread(NULL);
2193 syncer_thread_ = NULL; 1969 syncer_thread_ = NULL;
2194 1970
2195 if (!dir_manager()->Open(username_for_share())) 1971 if (!dir_manager()->Open(username_for_share())) {
2196 DCHECK(false) << "Could not open directory when running in test mode"; 1972 DCHECK(false) << "Could not open directory when running in test mode";
2197
2198 // Hook up the DirectoryChangeEvent listener, HandleChangeEvent.
2199 {
2200 syncable::ScopedDirLookup lookup(dir_manager(), username_for_share());
2201 if (!lookup.good()) {
2202 DCHECK(false) << "ScopedDirLookup creation failed; unable to hook "
2203 << "up directory change event listener!";
2204 return;
2205 }
2206 dir_change_hookup_.reset(lookup->AddChangeObserver(this));
2207 } 1973 }
2208 } 1974 }
2209 1975
2210 ////////////////////////////////////////////////////////////////////////// 1976 //////////////////////////////////////////////////////////////////////////
2211 // BaseTransaction member definitions 1977 // BaseTransaction member definitions
2212 BaseTransaction::BaseTransaction(UserShare* share) 1978 BaseTransaction::BaseTransaction(UserShare* share)
2213 : lookup_(NULL) { 1979 : lookup_(NULL) {
2214 DCHECK(share && share->dir_manager.get()); 1980 DCHECK(share && share->dir_manager.get());
2215 lookup_ = new syncable::ScopedDirLookup(share->dir_manager.get(), 1981 lookup_ = new syncable::ScopedDirLookup(share->dir_manager.get(),
2216 share->authenticated_name); 1982 share->name);
2217 cryptographer_ = share->dir_manager->cryptographer(); 1983 cryptographer_ = share->dir_manager->cryptographer();
2218 if (!(lookup_->good())) 1984 if (!(lookup_->good()))
2219 DCHECK(false) << "ScopedDirLookup failed on valid DirManager."; 1985 DCHECK(false) << "ScopedDirLookup failed on valid DirManager.";
2220 } 1986 }
2221 BaseTransaction::~BaseTransaction() { 1987 BaseTransaction::~BaseTransaction() {
2222 delete lookup_; 1988 delete lookup_;
2223 } 1989 }
2224 1990
2225 UserShare* SyncManager::GetUserShare() const { 1991 UserShare* SyncManager::GetUserShare() const {
2226 DCHECK(data_->initialized()) << "GetUserShare requires initialization!"; 1992 DCHECK(data_->initialized()) << "GetUserShare requires initialization!";
2227 return data_->GetUserShare(); 1993 return data_->GetUserShare();
2228 } 1994 }
2229 1995
2230 bool SyncManager::HasUnsyncedItems() const { 1996 bool SyncManager::HasUnsyncedItems() const {
2231 sync_api::ReadTransaction trans(GetUserShare()); 1997 sync_api::ReadTransaction trans(GetUserShare());
2232 return (trans.GetWrappedTrans()->directory()->unsynced_entity_count() != 0); 1998 return (trans.GetWrappedTrans()->directory()->unsynced_entity_count() != 0);
2233 } 1999 }
2234 2000
2235 } // namespace sync_api 2001 } // namespace sync_api
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698