1 // Copyright (c) 2012 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_GLUE_SYNC_BACKEND_HOST_H_ 6 #define CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_ 7 8 #include <string> 9 10 #include "base/basictypes.h" 11 #include "base/callback.h" 12 #include "base/compiler_specific.h" 13 #include "base/memory/ref_counted.h" 14 #include "base/memory/scoped_ptr.h" 15 #include "base/memory/weak_ptr.h" 16 #include "base/threading/thread.h" 17 #include "chrome/browser/invalidation/invalidation_service.h" 18 #include "chrome/browser/sync/glue/backend_data_type_configurer.h" 19 #include "chrome/browser/sync/glue/extensions_activity_monitor.h" 20 #include "content/public/browser/notification_observer.h" 21 #include "content/public/browser/notification_registrar.h" 22 #include "google_apis/gaia/google_service_auth_error.h" 23 #include "sync/internal_api/public/base/model_type.h" 24 #include "sync/internal_api/public/configure_reason.h" 25 #include "sync/internal_api/public/engine/model_safe_worker.h" 26 #include "sync/internal_api/public/sessions/sync_session_snapshot.h" 27 #include "sync/internal_api/public/sync_encryption_handler.h" 28 #include "sync/internal_api/public/sync_manager.h" 29 #include "sync/internal_api/public/util/report_unrecoverable_error_function.h" 30 #include "sync/internal_api/public/util/unrecoverable_error_handler.h" 31 #include "sync/internal_api/public/util/weak_handle.h" 32 #include "sync/notifier/invalidation_handler.h" 33 #include "sync/protocol/encryption.pb.h" 34 #include "sync/protocol/sync_protocol_error.h" 35 #include "sync/util/extensions_activity.h" 36 #include "url/gurl.h" 37 38 class Profile; 39 40 namespace base { 41 class MessageLoop; 42 } 43 44 namespace syncer { 45 class SyncManagerFactory; 46 } 47 48 namespace browser_sync { 49 50 class ChangeProcessor; 51 class InvalidatorStorage; 52 class SyncBackendRegistrar; 53 class SyncPrefs; 54 class SyncedDeviceTracker; 55 struct Experiments; 56 57 // SyncFrontend is the interface used by SyncBackendHost to communicate with 58 // the entity that created it and, presumably, is interested in sync-related 59 // activity. 60 // NOTE: All methods will be invoked by a SyncBackendHost on the same thread 61 // used to create that SyncBackendHost. 62 class SyncFrontend { 63 public: 64 SyncFrontend() {} 65 66 // The backend has completed initialization and it is now ready to 67 // accept and process changes. If success is false, initialization 68 // wasn't able to be completed and should be retried. 69 // 70 // |js_backend| is what about:sync interacts with; it's different 71 // from the 'Backend' in 'OnBackendInitialized' (unfortunately). It 72 // is initialized only if |success| is true. 73 virtual void OnBackendInitialized( 74 const syncer::WeakHandle<syncer::JsBackend>& js_backend, 75 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& 76 debug_info_listener, 77 bool success) = 0; 78 79 // The backend queried the server recently and received some updates. 80 virtual void OnSyncCycleCompleted() = 0; 81 82 // Configure ran into some kind of error. But it is scheduled to be 83 // retried. 84 virtual void OnSyncConfigureRetry() = 0; 85 86 // The status of the connection to the sync server has changed. 87 virtual void OnConnectionStatusChange( 88 syncer::ConnectionStatus status) = 0; 89 90 // We are no longer permitted to communicate with the server. Sync should 91 // be disabled and state cleaned up at once. 92 virtual void OnStopSyncingPermanently() = 0; 93 94 // The syncer requires a passphrase to decrypt sensitive updates. This is 95 // called when the first sensitive data type is setup by the user and anytime 96 // the passphrase is changed by another synced client. |reason| denotes why 97 // the passphrase was required. |pending_keys| is a copy of the 98 // cryptographer's pending keys to be passed on to the frontend in order to 99 // be cached. 100 virtual void OnPassphraseRequired( 101 syncer::PassphraseRequiredReason reason, 102 const sync_pb::EncryptedData& pending_keys) = 0; 103 104 // Called when the passphrase provided by the user is 105 // accepted. After this is called, updates to sensitive nodes are 106 // encrypted using the accepted passphrase. 107 virtual void OnPassphraseAccepted() = 0; 108 109 // Called when the set of encrypted types or the encrypt everything 110 // flag has been changed. Note that encryption isn't complete until 111 // the OnEncryptionComplete() notification has been sent (see 112 // below). 113 // 114 // |encrypted_types| will always be a superset of 115 // syncer::Cryptographer::SensitiveTypes(). If |encrypt_everything| is 116 // true, |encrypted_types| will be the set of all known types. 117 // 118 // Until this function is called, observers can assume that the set 119 // of encrypted types is syncer::Cryptographer::SensitiveTypes() and that 120 // the encrypt everything flag is false. 121 virtual void OnEncryptedTypesChanged( 122 syncer::ModelTypeSet encrypted_types, 123 bool encrypt_everything) = 0; 124 125 // Called after we finish encrypting the current set of encrypted 126 // types. 127 virtual void OnEncryptionComplete() = 0; 128 129 // Called to perform migration of |types|. 130 virtual void OnMigrationNeededForTypes(syncer::ModelTypeSet types) = 0; 131 132 // Inform the Frontend that new datatypes are available for registration. 133 virtual void OnExperimentsChanged( 134 const syncer::Experiments& experiments) = 0; 135 136 // Called when the sync cycle returns there is an user actionable error. 137 virtual void OnActionableError(const syncer::SyncProtocolError& error) = 0; 138 139 protected: 140 // Don't delete through SyncFrontend interface. 141 virtual ~SyncFrontend() { 142 } 143 private: 144 DISALLOW_COPY_AND_ASSIGN(SyncFrontend); 145 }; 146 147 // A UI-thread safe API into the sync backend that "hosts" the top-level 148 // syncapi element, the SyncManager, on its own thread. This class handles 149 // dispatch of potentially blocking calls to appropriate threads and ensures 150 // that the SyncFrontend is only accessed on the UI loop. 151 class SyncBackendHost 152 : public BackendDataTypeConfigurer, 153 public content::NotificationObserver, 154 public syncer::InvalidationHandler { 155 public: 156 typedef syncer::SyncStatus Status; 157 158 // Create a SyncBackendHost with a reference to the |frontend| that 159 // it serves and communicates to via the SyncFrontend interface (on 160 // the same thread it used to call the constructor). Must outlive 161 // |sync_prefs| and |invalidator_storage|. 162 SyncBackendHost( 163 const std::string& name, 164 Profile* profile, 165 const base::WeakPtr<SyncPrefs>& sync_prefs); 166 167 // For testing. 168 // TODO(skrul): Extract an interface so this is not needed. 169 explicit SyncBackendHost(Profile* profile); 170 virtual ~SyncBackendHost(); 171 172 // Called on |frontend_loop_| to kick off asynchronous initialization. 173 // As a fallback when no cached auth information is available, try to 174 // bootstrap authentication using |lsid|, if it isn't empty. 175 // Optionally delete the Sync Data folder (if it's corrupt). 176 // |report_unrecoverable_error_function| can be NULL. 177 // Note: |unrecoverable_error_handler| may be invoked from any thread. 178 void Initialize( 179 SyncFrontend* frontend, 180 scoped_ptr<base::Thread> sync_thread, 181 const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, 182 const GURL& service_url, 183 const syncer::SyncCredentials& credentials, 184 bool delete_sync_data_folder, 185 scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory, 186 scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler, 187 syncer::ReportUnrecoverableErrorFunction 188 report_unrecoverable_error_function); 189 190 // Called on |frontend_loop| to update SyncCredentials. 191 virtual void UpdateCredentials(const syncer::SyncCredentials& credentials); 192 193 // This starts the SyncerThread running a Syncer object to communicate with 194 // sync servers. Until this is called, no changes will leave or enter this 195 // browser from the cloud / sync servers. 196 // Called on |frontend_loop_|. 197 virtual void StartSyncingWithServer(); 198 199 // Called on |frontend_loop_| to asynchronously set a new passphrase for 200 // encryption. Note that it is an error to call SetEncryptionPassphrase under 201 // the following circumstances: 202 // - An explicit passphrase has already been set 203 // - |is_explicit| is true and we have pending keys. 204 // When |is_explicit| is false, a couple of things could happen: 205 // - If there are pending keys, we try to decrypt them. If decryption works, 206 // this acts like a call to SetDecryptionPassphrase. If not, the GAIA 207 // passphrase passed in is cached so we can re-encrypt with it in future. 208 // - If there are no pending keys, data is encrypted with |passphrase| (this 209 // is a no-op if data was already encrypted with |passphrase|.) 210 void SetEncryptionPassphrase(const std::string& passphrase, bool is_explicit); 211 212 // Called on |frontend_loop_| to use the provided passphrase to asynchronously 213 // attempt decryption. Returns false immediately if the passphrase could not 214 // be used to decrypt a locally cached copy of encrypted keys; returns true 215 // otherwise. If new encrypted keys arrive during the asynchronous call, 216 // OnPassphraseRequired may be triggered at a later time. It is an error to 217 // call this when there are no pending keys. 218 bool SetDecryptionPassphrase(const std::string& passphrase) 219 WARN_UNUSED_RESULT; 220 221 // Called on |frontend_loop_| to kick off shutdown procedure. After this, no 222 // further sync activity will occur with the sync server and no further 223 // change applications will occur from changes already downloaded. 224 // Furthermore, no notifications will be sent to any invalidation handler. 225 virtual void StopSyncingForShutdown(); 226 227 // Called on |frontend_loop_| to kick off shutdown. 228 // See the implementation and Core::DoShutdown for details. 229 // Must be called *after* StopSyncingForShutdown. Caller should claim sync 230 // thread using STOP_AND_CLAIM_THREAD or DISABLE_AND_CLAIM_THREAD if sync 231 // backend might be recreated later because otherwise: 232 // * sync loop may be stopped on main loop and cause it to be blocked. 233 // * new/old backend may interfere with each other if new backend is created 234 // before old one finishes cleanup. 235 enum ShutdownOption { 236 STOP, // Stop syncing and let backend stop sync thread. 237 STOP_AND_CLAIM_THREAD, // Stop syncing and return sync thread. 238 DISABLE_AND_CLAIM_THREAD, // Disable sync and return sync thread. 239 }; 240 scoped_ptr<base::Thread> Shutdown(ShutdownOption option); 241 242 // Removes all current registrations from the backend on the 243 // InvalidationService. 244 void UnregisterInvalidationIds(); 245 246 // Changes the set of data types that are currently being synced. 247 // The ready_task will be run when configuration is done with the 248 // set of all types that failed configuration (i.e., if its argument 249 // is non-empty, then an error was encountered). 250 virtual void ConfigureDataTypes( 251 syncer::ConfigureReason reason, 252 const DataTypeConfigStateMap& config_state_map, 253 const base::Callback<void(syncer::ModelTypeSet, 254 syncer::ModelTypeSet)>& ready_task, 255 const base::Callback<void()>& retry_callback) OVERRIDE; 256 257 // Turns on encryption of all present and future sync data. 258 virtual void EnableEncryptEverything(); 259 260 // Activates change processing for the given data type. This must 261 // be called synchronously with the data type's model association so 262 // no changes are dropped between model association and change 263 // processor activation. 264 void ActivateDataType( 265 syncer::ModelType type, syncer::ModelSafeGroup group, 266 ChangeProcessor* change_processor); 267 268 // Deactivates change processing for the given data type. 269 void DeactivateDataType(syncer::ModelType type); 270 271 // Called on |frontend_loop_| to obtain a handle to the UserShare needed for 272 // creating transactions. Should not be called before we signal 273 // initialization is complete with OnBackendInitialized(). 274 syncer::UserShare* GetUserShare() const; 275 276 // Called from any thread to obtain current status information in detailed or 277 // summarized form. 278 Status GetDetailedStatus(); 279 syncer::sessions::SyncSessionSnapshot GetLastSessionSnapshot() const; 280 281 // Determines if the underlying sync engine has made any local changes to 282 // items that have not yet been synced with the server. 283 // ONLY CALL THIS IF OnInitializationComplete was called! 284 bool HasUnsyncedItems() const; 285 286 // Whether or not we are syncing encryption keys. 287 bool IsNigoriEnabled() const; 288 289 // Returns the type of passphrase being used to encrypt data. See 290 // sync_encryption_handler.h. 291 syncer::PassphraseType GetPassphraseType() const; 292 293 // If an explicit passphrase is in use, returns the time at which that 294 // passphrase was set (if available). 295 base::Time GetExplicitPassphraseTime() const; 296 297 // True if the cryptographer has any keys available to attempt decryption. 298 // Could mean we've downloaded and loaded Nigori objects, or we bootstrapped 299 // using a token previously received. 300 bool IsCryptographerReady(const syncer::BaseTransaction* trans) const; 301 302 void GetModelSafeRoutingInfo(syncer::ModelSafeRoutingInfo* out) const; 303 304 // Fetches the DeviceInfo tracker. 305 virtual SyncedDeviceTracker* GetSyncedDeviceTracker() const; 306 307 base::MessageLoop* GetSyncLoopForTesting(); 308 309 protected: 310 // The types and functions below are protected so that test 311 // subclasses can use them. 312 // 313 // TODO(akalin): Figure out a better way for tests to hook into 314 // SyncBackendHost. 315 316 typedef base::Callback<scoped_ptr<syncer::HttpPostProviderFactory>(void)> 317 MakeHttpBridgeFactoryFn; 318 319 // Utility struct for holding initialization options. 320 struct DoInitializeOptions { 321 DoInitializeOptions( 322 base::MessageLoop* sync_loop, 323 SyncBackendRegistrar* registrar, 324 const syncer::ModelSafeRoutingInfo& routing_info, 325 const std::vector<syncer::ModelSafeWorker*>& workers, 326 const scoped_refptr<syncer::ExtensionsActivity>& extensions_activity, 327 const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, 328 const GURL& service_url, 329 MakeHttpBridgeFactoryFn make_http_bridge_factory_fn, 330 const syncer::SyncCredentials& credentials, 331 const std::string& invalidator_client_id, 332 scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory, 333 bool delete_sync_data_folder, 334 const std::string& restored_key_for_bootstrapping, 335 const std::string& restored_keystore_key_for_bootstrapping, 336 scoped_ptr<syncer::InternalComponentsFactory> 337 internal_components_factory, 338 scoped_ptr<syncer::UnrecoverableErrorHandler> 339 unrecoverable_error_handler, 340 syncer::ReportUnrecoverableErrorFunction 341 report_unrecoverable_error_function, 342 bool use_oauth2_token); 343 ~DoInitializeOptions(); 344 345 base::MessageLoop* sync_loop; 346 SyncBackendRegistrar* registrar; 347 syncer::ModelSafeRoutingInfo routing_info; 348 std::vector<syncer::ModelSafeWorker*> workers; 349 scoped_refptr<syncer::ExtensionsActivity> extensions_activity; 350 syncer::WeakHandle<syncer::JsEventHandler> event_handler; 351 GURL service_url; 352 // Overridden by tests. 353 MakeHttpBridgeFactoryFn make_http_bridge_factory_fn; 354 syncer::SyncCredentials credentials; 355 const std::string invalidator_client_id; 356 scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory; 357 std::string lsid; 358 bool delete_sync_data_folder; 359 std::string restored_key_for_bootstrapping; 360 std::string restored_keystore_key_for_bootstrapping; 361 scoped_ptr<syncer::InternalComponentsFactory> internal_components_factory; 362 scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler; 363 syncer::ReportUnrecoverableErrorFunction 364 report_unrecoverable_error_function; 365 bool use_oauth2_token; 366 }; 367 368 // Allows tests to perform alternate core initialization work. 369 virtual void InitCore(scoped_ptr<DoInitializeOptions> options); 370 371 // Request the syncer to reconfigure with the specfied params. 372 // Virtual for testing. 373 virtual void RequestConfigureSyncer( 374 syncer::ConfigureReason reason, 375 syncer::ModelTypeSet to_download, 376 syncer::ModelTypeSet to_purge, 377 syncer::ModelTypeSet to_journal, 378 syncer::ModelTypeSet to_unapply, 379 syncer::ModelTypeSet to_ignore, 380 const syncer::ModelSafeRoutingInfo& routing_info, 381 const base::Callback<void(syncer::ModelTypeSet, 382 syncer::ModelTypeSet)>& ready_task, 383 const base::Closure& retry_callback); 384 385 // Called when the syncer has finished performing a configuration. 386 void FinishConfigureDataTypesOnFrontendLoop( 387 const syncer::ModelTypeSet enabled_types, 388 const syncer::ModelTypeSet succeeded_configuration_types, 389 const syncer::ModelTypeSet failed_configuration_types, 390 const base::Callback<void(syncer::ModelTypeSet, 391 syncer::ModelTypeSet)>& ready_task); 392 393 // Called when the SyncManager has been constructed and initialized. 394 // Stores |js_backend| and |debug_info_listener| on the UI thread for 395 // consumption when initialization is complete. 396 virtual void HandleSyncManagerInitializationOnFrontendLoop( 397 const syncer::WeakHandle<syncer::JsBackend>& js_backend, 398 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener>& 399 debug_info_listener, 400 syncer::ModelTypeSet restored_types); 401 402 SyncFrontend* frontend() { return frontend_; } 403 404 private: 405 // The real guts of SyncBackendHost, to keep the public client API clean. 406 class Core; 407 408 // An enum representing the steps to initializing the SyncBackendHost. 409 enum InitializationState { 410 NOT_ATTEMPTED, 411 CREATING_SYNC_MANAGER, // We're waiting for the first callback from the 412 // sync thread to inform us that the sync 413 // manager has been created. 414 NOT_INITIALIZED, // Initialization hasn't completed, but we've 415 // constructed a SyncManager. 416 INITIALIZATING_CONTROL_TYPES, // Downloading control types and 417 // initializing their handlers. 418 INITIALIZED, // Initialization is complete. 419 }; 420 421 // Checks if we have received a notice to turn on experimental datatypes 422 // (via the nigori node) and informs the frontend if that is the case. 423 // Note: it is illegal to call this before the backend is initialized. 424 void AddExperimentalTypes(); 425 426 // Downloading of control types failed and will be retried. Invokes the 427 // frontend's sync configure retry method. 428 void HandleControlTypesDownloadRetry(); 429 430 // InitializationComplete passes through the SyncBackendHost to forward 431 // on to |frontend_|, and so that tests can intercept here if they need to 432 // set up initial conditions. 433 void HandleInitializationCompletedOnFrontendLoop( 434 bool success); 435 436 // Called from Core::OnSyncCycleCompleted to handle updating frontend 437 // thread components. 438 void HandleSyncCycleCompletedOnFrontendLoop( 439 const syncer::sessions::SyncSessionSnapshot& snapshot); 440 441 // Called when the syncer failed to perform a configuration and will 442 // eventually retry. FinishingConfigurationOnFrontendLoop(..) will be called 443 // on successful completion. 444 void RetryConfigurationOnFrontendLoop(const base::Closure& retry_callback); 445 446 // Helpers to persist a token that can be used to bootstrap sync encryption 447 // across browser restart to avoid requiring the user to re-enter their 448 // passphrase. |token| must be valid UTF-8 as we use the PrefService for 449 // storage. 450 void PersistEncryptionBootstrapToken( 451 const std::string& token, 452 syncer::BootstrapTokenType token_type); 453 454 // For convenience, checks if initialization state is INITIALIZED. 455 bool initialized() const { return initialization_state_ == INITIALIZED; } 456 457 // Let the front end handle the actionable error event. 458 void HandleActionableErrorEventOnFrontendLoop( 459 const syncer::SyncProtocolError& sync_error); 460 461 // Checks if |passphrase| can be used to decrypt the cryptographer's pending 462 // keys that were cached during NotifyPassphraseRequired. Returns true if 463 // decryption was successful. Returns false otherwise. Must be called with a 464 // non-empty pending keys cache. 465 bool CheckPassphraseAgainstCachedPendingKeys( 466 const std::string& passphrase) const; 467 468 // Invoked when a passphrase is required to decrypt a set of Nigori keys, 469 // or for encrypting. |reason| denotes why the passphrase was required. 470 // |pending_keys| is a copy of the cryptographer's pending keys, that are 471 // cached by the frontend. If there are no pending keys, or if the passphrase 472 // required reason is REASON_ENCRYPTION, an empty EncryptedData object is 473 // passed. 474 void NotifyPassphraseRequired(syncer::PassphraseRequiredReason reason, 475 sync_pb::EncryptedData pending_keys); 476 477 // Invoked when the passphrase provided by the user has been accepted. 478 void NotifyPassphraseAccepted(); 479 480 // Invoked when an updated token is available from the sync server. 481 void NotifyUpdatedToken(const std::string& token); 482 483 // Invoked when the set of encrypted types or the encrypt 484 // everything flag changes. 485 void NotifyEncryptedTypesChanged( 486 syncer::ModelTypeSet encrypted_types, 487 bool encrypt_everything); 488 489 // Invoked when sync finishes encrypting new datatypes. 490 void NotifyEncryptionComplete(); 491 492 // Invoked when the passphrase state has changed. Caches the passphrase state 493 // for later use on the UI thread. 494 // If |type| is FROZEN_IMPLICIT_PASSPHRASE or CUSTOM_PASSPHRASE, 495 // |explicit_passphrase_time| is the time at which that passphrase was set 496 // (if available). 497 void HandlePassphraseTypeChangedOnFrontendLoop( 498 syncer::PassphraseType type, 499 base::Time explicit_passphrase_time); 500 501 void HandleStopSyncingPermanentlyOnFrontendLoop(); 502 503 // Dispatched to from OnConnectionStatusChange to handle updating 504 // frontend UI components. 505 void HandleConnectionStatusChangeOnFrontendLoop( 506 syncer::ConnectionStatus status); 507 508 // syncer::InvalidationHandler-like functions. 509 void HandleInvalidatorStateChangeOnFrontendLoop( 510 syncer::InvalidatorState state); 511 void HandleIncomingInvalidationOnFrontendLoop( 512 const syncer::ObjectIdInvalidationMap& invalidation_map); 513 514 // NotificationObserver implementation. 515 virtual void Observe( 516 int type, 517 const content::NotificationSource& source, 518 const content::NotificationDetails& details) OVERRIDE; 519 520 // InvalidationHandler implementation. 521 virtual void OnInvalidatorStateChange( 522 syncer::InvalidatorState state) OVERRIDE; 523 virtual void OnIncomingInvalidation( 524 const syncer::ObjectIdInvalidationMap& invalidation_map) OVERRIDE; 525 526 // Handles stopping the core's SyncManager, accounting for whether 527 // initialization is done yet. 528 void StopSyncManagerForShutdown(); 529 530 base::WeakPtrFactory<SyncBackendHost> weak_ptr_factory_; 531 532 content::NotificationRegistrar notification_registrar_; 533 534 // A reference to the MessageLoop used to construct |this|, so we know how 535 // to safely talk back to the SyncFrontend. 536 base::MessageLoop* const frontend_loop_; 537 538 Profile* const profile_; 539 540 // Name used for debugging (set from profile_->GetDebugName()). 541 const std::string name_; 542 543 // Our core, which communicates directly to the syncapi. Use refptr instead 544 // of WeakHandle because |core_| is created on UI loop but released on 545 // sync loop. 546 scoped_refptr<Core> core_; 547 548 InitializationState initialization_state_; 549 550 const base::WeakPtr<SyncPrefs> sync_prefs_; 551 552 ExtensionsActivityMonitor extensions_activity_monitor_; 553 554 scoped_ptr<SyncBackendRegistrar> registrar_; 555 556 // The frontend which we serve (and are owned by). 557 SyncFrontend* frontend_; 558 559 // We cache the cryptographer's pending keys whenever NotifyPassphraseRequired 560 // is called. This way, before the UI calls SetDecryptionPassphrase on the 561 // syncer, it can avoid the overhead of an asynchronous decryption call and 562 // give the user immediate feedback about the passphrase entered by first 563 // trying to decrypt the cached pending keys on the UI thread. Note that 564 // SetDecryptionPassphrase can still fail after the cached pending keys are 565 // successfully decrypted if the pending keys have changed since the time they 566 // were cached. 567 sync_pb::EncryptedData cached_pending_keys_; 568 569 // The state of the passphrase required to decrypt the bag of encryption keys 570 // in the nigori node. Updated whenever a new nigori node arrives or the user 571 // manually changes their passphrase state. Cached so we can synchronously 572 // check it from the UI thread. 573 syncer::PassphraseType cached_passphrase_type_; 574 575 // If an explicit passphrase is in use, the time at which the passphrase was 576 // first set (if available). 577 base::Time cached_explicit_passphrase_time_; 578 579 // UI-thread cache of the last SyncSessionSnapshot received from syncapi. 580 syncer::sessions::SyncSessionSnapshot last_snapshot_; 581 582 // Temporary holder of sync manager's initialization results. Set by 583 // HandleSyncManagerInitializationOnFrontendLoop, and consumed when we pass 584 // it via OnBackendInitialized in the final state of 585 // HandleInitializationCompletedOnFrontendLoop. 586 syncer::WeakHandle<syncer::JsBackend> js_backend_; 587 syncer::WeakHandle<syncer::DataTypeDebugInfoListener> debug_info_listener_; 588 589 invalidation::InvalidationService* invalidator_; 590 bool invalidation_handler_registered_; 591 592 DISALLOW_COPY_AND_ASSIGN(SyncBackendHost); 593 }; 594 595 } // namespace browser_sync 596 597 #endif // CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_H_ 598