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

Side by Side Diff: chrome/browser/sync/engine/sync_manager.h

Issue 7633077: Refactor syncapi.h (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Created 9 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 | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 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 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNC_MANAGER_H_
6 #define CHROME_BROWSER_SYNC_ENGINE_SYNC_MANAGER_H_
7
8 #include <string>
9
10 #include "base/basictypes.h"
11 #include "base/callback_old.h"
12 #include "base/memory/linked_ptr.h"
13 #include "chrome/browser/sync/engine/configure_reason.h"
14 #include "chrome/browser/sync/protocol/password_specifics.pb.h"
15 #include "chrome/browser/sync/syncable/model_type.h"
16 #include "chrome/browser/sync/weak_handle.h"
17 #include "chrome/common/net/gaia/google_service_auth_error.h"
18
19 class FilePath;
20
21 namespace base {
22 class DictionaryValue;
23 }
tim (not reviewing) 2011/08/15 22:53:55 // namespace base
rlarocque 2011/08/16 18:12:46 Done.
24
25 namespace browser_sync {
26 class JsBackend;
27 class JsEventHandler;
28 class ModelSafeWorkerRegistrar;
29
30 namespace sessions {
31 struct SyncSessionSnapshot;
32 }
tim (not reviewing) 2011/08/15 22:53:55 } // namespace sessions } // namespace browser_s
rlarocque 2011/08/16 18:12:46 Done.
33 }
34
35 namespace sync_notifier {
36 class SyncNotifier;
37 } // namespace sync_notifier
38
tim (not reviewing) 2011/08/15 22:53:55 // namespace sync_notifier
rlarocque 2011/08/16 18:12:46 Done.
39 namespace sync_pb {
40 class PasswordSpecificsData;
41 }
tim (not reviewing) 2011/08/15 22:53:55 namespace sync_pb
rlarocque 2011/08/16 18:12:46 Done.
42
43 namespace sync_api {
44
45 class BaseTransaction;
46 class HttpPostProviderFactory;
47 class UserShare;
48
49 // Reasons due to which browser_sync::Cryptographer might require a passphrase.
50 enum PassphraseRequiredReason {
51 REASON_PASSPHRASE_NOT_REQUIRED = 0, // Initial value.
52 REASON_ENCRYPTION = 1, // The cryptographer requires a
53 // passphrase for its first attempt at
54 // encryption. Happens only during
55 // migration or upgrade.
56 REASON_DECRYPTION = 2, // The cryptographer requires a
57 // passphrase for its first attempt at
58 // decryption.
59 REASON_SET_PASSPHRASE_FAILED = 3, // The cryptographer requires a new
60 // passphrase because its attempt at
61 // decryption with the cached passphrase
62 // was unsuccessful.
63 };
64
65 // Contains everything needed to talk to and identify a user account.
66 struct SyncCredentials {
67 std::string email;
68 std::string sync_token;
69 };
70
71 // SyncManager encapsulates syncable::DirectoryManager and serves as the parent
72 // of all other objects in the sync API. SyncManager is thread-safe. If
73 // multiple threads interact with the same local sync repository (i.e. the
74 // same sqlite database), they should share a single SyncManager instance. The
75 // caller should typically create one SyncManager for the lifetime of a user
76 // session.
77 class SyncManager {
78 public:
79 // SyncInternal contains the implementation of SyncManager, while abstracting
80 // internal types from clients of the interface.
81 class SyncInternal;
82
83 // TODO(zea): One day get passwords playing nicely with the rest of encryption
84 // and get rid of this.
85 class ExtraPasswordChangeRecordData {
86 public:
87 ExtraPasswordChangeRecordData();
88 explicit ExtraPasswordChangeRecordData(
89 const sync_pb::PasswordSpecificsData& data);
90 virtual ~ExtraPasswordChangeRecordData();
91
92 // Transfers ownership of the DictionaryValue to the caller.
93 virtual base::DictionaryValue* ToValue() const;
94
95 const sync_pb::PasswordSpecificsData& unencrypted() const;
96 private:
97 sync_pb::PasswordSpecificsData unencrypted_;
98 };
99
100 // ChangeRecord indicates a single item that changed as a result of a sync
101 // operation. This gives the sync id of the node that changed, and the type
102 // of change. To get the actual property values after an ADD or UPDATE, the
103 // client should get the node with InitByIdLookup(), using the provided id.
104 struct ChangeRecord {
105 enum Action {
106 ACTION_ADD,
107 ACTION_DELETE,
108 ACTION_UPDATE,
109 };
110 ChangeRecord();
111 ~ChangeRecord();
112
113 // Transfers ownership of the DictionaryValue to the caller.
114 base::DictionaryValue* ToValue(const BaseTransaction* trans) const;
115
116 int64 id;
117 Action action;
118 sync_pb::EntitySpecifics specifics;
119 linked_ptr<ExtraPasswordChangeRecordData> extra;
120 };
121
122 // Status encapsulates detailed state about the internals of the SyncManager.
123 struct Status {
124 // Summary is a distilled set of important information that the end-user may
125 // wish to be informed about (through UI, for example). Note that if a
126 // summary state requires user interaction (such as auth failures), more
127 // detailed information may be contained in additional status fields.
128 enum Summary {
129 // The internal instance is in an unrecognizable state. This should not
130 // happen.
131 INVALID = 0,
132 // Can't connect to server, but there are no pending changes in
133 // our local cache.
134 OFFLINE,
135 // Can't connect to server, and there are pending changes in our
136 // local cache.
137 OFFLINE_UNSYNCED,
138 // Connected and syncing.
139 SYNCING,
140 // Connected, no pending changes.
141 READY,
142 // Internal sync error.
143 CONFLICT,
144 // Can't connect to server, and we haven't completed the initial
145 // sync yet. So there's nothing we can do but wait for the server.
146 OFFLINE_UNUSABLE,
147
148 SUMMARY_STATUS_COUNT,
149 };
150
151 Status();
152 ~Status();
153
154 Summary summary;
155 bool authenticated; // Successfully authenticated via GAIA.
156 bool server_up; // True if we have received at least one good
157 // reply from the server.
158 bool server_reachable; // True if we received any reply from the server.
159 bool server_broken; // True of the syncer is stopped because of server
160 // issues.
161 bool notifications_enabled; // True only if subscribed for notifications.
162
163 // Notifications counters updated by the actions in synapi.
164 int notifications_received;
165 int notifiable_commits;
166
167 // The max number of consecutive errors from any component.
168 int max_consecutive_errors;
169
170 int unsynced_count;
171
172 int conflicting_count;
173 bool syncing;
174 // True after a client has done a first sync.
175 bool initial_sync_ended;
176 // True if any syncer is stuck.
177 bool syncer_stuck;
178
179 // Total updates available. If zero, nothing left to download.
180 int64 updates_available;
181 // Total updates received by the syncer since browser start.
182 int updates_received;
183
184 // Of updates_received, how many were tombstones.
185 int tombstone_updates_received;
186 bool disk_full;
187
188 // Total number of overwrites due to conflict resolver since browser start.
189 int num_local_overwrites_total;
190 int num_server_overwrites_total;
191
192 // Count of empty and non empty getupdates;
193 int nonempty_get_updates;
194 int empty_get_updates;
195
196 // Count of useless and useful syncs we perform.
197 int useless_sync_cycles;
198 int useful_sync_cycles;
199
200 // Encryption related.
201 syncable::ModelTypeSet encrypted_types;
202 bool cryptographer_ready;
203 bool crypto_has_pending_keys;
204 };
205
206 // An interface the embedding application implements to receive notifications
207 // from the SyncManager. Register an observer via SyncManager::AddObserver.
208 // This observer is an event driven model as the events may be raised from
209 // different internal threads, and simply providing an "OnStatusChanged" type
210 // notification complicates things such as trying to determine "what changed",
211 // if different members of the Status object are modified from different
212 // threads. This way, the event is explicit, and it is safe for the Observer
213 // to dispatch to a native thread or synchronize accordingly.
214 class Observer {
215 public:
216 // Notify the observer that changes have been applied to the sync model.
217 //
218 // This will be invoked on the same thread as on which ApplyChanges was
219 // called. |changes| is an array of size |change_count|, and contains the
220 // ID of each individual item that was changed. |changes| exists only for
221 // the duration of the call. If items of multiple data types change at
222 // the same time, this method is invoked once per data type and |changes|
223 // is restricted to items of the ModelType indicated by |model_type|.
224 // Because the observer is passed a |trans|, the observer can assume a
225 // read lock on the sync model that will be released after the function
226 // returns.
227 //
228 // The SyncManager constructs |changes| in the following guaranteed order:
229 //
230 // 1. Deletions, from leaves up to parents.
231 // 2. Updates to existing items with synced parents & predecessors.
232 // 3. New items with synced parents & predecessors.
233 // 4. Items with parents & predecessors in |changes|.
234 // 5. Repeat #4 until all items are in |changes|.
235 //
236 // Thus, an implementation of OnChangesApplied should be able to
237 // process the change records in the order without having to worry about
238 // forward dependencies. But since deletions come before reparent
239 // operations, a delete may temporarily orphan a node that is
240 // updated later in the list.
241 virtual void OnChangesApplied(syncable::ModelType model_type,
242 const BaseTransaction* trans,
243 const ChangeRecord* changes,
244 int change_count) = 0;
245
246 // OnChangesComplete gets called when the TransactionComplete event is
247 // posted (after OnChangesApplied finishes), after the transaction lock
248 // and the change channel mutex are released.
249 //
250 // The purpose of this function is to support processors that require
251 // split-transactions changes. For example, if a model processor wants to
252 // perform blocking I/O due to a change, it should calculate the changes
253 // while holding the transaction lock (from within OnChangesApplied), buffer
254 // those changes, let the transaction fall out of scope, and then commit
255 // those changes from within OnChangesComplete (postponing the blocking
256 // I/O to when it no longer holds any lock).
257 virtual void OnChangesComplete(syncable::ModelType model_type) = 0;
258
259 // A round-trip sync-cycle took place and the syncer has resolved any
260 // conflicts that may have arisen.
261 virtual void OnSyncCycleCompleted(
262 const browser_sync::sessions::SyncSessionSnapshot* snapshot) = 0;
263
264 // Called when user interaction may be required due to an auth problem.
265 virtual void OnAuthError(const GoogleServiceAuthError& auth_error) = 0;
266
267 // Called when a new auth token is provided by the sync server.
268 virtual void OnUpdatedToken(const std::string& token) = 0;
269
270 // Called when user interaction is required to obtain a valid passphrase.
271 // - If the passphrase is required for encryption, |reason| will be
272 // REASON_ENCRYPTION.
273 // - If the passphrase is required for the decryption of data that has
274 // already been encrypted, |reason| will be REASON_DECRYPTION.
275 // - If the passphrase is required because decryption failed, and a new
276 // passphrase is required, |reason| will be REASON_SET_PASSPHRASE_FAILED.
277 virtual void OnPassphraseRequired(PassphraseRequiredReason reason) = 0;
278
279 // Called when the passphrase provided by the user has been accepted and is
280 // now used to encrypt sync data. |bootstrap_token| is an opaque base64
281 // encoded representation of the key generated by the accepted passphrase,
282 // and is provided to the observer for persistence purposes and use in a
283 // future initialization of sync (e.g. after restart).
284 virtual void OnPassphraseAccepted(const std::string& bootstrap_token) = 0;
285
286 // Called when initialization is complete to the point that SyncManager can
287 // process changes. This does not necessarily mean authentication succeeded
288 // or that the SyncManager is online.
289 // IMPORTANT: Creating any type of transaction before receiving this
290 // notification is illegal!
291 // WARNING: Calling methods on the SyncManager before receiving this
292 // message, unless otherwise specified, produces undefined behavior.
293 //
294 // The given backend can emit the following events:
295
296 /**
297 * @param {{ enabled: boolean }} details A dictionary containing:
298 * - enabled: whether or not notifications are enabled.
299 */
300 // function onNotificationStateChange(details);
301
302 /**
303 * @param {{ changedTypes: Array.<string> }} details A dictionary
304 * containing:
305 * - changedTypes: a list of types (as strings) for which there
306 are new updates.
307 */
308 // function onIncomingNotification(details);
309
310 // The given backend responds to the following messages (all other
311 // messages are ignored):
312
313 /**
314 * Gets the current notification state.
315 *
316 * @param {function(boolean)} callback Called with whether or not
317 * notifications are enabled.
318 */
319 // function getNotificationState(callback);
320
321 /**
322 * Gets details about the root node.
323 *
324 * @param {function(!Object)} callback Called with details about the
325 * root node.
326 */
327 // TODO(akalin): Change this to getRootNodeId or eliminate it
328 // entirely.
329 // function getRootNodeDetails(callback);
330
331 /**
332 * Gets summary information for a list of ids.
333 *
334 * @param {Array.<string>} idList List of 64-bit ids in decimal
335 * string form.
336 * @param {Array.<{id: string, title: string, isFolder: boolean}>}
337 * callback Called with summaries for the nodes in idList that
338 * exist.
339 */
340 // function getNodeSummariesById(idList, callback);
341
342 /**
343 * Gets detailed information for a list of ids.
344 *
345 * @param {Array.<string>} idList List of 64-bit ids in decimal
346 * string form.
347 * @param {Array.<!Object>} callback Called with detailed
348 * information for the nodes in idList that exist.
349 */
350 // function getNodeDetailsById(idList, callback);
351
352 /**
353 * Gets child ids for a given id.
354 *
355 * @param {string} id 64-bit id in decimal string form of the parent
356 * node.
357 * @param {Array.<string>} callback Called with the (possibly empty)
358 * list of child ids.
359 */
360 // function getChildNodeIds(id);
361
362 virtual void OnInitializationComplete(
363 const browser_sync::WeakHandle<browser_sync::JsBackend>&
364 js_backend) = 0;
365
366 // We are no longer permitted to communicate with the server. Sync should
367 // be disabled and state cleaned up at once. This can happen for a number
368 // of reasons, e.g. swapping from a test instance to production, or a
369 // global stop syncing operation has wiped the store.
370 virtual void OnStopSyncingPermanently() = 0;
371
372 // After a request to clear server data, these callbacks are invoked to
373 // indicate success or failure.
374 virtual void OnClearServerDataSucceeded() = 0;
375 virtual void OnClearServerDataFailed() = 0;
376
377 // Called after we finish encrypting all appropriate datatypes.
378 virtual void OnEncryptionComplete(
379 const syncable::ModelTypeSet& encrypted_types) = 0;
380
381 protected:
382 virtual ~Observer();
383 };
384
385 typedef Callback0::Type ModeChangeCallback;
386
387 // Create an uninitialized SyncManager. Callers must Init() before using.
388 explicit SyncManager(const std::string& name);
389 virtual ~SyncManager();
390
391 // Initialize the sync manager. |database_location| specifies the path of
392 // the directory in which to locate a sqlite repository storing the syncer
393 // backend state. Initialization will open the database, or create it if it
394 // does not already exist. Returns false on failure.
395 // |event_handler| is the JsEventHandler used to propagate events to
396 // chrome://sync-internals. |event_handler| may be uninitialized.
397 // |sync_server_and_path| and |sync_server_port| represent the Chrome sync
398 // server to use, and |use_ssl| specifies whether to communicate securely;
399 // the default is false.
400 // |post_factory| will be owned internally and used to create
401 // instances of an HttpPostProvider.
402 // |model_safe_worker| ownership is given to the SyncManager.
403 // |user_agent| is a 7-bit ASCII string suitable for use as the User-Agent
404 // HTTP header. Used internally when collecting stats to classify clients.
405 // |sync_notifier| is owned and used to listen for notifications.
406 bool Init(const FilePath& database_location,
407 const browser_sync::WeakHandle<browser_sync::JsEventHandler>&
408 event_handler,
409 const std::string& sync_server_and_path,
410 int sync_server_port,
411 bool use_ssl,
412 HttpPostProviderFactory* post_factory,
413 browser_sync::ModelSafeWorkerRegistrar* registrar,
414 const std::string& user_agent,
415 const SyncCredentials& credentials,
416 sync_notifier::SyncNotifier* sync_notifier,
417 const std::string& restored_key_for_bootstrapping,
418 bool setup_for_test_mode);
419
420 // Returns the username last used for a successful authentication.
421 // Returns empty if there is no such username.
422 const std::string& GetAuthenticatedUsername();
423
424 // Check if the database has been populated with a full "initial" download of
425 // sync items for each data type currently present in the routing info.
426 // Prerequisite for calling this is that OnInitializationComplete has been
427 // called.
428 bool InitialSyncEndedForAllEnabledTypes();
429
430 // Update tokens that we're using in Sync. Email must stay the same.
431 void UpdateCredentials(const SyncCredentials& credentials);
432
433 // Called when the user disables or enables a sync type.
434 void UpdateEnabledTypes();
435
436 // Put the syncer in normal mode ready to perform nudges and polls.
437 void StartSyncingNormally();
438
439 // Attempt to set the passphrase. If the passphrase is valid,
440 // OnPassphraseAccepted will be fired to notify the ProfileSyncService and the
441 // syncer will be nudged so that any update that was waiting for this
442 // passphrase gets applied as soon as possible.
443 // If the passphrase in invalid, OnPassphraseRequired will be fired.
444 // Calling this metdod again is the appropriate course of action to "retry"
445 // with a new passphrase.
446 // |is_explicit| is true if the call is in response to the user explicitly
447 // setting a passphrase as opposed to implicitly (from the users' perspective)
448 // using their Google Account password. An implicit SetPassphrase will *not*
449 // *not* override an explicit passphrase set previously.
450 void SetPassphrase(const std::string& passphrase, bool is_explicit);
451
452 // Set the datatypes we want to encrypt and encrypt any nodes as necessary.
453 // Note: |encrypted_types| will be unioned with the current set of encrypted
454 // types, as we do not currently support decrypting datatypes.
455 void EncryptDataTypes(const syncable::ModelTypeSet& encrypted_types);
456
457 // Puts the SyncScheduler into a mode where no normal nudge or poll traffic
458 // will occur, but calls to RequestConfig will be supported. If |callback|
459 // is provided, it will be invoked (from the internal SyncScheduler) when
460 // the thread has changed to configuration mode.
461 void StartConfigurationMode(ModeChangeCallback* callback);
462
463 // Switches the mode of operation to CONFIGURATION_MODE and
464 // schedules a config task to fetch updates for |types|.
465 void RequestConfig(const syncable::ModelTypeBitSet& types,
466 sync_api::ConfigureReason reason);
467
468 void RequestCleanupDisabledTypes();
469
470 // Request a clearing of all data on the server
471 void RequestClearServerData();
472
473 // Adds a listener to be notified of sync events.
474 // NOTE: It is OK (in fact, it's probably a good idea) to call this before
475 // having received OnInitializationCompleted.
476 void AddObserver(Observer* observer);
477
478 // Remove the given observer. Make sure to call this if the
479 // Observer is being destroyed so the SyncManager doesn't
480 // potentially dereference garbage.
481 void RemoveObserver(Observer* observer);
482
483 // Status-related getters. Typically GetStatusSummary will suffice, but
484 // GetDetailedSyncStatus can be useful for gathering debug-level details of
485 // the internals of the sync engine.
486 Status::Summary GetStatusSummary() const;
487 Status GetDetailedStatus() const;
488
489 // Whether or not the Nigori node is encrypted using an explicit passphrase.
490 bool IsUsingExplicitPassphrase();
491
492 // Get the internal implementation for use by BaseTransaction, etc.
493 SyncInternal* GetImpl() const;
494
495 // Call periodically from a database-safe thread to persist recent changes
496 // to the syncapi model.
497 void SaveChanges();
498
499 void RequestEarlyExit();
500
501 // Issue a final SaveChanges, close sqlite handles, and stop running threads.
502 // Must be called from the same thread that called Init().
503 void Shutdown();
504
505 UserShare* GetUserShare() const;
506
507 // Inform the cryptographer of the most recent passphrase and set of encrypted
508 // types (from nigori node), then ensure all data that needs encryption is
509 // encrypted with the appropriate passphrase.
510 // Note: opens a transaction and can trigger ON_PASSPHRASE_REQUIRED, so must
511 // only be called after syncapi has been initialized.
512 void RefreshEncryption();
513
514 syncable::ModelTypeSet GetEncryptedDataTypes() const;
515
516 // Uses a read-only transaction to determine if the directory being synced has
517 // any remaining unsynced items.
518 bool HasUnsyncedItems() const;
519
520 // Logs the list of unsynced meta handles.
521 void LogUnsyncedItems(int level) const;
522
523 // Functions used for testing.
524
525 void TriggerOnNotificationStateChangeForTest(
526 bool notifications_enabled);
527
528 void TriggerOnIncomingNotificationForTest(
529 const syncable::ModelTypeBitSet& model_types);
530
531 private:
532 // An opaque pointer to the nested private class.
533 SyncInternal* data_;
534
535 DISALLOW_COPY_AND_ASSIGN(SyncManager);
536 };
537
538 } // namespace sync_api
539
540 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNC_MANAGER_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698