1 // Copyright 2013 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_IMPL_H_ 6 #define CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_IMPL_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/scoped_ptr.h" 14 #include "base/memory/weak_ptr.h" 15 #include "base/threading/thread.h" 16 #include "chrome/browser/sync/glue/extensions_activity_monitor.h" 17 #include "chrome/browser/sync/glue/sync_backend_host.h" 18 #include "components/sync_driver/backend_data_type_configurer.h" 19 #include "content/public/browser/notification_observer.h" 20 #include "content/public/browser/notification_registrar.h" 21 #include "sync/internal_api/public/base/model_type.h" 22 #include "sync/internal_api/public/configure_reason.h" 23 #include "sync/internal_api/public/sessions/sync_session_snapshot.h" 24 #include "sync/internal_api/public/sessions/type_debug_info_observer.h" 25 #include "sync/internal_api/public/sync_manager.h" 26 #include "sync/internal_api/public/util/report_unrecoverable_error_function.h" 27 #include "sync/internal_api/public/util/unrecoverable_error_handler.h" 28 #include "sync/internal_api/public/util/weak_handle.h" 29 #include "sync/notifier/invalidation_handler.h" 30 #include "sync/protocol/encryption.pb.h" 31 #include "sync/protocol/sync_protocol_error.h" 32 #include "sync/util/extensions_activity.h" 33 34 class GURL; 35 class Profile; 36 37 namespace base { 38 class MessageLoop; 39 } 40 41 namespace invalidation { 42 class InvalidationService; 43 } 44 45 namespace syncer { 46 class NetworkResources; 47 class SyncManagerFactory; 48 } 49 50 namespace sync_driver { 51 class SyncPrefs; 52 } 53 54 namespace browser_sync { 55 56 class ChangeProcessor; 57 class SyncBackendHostCore; 58 class SyncBackendRegistrar; 59 class SyncedDeviceTracker; 60 struct DoInitializeOptions; 61 62 // The only real implementation of the SyncBackendHost. See that interface's 63 // definition for documentation of public methods. 64 class SyncBackendHostImpl 65 : public SyncBackendHost, 66 public content::NotificationObserver, 67 public syncer::InvalidationHandler { 68 public: 69 typedef syncer::SyncStatus Status; 70 71 // Create a SyncBackendHost with a reference to the |frontend| that 72 // it serves and communicates to via the SyncFrontend interface (on 73 // the same thread it used to call the constructor). Must outlive 74 // |sync_prefs|. 75 SyncBackendHostImpl(const std::string& name, 76 Profile* profile, 77 invalidation::InvalidationService* invalidator, 78 const base::WeakPtr<sync_driver::SyncPrefs>& sync_prefs, 79 const base::FilePath& sync_folder); 80 virtual ~SyncBackendHostImpl(); 81 82 // SyncBackendHost implementation. 83 virtual void Initialize( 84 SyncFrontend* frontend, 85 scoped_ptr<base::Thread> sync_thread, 86 const syncer::WeakHandle<syncer::JsEventHandler>& event_handler, 87 const GURL& service_url, 88 const syncer::SyncCredentials& credentials, 89 bool delete_sync_data_folder, 90 scoped_ptr<syncer::SyncManagerFactory> sync_manager_factory, 91 scoped_ptr<syncer::UnrecoverableErrorHandler> unrecoverable_error_handler, 92 syncer::ReportUnrecoverableErrorFunction 93 report_unrecoverable_error_function, 94 syncer::NetworkResources* network_resources) OVERRIDE; 95 virtual void UpdateCredentials( 96 const syncer::SyncCredentials& credentials) OVERRIDE; 97 virtual void StartSyncingWithServer() OVERRIDE; 98 virtual void SetEncryptionPassphrase( 99 const std::string& passphrase, 100 bool is_explicit) OVERRIDE; 101 virtual bool SetDecryptionPassphrase(const std::string& passphrase) 102 OVERRIDE WARN_UNUSED_RESULT; 103 virtual void StopSyncingForShutdown() OVERRIDE; 104 virtual scoped_ptr<base::Thread> Shutdown(ShutdownOption option) OVERRIDE; 105 virtual void UnregisterInvalidationIds() OVERRIDE; 106 virtual void ConfigureDataTypes( 107 syncer::ConfigureReason reason, 108 const DataTypeConfigStateMap& config_state_map, 109 const base::Callback<void(syncer::ModelTypeSet, 110 syncer::ModelTypeSet)>& ready_task, 111 const base::Callback<void()>& retry_callback) OVERRIDE; 112 virtual void ActivateDataType( 113 syncer::ModelType type, syncer::ModelSafeGroup group, 114 ChangeProcessor* change_processor) OVERRIDE; 115 virtual void DeactivateDataType(syncer::ModelType type) OVERRIDE; 116 virtual void EnableEncryptEverything() OVERRIDE; 117 virtual syncer::UserShare* GetUserShare() const OVERRIDE; 118 virtual scoped_ptr<syncer::SyncCoreProxy> GetSyncCoreProxy() OVERRIDE; 119 virtual Status GetDetailedStatus() OVERRIDE; 120 virtual syncer::sessions::SyncSessionSnapshot 121 GetLastSessionSnapshot() const OVERRIDE; 122 virtual bool HasUnsyncedItems() const OVERRIDE; 123 virtual bool IsNigoriEnabled() const OVERRIDE; 124 virtual syncer::PassphraseType GetPassphraseType() const OVERRIDE; 125 virtual base::Time GetExplicitPassphraseTime() const OVERRIDE; 126 virtual bool IsCryptographerReady( 127 const syncer::BaseTransaction* trans) const OVERRIDE; 128 virtual void GetModelSafeRoutingInfo( 129 syncer::ModelSafeRoutingInfo* out) const OVERRIDE; 130 virtual SyncedDeviceTracker* GetSyncedDeviceTracker() const OVERRIDE; 131 virtual void RequestBufferedProtocolEventsAndEnableForwarding() OVERRIDE; 132 virtual void DisableProtocolEventForwarding() OVERRIDE; 133 virtual void EnableDirectoryTypeDebugInfoForwarding() OVERRIDE; 134 virtual void DisableDirectoryTypeDebugInfoForwarding() OVERRIDE; 135 virtual void GetAllNodesForTypes( 136 syncer::ModelTypeSet types, 137 base::Callback<void(const std::vector<syncer::ModelType>&, 138 ScopedVector<base::ListValue>)> type) OVERRIDE; 139 virtual base::MessageLoop* GetSyncLoopForTesting() OVERRIDE; 140 141 protected: 142 // The types and functions below are protected so that test 143 // subclasses can use them. 144 145 // Allows tests to perform alternate core initialization work. 146 virtual void InitCore(scoped_ptr<DoInitializeOptions> options); 147 148 // Request the syncer to reconfigure with the specfied params. 149 // Virtual for testing. 150 virtual void RequestConfigureSyncer( 151 syncer::ConfigureReason reason, 152 syncer::ModelTypeSet to_download, 153 syncer::ModelTypeSet to_purge, 154 syncer::ModelTypeSet to_journal, 155 syncer::ModelTypeSet to_unapply, 156 syncer::ModelTypeSet to_ignore, 157 const syncer::ModelSafeRoutingInfo& routing_info, 158 const base::Callback<void(syncer::ModelTypeSet, 159 syncer::ModelTypeSet)>& ready_task, 160 const base::Closure& retry_callback); 161 162 // Called when the syncer has finished performing a configuration. 163 void FinishConfigureDataTypesOnFrontendLoop( 164 const syncer::ModelTypeSet enabled_types, 165 const syncer::ModelTypeSet succeeded_configuration_types, 166 const syncer::ModelTypeSet failed_configuration_types, 167 const base::Callback<void(syncer::ModelTypeSet, 168 syncer::ModelTypeSet)>& ready_task); 169 170 // Reports backend initialization success. Includes some objects from sync 171 // manager initialization to be passed back to the UI thread. 172 // 173 // |sync_core_proxy| points to an object owned by the SyncManager. Ownership 174 // is not transferred, but we can obtain our own copy of the object using its 175 // Clone() method. 176 virtual void HandleInitializationSuccessOnFrontendLoop( 177 const syncer::WeakHandle<syncer::JsBackend> js_backend, 178 const syncer::WeakHandle<syncer::DataTypeDebugInfoListener> 179 debug_info_listener, 180 syncer::SyncCoreProxy* sync_core_proxy); 181 182 // Downloading of control types failed and will be retried. Invokes the 183 // frontend's sync configure retry method. 184 void HandleControlTypesDownloadRetry(); 185 186 // Forwards a ProtocolEvent to the frontend. Will not be called unless a 187 // call to SetForwardProtocolEvents() explicitly requested that we start 188 // forwarding these events. 189 void HandleProtocolEventOnFrontendLoop(syncer::ProtocolEvent* event); 190 191 // Forwards a directory commit counter update to the frontend loop. Will not 192 // be called unless a call to EnableDirectoryTypeDebugInfoForwarding() 193 // explicitly requested that we start forwarding these events. 194 void HandleDirectoryCommitCountersUpdatedOnFrontendLoop( 195 syncer::ModelType type, 196 const syncer::CommitCounters& counters); 197 198 // Forwards a directory update counter update to the frontend loop. Will not 199 // be called unless a call to EnableDirectoryTypeDebugInfoForwarding() 200 // explicitly requested that we start forwarding these events. 201 void HandleDirectoryUpdateCountersUpdatedOnFrontendLoop( 202 syncer::ModelType type, 203 const syncer::UpdateCounters& counters); 204 205 // Forwards a directory status counter update to the frontend loop. Will not 206 // be called unless a call to EnableDirectoryTypeDebugInfoForwarding() 207 // explicitly requested that we start forwarding these events. 208 void HandleDirectoryStatusCountersUpdatedOnFrontendLoop( 209 syncer::ModelType type, 210 const syncer::StatusCounters& counters); 211 212 SyncFrontend* frontend() { return frontend_; } 213 214 private: 215 friend class SyncBackendHostCore; 216 217 // Checks if we have received a notice to turn on experimental datatypes 218 // (via the nigori node) and informs the frontend if that is the case. 219 // Note: it is illegal to call this before the backend is initialized. 220 void AddExperimentalTypes(); 221 222 // Handles backend initialization failure. 223 void HandleInitializationFailureOnFrontendLoop(); 224 225 // Called from Core::OnSyncCycleCompleted to handle updating frontend 226 // thread components. 227 void HandleSyncCycleCompletedOnFrontendLoop( 228 const syncer::sessions::SyncSessionSnapshot& snapshot); 229 230 // Called when the syncer failed to perform a configuration and will 231 // eventually retry. FinishingConfigurationOnFrontendLoop(..) will be called 232 // on successful completion. 233 void RetryConfigurationOnFrontendLoop(const base::Closure& retry_callback); 234 235 // Helpers to persist a token that can be used to bootstrap sync encryption 236 // across browser restart to avoid requiring the user to re-enter their 237 // passphrase. |token| must be valid UTF-8 as we use the PrefService for 238 // storage. 239 void PersistEncryptionBootstrapToken( 240 const std::string& token, 241 syncer::BootstrapTokenType token_type); 242 243 // For convenience, checks if initialization state is INITIALIZED. 244 bool initialized() const { return initialized_; } 245 246 // Let the front end handle the actionable error event. 247 void HandleActionableErrorEventOnFrontendLoop( 248 const syncer::SyncProtocolError& sync_error); 249 250 // Handle a migration request. 251 void HandleMigrationRequestedOnFrontendLoop(const syncer::ModelTypeSet types); 252 253 // Checks if |passphrase| can be used to decrypt the cryptographer's pending 254 // keys that were cached during NotifyPassphraseRequired. Returns true if 255 // decryption was successful. Returns false otherwise. Must be called with a 256 // non-empty pending keys cache. 257 bool CheckPassphraseAgainstCachedPendingKeys( 258 const std::string& passphrase) const; 259 260 // Invoked when a passphrase is required to decrypt a set of Nigori keys, 261 // or for encrypting. |reason| denotes why the passphrase was required. 262 // |pending_keys| is a copy of the cryptographer's pending keys, that are 263 // cached by the frontend. If there are no pending keys, or if the passphrase 264 // required reason is REASON_ENCRYPTION, an empty EncryptedData object is 265 // passed. 266 void NotifyPassphraseRequired(syncer::PassphraseRequiredReason reason, 267 sync_pb::EncryptedData pending_keys); 268 269 // Invoked when the passphrase provided by the user has been accepted. 270 void NotifyPassphraseAccepted(); 271 272 // Invoked when the set of encrypted types or the encrypt 273 // everything flag changes. 274 void NotifyEncryptedTypesChanged( 275 syncer::ModelTypeSet encrypted_types, 276 bool encrypt_everything); 277 278 // Invoked when sync finishes encrypting new datatypes. 279 void NotifyEncryptionComplete(); 280 281 // Invoked when the passphrase state has changed. Caches the passphrase state 282 // for later use on the UI thread. 283 // If |type| is FROZEN_IMPLICIT_PASSPHRASE or CUSTOM_PASSPHRASE, 284 // |explicit_passphrase_time| is the time at which that passphrase was set 285 // (if available). 286 void HandlePassphraseTypeChangedOnFrontendLoop( 287 syncer::PassphraseType type, 288 base::Time explicit_passphrase_time); 289 290 void HandleStopSyncingPermanentlyOnFrontendLoop(); 291 292 // Dispatched to from OnConnectionStatusChange to handle updating 293 // frontend UI components. 294 void HandleConnectionStatusChangeOnFrontendLoop( 295 syncer::ConnectionStatus status); 296 297 // NotificationObserver implementation. 298 virtual void Observe( 299 int type, 300 const content::NotificationSource& source, 301 const content::NotificationDetails& details) OVERRIDE; 302 303 // InvalidationHandler implementation. 304 virtual void OnInvalidatorStateChange( 305 syncer::InvalidatorState state) OVERRIDE; 306 virtual void OnIncomingInvalidation( 307 const syncer::ObjectIdInvalidationMap& invalidation_map) OVERRIDE; 308 virtual std::string GetOwnerName() const OVERRIDE; 309 310 content::NotificationRegistrar notification_registrar_; 311 312 // A reference to the MessageLoop used to construct |this|, so we know how 313 // to safely talk back to the SyncFrontend. 314 base::MessageLoop* const frontend_loop_; 315 316 Profile* const profile_; 317 318 // Name used for debugging (set from profile_->GetDebugName()). 319 const std::string name_; 320 321 // Our core, which communicates directly to the syncapi. Use refptr instead 322 // of WeakHandle because |core_| is created on UI loop but released on 323 // sync loop. 324 scoped_refptr<SyncBackendHostCore> core_; 325 326 // A handle referencing the main interface for non-blocking sync types. 327 scoped_ptr<syncer::SyncCoreProxy> sync_core_proxy_; 328 329 bool initialized_; 330 331 const base::WeakPtr<sync_driver::SyncPrefs> sync_prefs_; 332 333 ExtensionsActivityMonitor extensions_activity_monitor_; 334 335 scoped_ptr<SyncBackendRegistrar> registrar_; 336 337 // The frontend which we serve (and are owned by). 338 SyncFrontend* frontend_; 339 340 // We cache the cryptographer's pending keys whenever NotifyPassphraseRequired 341 // is called. This way, before the UI calls SetDecryptionPassphrase on the 342 // syncer, it can avoid the overhead of an asynchronous decryption call and 343 // give the user immediate feedback about the passphrase entered by first 344 // trying to decrypt the cached pending keys on the UI thread. Note that 345 // SetDecryptionPassphrase can still fail after the cached pending keys are 346 // successfully decrypted if the pending keys have changed since the time they 347 // were cached. 348 sync_pb::EncryptedData cached_pending_keys_; 349 350 // The state of the passphrase required to decrypt the bag of encryption keys 351 // in the nigori node. Updated whenever a new nigori node arrives or the user 352 // manually changes their passphrase state. Cached so we can synchronously 353 // check it from the UI thread. 354 syncer::PassphraseType cached_passphrase_type_; 355 356 // If an explicit passphrase is in use, the time at which the passphrase was 357 // first set (if available). 358 base::Time cached_explicit_passphrase_time_; 359 360 // UI-thread cache of the last SyncSessionSnapshot received from syncapi. 361 syncer::sessions::SyncSessionSnapshot last_snapshot_; 362 363 invalidation::InvalidationService* invalidator_; 364 bool invalidation_handler_registered_; 365 366 base::WeakPtrFactory<SyncBackendHostImpl> weak_ptr_factory_; 367 368 DISALLOW_COPY_AND_ASSIGN(SyncBackendHostImpl); 369 }; 370 371 } // namespace browser_sync 372 373 #endif // CHROME_BROWSER_SYNC_GLUE_SYNC_BACKEND_HOST_IMPL_H_ 374 375