| OLD | NEW |
| 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 #ifndef CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_ | 5 #ifndef CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_ |
| 6 #define CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_ | 6 #define CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_ |
| 7 | 7 |
| 8 #include <set> | 8 #include <set> |
| 9 #include <string> | 9 #include <string> |
| 10 #include <vector> |
| 10 | 11 |
| 11 #include "base/file_path.h" | 12 #include "base/file_path.h" |
| 12 #include "base/lock.h" | 13 #include "base/lock.h" |
| 13 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
| 14 #include "base/ref_counted.h" | 15 #include "base/ref_counted.h" |
| 15 #include "base/thread.h" | 16 #include "base/thread.h" |
| 16 #include "base/timer.h" | 17 #include "base/timer.h" |
| 17 #include "chrome/browser/google_service_auth_error.h" | 18 #include "chrome/browser/google_service_auth_error.h" |
| 18 #include "chrome/browser/net/url_request_context_getter.h" | 19 #include "chrome/browser/net/url_request_context_getter.h" |
| 19 #include "chrome/browser/sync/engine/syncapi.h" | 20 #include "chrome/browser/sync/engine/syncapi.h" |
| 20 #include "chrome/browser/sync/glue/bookmark_model_worker.h" | 21 #include "chrome/browser/sync/engine/model_safe_worker.h" |
| 22 #include "chrome/browser/sync/glue/ui_model_worker.h" |
| 23 #include "chrome/browser/sync/syncable/model_type.h" |
| 21 #include "googleurl/src/gurl.h" | 24 #include "googleurl/src/gurl.h" |
| 22 | 25 |
| 23 namespace browser_sync { | 26 namespace browser_sync { |
| 24 | 27 |
| 25 class ChangeProcessor; | 28 class ChangeProcessor; |
| 26 | 29 |
| 27 // SyncFrontend is the interface used by SyncBackendHost to communicate with | 30 // SyncFrontend is the interface used by SyncBackendHost to communicate with |
| 28 // the entity that created it and, presumably, is interested in sync-related | 31 // the entity that created it and, presumably, is interested in sync-related |
| 29 // activity. | 32 // activity. |
| 30 // NOTE: All methods will be invoked by a SyncBackendHost on the same thread | 33 // NOTE: All methods will be invoked by a SyncBackendHost on the same thread |
| (...skipping 18 matching lines...) Expand all Loading... |
| 49 virtual ~SyncFrontend() { | 52 virtual ~SyncFrontend() { |
| 50 } | 53 } |
| 51 private: | 54 private: |
| 52 DISALLOW_COPY_AND_ASSIGN(SyncFrontend); | 55 DISALLOW_COPY_AND_ASSIGN(SyncFrontend); |
| 53 }; | 56 }; |
| 54 | 57 |
| 55 // A UI-thread safe API into the sync backend that "hosts" the top-level | 58 // A UI-thread safe API into the sync backend that "hosts" the top-level |
| 56 // syncapi element, the SyncManager, on its own thread. This class handles | 59 // syncapi element, the SyncManager, on its own thread. This class handles |
| 57 // dispatch of potentially blocking calls to appropriate threads and ensures | 60 // dispatch of potentially blocking calls to appropriate threads and ensures |
| 58 // that the SyncFrontend is only accessed on the UI loop. | 61 // that the SyncFrontend is only accessed on the UI loop. |
| 59 class SyncBackendHost { | 62 class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar { |
| 60 public: | 63 public: |
| 61 typedef sync_api::UserShare* UserShareHandle; | 64 typedef sync_api::UserShare* UserShareHandle; |
| 62 typedef sync_api::SyncManager::Status::Summary StatusSummary; | 65 typedef sync_api::SyncManager::Status::Summary StatusSummary; |
| 63 typedef sync_api::SyncManager::Status Status; | 66 typedef sync_api::SyncManager::Status Status; |
| 64 | 67 |
| 65 // Create a SyncBackendHost with a reference to the |frontend| that it serves | 68 // Create a SyncBackendHost with a reference to the |frontend| that it serves |
| 66 // and communicates to via the SyncFrontend interface (on the same thread | 69 // and communicates to via the SyncFrontend interface (on the same thread |
| 67 // it used to call the constructor), and push changes from sync_api through | 70 // it used to call the constructor), and push changes from sync_api through |
| 68 // |processor|. | 71 // |processor|. |
| 69 SyncBackendHost(SyncFrontend* frontend, const FilePath& profile_path, | 72 SyncBackendHost(SyncFrontend* frontend, const FilePath& profile_path, |
| (...skipping 28 matching lines...) Expand all Loading... |
| 98 | 101 |
| 99 const FilePath& sync_data_folder_path() const { | 102 const FilePath& sync_data_folder_path() const { |
| 100 return sync_data_folder_path_; | 103 return sync_data_folder_path_; |
| 101 } | 104 } |
| 102 | 105 |
| 103 // Returns the authenticated username of the sync user, or empty if none | 106 // Returns the authenticated username of the sync user, or empty if none |
| 104 // exists. It will only exist if the authentication service provider (e.g | 107 // exists. It will only exist if the authentication service provider (e.g |
| 105 // GAIA) has confirmed the username is authentic. | 108 // GAIA) has confirmed the username is authentic. |
| 106 string16 GetAuthenticatedUsername() const; | 109 string16 GetAuthenticatedUsername() const; |
| 107 | 110 |
| 111 // ModelSafeWorkerRegistrar implementation. |
| 112 virtual void GetWorkers(std::vector<browser_sync::ModelSafeWorker*>* out); |
| 113 virtual void GetModelSafeRoutingInfo(ModelSafeRoutingInfo* out); |
| 114 |
| 108 #if defined(UNIT_TEST) | 115 #if defined(UNIT_TEST) |
| 109 // Called from unit test to bypass authentication and initialize the syncapi | 116 // Called from unit test to bypass authentication and initialize the syncapi |
| 110 // to a state suitable for testing but not production. | 117 // to a state suitable for testing but not production. |
| 111 void InitializeForTestMode(const std::wstring& test_user, | 118 void InitializeForTestMode(const std::wstring& test_user, |
| 112 sync_api::HttpPostProviderFactory* factory, | 119 sync_api::HttpPostProviderFactory* factory, |
| 113 sync_api::HttpPostProviderFactory* auth_factory) { | 120 sync_api::HttpPostProviderFactory* auth_factory) { |
| 114 if (!core_thread_.Start()) | 121 if (!core_thread_.Start()) |
| 115 return; | 122 return; |
| 116 bookmark_model_worker_ = new BookmarkModelWorker(frontend_loop_); | 123 registrar_.workers[GROUP_UI] = new UIModelWorker(frontend_loop_); |
| 124 registrar_.routing_info[syncable::BOOKMARKS] = GROUP_UI; |
| 117 | 125 |
| 118 core_thread_.message_loop()->PostTask(FROM_HERE, | 126 core_thread_.message_loop()->PostTask(FROM_HERE, |
| 119 NewRunnableMethod(core_.get(), | 127 NewRunnableMethod(core_.get(), |
| 120 &SyncBackendHost::Core::DoInitializeForTest, | 128 &SyncBackendHost::Core::DoInitializeForTest, |
| 121 bookmark_model_worker_, | |
| 122 test_user, | 129 test_user, |
| 123 factory, | 130 factory, |
| 124 auth_factory)); | 131 auth_factory)); |
| 125 } | 132 } |
| 126 #endif | 133 #endif |
| 127 | 134 |
| 128 private: | 135 private: |
| 129 // The real guts of SyncBackendHost, to keep the public client API clean. | 136 // The real guts of SyncBackendHost, to keep the public client API clean. |
| 130 class Core : public base::RefCountedThreadSafe<SyncBackendHost::Core>, | 137 class Core : public base::RefCountedThreadSafe<SyncBackendHost::Core>, |
| 131 public sync_api::SyncManager::Observer { | 138 public sync_api::SyncManager::Observer { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 145 | 152 |
| 146 // Note: | 153 // Note: |
| 147 // | 154 // |
| 148 // The Do* methods are the various entry points from our SyncBackendHost. | 155 // The Do* methods are the various entry points from our SyncBackendHost. |
| 149 // It calls us on a dedicated thread to actually perform synchronous | 156 // It calls us on a dedicated thread to actually perform synchronous |
| 150 // (and potentially blocking) syncapi operations. | 157 // (and potentially blocking) syncapi operations. |
| 151 // | 158 // |
| 152 // Called on the SyncBackendHost core_thread_ to perform initialization | 159 // Called on the SyncBackendHost core_thread_ to perform initialization |
| 153 // of the syncapi on behalf of SyncBackendHost::Initialize. | 160 // of the syncapi on behalf of SyncBackendHost::Initialize. |
| 154 void DoInitialize(const GURL& service_url, | 161 void DoInitialize(const GURL& service_url, |
| 155 BookmarkModelWorker* bookmark_model_worker, | |
| 156 bool attempt_last_user_authentication, | 162 bool attempt_last_user_authentication, |
| 157 sync_api::HttpPostProviderFactory* http_bridge_factory, | 163 sync_api::HttpPostProviderFactory* http_bridge_factory, |
| 158 sync_api::HttpPostProviderFactory* auth_http_bridge_factory, | 164 sync_api::HttpPostProviderFactory* auth_http_bridge_factory, |
| 159 const std::string& lsid); | 165 const std::string& lsid); |
| 160 | 166 |
| 161 // Called on our SyncBackendHost's core_thread_ to perform authentication | 167 // Called on our SyncBackendHost's core_thread_ to perform authentication |
| 162 // on behalf of SyncBackendHost::Authenticate. | 168 // on behalf of SyncBackendHost::Authenticate. |
| 163 void DoAuthenticate(const std::string& username, | 169 void DoAuthenticate(const std::string& username, |
| 164 const std::string& password, | 170 const std::string& password, |
| 165 const std::string& captcha); | 171 const std::string& captcha); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 178 // Set the base request context to use when making HTTP calls. | 184 // Set the base request context to use when making HTTP calls. |
| 179 // This method will add a reference to the context to persist it | 185 // This method will add a reference to the context to persist it |
| 180 // on the IO thread. Must be removed from IO thread. | 186 // on the IO thread. Must be removed from IO thread. |
| 181 | 187 |
| 182 sync_api::SyncManager* syncapi() { return syncapi_.get(); } | 188 sync_api::SyncManager* syncapi() { return syncapi_.get(); } |
| 183 | 189 |
| 184 #if defined(UNIT_TEST) | 190 #if defined(UNIT_TEST) |
| 185 // Special form of initialization that does not try and authenticate the | 191 // Special form of initialization that does not try and authenticate the |
| 186 // last known user (since it will fail in test mode) and does some extra | 192 // last known user (since it will fail in test mode) and does some extra |
| 187 // setup to nudge the syncapi into a useable state. | 193 // setup to nudge the syncapi into a useable state. |
| 188 void DoInitializeForTest(BookmarkModelWorker* bookmark_model_worker, | 194 void DoInitializeForTest(const std::wstring& test_user, |
| 189 const std::wstring& test_user, | |
| 190 sync_api::HttpPostProviderFactory* factory, | 195 sync_api::HttpPostProviderFactory* factory, |
| 191 sync_api::HttpPostProviderFactory* auth_factory) { | 196 sync_api::HttpPostProviderFactory* auth_factory) { |
| 192 DoInitialize(GURL(), bookmark_model_worker, false, factory, | 197 DoInitialize(GURL(), false, factory, auth_factory, std::string()); |
| 193 auth_factory, std::string()); | |
| 194 syncapi_->SetupForTestMode(test_user); | 198 syncapi_->SetupForTestMode(test_user); |
| 195 } | 199 } |
| 196 #endif | 200 #endif |
| 197 | 201 |
| 198 private: | 202 private: |
| 199 friend class base::RefCountedThreadSafe<SyncBackendHost::Core>; | 203 friend class base::RefCountedThreadSafe<SyncBackendHost::Core>; |
| 200 | 204 |
| 201 // FrontendNotification defines parameters for NotifyFrontend. Each enum | 205 // FrontendNotification defines parameters for NotifyFrontend. Each enum |
| 202 // value corresponds to the one SyncFrontend interface method that | 206 // value corresponds to the one SyncFrontend interface method that |
| 203 // NotifyFrontend should invoke. | 207 // NotifyFrontend should invoke. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 241 | 245 |
| 242 // The timer used to periodically call SaveChanges. | 246 // The timer used to periodically call SaveChanges. |
| 243 base::RepeatingTimer<Core> save_changes_timer_; | 247 base::RepeatingTimer<Core> save_changes_timer_; |
| 244 | 248 |
| 245 // The top-level syncapi entry point. | 249 // The top-level syncapi entry point. |
| 246 scoped_ptr<sync_api::SyncManager> syncapi_; | 250 scoped_ptr<sync_api::SyncManager> syncapi_; |
| 247 | 251 |
| 248 DISALLOW_COPY_AND_ASSIGN(Core); | 252 DISALLOW_COPY_AND_ASSIGN(Core); |
| 249 }; | 253 }; |
| 250 | 254 |
| 255 UIModelWorker* ui_worker(); |
| 256 |
| 251 // A thread we dedicate for use by our Core to perform initialization, | 257 // A thread we dedicate for use by our Core to perform initialization, |
| 252 // authentication, handle messages from the syncapi, and periodically tell | 258 // authentication, handle messages from the syncapi, and periodically tell |
| 253 // the syncapi to persist itself. | 259 // the syncapi to persist itself. |
| 254 base::Thread core_thread_; | 260 base::Thread core_thread_; |
| 255 | 261 |
| 256 // Our core, which communicates directly to the syncapi. | 262 // Our core, which communicates directly to the syncapi. |
| 257 scoped_refptr<Core> core_; | 263 scoped_refptr<Core> core_; |
| 258 | 264 |
| 259 // A reference to the MessageLoop used to construct |this|, so we know how | 265 // A reference to the MessageLoop used to construct |this|, so we know how |
| 260 // to safely talk back to the SyncFrontend. | 266 // to safely talk back to the SyncFrontend. |
| 261 MessageLoop* const frontend_loop_; | 267 MessageLoop* const frontend_loop_; |
| 262 | 268 |
| 263 // We hold on to the BookmarkModelWorker created for the syncapi to ensure | 269 // This is state required to implement ModelSafeWorkerRegistrar. |
| 264 // shutdown occurs in the sequence we expect by calling Stop() at the | 270 struct { |
| 265 // appropriate time. It is guaranteed to be valid because the worker is | 271 // We maintain ownership of all workers. In some cases, we need to ensure |
| 266 // only destroyed when the SyncManager is destroyed, which happens when | 272 // shutdown occurs in an expected sequence by Stop()ing certain workers. |
| 267 // our Core is destroyed, which happens in Shutdown(). | 273 // They are guaranteed to be valid because we only destroy elements of |
| 268 BookmarkModelWorker* bookmark_model_worker_; | 274 // |workers_| after the syncapi has been destroyed. Unless a worker is no |
| 275 // longer needed because all types that get routed to it have been disabled |
| 276 // (from syncing). In that case, we'll destroy on demand *after* routing |
| 277 // any dependent types to GROUP_PASSIVE, so that the syncapi doesn't call |
| 278 // into garbage. If an index is non-NULL, it means at least one ModelType |
| 279 // that routes to that model safe group is being synced. |
| 280 browser_sync::ModelSafeWorker* |
| 281 workers[browser_sync::MODEL_SAFE_GROUP_COUNT]; |
| 282 browser_sync::ModelSafeRoutingInfo routing_info; |
| 283 } registrar_; |
| 284 |
| 285 // The user can incur changes to registrar_ at any time from the UI thread. |
| 286 // The syncapi needs to periodically get a consistent snapshot of the state, |
| 287 // and it does so from a different thread. Therefore, we protect creation, |
| 288 // destruction, and re-routing events by acquiring this lock. Note that the |
| 289 // SyncBackendHost may read (on the UI thread or core thread) from registrar_ |
| 290 // without acquiring the lock (which is typically "read ModelSafeWorker |
| 291 // pointer value", and then invoke methods), because lifetimes are managed on |
| 292 // the UI thread. Of course, this comment only applies to ModelSafeWorker |
| 293 // impls that are themselves thread-safe, such as UIModelWorker. |
| 294 Lock registrar_lock_; |
| 269 | 295 |
| 270 // The frontend which we serve (and are owned by). | 296 // The frontend which we serve (and are owned by). |
| 271 SyncFrontend* frontend_; | 297 SyncFrontend* frontend_; |
| 272 | 298 |
| 273 // The change processors that handle the different data types. | 299 // The change processors that handle the different data types. |
| 274 std::set<ChangeProcessor*> processors_; | 300 std::set<ChangeProcessor*> processors_; |
| 275 | 301 |
| 276 // Path of the folder that stores the sync data files. | 302 // Path of the folder that stores the sync data files. |
| 277 FilePath sync_data_folder_path_; | 303 FilePath sync_data_folder_path_; |
| 278 | 304 |
| 279 // UI-thread cache of the last AuthErrorState received from syncapi. | 305 // UI-thread cache of the last AuthErrorState received from syncapi. |
| 280 GoogleServiceAuthError last_auth_error_; | 306 GoogleServiceAuthError last_auth_error_; |
| 281 | 307 |
| 282 DISALLOW_COPY_AND_ASSIGN(SyncBackendHost); | 308 DISALLOW_COPY_AND_ASSIGN(SyncBackendHost); |
| 283 }; | 309 }; |
| 284 | 310 |
| 285 } // namespace browser_sync | 311 } // namespace browser_sync |
| 286 | 312 |
| 287 #endif // CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_ | 313 #endif // CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_ |
| OLD | NEW |