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.
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_
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_v1/api_util_interface.h"
25 #include "chrome/browser/sync_file_system/drive_backend_v1/drive_metadata_store.h"
26 #include "chrome/browser/sync_file_system/drive_backend_v1/local_sync_operation_resolver.h"
27 #include "chrome/browser/sync_file_system/drive_backend_v1/origin_operation_queue.h"
28 #include "chrome/browser/sync_file_system/drive_backend_v1/remote_change_handler.h"
29 #include "chrome/browser/sync_file_system/file_change.h"
30 #include "chrome/browser/sync_file_system/local_change_processor.h"
31 #include "chrome/browser/sync_file_system/remote_file_sync_service.h"
32 #include "chrome/browser/sync_file_system/sync_action.h"
33 #include "chrome/browser/sync_file_system/sync_callbacks.h"
34 #include "chrome/browser/sync_file_system/sync_direction.h"
35 #include "chrome/browser/sync_file_system/sync_file_system.pb.h"
36 #include "chrome/browser/sync_file_system/sync_status_code.h"
37 #include "chrome/browser/sync_file_system/sync_task_manager.h"
39 class ExtensionService;
41 namespace google_apis {
45 namespace tracked_objects {
49 namespace sync_file_system {
51 namespace drive_backend {
52 class LocalSyncDelegate;
53 class RemoteSyncDelegate;
56 class SyncTaskManager;
58 // Maintains remote file changes.
59 // Owned by SyncFileSystemService (which is a per-profile object).
60 class DriveFileSyncService : public RemoteFileSyncService,
61 public LocalChangeProcessor,
62 public drive_backend::APIUtilObserver,
63 public SyncTaskManager::Client,
64 public base::NonThreadSafe,
65 public base::SupportsWeakPtr<DriveFileSyncService>,
66 public drive::DriveNotificationObserver {
68 typedef base::Callback<void(const SyncStatusCallback& callback)> Task;
70 static ConflictResolutionPolicy kDefaultPolicy;
72 virtual ~DriveFileSyncService();
74 // Creates DriveFileSyncService.
75 static scoped_ptr<DriveFileSyncService> Create(Profile* profile);
76 static void AppendDependsOnFactories(
77 std::set<BrowserContextKeyedServiceFactory*>* factories);
79 // Creates DriveFileSyncService instance for testing.
80 // |metadata_store| must be initialized beforehand.
81 static scoped_ptr<DriveFileSyncService> CreateForTesting(
83 const base::FilePath& base_dir,
84 scoped_ptr<drive_backend::APIUtilInterface> api_util,
85 scoped_ptr<DriveMetadataStore> metadata_store);
87 // RemoteFileSyncService overrides.
88 virtual void AddServiceObserver(Observer* observer) OVERRIDE;
89 virtual void AddFileStatusObserver(FileStatusObserver* observer) OVERRIDE;
90 virtual void RegisterOrigin(const GURL& origin,
91 const SyncStatusCallback& callback) OVERRIDE;
92 virtual void EnableOrigin(const GURL& origin,
93 const SyncStatusCallback& callback) OVERRIDE;
94 virtual void DisableOrigin(const GURL& origin,
95 const SyncStatusCallback& callback) OVERRIDE;
96 virtual void UninstallOrigin(const GURL& origin,
98 const SyncStatusCallback& callback) OVERRIDE;
99 virtual void ProcessRemoteChange(const SyncFileCallback& callback) OVERRIDE;
100 virtual void SetRemoteChangeProcessor(
101 RemoteChangeProcessor* processor) OVERRIDE;
102 virtual LocalChangeProcessor* GetLocalChangeProcessor() OVERRIDE;
103 virtual bool IsConflicting(const fileapi::FileSystemURL& url) OVERRIDE;
104 virtual RemoteServiceState GetCurrentState() const OVERRIDE;
105 virtual void GetOriginStatusMap(OriginStatusMap* status_map) OVERRIDE;
106 virtual scoped_ptr<base::ListValue> DumpFiles(const GURL& origin) OVERRIDE;
107 virtual scoped_ptr<base::ListValue> DumpDatabase() OVERRIDE;
108 virtual void SetSyncEnabled(bool enabled) OVERRIDE;
109 virtual SyncStatusCode SetConflictResolutionPolicy(
110 ConflictResolutionPolicy policy) OVERRIDE;
111 virtual ConflictResolutionPolicy GetConflictResolutionPolicy() const OVERRIDE;
112 virtual void GetRemoteVersions(
113 const fileapi::FileSystemURL& url,
114 const RemoteVersionsCallback& callback) OVERRIDE;
115 virtual void DownloadRemoteVersion(
116 const fileapi::FileSystemURL& url,
117 const std::string& version_id,
118 const DownloadVersionCallback& callback) OVERRIDE;
119 virtual void PromoteDemotedChanges() OVERRIDE;
121 // LocalChangeProcessor overrides.
122 virtual void ApplyLocalChange(
123 const FileChange& change,
124 const base::FilePath& local_file_path,
125 const SyncFileMetadata& local_file_metadata,
126 const fileapi::FileSystemURL& url,
127 const SyncStatusCallback& callback) OVERRIDE;
129 // DriveFileSyncClientObserver overrides.
130 virtual void OnAuthenticated() OVERRIDE;
131 virtual void OnNetworkConnected() OVERRIDE;
133 // drive::DriveNotificationObserver implementation.
134 virtual void OnNotificationReceived() OVERRIDE;
135 virtual void OnPushNotificationEnabled(bool enabled) OVERRIDE;
137 // SyncTaskManager::Client overrides.
138 virtual void MaybeScheduleNextTask() OVERRIDE;
139 virtual void NotifyLastOperationStatus(
140 SyncStatusCode sync_status,
141 bool used_network) OVERRIDE;
143 static std::string PathToTitle(const base::FilePath& path);
144 static base::FilePath TitleToPath(const std::string& title);
145 static DriveMetadata::ResourceType SyncFileTypeToDriveMetadataResourceType(
146 SyncFileType file_type);
147 static SyncFileType DriveMetadataResourceTypeToSyncFileType(
148 DriveMetadata::ResourceType resource_type);
151 friend class SyncTaskManager;
152 friend class drive_backend::LocalSyncDelegate;
153 friend class drive_backend::RemoteSyncDelegate;
155 friend class DriveFileSyncServiceFakeTest;
156 friend class DriveFileSyncServiceSyncTest;
157 friend class DriveFileSyncServiceTest;
158 struct ApplyLocalChangeParam;
159 struct ProcessRemoteChangeParam;
161 typedef base::Callback<
162 void(SyncStatusCode status,
163 const std::string& resource_id)> ResourceIdCallback;
165 explicit DriveFileSyncService(Profile* profile);
167 void Initialize(scoped_ptr<SyncTaskManager> task_manager,
168 const SyncStatusCallback& callback);
169 void InitializeForTesting(
170 scoped_ptr<SyncTaskManager> task_manager,
171 const base::FilePath& base_dir,
172 scoped_ptr<drive_backend::APIUtilInterface> sync_client,
173 scoped_ptr<DriveMetadataStore> metadata_store,
174 const SyncStatusCallback& callback);
176 void DidInitializeMetadataStore(const SyncStatusCallback& callback,
177 SyncStatusCode status,
180 void UpdateServiceStateFromLastOperationStatus(
181 SyncStatusCode sync_status,
182 google_apis::GDataErrorCode gdata_error);
184 // Updates the service state. Also this may notify observers if the
185 // service state has been changed from the original value.
186 void UpdateServiceState(RemoteServiceState state,
187 const std::string& description);
189 void DoRegisterOrigin(
191 const SyncStatusCallback& callback);
194 const SyncStatusCallback& callback);
195 void DoDisableOrigin(
197 const SyncStatusCallback& callback);
198 void DoUninstallOrigin(
201 const SyncStatusCallback& callback);
202 void DoProcessRemoteChange(
203 const SyncFileCallback& sync_callback,
204 const SyncStatusCallback& completion_callback);
205 void DoApplyLocalChange(
206 const FileChange& change,
207 const base::FilePath& local_file_path,
208 const SyncFileMetadata& local_file_metadata,
209 const fileapi::FileSystemURL& url,
210 const SyncStatusCallback& callback);
212 void DoGetRemoteVersions(
213 const fileapi::FileSystemURL& url,
214 const RemoteVersionsCallback& callback,
215 const SyncStatusCallback& completion_callback);
216 void DidGetEntryForRemoteVersions(
217 const RemoteVersionsCallback& callback,
218 google_apis::GDataErrorCode error,
219 scoped_ptr<google_apis::ResourceEntry> entry);
221 void DoDownloadRemoteVersion(
222 const fileapi::FileSystemURL& url,
223 const std::string& version_id,
224 const DownloadVersionCallback& callback,
225 const SyncStatusCallback& completion_callback);
226 void DidDownloadVersion(
227 const DownloadVersionCallback& download_callback,
228 google_apis::GDataErrorCode error,
229 const std::string& file_md5,
231 const base::Time& last_updated,
232 webkit_blob::ScopedFile downloaded);
234 void UpdateRegisteredOrigins();
236 void StartBatchSync(const SyncStatusCallback& callback);
237 void DidGetDriveDirectoryForOrigin(const GURL& origin,
238 const SyncStatusCallback& callback,
239 SyncStatusCode status,
240 const std::string& resource_id);
241 void DidUninstallOrigin(const GURL& origin,
242 const SyncStatusCallback& callback,
243 google_apis::GDataErrorCode error);
244 void DidGetLargestChangeStampForBatchSync(
245 const SyncStatusCallback& callback,
247 const std::string& resource_id,
248 google_apis::GDataErrorCode error,
249 int64 largest_changestamp);
250 void DidGetDirectoryContentForBatchSync(
251 const SyncStatusCallback& callback,
253 const std::string& resource_id,
254 int64 largest_changestamp,
255 google_apis::GDataErrorCode error,
256 scoped_ptr<google_apis::ResourceList> feed);
258 void DidProcessRemoteChange(const SyncFileCallback& sync_callback,
259 const SyncStatusCallback& completion_callback,
260 SyncStatusCode status);
261 void DidApplyLocalChange(const SyncStatusCallback& callback,
262 SyncStatusCode status);
264 // Returns true if |pending_changes_| was updated.
265 bool AppendRemoteChange(
267 const google_apis::ResourceEntry& entry,
269 bool AppendFetchChange(
271 const base::FilePath& path,
272 const std::string& resource_id,
273 SyncFileType file_type);
274 bool AppendRemoteChangeInternal(
276 const base::FilePath& path,
278 const std::string& resource_id,
280 const std::string& remote_file_md5,
281 const base::Time& updated_time,
282 SyncFileType file_type);
283 void RemoveRemoteChange(const fileapi::FileSystemURL& url);
285 // TODO(kinuko,tzik): Move this out of DriveFileSyncService.
287 const fileapi::FileSystemURL& url,
288 DriveMetadata* drive_metadata,
289 const SyncStatusCallback& callback);
291 const fileapi::FileSystemURL& url,
292 const SyncStatusCallback& callback,
293 SyncStatusCode status);
295 // A wrapper implementation to GDataErrorCodeToSyncStatusCode which returns
296 // authentication error if the user is not signed in.
297 SyncStatusCode GDataErrorCodeToSyncStatusCodeWrapper(
298 google_apis::GDataErrorCode error);
300 base::FilePath temporary_file_dir_;
302 // May start batch sync or incremental sync.
303 // This posts either one of following tasks:
304 // - StartBatchSyncForOrigin() if it has any pending batch sync origins, or
305 // - FetchChangesForIncrementalSync() otherwise.
307 // These two methods are called only from this method.
308 void MaybeStartFetchChanges();
310 void FetchChangesForIncrementalSync(const SyncStatusCallback& callback);
311 void DidFetchChangesForIncrementalSync(
312 const SyncStatusCallback& callback,
313 bool has_new_changes,
314 google_apis::GDataErrorCode error,
315 scoped_ptr<google_apis::ResourceList> changes);
316 bool GetOriginForEntry(const google_apis::ResourceEntry& entry, GURL* origin);
317 void NotifyObserversFileStatusChanged(const fileapi::FileSystemURL& url,
318 SyncFileStatus sync_status,
319 SyncAction action_taken,
320 SyncDirection direction);
322 void EnsureSyncRootDirectory(const ResourceIdCallback& callback);
323 void DidEnsureSyncRoot(const ResourceIdCallback& callback,
324 google_apis::GDataErrorCode error,
325 const std::string& sync_root_resource_id);
326 void EnsureOriginRootDirectory(const GURL& origin,
327 const ResourceIdCallback& callback);
328 void DidEnsureSyncRootForOriginRoot(const GURL& origin,
329 const ResourceIdCallback& callback,
330 SyncStatusCode status,
331 const std::string& sync_root_resource_id);
332 void DidEnsureOriginRoot(const GURL& origin,
333 const ResourceIdCallback& callback,
334 google_apis::GDataErrorCode error,
335 const std::string& resource_id);
337 // This function returns Resouce ID for the sync root directory if available.
338 // Returns an empty string 1) when the resource ID has not been initialized
339 // yet, and 2) after the service has detected the remote sync root folder was
341 std::string sync_root_resource_id();
343 scoped_ptr<DriveMetadataStore> metadata_store_;
344 scoped_ptr<drive_backend::APIUtilInterface> api_util_;
348 scoped_ptr<SyncTaskManager> task_manager_;
350 scoped_ptr<drive_backend::LocalSyncDelegate> running_local_sync_task_;
351 scoped_ptr<drive_backend::RemoteSyncDelegate> running_remote_sync_task_;
353 // The current remote service state. This does NOT reflect the
354 // sync_enabled_ flag, while GetCurrentState() DOES reflect the flag
355 // value (i.e. it returns REMOTE_SERVICE_DISABLED when sync_enabled_
356 // is false even if state_ is REMOTE_SERVICE_OK).
357 RemoteServiceState state_;
359 // Indicates if sync is enabled or not. This flag can be turned on or
360 // off by SetSyncEnabled() method. To start synchronization
361 // this needs to be true and state_ needs to be REMOTE_SERVICE_OK.
364 int64 largest_fetched_changestamp_;
366 std::map<GURL, std::string> pending_batch_sync_origins_;
368 // Is set to true when there's a fair possibility that we have some
369 // remote changes that haven't been fetched yet.
371 // This flag is set when:
372 // - This gets invalidation notification,
373 // - The service is authenticated or becomes online, and
374 // - The polling timer is fired.
376 // This flag is cleared when:
377 // - A batch or incremental sync has been started, and
378 // - When all pending batch sync tasks have been finished.
379 bool may_have_unfetched_changes_;
381 ObserverList<Observer> service_observers_;
382 ObserverList<FileStatusObserver> file_status_observers_;
384 RemoteChangeHandler remote_change_handler_;
385 RemoteChangeProcessor* remote_change_processor_;
387 google_apis::GDataErrorCode last_gdata_error_;
389 ConflictResolutionResolver conflict_resolution_resolver_;
391 OriginOperationQueue pending_origin_operations_;
393 DISALLOW_COPY_AND_ASSIGN(DriveFileSyncService);
396 } // namespace sync_file_system
398 #endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_V1_DRIVE_FILE_SYNC_SERVICE_H_