| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef CHROME_BROWSER_SYNC_INTERNAL_API_SYNC_MANAGER_H_ | 5 #ifndef CHROME_BROWSER_SYNC_INTERNAL_API_SYNC_MANAGER_H_ |
| 6 #define CHROME_BROWSER_SYNC_INTERNAL_API_SYNC_MANAGER_H_ | 6 #define CHROME_BROWSER_SYNC_INTERNAL_API_SYNC_MANAGER_H_ |
| 7 | 7 |
| 8 #include <string> | 8 #include <string> |
| 9 #include <vector> | 9 #include <vector> |
| 10 | 10 |
| 11 #include "base/basictypes.h" | 11 #include "base/basictypes.h" |
| 12 #include "base/callback_old.h" | 12 #include "base/callback_old.h" |
| 13 #include "base/threading/thread_checker.h" |
| 13 #include "chrome/browser/sync/internal_api/change_record.h" | 14 #include "chrome/browser/sync/internal_api/change_record.h" |
| 14 #include "chrome/browser/sync/internal_api/configure_reason.h" | 15 #include "chrome/browser/sync/internal_api/configure_reason.h" |
| 15 #include "chrome/browser/sync/protocol/sync_protocol_error.h" | 16 #include "chrome/browser/sync/protocol/sync_protocol_error.h" |
| 16 #include "chrome/browser/sync/syncable/model_type.h" | 17 #include "chrome/browser/sync/syncable/model_type.h" |
| 17 #include "chrome/browser/sync/util/weak_handle.h" | 18 #include "chrome/browser/sync/util/weak_handle.h" |
| 18 #include "chrome/common/net/gaia/google_service_auth_error.h" | 19 #include "chrome/common/net/gaia/google_service_auth_error.h" |
| 19 | 20 |
| 20 class FilePath; | 21 class FilePath; |
| 21 | 22 |
| 22 namespace base { | 23 namespace base { |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 58 // decryption with the cached passphrase | 59 // decryption with the cached passphrase |
| 59 // was unsuccessful. | 60 // was unsuccessful. |
| 60 }; | 61 }; |
| 61 | 62 |
| 62 // Contains everything needed to talk to and identify a user account. | 63 // Contains everything needed to talk to and identify a user account. |
| 63 struct SyncCredentials { | 64 struct SyncCredentials { |
| 64 std::string email; | 65 std::string email; |
| 65 std::string sync_token; | 66 std::string sync_token; |
| 66 }; | 67 }; |
| 67 | 68 |
| 68 // SyncManager encapsulates syncable::DirectoryManager and serves as the parent | 69 // SyncManager encapsulates syncable::DirectoryManager and serves as |
| 69 // of all other objects in the sync API. SyncManager is thread-safe. If | 70 // the parent of all other objects in the sync API. If multiple |
| 70 // multiple threads interact with the same local sync repository (i.e. the | 71 // threads interact with the same local sync repository (i.e. the same |
| 71 // same sqlite database), they should share a single SyncManager instance. The | 72 // sqlite database), they should share a single SyncManager instance. |
| 72 // caller should typically create one SyncManager for the lifetime of a user | 73 // The caller should typically create one SyncManager for the lifetime |
| 73 // session. | 74 // of a user session. |
| 75 // |
| 76 // Unless stated otherwise, all methods of SyncManager should be |
| 77 // called on the same thread. |
| 74 class SyncManager { | 78 class SyncManager { |
| 75 public: | 79 public: |
| 76 // SyncInternal contains the implementation of SyncManager, while abstracting | 80 // SyncInternal contains the implementation of SyncManager, while abstracting |
| 77 // internal types from clients of the interface. | 81 // internal types from clients of the interface. |
| 78 class SyncInternal; | 82 class SyncInternal; |
| 79 | 83 |
| 80 // Status encapsulates detailed state about the internals of the SyncManager. | 84 // Status encapsulates detailed state about the internals of the SyncManager. |
| 81 struct Status { | 85 struct Status { |
| 82 // Summary is a distilled set of important information that the end-user may | 86 // Summary is a distilled set of important information that the end-user may |
| 83 // wish to be informed about (through UI, for example). Note that if a | 87 // wish to be informed about (through UI, for example). Note that if a |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 156 // Count of useless and useful syncs we perform. | 160 // Count of useless and useful syncs we perform. |
| 157 int useless_sync_cycles; | 161 int useless_sync_cycles; |
| 158 int useful_sync_cycles; | 162 int useful_sync_cycles; |
| 159 | 163 |
| 160 // Encryption related. | 164 // Encryption related. |
| 161 syncable::ModelTypeSet encrypted_types; | 165 syncable::ModelTypeSet encrypted_types; |
| 162 bool cryptographer_ready; | 166 bool cryptographer_ready; |
| 163 bool crypto_has_pending_keys; | 167 bool crypto_has_pending_keys; |
| 164 }; | 168 }; |
| 165 | 169 |
| 166 // An interface the embedding application implements to receive notifications | 170 // An interface the embedding application implements to be notified |
| 167 // from the SyncManager. Register an observer via SyncManager::AddObserver. | 171 // on change events. Note that these methods may be called on *any* |
| 168 // This observer is an event driven model as the events may be raised from | 172 // thread. |
| 169 // different internal threads, and simply providing an "OnStatusChanged" type | 173 class ChangeDelegate { |
| 170 // notification complicates things such as trying to determine "what changed", | |
| 171 // if different members of the Status object are modified from different | |
| 172 // threads. This way, the event is explicit, and it is safe for the Observer | |
| 173 // to dispatch to a native thread or synchronize accordingly. | |
| 174 class Observer { | |
| 175 public: | 174 public: |
| 176 // Notify the observer that changes have been applied to the sync model. | 175 // Notify the delegate that changes have been applied to the sync model. |
| 177 // | 176 // |
| 178 // This will be invoked on the same thread as on which ApplyChanges was | 177 // This will be invoked on the same thread as on which ApplyChanges was |
| 179 // called. |changes| is an array of size |change_count|, and contains the | 178 // called. |changes| is an array of size |change_count|, and contains the |
| 180 // ID of each individual item that was changed. |changes| exists only for | 179 // ID of each individual item that was changed. |changes| exists only for |
| 181 // the duration of the call. If items of multiple data types change at | 180 // the duration of the call. If items of multiple data types change at |
| 182 // the same time, this method is invoked once per data type and |changes| | 181 // the same time, this method is invoked once per data type and |changes| |
| 183 // is restricted to items of the ModelType indicated by |model_type|. | 182 // is restricted to items of the ModelType indicated by |model_type|. |
| 184 // Because the observer is passed a |trans|, the observer can assume a | 183 // Because the observer is passed a |trans|, the observer can assume a |
| 185 // read lock on the sync model that will be released after the function | 184 // read lock on the sync model that will be released after the function |
| 186 // returns. | 185 // returns. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 209 // | 208 // |
| 210 // The purpose of this function is to support processors that require | 209 // The purpose of this function is to support processors that require |
| 211 // split-transactions changes. For example, if a model processor wants to | 210 // split-transactions changes. For example, if a model processor wants to |
| 212 // perform blocking I/O due to a change, it should calculate the changes | 211 // perform blocking I/O due to a change, it should calculate the changes |
| 213 // while holding the transaction lock (from within OnChangesApplied), buffer | 212 // while holding the transaction lock (from within OnChangesApplied), buffer |
| 214 // those changes, let the transaction fall out of scope, and then commit | 213 // those changes, let the transaction fall out of scope, and then commit |
| 215 // those changes from within OnChangesComplete (postponing the blocking | 214 // those changes from within OnChangesComplete (postponing the blocking |
| 216 // I/O to when it no longer holds any lock). | 215 // I/O to when it no longer holds any lock). |
| 217 virtual void OnChangesComplete(syncable::ModelType model_type) = 0; | 216 virtual void OnChangesComplete(syncable::ModelType model_type) = 0; |
| 218 | 217 |
| 218 protected: |
| 219 virtual ~ChangeDelegate(); |
| 220 }; |
| 221 |
| 222 // Like ChangeDelegate, except called only on the sync thread and |
| 223 // not while a transaction is held. For objects that want to know |
| 224 // when changes happen, but don't need to process them. |
| 225 class ChangeObserver { |
| 226 public: |
| 227 // Ids referred to in |changes| may or may not be in the write |
| 228 // transaction specified by |write_transaction_id|. If they're |
| 229 // not, that means that the node didn't actually change, but we |
| 230 // marked them as changed for some other reason (e.g., siblings of |
| 231 // re-ordered nodes). |
| 232 // |
| 233 // TODO(sync, long-term): Ideally, ChangeDelegate/Observer would |
| 234 // be passed a transformed version of EntryKernelMutation instead |
| 235 // of a transaction that would have to be used to look up the |
| 236 // changed nodes. That is, ChangeDelegate::OnChangesApplied() |
| 237 // would still be called under the transaction, but all the needed |
| 238 // data will be passed down. |
| 239 // |
| 240 // Even more ideally, we would have sync semantics such that we'd |
| 241 // be able to apply changes without being under a transaction. |
| 242 // But that's a ways off... |
| 243 virtual void OnChangesApplied( |
| 244 syncable::ModelType model_type, |
| 245 int64 write_transaction_id, |
| 246 const ImmutableChangeRecordList& changes) = 0; |
| 247 |
| 248 virtual void OnChangesComplete(syncable::ModelType model_type) = 0; |
| 249 |
| 250 protected: |
| 251 virtual ~ChangeObserver(); |
| 252 }; |
| 253 |
| 254 // An interface the embedding application implements to receive |
| 255 // notifications from the SyncManager. Register an observer via |
| 256 // SyncManager::AddObserver. All methods are called only on the |
| 257 // sync thread. |
| 258 class Observer { |
| 259 public: |
| 219 // A round-trip sync-cycle took place and the syncer has resolved any | 260 // A round-trip sync-cycle took place and the syncer has resolved any |
| 220 // conflicts that may have arisen. | 261 // conflicts that may have arisen. |
| 221 virtual void OnSyncCycleCompleted( | 262 virtual void OnSyncCycleCompleted( |
| 222 const browser_sync::sessions::SyncSessionSnapshot* snapshot) = 0; | 263 const browser_sync::sessions::SyncSessionSnapshot* snapshot) = 0; |
| 223 | 264 |
| 224 // Called when user interaction may be required due to an auth problem. | 265 // Called when user interaction may be required due to an auth problem. |
| 225 virtual void OnAuthError(const GoogleServiceAuthError& auth_error) = 0; | 266 virtual void OnAuthError(const GoogleServiceAuthError& auth_error) = 0; |
| 226 | 267 |
| 227 // Called when a new auth token is provided by the sync server. | 268 // Called when a new auth token is provided by the sync server. |
| 228 virtual void OnUpdatedToken(const std::string& token) = 0; | 269 virtual void OnUpdatedToken(const std::string& token) = 0; |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 333 // After a request to clear server data, these callbacks are invoked to | 374 // After a request to clear server data, these callbacks are invoked to |
| 334 // indicate success or failure. | 375 // indicate success or failure. |
| 335 virtual void OnClearServerDataSucceeded() = 0; | 376 virtual void OnClearServerDataSucceeded() = 0; |
| 336 virtual void OnClearServerDataFailed() = 0; | 377 virtual void OnClearServerDataFailed() = 0; |
| 337 | 378 |
| 338 // Called after we finish encrypting all appropriate datatypes. | 379 // Called after we finish encrypting all appropriate datatypes. |
| 339 virtual void OnEncryptionComplete( | 380 virtual void OnEncryptionComplete( |
| 340 const syncable::ModelTypeSet& encrypted_types) = 0; | 381 const syncable::ModelTypeSet& encrypted_types) = 0; |
| 341 | 382 |
| 342 virtual void OnActionableError( | 383 virtual void OnActionableError( |
| 343 const browser_sync::SyncProtocolError& sync_protocol_error) | 384 const browser_sync::SyncProtocolError& sync_protocol_error) = 0; |
| 344 = 0; | |
| 345 | 385 |
| 346 protected: | 386 protected: |
| 347 virtual ~Observer(); | 387 virtual ~Observer(); |
| 348 }; | 388 }; |
| 349 | 389 |
| 350 typedef Callback0::Type ModeChangeCallback; | 390 typedef Callback0::Type ModeChangeCallback; |
| 351 | 391 |
| 352 // Create an uninitialized SyncManager. Callers must Init() before using. | 392 // Create an uninitialized SyncManager. Callers must Init() before using. |
| 353 explicit SyncManager(const std::string& name); | 393 explicit SyncManager(const std::string& name); |
| 354 virtual ~SyncManager(); | 394 virtual ~SyncManager(); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 369 // HTTP header. Used internally when collecting stats to classify clients. | 409 // HTTP header. Used internally when collecting stats to classify clients. |
| 370 // |sync_notifier| is owned and used to listen for notifications. | 410 // |sync_notifier| is owned and used to listen for notifications. |
| 371 bool Init(const FilePath& database_location, | 411 bool Init(const FilePath& database_location, |
| 372 const browser_sync::WeakHandle<browser_sync::JsEventHandler>& | 412 const browser_sync::WeakHandle<browser_sync::JsEventHandler>& |
| 373 event_handler, | 413 event_handler, |
| 374 const std::string& sync_server_and_path, | 414 const std::string& sync_server_and_path, |
| 375 int sync_server_port, | 415 int sync_server_port, |
| 376 bool use_ssl, | 416 bool use_ssl, |
| 377 HttpPostProviderFactory* post_factory, | 417 HttpPostProviderFactory* post_factory, |
| 378 browser_sync::ModelSafeWorkerRegistrar* registrar, | 418 browser_sync::ModelSafeWorkerRegistrar* registrar, |
| 419 ChangeDelegate* change_delegate, |
| 379 const std::string& user_agent, | 420 const std::string& user_agent, |
| 380 const SyncCredentials& credentials, | 421 const SyncCredentials& credentials, |
| 381 sync_notifier::SyncNotifier* sync_notifier, | 422 sync_notifier::SyncNotifier* sync_notifier, |
| 382 const std::string& restored_key_for_bootstrapping, | 423 const std::string& restored_key_for_bootstrapping, |
| 383 bool setup_for_test_mode); | 424 bool setup_for_test_mode); |
| 384 | 425 |
| 385 // Returns the username last used for a successful authentication. | 426 // Returns the username last used for a successful authentication. |
| 386 // Returns empty if there is no such username. | 427 // Returns empty if there is no such username. May be called on any |
| 428 // thread. |
| 387 const std::string& GetAuthenticatedUsername(); | 429 const std::string& GetAuthenticatedUsername(); |
| 388 | 430 |
| 389 // Check if the database has been populated with a full "initial" download of | 431 // Check if the database has been populated with a full "initial" download of |
| 390 // sync items for each data type currently present in the routing info. | 432 // sync items for each data type currently present in the routing info. |
| 391 // Prerequisite for calling this is that OnInitializationComplete has been | 433 // Prerequisite for calling this is that OnInitializationComplete has been |
| 392 // called. | 434 // called. May be called from any thread. |
| 393 bool InitialSyncEndedForAllEnabledTypes(); | 435 bool InitialSyncEndedForAllEnabledTypes(); |
| 394 | 436 |
| 395 // Update tokens that we're using in Sync. Email must stay the same. | 437 // Update tokens that we're using in Sync. Email must stay the same. |
| 396 void UpdateCredentials(const SyncCredentials& credentials); | 438 void UpdateCredentials(const SyncCredentials& credentials); |
| 397 | 439 |
| 398 // Called when the user disables or enables a sync type. | 440 // Called when the user disables or enables a sync type. |
| 399 void UpdateEnabledTypes(); | 441 void UpdateEnabledTypes(); |
| 400 | 442 |
| 401 // Conditionally sets the flag in the Nigori node which instructs other | 443 // Conditionally sets the flag in the Nigori node which instructs other |
| 402 // clients to start syncing tabs. | 444 // clients to start syncing tabs. |
| (...skipping 24 matching lines...) Expand all Loading... |
| 427 // Switches the mode of operation to CONFIGURATION_MODE and | 469 // Switches the mode of operation to CONFIGURATION_MODE and |
| 428 // schedules a config task to fetch updates for |types|. | 470 // schedules a config task to fetch updates for |types|. |
| 429 void RequestConfig(const syncable::ModelTypeBitSet& types, | 471 void RequestConfig(const syncable::ModelTypeBitSet& types, |
| 430 sync_api::ConfigureReason reason); | 472 sync_api::ConfigureReason reason); |
| 431 | 473 |
| 432 void RequestCleanupDisabledTypes(); | 474 void RequestCleanupDisabledTypes(); |
| 433 | 475 |
| 434 // Request a clearing of all data on the server | 476 // Request a clearing of all data on the server |
| 435 void RequestClearServerData(); | 477 void RequestClearServerData(); |
| 436 | 478 |
| 479 // Add/remove change observers. |
| 480 void AddChangeObserver(ChangeObserver* observer); |
| 481 void RemoveChangeObserver(ChangeObserver* observer); |
| 482 |
| 437 // Adds a listener to be notified of sync events. | 483 // Adds a listener to be notified of sync events. |
| 438 // NOTE: It is OK (in fact, it's probably a good idea) to call this before | 484 // NOTE: It is OK (in fact, it's probably a good idea) to call this before |
| 439 // having received OnInitializationCompleted. | 485 // having received OnInitializationCompleted. |
| 440 void AddObserver(Observer* observer); | 486 void AddObserver(Observer* observer); |
| 441 | 487 |
| 442 // Remove the given observer. Make sure to call this if the | 488 // Remove the given observer. Make sure to call this if the |
| 443 // Observer is being destroyed so the SyncManager doesn't | 489 // Observer is being destroyed so the SyncManager doesn't |
| 444 // potentially dereference garbage. | 490 // potentially dereference garbage. |
| 445 void RemoveObserver(Observer* observer); | 491 void RemoveObserver(Observer* observer); |
| 446 | 492 |
| 447 // Status-related getters. Typically GetStatusSummary will suffice, but | 493 // Status-related getters. Typically GetStatusSummary will suffice, but |
| 448 // GetDetailedSyncStatus can be useful for gathering debug-level details of | 494 // GetDetailedSyncStatus can be useful for gathering debug-level details of |
| 449 // the internals of the sync engine. | 495 // the internals of the sync engine. May be called on any thread. |
| 450 Status::Summary GetStatusSummary() const; | 496 Status::Summary GetStatusSummary() const; |
| 451 Status GetDetailedStatus() const; | 497 Status GetDetailedStatus() const; |
| 452 | 498 |
| 453 // Whether or not the Nigori node is encrypted using an explicit passphrase. | 499 // Whether or not the Nigori node is encrypted using an explicit passphrase. |
| 500 // May be called on any thread. |
| 454 bool IsUsingExplicitPassphrase(); | 501 bool IsUsingExplicitPassphrase(); |
| 455 | 502 |
| 456 // Get the internal implementation for use by BaseTransaction, etc. | |
| 457 SyncInternal* GetImpl() const; | |
| 458 | |
| 459 // Call periodically from a database-safe thread to persist recent changes | 503 // Call periodically from a database-safe thread to persist recent changes |
| 460 // to the syncapi model. | 504 // to the syncapi model. |
| 461 void SaveChanges(); | 505 void SaveChanges(); |
| 462 | 506 |
| 507 // Requests the syncer to stop as soon as possible. May be called |
| 508 // from any thread. |
| 463 void RequestEarlyExit(); | 509 void RequestEarlyExit(); |
| 464 | 510 |
| 465 // Issue a final SaveChanges, close sqlite handles, and stop running threads. | 511 // Issue a final SaveChanges, close sqlite handles, and stop running threads. |
| 466 // Must be called from the same thread that called Init(). | |
| 467 void Shutdown(); | 512 void Shutdown(); |
| 468 | 513 |
| 514 // May be called from any thread. |
| 469 UserShare* GetUserShare() const; | 515 UserShare* GetUserShare() const; |
| 470 | 516 |
| 471 // Inform the cryptographer of the most recent passphrase and set of encrypted | 517 // Inform the cryptographer of the most recent passphrase and set of encrypted |
| 472 // types (from nigori node), then ensure all data that needs encryption is | 518 // types (from nigori node), then ensure all data that needs encryption is |
| 473 // encrypted with the appropriate passphrase. | 519 // encrypted with the appropriate passphrase. |
| 474 // Note: opens a transaction and can trigger ON_PASSPHRASE_REQUIRED, so must | 520 // Note: opens a transaction and can trigger ON_PASSPHRASE_REQUIRED, so must |
| 475 // only be called after syncapi has been initialized. | 521 // only be called after syncapi has been initialized. |
| 476 void RefreshEncryption(); | 522 void RefreshEncryption(); |
| 477 | 523 |
| 478 // Enable encryption of all sync data. Once enabled, it can never be disabled | 524 // Enable encryption of all sync data. Once enabled, it can never be disabled |
| 479 // without clearing the server data. | 525 // without clearing the server data. |
| 480 void EnableEncryptEverything(); | 526 void EnableEncryptEverything(); |
| 481 | 527 |
| 482 // Returns true if we are currently encrypting all sync data. | 528 // Returns true if we are currently encrypting all sync data. May |
| 529 // be called on any thread. |
| 483 bool EncryptEverythingEnabled() const; | 530 bool EncryptEverythingEnabled() const; |
| 484 | 531 |
| 485 // Gets the set of encrypted types from the cryptographer | 532 // Gets the set of encrypted types from the cryptographer |
| 486 // Note: opens a transaction. | 533 // Note: opens a transaction. May be called from any thread. |
| 487 syncable::ModelTypeSet GetEncryptedDataTypes() const; | 534 syncable::ModelTypeSet GetEncryptedDataTypes() const; |
| 488 | 535 |
| 489 // Reads the nigori node to determine if any experimental types should be | 536 // Reads the nigori node to determine if any experimental types should be |
| 490 // enabled. | 537 // enabled. |
| 491 // Note: opens a transaction. | 538 // Note: opens a transaction. May be called on any thread. |
| 492 bool ReceivedExperimentalTypes(syncable::ModelTypeSet* to_add) const; | 539 bool ReceivedExperimentalTypes(syncable::ModelTypeSet* to_add) const; |
| 493 | 540 |
| 494 // Uses a read-only transaction to determine if the directory being synced has | 541 // Uses a read-only transaction to determine if the directory being synced has |
| 495 // any remaining unsynced items. | 542 // any remaining unsynced items. May be called on any thread. |
| 496 bool HasUnsyncedItems() const; | 543 bool HasUnsyncedItems() const; |
| 497 | 544 |
| 498 // Logs the list of unsynced meta handles. | |
| 499 void LogUnsyncedItems(int level) const; | |
| 500 | |
| 501 // Functions used for testing. | 545 // Functions used for testing. |
| 502 | 546 |
| 503 void TriggerOnNotificationStateChangeForTest( | 547 void TriggerOnNotificationStateChangeForTest( |
| 504 bool notifications_enabled); | 548 bool notifications_enabled); |
| 505 | 549 |
| 506 void TriggerOnIncomingNotificationForTest( | 550 void TriggerOnIncomingNotificationForTest( |
| 507 const syncable::ModelTypeBitSet& model_types); | 551 const syncable::ModelTypeBitSet& model_types); |
| 508 | 552 |
| 509 private: | 553 private: |
| 554 base::ThreadChecker thread_checker_; |
| 555 |
| 510 // An opaque pointer to the nested private class. | 556 // An opaque pointer to the nested private class. |
| 511 SyncInternal* data_; | 557 SyncInternal* data_; |
| 512 | 558 |
| 513 DISALLOW_COPY_AND_ASSIGN(SyncManager); | 559 DISALLOW_COPY_AND_ASSIGN(SyncManager); |
| 514 }; | 560 }; |
| 515 | 561 |
| 516 bool InitialSyncEndedForTypes(syncable::ModelTypeSet types, UserShare* share); | 562 bool InitialSyncEndedForTypes(syncable::ModelTypeSet types, UserShare* share); |
| 517 | 563 |
| 518 // Returns the string representation of a PassphraseRequiredReason value. | 564 // Returns the string representation of a PassphraseRequiredReason value. |
| 519 std::string PassphraseRequiredReasonToString(PassphraseRequiredReason reason); | 565 std::string PassphraseRequiredReasonToString(PassphraseRequiredReason reason); |
| 520 | 566 |
| 521 } // namespace sync_api | 567 } // namespace sync_api |
| 522 | 568 |
| 523 #endif // CHROME_BROWSER_SYNC_INTERNAL_API_SYNC_MANAGER_H_ | 569 #endif // CHROME_BROWSER_SYNC_INTERNAL_API_SYNC_MANAGER_H_ |
| OLD | NEW |