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 // This file defines the "sync API", an interface to the syncer 6 // backend that exposes (1) the core functionality of maintaining a consistent 7 // local snapshot of a hierarchical object set; (2) a means to transactionally 8 // access and modify those objects; (3) a means to control client/server 9 // synchronization tasks, namely: pushing local object modifications to a 10 // server, pulling nonlocal object modifications from a server to this client, 11 // and resolving conflicts that may arise between the two; and (4) an 12 // abstraction of some external functionality that is to be provided by the 13 // host environment. 14 // 15 // This interface is used as the entry point into the syncer backend 16 // when the backend is compiled as a library and embedded in another 17 // application. A goal for this interface layer is to depend on very few 18 // external types, so that an application can use the sync backend 19 // without introducing a dependency on specific types. A non-goal is to 20 // have binary compatibility across versions or compilers; this allows the 21 // interface to use C++ classes. An application wishing to use the sync API 22 // should ideally compile the syncer backend and this API as part of the 23 // application's own build, to avoid e.g. mismatches in calling convention, 24 // structure padding, or name mangling that could arise if there were a 25 // compiler mismatch. 26 // 27 // The schema of the objects in the sync domain is based on the model, which 28 // is essentially a hierarchy of items and folders similar to a filesystem, 29 // but with a few important differences. The sync API contains fields 30 // such as URL to easily allow the embedding application to store web 31 // browser bookmarks. Also, the sync API allows duplicate titles in a parent. 32 // Consequently, it does not support looking up an object by title 33 // and parent, since such a lookup is not uniquely determined. Lastly, 34 // unlike a filesystem model, objects in the Sync API model have a strict 35 // ordering within a parent; the position is manipulable by callers, and 36 // children of a node can be enumerated in the order of their position. 37 38 #ifndef CHROME_BROWSER_SYNC_ENGINE_SYNCAPI_H_ 39 #define CHROME_BROWSER_SYNC_ENGINE_SYNCAPI_H_ 40 #pragma once 41 42 #include <string> 43 #include <vector> 44 45 #include "base/basictypes.h" 46 #include "base/callback.h" 47 #include "base/gtest_prod_util.h" 48 #include "base/memory/scoped_ptr.h" 49 #include "base/tracked.h" 50 #include "build/build_config.h" 51 #include "chrome/browser/sync/protocol/password_specifics.pb.h" 52 #include "chrome/browser/sync/syncable/autofill_migration.h" 53 #include "chrome/browser/sync/syncable/model_type.h" 54 #include "chrome/browser/sync/util/cryptographer.h" 55 #include "chrome/common/net/gaia/google_service_auth_error.h" 56 #include "googleurl/src/gurl.h" 57 58 class DictionaryValue; 59 class FilePath; 60 61 namespace browser_sync { 62 class JsBackend; 63 class ModelSafeWorkerRegistrar; 64 65 namespace sessions { 66 struct SyncSessionSnapshot; 67 } 68 } 69 70 namespace sync_notifier { 71 class SyncNotifier; 72 } // namespace sync_notifier 73 74 // Forward declarations of internal class types so that sync API objects 75 // may have opaque pointers to these types. 76 namespace syncable { 77 class BaseTransaction; 78 class DirectoryManager; 79 class Entry; 80 class MutableEntry; 81 class ReadTransaction; 82 class ScopedDirLookup; 83 class WriteTransaction; 84 } 85 86 namespace sync_pb { 87 class AppSpecifics; 88 class AutofillSpecifics; 89 class AutofillProfileSpecifics; 90 class BookmarkSpecifics; 91 class EntitySpecifics; 92 class ExtensionSpecifics; 93 class SessionSpecifics; 94 class NigoriSpecifics; 95 class PasswordSpecifics; 96 class PreferenceSpecifics; 97 class PasswordSpecifics; 98 class PasswordSpecificsData; 99 class ThemeSpecifics; 100 class TypedUrlSpecifics; 101 } 102 103 namespace sync_api { 104 105 class BaseTransaction; 106 class HttpPostProviderFactory; 107 class SyncManager; 108 class WriteTransaction; 109 110 // A UserShare encapsulates the syncable pieces that represent an authenticated 111 // user and their data (share). 112 // This encompasses all pieces required to build transaction objects on the 113 // syncable share. 114 struct UserShare { 115 UserShare(); 116 ~UserShare(); 117 118 // The DirectoryManager itself, which is the parent of Transactions and can 119 // be shared across multiple threads (unlike Directory). 120 scoped_ptr<syncable::DirectoryManager> dir_manager; 121 122 // The username of the sync user. 123 std::string name; 124 }; 125 126 // Contains everything needed to talk to and identify a user account. 127 struct SyncCredentials { 128 std::string email; 129 std::string sync_token; 130 }; 131 132 // A valid BaseNode will never have an ID of zero. 133 static const int64 kInvalidId = 0; 134 135 // BaseNode wraps syncable::Entry, and corresponds to a single object's state. 136 // This, like syncable::Entry, is intended for use on the stack. A valid 137 // transaction is necessary to create a BaseNode or any of its children. 138 // Unlike syncable::Entry, a sync API BaseNode is identified primarily by its 139 // int64 metahandle, which we call an ID here. 140 class BaseNode { 141 public: 142 // All subclasses of BaseNode must provide a way to initialize themselves by 143 // doing an ID lookup. Returns false on failure. An invalid or deleted 144 // ID will result in failure. 145 virtual bool InitByIdLookup(int64 id) = 0; 146 147 // All subclasses of BaseNode must also provide a way to initialize themselves 148 // by doing a client tag lookup. Returns false on failure. A deleted node 149 // will return FALSE. 150 virtual bool InitByClientTagLookup(syncable::ModelType model_type, 151 const std::string& tag) = 0; 152 153 // Each object is identified by a 64-bit id (internally, the syncable 154 // metahandle). These ids are strictly local handles. They will persist 155 // on this client, but the same object on a different client may have a 156 // different ID value. 157 virtual int64 GetId() const; 158 159 // Returns the modification time of the object (in TimeTicks internal format). 160 int64 GetModificationTime() const; 161 162 // Nodes are hierarchically arranged into a single-rooted tree. 163 // InitByRootLookup on ReadNode allows access to the root. GetParentId is 164 // how you find a node's parent. 165 int64 GetParentId() const; 166 167 // Nodes are either folders or not. This corresponds to the IS_DIR property 168 // of syncable::Entry. 169 bool GetIsFolder() const; 170 171 // Returns the title of the object. 172 // Uniqueness of the title is not enforced on siblings -- it is not an error 173 // for two children to share a title. 174 std::wstring GetTitle() const; 175 176 // Returns the model type of this object. The model type is set at node 177 // creation time and is expected never to change. 178 syncable::ModelType GetModelType() const; 179 180 // Getter specific to the BOOKMARK datatype. Returns protobuf 181 // data. Can only be called if GetModelType() == BOOKMARK. 182 const sync_pb::BookmarkSpecifics& GetBookmarkSpecifics() const; 183 184 // Legacy, bookmark-specific getter that wraps GetBookmarkSpecifics() above. 185 // Returns the URL of a bookmark object. 186 // TODO(ncarter): Remove this datatype-specific accessor. 187 GURL GetURL() const; 188 189 // Legacy, bookmark-specific getter that wraps GetBookmarkSpecifics() above. 190 // Fill in a vector with the byte data of this node's favicon. Assumes 191 // that the node is a bookmark. 192 // Favicons are expected to be PNG images, and though no verification is 193 // done on the syncapi client of this, the server may reject favicon updates 194 // that are invalid for whatever reason. 195 // TODO(ncarter): Remove this datatype-specific accessor. 196 void GetFaviconBytes(std::vector<unsigned char>* output) const; 197 198 // Getter specific to the APPS datatype. Returns protobuf 199 // data. Can only be called if GetModelType() == APPS. 200 const sync_pb::AppSpecifics& GetAppSpecifics() const; 201 202 // Getter specific to the AUTOFILL datatype. Returns protobuf 203 // data. Can only be called if GetModelType() == AUTOFILL. 204 const sync_pb::AutofillSpecifics& GetAutofillSpecifics() const; 205 206 virtual const sync_pb::AutofillProfileSpecifics& 207 GetAutofillProfileSpecifics() const; 208 209 // Getter specific to the NIGORI datatype. Returns protobuf 210 // data. Can only be called if GetModelType() == NIGORI. 211 const sync_pb::NigoriSpecifics& GetNigoriSpecifics() const; 212 213 // Getter specific to the PASSWORD datatype. Returns protobuf 214 // data. Can only be called if GetModelType() == PASSWORD. 215 const sync_pb::PasswordSpecificsData& GetPasswordSpecifics() const; 216 217 // Getter specific to the PREFERENCE datatype. Returns protobuf 218 // data. Can only be called if GetModelType() == PREFERENCE. 219 const sync_pb::PreferenceSpecifics& GetPreferenceSpecifics() const; 220 221 // Getter specific to the THEME datatype. Returns protobuf 222 // data. Can only be called if GetModelType() == THEME. 223 const sync_pb::ThemeSpecifics& GetThemeSpecifics() const; 224 225 // Getter specific to the TYPED_URLS datatype. Returns protobuf 226 // data. Can only be called if GetModelType() == TYPED_URLS. 227 const sync_pb::TypedUrlSpecifics& GetTypedUrlSpecifics() const; 228 229 // Getter specific to the EXTENSIONS datatype. Returns protobuf 230 // data. Can only be called if GetModelType() == EXTENSIONS. 231 const sync_pb::ExtensionSpecifics& GetExtensionSpecifics() const; 232 233 // Getter specific to the SESSIONS datatype. Returns protobuf 234 // data. Can only be called if GetModelType() == SESSIONS. 235 const sync_pb::SessionSpecifics& GetSessionSpecifics() const; 236 237 // Returns the local external ID associated with the node. 238 int64 GetExternalId() const; 239 240 // Return the ID of the node immediately before this in the sibling order. 241 // For the first node in the ordering, return 0. 242 int64 GetPredecessorId() const; 243 244 // Return the ID of the node immediately after this in the sibling order. 245 // For the last node in the ordering, return 0. 246 virtual int64 GetSuccessorId() const; 247 248 // Return the ID of the first child of this node. If this node has no 249 // children, return 0. 250 virtual int64 GetFirstChildId() const; 251 252 // These virtual accessors provide access to data members of derived classes. 253 virtual const syncable::Entry* GetEntry() const = 0; 254 virtual const BaseTransaction* GetTransaction() const = 0; 255 256 // Dumps all node info into a DictionaryValue and returns it. 257 // Transfers ownership of the DictionaryValue to the caller. 258 DictionaryValue* ToValue() const; 259 260 // Does a case in-sensitive search for a given string, which must be 261 // lower case. 262 bool ContainsString(const std::string& lowercase_query) const; 263 264 protected: 265 BaseNode(); 266 virtual ~BaseNode(); 267 // The server has a size limit on client tags, so we generate a fixed length 268 // hash locally. This also ensures that ModelTypes have unique namespaces. 269 static std::string GenerateSyncableHash(syncable::ModelType model_type, 270 const std::string& client_tag); 271 272 // Determines whether part of the entry is encrypted, and if so attempts to 273 // decrypt it. Unless decryption is necessary and fails, this will always 274 // return |true|. If the contents are encrypted, the decrypted data will be 275 // stored in |unencrypted_data_|. 276 // This method is invoked once when the BaseNode is initialized. 277 bool DecryptIfNecessary(syncable::Entry* entry); 278 279 // Returns the unencrypted specifics associated with |entry|. If |entry| was 280 // not encrypted, it directly returns |entry|'s EntitySpecifics. Otherwise, 281 // returns |unencrypted_data_|. 282 // This method is invoked by the datatype specific Get<datatype>Specifics 283 // methods. 284 const sync_pb::EntitySpecifics& GetUnencryptedSpecifics( 285 const syncable::Entry* entry) const; 286 287 private: 288 void* operator new(size_t size); // Node is meant for stack use only. 289 290 // A holder for the unencrypted data stored in an encrypted node. 291 sync_pb::EntitySpecifics unencrypted_data_; 292 293 // Same as |unencrypted_data_|, but for legacy password encryption. 294 scoped_ptr<sync_pb::PasswordSpecificsData> password_data_; 295 296 friend class SyncApiTest; 297 FRIEND_TEST_ALL_PREFIXES(SyncApiTest, GenerateSyncableHash); 298 299 DISALLOW_COPY_AND_ASSIGN(BaseNode); 300 }; 301 302 // WriteNode extends BaseNode to add mutation, and wraps 303 // syncable::MutableEntry. A WriteTransaction is needed to create a WriteNode. 304 class WriteNode : public BaseNode { 305 public: 306 // Create a WriteNode using the given transaction. 307 explicit WriteNode(WriteTransaction* transaction); 308 virtual ~WriteNode(); 309 310 // A client must use one (and only one) of the following Init variants to 311 // populate the node. 312 313 // BaseNode implementation. 314 virtual bool InitByIdLookup(int64 id); 315 virtual bool InitByClientTagLookup(syncable::ModelType model_type, 316 const std::string& tag); 317 318 // Create a new node with the specified parent and predecessor. |model_type| 319 // dictates the type of the item, and controls which EntitySpecifics proto 320 // extension can be used with this item. Use a NULL |predecessor| 321 // to indicate that this is to be the first child. 322 // |predecessor| must be a child of |new_parent| or NULL. Returns false on 323 // failure. 324 bool InitByCreation(syncable::ModelType model_type, 325 const BaseNode& parent, 326 const BaseNode* predecessor); 327 328 // Create nodes using this function if they're unique items that 329 // you want to fetch using client_tag. Note that the behavior of these 330 // items is slightly different than that of normal items. 331 // Most importantly, if it exists locally, this function will 332 // actually undelete it 333 // Client unique tagged nodes must NOT be folders. 334 bool InitUniqueByCreation(syncable::ModelType model_type, 335 const BaseNode& parent, 336 const std::string& client_tag); 337 338 // Each server-created permanent node is tagged with a unique string. 339 // Look up the node with the particular tag. If it does not exist, 340 // return false. 341 bool InitByTagLookup(const std::string& tag); 342 343 // These Set() functions correspond to the Get() functions of BaseNode. 344 void SetIsFolder(bool folder); 345 void SetTitle(const std::wstring& title); 346 347 // External ID is a client-only field, so setting it doesn't cause the item to 348 // be synced again. 349 void SetExternalId(int64 external_id); 350 351 // Remove this node and its children. 352 void Remove(); 353 354 // Set a new parent and position. Position is specified by |predecessor|; if 355 // it is NULL, the node is moved to the first position. |predecessor| must 356 // be a child of |new_parent| or NULL. Returns false on failure.. 357 bool SetPosition(const BaseNode& new_parent, const BaseNode* predecessor); 358 359 // Set the bookmark specifics (url and favicon). 360 // Should only be called if GetModelType() == BOOKMARK. 361 void SetBookmarkSpecifics(const sync_pb::BookmarkSpecifics& specifics); 362 363 // Legacy, bookmark-specific setters that wrap SetBookmarkSpecifics() above. 364 // Should only be called if GetModelType() == BOOKMARK. 365 // TODO(ncarter): Remove these two datatype-specific accessors. 366 void SetURL(const GURL& url); 367 void SetFaviconBytes(const std::vector<unsigned char>& bytes); 368 369 // Set the app specifics (id, update url, enabled state, etc). 370 // Should only be called if GetModelType() == APPS. 371 void SetAppSpecifics(const sync_pb::AppSpecifics& specifics); 372 373 // Set the autofill specifics (name and value). 374 // Should only be called if GetModelType() == AUTOFILL. 375 void SetAutofillSpecifics(const sync_pb::AutofillSpecifics& specifics); 376 377 void SetAutofillProfileSpecifics( 378 const sync_pb::AutofillProfileSpecifics& specifics); 379 380 // Set the nigori specifics. 381 // Should only be called if GetModelType() == NIGORI. 382 void SetNigoriSpecifics(const sync_pb::NigoriSpecifics& specifics); 383 384 // Set the password specifics. 385 // Should only be called if GetModelType() == PASSWORD. 386 void SetPasswordSpecifics(const sync_pb::PasswordSpecificsData& specifics); 387 388 // Set the preference specifics (name and value). 389 // Should only be called if GetModelType() == PREFERENCE. 390 void SetPreferenceSpecifics(const sync_pb::PreferenceSpecifics& specifics); 391 392 // Set the theme specifics (name and value). 393 // Should only be called if GetModelType() == THEME. 394 void SetThemeSpecifics(const sync_pb::ThemeSpecifics& specifics); 395 396 // Set the typed_url specifics (url, title, typed_count, etc). 397 // Should only be called if GetModelType() == TYPED_URLS. 398 void SetTypedUrlSpecifics(const sync_pb::TypedUrlSpecifics& specifics); 399 400 // Set the extension specifics (id, update url, enabled state, etc). 401 // Should only be called if GetModelType() == EXTENSIONS. 402 void SetExtensionSpecifics(const sync_pb::ExtensionSpecifics& specifics); 403 404 // Set the session specifics (windows, tabs, navigations etc.). 405 // Should only be called if GetModelType() == SESSIONS. 406 void SetSessionSpecifics(const sync_pb::SessionSpecifics& specifics); 407 408 // Resets the EntitySpecifics for this node based on the unencrypted data. 409 // Will encrypt if necessary. 410 void ResetFromSpecifics(); 411 412 // Implementation of BaseNode's abstract virtual accessors. 413 virtual const syncable::Entry* GetEntry() const; 414 415 virtual const BaseTransaction* GetTransaction() const; 416 417 private: 418 void* operator new(size_t size); // Node is meant for stack use only. 419 420 // Helper to set model type. This will clear any specifics data. 421 void PutModelType(syncable::ModelType model_type); 422 423 // Helper to set the previous node. 424 void PutPredecessor(const BaseNode* predecessor); 425 426 // Private helpers to set type-specific protobuf data. These don't 427 // do any checking on the previous modeltype, so they can be used 428 // for internal initialization (you can use them to set the modeltype). 429 // Additionally, they will mark for syncing if the underlying value 430 // changes. 431 void PutAppSpecificsAndMarkForSyncing( 432 const sync_pb::AppSpecifics& new_value); 433 void PutAutofillSpecificsAndMarkForSyncing( 434 const sync_pb::AutofillSpecifics& new_value); 435 void PutAutofillProfileSpecificsAndMarkForSyncing( 436 const sync_pb::AutofillProfileSpecifics& new_value); 437 void PutBookmarkSpecificsAndMarkForSyncing( 438 const sync_pb::BookmarkSpecifics& new_value); 439 void PutNigoriSpecificsAndMarkForSyncing( 440 const sync_pb::NigoriSpecifics& new_value); 441 void PutPasswordSpecificsAndMarkForSyncing( 442 const sync_pb::PasswordSpecifics& new_value); 443 void PutPreferenceSpecificsAndMarkForSyncing( 444 const sync_pb::PreferenceSpecifics& new_value); 445 void PutThemeSpecificsAndMarkForSyncing( 446 const sync_pb::ThemeSpecifics& new_value); 447 void PutTypedUrlSpecificsAndMarkForSyncing( 448 const sync_pb::TypedUrlSpecifics& new_value); 449 void PutExtensionSpecificsAndMarkForSyncing( 450 const sync_pb::ExtensionSpecifics& new_value); 451 void PutSessionSpecificsAndMarkForSyncing( 452 const sync_pb::SessionSpecifics& new_value); 453 void PutSpecificsAndMarkForSyncing( 454 const sync_pb::EntitySpecifics& specifics); 455 456 // Sets IS_UNSYNCED and SYNCING to ensure this entry is considered in an 457 // upcoming commit pass. 458 void MarkForSyncing(); 459 460 // Encrypt the specifics if the datatype requries it. 461 void EncryptIfNecessary(sync_pb::EntitySpecifics* new_value); 462 463 // The underlying syncable object which this class wraps. 464 syncable::MutableEntry* entry_; 465 466 // The sync API transaction that is the parent of this node. 467 WriteTransaction* transaction_; 468 469 DISALLOW_COPY_AND_ASSIGN(WriteNode); 470 }; 471 472 // ReadNode wraps a syncable::Entry to provide the functionality of a 473 // read-only BaseNode. 474 class ReadNode : public BaseNode { 475 public: 476 // Create an unpopulated ReadNode on the given transaction. Call some flavor 477 // of Init to populate the ReadNode with a database entry. 478 explicit ReadNode(const BaseTransaction* transaction); 479 virtual ~ReadNode(); 480 481 // A client must use one (and only one) of the following Init variants to 482 // populate the node. 483 484 // BaseNode implementation. 485 virtual bool InitByIdLookup(int64 id); 486 virtual bool InitByClientTagLookup(syncable::ModelType model_type, 487 const std::string& tag); 488 489 // There is always a root node, so this can't fail. The root node is 490 // never mutable, so root lookup is only possible on a ReadNode. 491 void InitByRootLookup(); 492 493 // Each server-created permanent node is tagged with a unique string. 494 // Look up the node with the particular tag. If it does not exist, 495 // return false. 496 bool InitByTagLookup(const std::string& tag); 497 498 // Implementation of BaseNode's abstract virtual accessors. 499 virtual const syncable::Entry* GetEntry() const; 500 virtual const BaseTransaction* GetTransaction() const; 501 502 protected: 503 ReadNode(); 504 505 private: 506 void* operator new(size_t size); // Node is meant for stack use only. 507 508 // The underlying syncable object which this class wraps. 509 syncable::Entry* entry_; 510 511 // The sync API transaction that is the parent of this node. 512 const BaseTransaction* transaction_; 513 514 DISALLOW_COPY_AND_ASSIGN(ReadNode); 515 }; 516 517 // Sync API's BaseTransaction, ReadTransaction, and WriteTransaction allow for 518 // batching of several read and/or write operations. The read and write 519 // operations are performed by creating ReadNode and WriteNode instances using 520 // the transaction. These transaction classes wrap identically named classes in 521 // syncable, and are used in a similar way. Unlike syncable::BaseTransaction, 522 // whose construction requires an explicit syncable::ScopedDirLookup, a sync 523 // API BaseTransaction creates its own ScopedDirLookup implicitly. 524 class BaseTransaction { 525 public: 526 // Provide access to the underlying syncable.h objects from BaseNode. 527 virtual syncable::BaseTransaction* GetWrappedTrans() const = 0; GetLookup()528 const syncable::ScopedDirLookup& GetLookup() const { return *lookup_; } GetCryptographer()529 browser_sync::Cryptographer* GetCryptographer() const { 530 return cryptographer_; 531 } 532 533 protected: 534 // The ScopedDirLookup is created in the constructor and destroyed 535 // in the destructor. Creation of the ScopedDirLookup is not expected 536 // to fail. 537 explicit BaseTransaction(UserShare* share); 538 virtual ~BaseTransaction(); 539 BaseTransaction()540 BaseTransaction() { lookup_= NULL; } 541 542 private: 543 // A syncable ScopedDirLookup, which is the parent of syncable transactions. 544 syncable::ScopedDirLookup* lookup_; 545 546 browser_sync::Cryptographer* cryptographer_; 547 548 DISALLOW_COPY_AND_ASSIGN(BaseTransaction); 549 }; 550 551 // Sync API's ReadTransaction is a read-only BaseTransaction. It wraps 552 // a syncable::ReadTransaction. 553 class ReadTransaction : public BaseTransaction { 554 public: 555 // Start a new read-only transaction on the specified repository. 556 explicit ReadTransaction(UserShare* share); 557 558 // Resume the middle of a transaction. Will not close transaction. 559 ReadTransaction(UserShare* share, syncable::BaseTransaction* trans); 560 561 virtual ~ReadTransaction(); 562 563 // BaseTransaction override. 564 virtual syncable::BaseTransaction* GetWrappedTrans() const; 565 private: 566 void* operator new(size_t size); // Transaction is meant for stack use only. 567 568 // The underlying syncable object which this class wraps. 569 syncable::BaseTransaction* transaction_; 570 bool close_transaction_; 571 572 DISALLOW_COPY_AND_ASSIGN(ReadTransaction); 573 }; 574 575 // Sync API's WriteTransaction is a read/write BaseTransaction. It wraps 576 // a syncable::WriteTransaction. 577 class WriteTransaction : public BaseTransaction { 578 public: 579 // Start a new read/write transaction. 580 explicit WriteTransaction(UserShare* share); 581 virtual ~WriteTransaction(); 582 583 // Provide access to the syncable.h transaction from the API WriteNode. 584 virtual syncable::BaseTransaction* GetWrappedTrans() const; GetWrappedWriteTrans()585 syncable::WriteTransaction* GetWrappedWriteTrans() { return transaction_; } 586 587 protected: WriteTransaction()588 WriteTransaction() {} 589 SetTransaction(syncable::WriteTransaction * trans)590 void SetTransaction(syncable::WriteTransaction* trans) { 591 transaction_ = trans;} 592 593 private: 594 void* operator new(size_t size); // Transaction is meant for stack use only. 595 596 // The underlying syncable object which this class wraps. 597 syncable::WriteTransaction* transaction_; 598 599 DISALLOW_COPY_AND_ASSIGN(WriteTransaction); 600 }; 601 602 // SyncManager encapsulates syncable::DirectoryManager and serves as the parent 603 // of all other objects in the sync API. SyncManager is thread-safe. If 604 // multiple threads interact with the same local sync repository (i.e. the 605 // same sqlite database), they should share a single SyncManager instance. The 606 // caller should typically create one SyncManager for the lifetime of a user 607 // session. 608 class SyncManager { 609 public: 610 // SyncInternal contains the implementation of SyncManager, while abstracting 611 // internal types from clients of the interface. 612 class SyncInternal; 613 614 // TODO(zea): One day get passwords playing nicely with the rest of encryption 615 // and get rid of this. 616 class ExtraPasswordChangeRecordData { 617 public: 618 ExtraPasswordChangeRecordData(); 619 explicit ExtraPasswordChangeRecordData( 620 const sync_pb::PasswordSpecificsData& data); 621 virtual ~ExtraPasswordChangeRecordData(); 622 623 // Transfers ownership of the DictionaryValue to the caller. 624 virtual DictionaryValue* ToValue() const; 625 626 const sync_pb::PasswordSpecificsData& unencrypted() const; 627 private: 628 sync_pb::PasswordSpecificsData unencrypted_; 629 }; 630 631 // ChangeRecord indicates a single item that changed as a result of a sync 632 // operation. This gives the sync id of the node that changed, and the type 633 // of change. To get the actual property values after an ADD or UPDATE, the 634 // client should get the node with InitByIdLookup(), using the provided id. 635 struct ChangeRecord { 636 enum Action { 637 ACTION_ADD, 638 ACTION_DELETE, 639 ACTION_UPDATE, 640 }; 641 ChangeRecord(); 642 ~ChangeRecord(); 643 644 // Transfers ownership of the DictionaryValue to the caller. 645 DictionaryValue* ToValue(const BaseTransaction* trans) const; 646 647 int64 id; 648 Action action; 649 sync_pb::EntitySpecifics specifics; 650 linked_ptr<ExtraPasswordChangeRecordData> extra; 651 }; 652 653 // Status encapsulates detailed state about the internals of the SyncManager. 654 struct Status { 655 // Summary is a distilled set of important information that the end-user may 656 // wish to be informed about (through UI, for example). Note that if a 657 // summary state requires user interaction (such as auth failures), more 658 // detailed information may be contained in additional status fields. 659 enum Summary { 660 // The internal instance is in an unrecognizable state. This should not 661 // happen. 662 INVALID = 0, 663 // Can't connect to server, but there are no pending changes in 664 // our local cache. 665 OFFLINE, 666 // Can't connect to server, and there are pending changes in our 667 // local cache. 668 OFFLINE_UNSYNCED, 669 // Connected and syncing. 670 SYNCING, 671 // Connected, no pending changes. 672 READY, 673 // Internal sync error. 674 CONFLICT, 675 // Can't connect to server, and we haven't completed the initial 676 // sync yet. So there's nothing we can do but wait for the server. 677 OFFLINE_UNUSABLE, 678 679 SUMMARY_STATUS_COUNT, 680 }; 681 682 Summary summary; 683 bool authenticated; // Successfully authenticated via GAIA. 684 bool server_up; // True if we have received at least one good 685 // reply from the server. 686 bool server_reachable; // True if we received any reply from the server. 687 bool server_broken; // True of the syncer is stopped because of server 688 // issues. 689 bool notifications_enabled; // True only if subscribed for notifications. 690 691 // Notifications counters updated by the actions in synapi. 692 int notifications_received; 693 int notifications_sent; 694 695 // The max number of consecutive errors from any component. 696 int max_consecutive_errors; 697 698 int unsynced_count; 699 700 int conflicting_count; 701 bool syncing; 702 // True after a client has done a first sync. 703 bool initial_sync_ended; 704 // True if any syncer is stuck. 705 bool syncer_stuck; 706 707 // Total updates available. If zero, nothing left to download. 708 int64 updates_available; 709 // Total updates received by the syncer since browser start. 710 int updates_received; 711 712 // Of updates_received, how many were tombstones. 713 int tombstone_updates_received; 714 bool disk_full; 715 }; 716 717 // An interface the embedding application implements to receive notifications 718 // from the SyncManager. Register an observer via SyncManager::AddObserver. 719 // This observer is an event driven model as the events may be raised from 720 // different internal threads, and simply providing an "OnStatusChanged" type 721 // notification complicates things such as trying to determine "what changed", 722 // if different members of the Status object are modified from different 723 // threads. This way, the event is explicit, and it is safe for the Observer 724 // to dispatch to a native thread or synchronize accordingly. 725 class Observer { 726 public: 727 // Notify the observer that changes have been applied to the sync model. 728 // 729 // This will be invoked on the same thread as on which ApplyChanges was 730 // called. |changes| is an array of size |change_count|, and contains the 731 // ID of each individual item that was changed. |changes| exists only for 732 // the duration of the call. If items of multiple data types change at 733 // the same time, this method is invoked once per data type and |changes| 734 // is restricted to items of the ModelType indicated by |model_type|. 735 // Because the observer is passed a |trans|, the observer can assume a 736 // read lock on the sync model that will be released after the function 737 // returns. 738 // 739 // The SyncManager constructs |changes| in the following guaranteed order: 740 // 741 // 1. Deletions, from leaves up to parents. 742 // 2. Updates to existing items with synced parents & predecessors. 743 // 3. New items with synced parents & predecessors. 744 // 4. Items with parents & predecessors in |changes|. 745 // 5. Repeat #4 until all items are in |changes|. 746 // 747 // Thus, an implementation of OnChangesApplied should be able to 748 // process the change records in the order without having to worry about 749 // forward dependencies. But since deletions come before reparent 750 // operations, a delete may temporarily orphan a node that is 751 // updated later in the list. 752 virtual void OnChangesApplied(syncable::ModelType model_type, 753 const BaseTransaction* trans, 754 const ChangeRecord* changes, 755 int change_count) = 0; 756 757 // OnChangesComplete gets called when the TransactionComplete event is 758 // posted (after OnChangesApplied finishes), after the transaction lock 759 // and the change channel mutex are released. 760 // 761 // The purpose of this function is to support processors that require 762 // split-transactions changes. For example, if a model processor wants to 763 // perform blocking I/O due to a change, it should calculate the changes 764 // while holding the transaction lock (from within OnChangesApplied), buffer 765 // those changes, let the transaction fall out of scope, and then commit 766 // those changes from within OnChangesComplete (postponing the blocking 767 // I/O to when it no longer holds any lock). 768 virtual void OnChangesComplete(syncable::ModelType model_type) = 0; 769 770 // A round-trip sync-cycle took place and the syncer has resolved any 771 // conflicts that may have arisen. 772 virtual void OnSyncCycleCompleted( 773 const browser_sync::sessions::SyncSessionSnapshot* snapshot) = 0; 774 775 // Called when user interaction may be required due to an auth problem. 776 virtual void OnAuthError(const GoogleServiceAuthError& auth_error) = 0; 777 778 // Called when a new auth token is provided by the sync server. 779 virtual void OnUpdatedToken(const std::string& token) = 0; 780 781 // Called when user interaction is required to obtain a valid passphrase. 782 // If the passphrase is required to decrypt something that has 783 // already been encrypted (and thus has to match the existing key), 784 // |for_decryption| will be true. If the passphrase is needed for 785 // encryption, |for_decryption| will be false. 786 virtual void OnPassphraseRequired(bool for_decryption) = 0; 787 788 // Called only by SyncInternal::SetPassphrase to indiciate that an attempted 789 // passphrase failed to decrypt pending keys. This is different from 790 // OnPassphraseRequired in that it denotes we finished an attempt to set 791 // a passphrase. OnPassphraseRequired means we have data we could not 792 // decrypt yet, and can come from numerous places. 793 virtual void OnPassphraseFailed() = 0; 794 795 // Called when the passphrase provided by the user has been accepted and is 796 // now used to encrypt sync data. |bootstrap_token| is an opaque base64 797 // encoded representation of the key generated by the accepted passphrase, 798 // and is provided to the observer for persistence purposes and use in a 799 // future initialization of sync (e.g. after restart). 800 virtual void OnPassphraseAccepted(const std::string& bootstrap_token) = 0; 801 802 // Called when initialization is complete to the point that SyncManager can 803 // process changes. This does not necessarily mean authentication succeeded 804 // or that the SyncManager is online. 805 // IMPORTANT: Creating any type of transaction before receiving this 806 // notification is illegal! 807 // WARNING: Calling methods on the SyncManager before receiving this 808 // message, unless otherwise specified, produces undefined behavior. 809 virtual void OnInitializationComplete() = 0; 810 811 // We are no longer permitted to communicate with the server. Sync should 812 // be disabled and state cleaned up at once. This can happen for a number 813 // of reasons, e.g. swapping from a test instance to production, or a 814 // global stop syncing operation has wiped the store. 815 virtual void OnStopSyncingPermanently() = 0; 816 817 // After a request to clear server data, these callbacks are invoked to 818 // indicate success or failure. 819 virtual void OnClearServerDataSucceeded() = 0; 820 virtual void OnClearServerDataFailed() = 0; 821 822 // Called after we finish encrypting all appropriate datatypes. 823 virtual void OnEncryptionComplete( 824 const syncable::ModelTypeSet& encrypted_types) = 0; 825 826 protected: 827 virtual ~Observer(); 828 }; 829 830 typedef Callback0::Type ModeChangeCallback; 831 832 // Create an uninitialized SyncManager. Callers must Init() before using. 833 SyncManager(); 834 virtual ~SyncManager(); 835 836 // Initialize the sync manager. |database_location| specifies the path of 837 // the directory in which to locate a sqlite repository storing the syncer 838 // backend state. Initialization will open the database, or create it if it 839 // does not already exist. Returns false on failure. 840 // |sync_server_and_path| and |sync_server_port| represent the Chrome sync 841 // server to use, and |use_ssl| specifies whether to communicate securely; 842 // the default is false. 843 // |post_factory| will be owned internally and used to create 844 // instances of an HttpPostProvider. 845 // |model_safe_worker| ownership is given to the SyncManager. 846 // |user_agent| is a 7-bit ASCII string suitable for use as the User-Agent 847 // HTTP header. Used internally when collecting stats to classify clients. 848 // |sync_notifier| used to listen for notifications, not owned. 849 bool Init(const FilePath& database_location, 850 const char* sync_server_and_path, 851 int sync_server_port, 852 bool use_ssl, 853 HttpPostProviderFactory* post_factory, 854 browser_sync::ModelSafeWorkerRegistrar* registrar, 855 const char* user_agent, 856 const SyncCredentials& credentials, 857 sync_notifier::SyncNotifier* sync_notifier, 858 const std::string& restored_key_for_bootstrapping, 859 bool setup_for_test_mode); 860 861 // Returns the username last used for a successful authentication. 862 // Returns empty if there is no such username. 863 const std::string& GetAuthenticatedUsername(); 864 865 // Check if the database has been populated with a full "initial" download of 866 // sync items for each data type currently present in the routing info. 867 // Prerequisite for calling this is that OnInitializationComplete has been 868 // called. 869 bool InitialSyncEndedForAllEnabledTypes(); 870 871 syncable::AutofillMigrationState GetAutofillMigrationState(); 872 873 void SetAutofillMigrationState( 874 syncable::AutofillMigrationState state); 875 876 syncable::AutofillMigrationDebugInfo GetAutofillMigrationDebugInfo(); 877 878 void SetAutofillMigrationDebugInfo( 879 syncable::AutofillMigrationDebugInfo::PropertyToSet property_to_set, 880 const syncable::AutofillMigrationDebugInfo& info); 881 882 // Migrate tokens from user settings DB to the token service. 883 void MigrateTokens(); 884 885 // Update tokens that we're using in Sync. Email must stay the same. 886 void UpdateCredentials(const SyncCredentials& credentials); 887 888 // Called when the user disables or enables a sync type. 889 void UpdateEnabledTypes(); 890 891 // Start the SyncerThread. 892 // TODO(tim): With the new impl, this would mean starting "NORMAL" operation. 893 // Rename this when switched over or at least update comment. 894 void StartSyncing(); 895 896 // Attempt to set the passphrase. If the passphrase is valid, 897 // OnPassphraseAccepted will be fired to notify the ProfileSyncService and the 898 // syncer will be nudged so that any update that was waiting for this 899 // passphrase gets applied as soon as possible. 900 // If the passphrase in invalid, OnPassphraseRequired will be fired. 901 // Calling this metdod again is the appropriate course of action to "retry" 902 // with a new passphrase. 903 // |is_explicit| is true if the call is in response to the user explicitly 904 // setting a passphrase as opposed to implicitly (from the users' perspective) 905 // using their Google Account password. An implicit SetPassphrase will *not* 906 // *not* override an explicit passphrase set previously. 907 void SetPassphrase(const std::string& passphrase, bool is_explicit); 908 909 // Set the datatypes we want to encrypt and encrypt any nodes as necessary. 910 // Note: |encrypted_types| will be unioned with the current set of encrypted 911 // types, as we do not currently support decrypting datatypes. 912 void EncryptDataTypes(const syncable::ModelTypeSet& encrypted_types); 913 914 // Puts the SyncerThread into a mode where no normal nudge or poll traffic 915 // will occur, but calls to RequestConfig will be supported. If |callback| 916 // is provided, it will be invoked (from the internal SyncerThread) when 917 // the thread has changed to configuration mode. 918 void StartConfigurationMode(ModeChangeCallback* callback); 919 920 // For the new SyncerThread impl, this switches the mode of operation to 921 // CONFIGURATION_MODE and schedules a config task to fetch updates for 922 // |types|. It is an error to call this with legacy SyncerThread in use. 923 void RequestConfig(const syncable::ModelTypeBitSet& types); 924 925 // Request a nudge of the syncer, which will cause the syncer thread 926 // to run at the next available opportunity. 927 void RequestNudge(const tracked_objects::Location& nudge_location); 928 929 // Request a clearing of all data on the server 930 void RequestClearServerData(); 931 932 // Adds a listener to be notified of sync events. 933 // NOTE: It is OK (in fact, it's probably a good idea) to call this before 934 // having received OnInitializationCompleted. 935 void AddObserver(Observer* observer); 936 937 // Remove the given observer. Make sure to call this if the 938 // Observer is being destroyed so the SyncManager doesn't 939 // potentially dereference garbage. 940 void RemoveObserver(Observer* observer); 941 942 // Returns a pointer to the JsBackend (which is owned by the sync 943 // manager). Never returns NULL. The following events are sent by 944 // the returned backend: 945 // 946 // onSyncNotificationStateChange(boolean notificationsEnabled): 947 // Sent when notifications are enabled or disabled. 948 // 949 // onSyncIncomingNotification(array changedTypes): 950 // Sent when an incoming notification arrives. |changedTypes| 951 // contains a list of sync types (strings) which have changed. 952 // 953 // The following messages are processed by the returned backend: 954 // 955 // getNotificationState(): 956 // If there is a parent router, sends the 957 // onGetNotificationStateFinished(boolean notificationsEnabled) 958 // event to |sender| via the parent router with whether or not 959 // notifications are enabled. 960 // 961 // getRootNode(): 962 // If there is a parent router, sends the 963 // onGetRootNodeFinished(dictionary nodeInfo) event to |sender| 964 // via the parent router with information on the root node. 965 // 966 // getNodeById(string id): 967 // If there is a parent router, sends the 968 // onGetNodeByIdFinished(dictionary nodeInfo) event to |sender| 969 // via the parent router with information on the node with the 970 // given id (metahandle), if the id is valid and a node with that 971 // id exists. Otherwise, calls onGetNodeByIdFinished(null). 972 // 973 // All other messages are dropped. 974 browser_sync::JsBackend* GetJsBackend(); 975 976 // Status-related getters. Typically GetStatusSummary will suffice, but 977 // GetDetailedSyncStatus can be useful for gathering debug-level details of 978 // the internals of the sync engine. 979 Status::Summary GetStatusSummary() const; 980 Status GetDetailedStatus() const; 981 982 // Whether or not the Nigori node is encrypted using an explicit passphrase. 983 bool IsUsingExplicitPassphrase(); 984 985 // Get the internal implementation for use by BaseTransaction, etc. 986 SyncInternal* GetImpl() const; 987 988 // Call periodically from a database-safe thread to persist recent changes 989 // to the syncapi model. 990 void SaveChanges(); 991 992 // Issue a final SaveChanges, close sqlite handles, and stop running threads. 993 // Must be called from the same thread that called Init(). 994 void Shutdown(); 995 996 UserShare* GetUserShare() const; 997 998 // Uses a read-only transaction to determine if the directory being synced has 999 // any remaining unsynced items. 1000 bool HasUnsyncedItems() const; 1001 1002 // Functions used for testing. 1003 1004 void TriggerOnNotificationStateChangeForTest( 1005 bool notifications_enabled); 1006 1007 void TriggerOnIncomingNotificationForTest( 1008 const syncable::ModelTypeBitSet& model_types); 1009 1010 private: 1011 // An opaque pointer to the nested private class. 1012 SyncInternal* data_; 1013 1014 DISALLOW_COPY_AND_ASSIGN(SyncManager); 1015 }; 1016 1017 } // namespace sync_api 1018 1019 #endif // CHROME_BROWSER_SYNC_ENGINE_SYNCAPI_H_ 1020