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_FILE_SYSTEM_DRIVE_BACKEND_V1_DRIVE_FILE_SYNC_SERVICE_H_ 6 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_V1_DRIVE_FILE_SYNC_SERVICE_H_ 7 8 #include <deque> 9 #include <map> 10 #include <set> 11 #include <string> 12 #include <vector> 13 14 #include "base/callback.h" 15 #include "base/memory/scoped_ptr.h" 16 #include "base/memory/weak_ptr.h" 17 #include "base/observer_list.h" 18 #include "base/threading/non_thread_safe.h" 19 #include "chrome/browser/drive/drive_notification_manager_factory.h" 20 #include "chrome/browser/drive/drive_notification_observer.h" 21 #include "chrome/browser/profiles/profile.h" 22 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h" 23 #include "chrome/browser/sync_file_system/conflict_resolution_resolver.h" 24 #include "chrome/browser/sync_file_system/drive_backend/sync_task_manager.h" 25 #include "chrome/browser/sync_file_system/drive_backend_v1/api_util_interface.h" 26 #include "chrome/browser/sync_file_system/drive_backend_v1/drive_metadata_store.h" 27 #include "chrome/browser/sync_file_system/drive_backend_v1/local_sync_operation_resolver.h" 28 #include "chrome/browser/sync_file_system/drive_backend_v1/origin_operation_queue.h" 29 #include "chrome/browser/sync_file_system/drive_backend_v1/remote_change_handler.h" 30 #include "chrome/browser/sync_file_system/file_change.h" 31 #include "chrome/browser/sync_file_system/local_change_processor.h" 32 #include "chrome/browser/sync_file_system/remote_file_sync_service.h" 33 #include "chrome/browser/sync_file_system/sync_action.h" 34 #include "chrome/browser/sync_file_system/sync_callbacks.h" 35 #include "chrome/browser/sync_file_system/sync_direction.h" 36 #include "chrome/browser/sync_file_system/sync_file_system.pb.h" 37 #include "chrome/browser/sync_file_system/sync_status_code.h" 38 39 namespace google_apis { 40 class ResourceList; 41 } 42 43 namespace tracked_objects { 44 class Location; 45 } 46 47 namespace sync_file_system { 48 49 namespace drive_backend { 50 class LocalSyncDelegate; 51 class RemoteSyncDelegate; 52 class SyncTaskManager; 53 } 54 55 // Maintains remote file changes. 56 // Owned by SyncFileSystemService (which is a per-profile object). 57 class DriveFileSyncService : public RemoteFileSyncService, 58 public LocalChangeProcessor, 59 public drive_backend::APIUtilObserver, 60 public drive_backend::SyncTaskManager::Client, 61 public base::NonThreadSafe, 62 public base::SupportsWeakPtr<DriveFileSyncService>, 63 public drive::DriveNotificationObserver { 64 public: 65 typedef base::Callback<void(const SyncStatusCallback& callback)> Task; 66 67 static ConflictResolutionPolicy kDefaultPolicy; 68 69 virtual ~DriveFileSyncService(); 70 71 // Creates DriveFileSyncService. 72 static scoped_ptr<DriveFileSyncService> Create(Profile* profile); 73 static void AppendDependsOnFactories( 74 std::set<BrowserContextKeyedServiceFactory*>* factories); 75 76 // Creates DriveFileSyncService instance for testing. 77 // |metadata_store| must be initialized beforehand. 78 static scoped_ptr<DriveFileSyncService> CreateForTesting( 79 Profile* profile, 80 const base::FilePath& base_dir, 81 scoped_ptr<drive_backend::APIUtilInterface> api_util, 82 scoped_ptr<DriveMetadataStore> metadata_store); 83 84 // RemoteFileSyncService overrides. 85 virtual void AddServiceObserver(Observer* observer) OVERRIDE; 86 virtual void AddFileStatusObserver(FileStatusObserver* observer) OVERRIDE; 87 virtual void RegisterOrigin(const GURL& origin, 88 const SyncStatusCallback& callback) OVERRIDE; 89 virtual void EnableOrigin(const GURL& origin, 90 const SyncStatusCallback& callback) OVERRIDE; 91 virtual void DisableOrigin(const GURL& origin, 92 const SyncStatusCallback& callback) OVERRIDE; 93 virtual void UninstallOrigin(const GURL& origin, 94 UninstallFlag flag, 95 const SyncStatusCallback& callback) OVERRIDE; 96 virtual void ProcessRemoteChange(const SyncFileCallback& callback) OVERRIDE; 97 virtual void SetRemoteChangeProcessor( 98 RemoteChangeProcessor* processor) OVERRIDE; 99 virtual LocalChangeProcessor* GetLocalChangeProcessor() OVERRIDE; 100 virtual RemoteServiceState GetCurrentState() const OVERRIDE; 101 virtual void GetOriginStatusMap(const StatusMapCallback& callback) OVERRIDE; 102 virtual void DumpFiles(const GURL& origin, 103 const ListCallback& callback) OVERRIDE; 104 virtual void DumpDatabase(const ListCallback& callback) OVERRIDE; 105 virtual void SetSyncEnabled(bool enabled) OVERRIDE; 106 virtual void PromoteDemotedChanges() OVERRIDE; 107 108 // LocalChangeProcessor overrides. 109 virtual void ApplyLocalChange( 110 const FileChange& change, 111 const base::FilePath& local_file_path, 112 const SyncFileMetadata& local_file_metadata, 113 const fileapi::FileSystemURL& url, 114 const SyncStatusCallback& callback) OVERRIDE; 115 116 // DriveFileSyncClientObserver overrides. 117 virtual void OnAuthenticated() OVERRIDE; 118 virtual void OnNetworkConnected() OVERRIDE; 119 120 // drive::DriveNotificationObserver implementation. 121 virtual void OnNotificationReceived() OVERRIDE; 122 virtual void OnPushNotificationEnabled(bool enabled) OVERRIDE; 123 124 // SyncTaskManager::Client overrides. 125 virtual void MaybeScheduleNextTask() OVERRIDE; 126 virtual void NotifyLastOperationStatus( 127 SyncStatusCode sync_status, 128 bool used_network) OVERRIDE; 129 virtual void RecordTaskLog(scoped_ptr<TaskLogger::TaskLog> log) OVERRIDE; 130 131 static std::string PathToTitle(const base::FilePath& path); 132 static base::FilePath TitleToPath(const std::string& title); 133 static DriveMetadata::ResourceType SyncFileTypeToDriveMetadataResourceType( 134 SyncFileType file_type); 135 static SyncFileType DriveMetadataResourceTypeToSyncFileType( 136 DriveMetadata::ResourceType resource_type); 137 138 private: 139 friend class SyncTaskManager; 140 friend class drive_backend::LocalSyncDelegate; 141 friend class drive_backend::RemoteSyncDelegate; 142 143 friend class DriveFileSyncServiceFakeTest; 144 friend class DriveFileSyncServiceSyncTest; 145 friend class DriveFileSyncServiceTest; 146 struct ApplyLocalChangeParam; 147 struct ProcessRemoteChangeParam; 148 149 typedef base::Callback< 150 void(SyncStatusCode status, 151 const std::string& resource_id)> ResourceIdCallback; 152 153 explicit DriveFileSyncService(Profile* profile); 154 155 void Initialize(scoped_ptr<drive_backend::SyncTaskManager> task_manager, 156 const SyncStatusCallback& callback); 157 void InitializeForTesting( 158 scoped_ptr<drive_backend::SyncTaskManager> task_manager, 159 const base::FilePath& base_dir, 160 scoped_ptr<drive_backend::APIUtilInterface> sync_client, 161 scoped_ptr<DriveMetadataStore> metadata_store, 162 const SyncStatusCallback& callback); 163 164 void DidInitializeMetadataStore(const SyncStatusCallback& callback, 165 SyncStatusCode status, 166 bool created); 167 168 void UpdateServiceStateFromLastOperationStatus( 169 SyncStatusCode sync_status, 170 google_apis::GDataErrorCode gdata_error); 171 172 // Updates the service state. Also this may notify observers if the 173 // service state has been changed from the original value. 174 void UpdateServiceState(RemoteServiceState state, 175 const std::string& description); 176 177 void DoRegisterOrigin( 178 const GURL& origin, 179 const SyncStatusCallback& callback); 180 void DoEnableOrigin( 181 const GURL& origin, 182 const SyncStatusCallback& callback); 183 void DoDisableOrigin( 184 const GURL& origin, 185 const SyncStatusCallback& callback); 186 void DoUninstallOrigin( 187 const GURL& origin, 188 UninstallFlag flag, 189 const SyncStatusCallback& callback); 190 void DoProcessRemoteChange( 191 const SyncFileCallback& sync_callback, 192 const SyncStatusCallback& completion_callback); 193 void DoApplyLocalChange( 194 const FileChange& change, 195 const base::FilePath& local_file_path, 196 const SyncFileMetadata& local_file_metadata, 197 const fileapi::FileSystemURL& url, 198 const SyncStatusCallback& callback); 199 200 void UpdateRegisteredOrigins(); 201 202 void StartBatchSync(const SyncStatusCallback& callback); 203 void DidGetDriveDirectoryForOrigin(const GURL& origin, 204 const SyncStatusCallback& callback, 205 SyncStatusCode status, 206 const std::string& resource_id); 207 void DidUninstallOrigin(const GURL& origin, 208 const SyncStatusCallback& callback, 209 google_apis::GDataErrorCode error); 210 void DidGetLargestChangeStampForBatchSync( 211 const SyncStatusCallback& callback, 212 const GURL& origin, 213 const std::string& resource_id, 214 google_apis::GDataErrorCode error, 215 int64 largest_changestamp); 216 void DidGetDirectoryContentForBatchSync( 217 const SyncStatusCallback& callback, 218 const GURL& origin, 219 const std::string& resource_id, 220 int64 largest_changestamp, 221 google_apis::GDataErrorCode error, 222 scoped_ptr<google_apis::ResourceList> feed); 223 224 void DidProcessRemoteChange(const SyncFileCallback& sync_callback, 225 const SyncStatusCallback& completion_callback, 226 SyncStatusCode status); 227 void DidApplyLocalChange(const SyncStatusCallback& callback, 228 SyncStatusCode status); 229 230 // Returns true if |pending_changes_| was updated. 231 bool AppendRemoteChange( 232 const GURL& origin, 233 const google_apis::ResourceEntry& entry, 234 int64 changestamp); 235 bool AppendFetchChange( 236 const GURL& origin, 237 const base::FilePath& path, 238 const std::string& resource_id, 239 SyncFileType file_type); 240 bool AppendRemoteChangeInternal( 241 const GURL& origin, 242 const base::FilePath& path, 243 bool is_deleted, 244 const std::string& resource_id, 245 int64 changestamp, 246 const std::string& remote_file_md5, 247 const base::Time& updated_time, 248 SyncFileType file_type); 249 void RemoveRemoteChange(const fileapi::FileSystemURL& url); 250 251 // TODO(kinuko,tzik): Move this out of DriveFileSyncService. 252 void MarkConflict( 253 const fileapi::FileSystemURL& url, 254 DriveMetadata* drive_metadata, 255 const SyncStatusCallback& callback); 256 void NotifyConflict( 257 const fileapi::FileSystemURL& url, 258 const SyncStatusCallback& callback, 259 SyncStatusCode status); 260 261 // A wrapper implementation to GDataErrorCodeToSyncStatusCode which returns 262 // authentication error if the user is not signed in. 263 SyncStatusCode GDataErrorCodeToSyncStatusCodeWrapper( 264 google_apis::GDataErrorCode error); 265 266 base::FilePath temporary_file_dir_; 267 268 // May start batch sync or incremental sync. 269 // This posts either one of following tasks: 270 // - StartBatchSyncForOrigin() if it has any pending batch sync origins, or 271 // - FetchChangesForIncrementalSync() otherwise. 272 // 273 // These two methods are called only from this method. 274 void MaybeStartFetchChanges(); 275 276 void FetchChangesForIncrementalSync(const SyncStatusCallback& callback); 277 void DidFetchChangesForIncrementalSync( 278 const SyncStatusCallback& callback, 279 bool has_new_changes, 280 google_apis::GDataErrorCode error, 281 scoped_ptr<google_apis::ResourceList> changes); 282 bool GetOriginForEntry(const google_apis::ResourceEntry& entry, GURL* origin); 283 void NotifyObserversFileStatusChanged(const fileapi::FileSystemURL& url, 284 SyncFileStatus sync_status, 285 SyncAction action_taken, 286 SyncDirection direction); 287 288 void EnsureSyncRootDirectory(const ResourceIdCallback& callback); 289 void DidEnsureSyncRoot(const ResourceIdCallback& callback, 290 google_apis::GDataErrorCode error, 291 const std::string& sync_root_resource_id); 292 void EnsureOriginRootDirectory(const GURL& origin, 293 const ResourceIdCallback& callback); 294 void DidEnsureSyncRootForOriginRoot(const GURL& origin, 295 const ResourceIdCallback& callback, 296 SyncStatusCode status, 297 const std::string& sync_root_resource_id); 298 void DidEnsureOriginRoot(const GURL& origin, 299 const ResourceIdCallback& callback, 300 google_apis::GDataErrorCode error, 301 const std::string& resource_id); 302 303 // This function returns Resouce ID for the sync root directory if available. 304 // Returns an empty string 1) when the resource ID has not been initialized 305 // yet, and 2) after the service has detected the remote sync root folder was 306 // removed. 307 std::string sync_root_resource_id(); 308 309 scoped_ptr<DriveMetadataStore> metadata_store_; 310 scoped_ptr<drive_backend::APIUtilInterface> api_util_; 311 312 Profile* profile_; 313 314 scoped_ptr<drive_backend::SyncTaskManager> task_manager_; 315 316 scoped_ptr<drive_backend::LocalSyncDelegate> running_local_sync_task_; 317 scoped_ptr<drive_backend::RemoteSyncDelegate> running_remote_sync_task_; 318 319 // The current remote service state. This does NOT reflect the 320 // sync_enabled_ flag, while GetCurrentState() DOES reflect the flag 321 // value (i.e. it returns REMOTE_SERVICE_DISABLED when sync_enabled_ 322 // is false even if state_ is REMOTE_SERVICE_OK). 323 RemoteServiceState state_; 324 325 // Indicates if sync is enabled or not. This flag can be turned on or 326 // off by SetSyncEnabled() method. To start synchronization 327 // this needs to be true and state_ needs to be REMOTE_SERVICE_OK. 328 bool sync_enabled_; 329 330 int64 largest_fetched_changestamp_; 331 332 std::map<GURL, std::string> pending_batch_sync_origins_; 333 334 // Is set to true when there's a fair possibility that we have some 335 // remote changes that haven't been fetched yet. 336 // 337 // This flag is set when: 338 // - This gets invalidation notification, 339 // - The service is authenticated or becomes online, and 340 // - The polling timer is fired. 341 // 342 // This flag is cleared when: 343 // - A batch or incremental sync has been started, and 344 // - When all pending batch sync tasks have been finished. 345 bool may_have_unfetched_changes_; 346 347 ObserverList<Observer> service_observers_; 348 ObserverList<FileStatusObserver> file_status_observers_; 349 350 RemoteChangeHandler remote_change_handler_; 351 RemoteChangeProcessor* remote_change_processor_; 352 353 google_apis::GDataErrorCode last_gdata_error_; 354 355 ConflictResolutionResolver conflict_resolution_resolver_; 356 357 OriginOperationQueue pending_origin_operations_; 358 359 DISALLOW_COPY_AND_ASSIGN(DriveFileSyncService); 360 }; 361 362 } // namespace sync_file_system 363 364 #endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_V1_DRIVE_FILE_SYNC_SERVICE_H_ 365