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

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

Issue 7633077: Refactor syncapi.h (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: This patch has compiled from a clean build 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_INTERNAL_API_SYNC_MANAGER_H_
6 #define CHROME_BROWSER_SYNC_INTERNAL_API_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 } // namespace base
24
25 namespace browser_sync {
26 class JsBackend;
27 class JsEventHandler;
28 class ModelSafeWorkerRegistrar;
29
30 namespace sessions {
31 struct SyncSessionSnapshot;
32 } // namespace sessions
33 } // namespace browser_sync
34
35 namespace sync_notifier {
36 class SyncNotifier;
37 } // namespace sync_notifier
38
39 namespace sync_pb {
40 class PasswordSpecificsData;
41 } // namespace sync_pb
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 // |js_backend| is what about:sync interacts with. It can emit
295 // the following events:
296
297 /**
298 * @param {{ enabled: boolean }} details A dictionary containing:
299 * - enabled: whether or not notifications are enabled.
300 */
301 // function onNotificationStateChange(details);
302
303 /**
304 * @param {{ changedTypes: Array.<string> }} details A dictionary
305 * containing:
306 * - changedTypes: a list of types (as strings) for which there
307 are new updates.
308 */
309 // function onIncomingNotification(details);
310
311 // Also, it responds to the following messages (all other messages
312 // are ignored):
313
314 /**
315 * Gets the current notification state.
316 *
317 * @param {function(boolean)} callback Called with whether or not
318 * notifications are enabled.
319 */
320 // function getNotificationState(callback);
321
322 /**
323 * Gets details about the root node.
324 *
325 * @param {function(!Object)} callback Called with details about the
326 * root node.
327 */
328 // TODO(akalin): Change this to getRootNodeId or eliminate it
329 // entirely.
330 // function getRootNodeDetails(callback);
331
332 /**
333 * Gets summary information for a list of ids.
334 *
335 * @param {Array.<string>} idList List of 64-bit ids in decimal
336 * string form.
337 * @param {Array.<{id: string, title: string, isFolder: boolean}>}
338 * callback Called with summaries for the nodes in idList that
339 * exist.
340 */
341 // function getNodeSummariesById(idList, callback);
342
343 /**
344 * Gets detailed information for a list of ids.
345 *
346 * @param {Array.<string>} idList List of 64-bit ids in decimal
347 * string form.
348 * @param {Array.<!Object>} callback Called with detailed
349 * information for the nodes in idList that exist.
350 */
351 // function getNodeDetailsById(idList, callback);
352
353 /**
354 * Gets child ids for a given id.
355 *
356 * @param {string} id 64-bit id in decimal string form of the parent
357 * node.
358 * @param {Array.<string>} callback Called with the (possibly empty)
359 * list of child ids.
360 */
361 // function getChildNodeIds(id);
362
363 virtual void OnInitializationComplete(
364 const browser_sync::WeakHandle<browser_sync::JsBackend>&
365 js_backend) = 0;
366
367 // We are no longer permitted to communicate with the server. Sync should
368 // be disabled and state cleaned up at once. This can happen for a number
369 // of reasons, e.g. swapping from a test instance to production, or a
370 // global stop syncing operation has wiped the store.
371 virtual void OnStopSyncingPermanently() = 0;
372
373 // After a request to clear server data, these callbacks are invoked to
374 // indicate success or failure.
375 virtual void OnClearServerDataSucceeded() = 0;
376 virtual void OnClearServerDataFailed() = 0;
377
378 // Called after we finish encrypting all appropriate datatypes.
379 virtual void OnEncryptionComplete(
380 const syncable::ModelTypeSet& encrypted_types) = 0;
381
382 protected:
383 virtual ~Observer();
384 };
385
386 typedef Callback0::Type ModeChangeCallback;
387
388 // Create an uninitialized SyncManager. Callers must Init() before using.
389 explicit SyncManager(const std::string& name);
390 virtual ~SyncManager();
391
392 // Initialize the sync manager. |database_location| specifies the path of
393 // the directory in which to locate a sqlite repository storing the syncer
394 // backend state. Initialization will open the database, or create it if it
395 // does not already exist. Returns false on failure.
396 // |event_handler| is the JsEventHandler used to propagate events to
397 // chrome://sync-internals. |event_handler| may be uninitialized.
398 // |sync_server_and_path| and |sync_server_port| represent the Chrome sync
399 // server to use, and |use_ssl| specifies whether to communicate securely;
400 // the default is false.
401 // |post_factory| will be owned internally and used to create
402 // instances of an HttpPostProvider.
403 // |model_safe_worker| ownership is given to the SyncManager.
404 // |user_agent| is a 7-bit ASCII string suitable for use as the User-Agent
405 // HTTP header. Used internally when collecting stats to classify clients.
406 // |sync_notifier| is owned and used to listen for notifications.
407 bool Init(const FilePath& database_location,
408 const browser_sync::WeakHandle<browser_sync::JsEventHandler>&
409 event_handler,
410 const std::string& sync_server_and_path,
411 int sync_server_port,
412 bool use_ssl,
413 HttpPostProviderFactory* post_factory,
414 browser_sync::ModelSafeWorkerRegistrar* registrar,
415 const std::string& user_agent,
416 const SyncCredentials& credentials,
417 sync_notifier::SyncNotifier* sync_notifier,
418 const std::string& restored_key_for_bootstrapping,
419 bool setup_for_test_mode);
420
421 // Returns the username last used for a successful authentication.
422 // Returns empty if there is no such username.
423 const std::string& GetAuthenticatedUsername();
424
425 // Check if the database has been populated with a full "initial" download of
426 // sync items for each data type currently present in the routing info.
427 // Prerequisite for calling this is that OnInitializationComplete has been
428 // called.
429 bool InitialSyncEndedForAllEnabledTypes();
430
431 // Update tokens that we're using in Sync. Email must stay the same.
432 void UpdateCredentials(const SyncCredentials& credentials);
433
434 // Called when the user disables or enables a sync type.
435 void UpdateEnabledTypes();
436
437 // Put the syncer in normal mode ready to perform nudges and polls.
438 void StartSyncingNormally();
439
440 // Attempt to set the passphrase. If the passphrase is valid,
441 // OnPassphraseAccepted will be fired to notify the ProfileSyncService and the
442 // syncer will be nudged so that any update that was waiting for this
443 // passphrase gets applied as soon as possible.
444 // If the passphrase in invalid, OnPassphraseRequired will be fired.
445 // Calling this metdod again is the appropriate course of action to "retry"
446 // with a new passphrase.
447 // |is_explicit| is true if the call is in response to the user explicitly
448 // setting a passphrase as opposed to implicitly (from the users' perspective)
449 // using their Google Account password. An implicit SetPassphrase will *not*
450 // *not* override an explicit passphrase set previously.
451 void SetPassphrase(const std::string& passphrase, bool is_explicit);
452
453 // Set the datatypes we want to encrypt and encrypt any nodes as necessary.
454 // Note: |encrypted_types| will be unioned with the current set of encrypted
455 // types, as we do not currently support decrypting datatypes.
456 void EncryptDataTypes(const syncable::ModelTypeSet& encrypted_types);
457
458 // Puts the SyncScheduler into a mode where no normal nudge or poll traffic
459 // will occur, but calls to RequestConfig will be supported. If |callback|
460 // is provided, it will be invoked (from the internal SyncScheduler) when
461 // the thread has changed to configuration mode.
462 void StartConfigurationMode(ModeChangeCallback* callback);
463
464 // Switches the mode of operation to CONFIGURATION_MODE and
465 // schedules a config task to fetch updates for |types|.
466 void RequestConfig(const syncable::ModelTypeBitSet& types,
467 sync_api::ConfigureReason reason);
468
469 void RequestCleanupDisabledTypes();
470
471 // Request a clearing of all data on the server
472 void RequestClearServerData();
473
474 // Adds a listener to be notified of sync events.
475 // NOTE: It is OK (in fact, it's probably a good idea) to call this before
476 // having received OnInitializationCompleted.
477 void AddObserver(Observer* observer);
478
479 // Remove the given observer. Make sure to call this if the
480 // Observer is being destroyed so the SyncManager doesn't
481 // potentially dereference garbage.
482 void RemoveObserver(Observer* observer);
483
484 // Status-related getters. Typically GetStatusSummary will suffice, but
485 // GetDetailedSyncStatus can be useful for gathering debug-level details of
486 // the internals of the sync engine.
487 Status::Summary GetStatusSummary() const;
488 Status GetDetailedStatus() const;
489
490 // Whether or not the Nigori node is encrypted using an explicit passphrase.
491 bool IsUsingExplicitPassphrase();
492
493 // Get the internal implementation for use by BaseTransaction, etc.
494 SyncInternal* GetImpl() const;
495
496 // Call periodically from a database-safe thread to persist recent changes
497 // to the syncapi model.
498 void SaveChanges();
499
500 void RequestEarlyExit();
501
502 // Issue a final SaveChanges, close sqlite handles, and stop running threads.
503 // Must be called from the same thread that called Init().
504 void Shutdown();
505
506 UserShare* GetUserShare() const;
507
508 // Inform the cryptographer of the most recent passphrase and set of encrypted
509 // types (from nigori node), then ensure all data that needs encryption is
510 // encrypted with the appropriate passphrase.
511 // Note: opens a transaction and can trigger ON_PASSPHRASE_REQUIRED, so must
512 // only be called after syncapi has been initialized.
513 void RefreshEncryption();
514
515 syncable::ModelTypeSet GetEncryptedDataTypes() const;
516
517 // Uses a read-only transaction to determine if the directory being synced has
518 // any remaining unsynced items.
519 bool HasUnsyncedItems() const;
520
521 // Logs the list of unsynced meta handles.
522 void LogUnsyncedItems(int level) const;
523
524 // Functions used for testing.
525
526 void TriggerOnNotificationStateChangeForTest(
527 bool notifications_enabled);
528
529 void TriggerOnIncomingNotificationForTest(
530 const syncable::ModelTypeBitSet& model_types);
531
532 private:
533 // An opaque pointer to the nested private class.
534 SyncInternal* data_;
535
536 DISALLOW_COPY_AND_ASSIGN(SyncManager);
537 };
538
539 bool InitialSyncEndedForTypes(syncable::ModelTypeSet types, UserShare* share);
540
541 // Returns the string representation of a PassphraseRequiredReason value.
542 std::string PassphraseRequiredReasonToString(PassphraseRequiredReason reason);
543
544 } // namespace sync_api
545
546 #endif // CHROME_BROWSER_SYNC_INTERNAL_API_SYNC_MANAGER_H_
OLDNEW
« no previous file with comments | « chrome/browser/sync/internal_api/read_transaction.cc ('k') | chrome/browser/sync/internal_api/sync_manager.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698