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