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

Side by Side Diff: chrome/browser/sync/glue/sync_backend_host.h

Issue 160542: Rolling back 22317 (Closed) Base URL: svn://chrome-svn.corp.google.com/chrome/trunk/src/
Patch Set: Created 11 years, 4 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
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #ifdef CHROME_PERSONALIZATION
6
7 #ifndef CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_
8 #define CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_
9
10 #include <string>
11
12 #include "base/file_path.h"
13 #include "base/lock.h"
14 #include "base/message_loop.h"
15 #include "base/ref_counted.h"
16 #include "base/thread.h"
17 #include "base/timer.h"
18 #include "chrome/browser/sync/auth_error_state.h"
19 #include "chrome/browser/sync/engine/syncapi.h"
20 #include "chrome/browser/sync/glue/bookmark_model_worker.h"
21 #include "googleurl/src/gurl.h"
22
23 namespace browser_sync {
24
25 class SyncFrontend;
26
27 // A UI-thread safe API into the sync backend that "hosts" the top-level
28 // syncapi element, the SyncManager, on its own thread. This class handles
29 // dispatch of potentially blocking calls to appropriate threads and ensures
30 // that the SyncFrontend is only accessed on the UI loop.
31 class SyncBackendHost {
32 public:
33 typedef sync_api::UserShare* UserShareHandle;
34 typedef sync_api::SyncManager::Status::Summary StatusSummary;
35 typedef sync_api::SyncManager::Status Status;
36
37 // Create a SyncBackendHost with a reference to the |frontend| that it serves
38 // and communicates to via the SyncFrontend interface (on the same thread
39 // it used to call the constructor).
40 SyncBackendHost(SyncFrontend* frontend, const FilePath& proifle_path);
41 ~SyncBackendHost();
42
43 // Called on |frontend_loop_| to kick off asynchronous initialization.
44 void Initialize(const GURL& service_url);
45
46 // Called on |frontend_loop_| to kick off asynchronous authentication.
47 void Authenticate(const std::string& username, const std::string& password);
48
49 // Called on |frontend_loop_| to kick off shutdown.
50 // |sync_disabled| indicates if syncing is being disabled or not.
51 // See the implementation and Core::DoShutdown for details.
52 void Shutdown(bool sync_disabled);
53
54 // Called on |frontend_loop_| to obtain a handle to the UserShare needed
55 // for creating transactions.
56 UserShareHandle GetUserShareHandle() const;
57
58 // Called from any thread to obtain current status information in detailed or
59 // summarized form.
60 Status GetDetailedStatus();
61 StatusSummary GetStatusSummary();
62 AuthErrorState GetAuthErrorState() const;
63
64 const FilePath& sync_data_folder_path() const {
65 return sync_data_folder_path_;
66 }
67
68 // Returns the authenticated username of the sync user, or empty if none
69 // exists. It will only exist if the authentication service provider (e.g
70 // GAIA) has confirmed the username is authentic.
71 string16 GetAuthenticatedUsername() const;
72
73 #ifdef UNIT_TEST
74 // Called from unit test to bypass authentication and initialize the syncapi
75 // to a state suitable for testing but not production.
76 void InitializeForTestMode(const std::wstring& test_user) {
77 if (!core_thread_.Start())
78 return;
79 bookmark_model_worker_ = new BookmarkModelWorker(frontend_loop_);
80 core_thread_.message_loop()->PostTask(FROM_HERE,
81 NewRunnableMethod(core_.get(),
82 &SyncBackendHost::Core::DoInitializeForTest,
83 bookmark_model_worker_,
84 test_user));
85 }
86 #endif
87
88 private:
89 // The real guts of SyncBackendHost, to keep the public client API clean.
90 class Core : public base::RefCountedThreadSafe<SyncBackendHost::Core>,
91 public sync_api::SyncManager::Observer {
92 public:
93 explicit Core(SyncBackendHost* backend);
94
95 // Note: This destructor should *always* be called from the thread that
96 // created it, and *always* after core_thread_ has exited. The syncapi
97 // watches thread exit events and keeps pointers to objects this dtor will
98 // destroy, so this ordering is important.
99 ~Core() {
100 }
101
102 // SyncManager::Observer implementation. The Core just acts like an air
103 // traffic controller here, forwarding incoming messages to appropriate
104 // landing threads.
105 virtual void OnChangesApplied(
106 const sync_api::BaseTransaction* trans,
107 const sync_api::SyncManager::ChangeRecord* changes,
108 int change_count);
109 virtual void OnSyncCycleCompleted();
110 virtual void OnInitializationComplete();
111 virtual void OnAuthProblem(
112 sync_api::SyncManager::AuthProblem auth_problem);
113
114 // Note:
115 //
116 // The Do* methods are the various entry points from our SyncBackendHost.
117 // It calls us on a dedicated thread to actually perform synchronous
118 // (and potentially blocking) syncapi operations.
119 //
120 // Called on the SyncBackendHost core_thread_ to perform initialization
121 // of the syncapi on behalf of SyncBackendHost::Initialize.
122 void DoInitialize(const GURL& service_url,
123 BookmarkModelWorker* bookmark_model_worker_,
124 bool attempt_last_user_authentication);
125
126 // Called on our SyncBackendHost's core_thread_ to perform authentication
127 // on behalf of SyncBackendHost::Authenticate.
128 void DoAuthenticate(const std::string& username,
129 const std::string& password);
130
131 // The shutdown order is a bit complicated:
132 // 1) From |core_thread_|, invoke the syncapi Shutdown call to do a final
133 // SaveChanges, close sqlite handles, and halt the syncer thread (which
134 // could potentially block for 1 minute).
135 // 2) Then, from |frontend_loop_|, halt the core_thread_. This causes
136 // syncapi thread-exit handlers to run and make use of cached pointers to
137 // various components owned implicitly by us.
138 // 3) Destroy this Core. That will delete syncapi components in a safe order
139 // because the thread that was using them has exited (in step 2).
140 void DoShutdown(bool stopping_sync);
141
142 sync_api::SyncManager* syncapi() { return syncapi_.get(); }
143
144 #ifdef UNIT_TEST
145 // Special form of initialization that does not try and authenticate the
146 // last known user (since it will fail in test mode) and does some extra
147 // setup to nudge the syncapi into a useable state.
148 void DoInitializeForTest(BookmarkModelWorker* bookmark_model_worker,
149 const std::wstring& test_user) {
150 DoInitialize(GURL(), bookmark_model_worker, false);
151 syncapi_->SetupForTestMode(WideToUTF16(test_user).c_str());
152 }
153 #endif
154
155 private:
156 // FrontendNotification defines parameters for NotifyFrontend. Each enum
157 // value corresponds to the one SyncFrontend interface method that
158 // NotifyFrontend should invoke.
159 enum FrontendNotification {
160 INITIALIZED, // OnBackendInitialized.
161 SYNC_CYCLE_COMPLETED, // A round-trip sync-cycle took place and
162 // the syncer has resolved any conflicts
163 // that may have arisen.
164 };
165
166 // NotifyFrontend is how the Core communicates with the frontend across
167 // threads. Having this extra method (rather than having the Core PostTask
168 // to the frontend explicitly) means SyncFrontend implementations don't
169 // need to be RefCountedThreadSafe because NotifyFrontend is invoked on the
170 // |frontend_loop_|.
171 void NotifyFrontend(FrontendNotification notification);
172
173 // Invoked when initialization of syncapi is complete and we can start
174 // our timer.
175 // This must be called from the thread on which SaveChanges is intended to
176 // be run on; the host's |core_thread_|.
177 void StartSavingChanges();
178
179 // Invoked periodically to tell the syncapi to persist its state
180 // by writing to disk.
181 // This is called from the thread we were created on (which is the
182 // SyncBackendHost |core_thread_|), using a repeating timer that is kicked
183 // off as soon as the SyncManager tells us it completed
184 // initialization.
185 void SaveChanges();
186
187 // Dispatched to from HandleAuthErrorEventOnCoreLoop to handle updating
188 // frontend UI components.
189 void HandleAuthErrorEventOnFrontendLoop(AuthErrorState new_auth_error);
190
191 // Our parent SyncBackendHost
192 SyncBackendHost* host_;
193
194 // The timer used to periodically call SaveChanges.
195 base::RepeatingTimer<Core> save_changes_timer_;
196
197 // The top-level syncapi entry point.
198 scoped_ptr<sync_api::SyncManager> syncapi_;
199
200 DISALLOW_COPY_AND_ASSIGN(Core);
201 };
202
203 // A thread we dedicate for use by our Core to perform initialization,
204 // authentication, handle messages from the syncapi, and periodically tell
205 // the syncapi to persist itself.
206 base::Thread core_thread_;
207
208 // Our core, which communicates directly to the syncapi.
209 scoped_refptr<Core> core_;
210
211 // A reference to the MessageLoop used to construct |this|, so we know how
212 // to safely talk back to the SyncFrontend.
213 MessageLoop* const frontend_loop_;
214
215 // We hold on to the BookmarkModelWorker created for the syncapi to ensure
216 // shutdown occurs in the sequence we expect by calling Stop() at the
217 // appropriate time. It is guaranteed to be valid because the worker is
218 // only destroyed when the SyncManager is destroyed, which happens when
219 // our Core is destroyed, which happens in Shutdown().
220 BookmarkModelWorker* bookmark_model_worker_;
221
222 // The frontend which we serve (and are owned by).
223 SyncFrontend* frontend_;
224
225 // Path of the folder that stores the sync data files.
226 FilePath sync_data_folder_path_;
227
228 // UI-thread cache of the last AuthErrorState received from syncapi.
229 AuthErrorState last_auth_error_;
230
231 DISALLOW_COPY_AND_ASSIGN(SyncBackendHost);
232 };
233
234 // SyncFrontend is the interface used by SyncBackendHost to communicate with
235 // the entity that created it and, presumably, is interested in sync-related
236 // activity.
237 // NOTE: All methods will be invoked by a SyncBackendHost on the same thread
238 // used to create that SyncBackendHost.
239 class SyncFrontend {
240 public:
241 typedef sync_api::BaseTransaction BaseTransaction;
242 typedef sync_api::SyncManager::ChangeRecord ChangeRecord;
243 SyncFrontend() {
244 }
245
246 // The backend has completed initialization and it is now ready to accept and
247 // process changes.
248 virtual void OnBackendInitialized() = 0;
249
250 // The backend queried the server recently and received some updates.
251 virtual void OnSyncCycleCompleted() = 0;
252
253 // The backend encountered an authentication problem and requests new
254 // credentials to be provided. See SyncBackendHost::Authenticate for details.
255 virtual void OnAuthError() = 0;
256
257 // Changes have been applied to the backend model and are ready to be
258 // applied to the frontend model. See syncapi.h for detailed instructions on
259 // how to interpret and process |changes|.
260 virtual void ApplyModelChanges(const BaseTransaction* trans,
261 const ChangeRecord* changes,
262 int change_count) = 0;
263 protected:
264 // Don't delete through SyncFrontend interface.
265 virtual ~SyncFrontend() {
266 }
267 private:
268 DISALLOW_COPY_AND_ASSIGN(SyncFrontend);
269 };
270
271 } // namespace browser_sync
272
273 #endif // CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_
274 #endif // CHROME_PERSONALIZATION
OLDNEW
« no previous file with comments | « chrome/browser/sync/glue/model_associator.cc ('k') | chrome/browser/sync/glue/sync_backend_host.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698