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/extensions/extension_system_factory.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/signin/profile_oauth2_token_service_factory.h"
24 #include "chrome/browser/sync_file_system/conflict_resolution_resolver.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 #include "chrome/browser/sync_file_system/sync_task_manager.h"
40 class ExtensionService;
42 namespace google_apis {
46 namespace tracked_objects {
50 namespace sync_file_system {
52 namespace drive_backend {
53 class LocalSyncDelegate;
54 class RemoteSyncDelegate;
57 class SyncTaskManager;
59 // Maintains remote file changes.
60 // Owned by SyncFileSystemService (which is a per-profile object).
61 class DriveFileSyncService : public RemoteFileSyncService,
62 public LocalChangeProcessor,
63 public drive_backend::APIUtilObserver,
64 public SyncTaskManager::Client,
65 public base::NonThreadSafe,
66 public base::SupportsWeakPtr<DriveFileSyncService>,
67 public drive::DriveNotificationObserver {
69 typedef base::Callback<void(const SyncStatusCallback& callback)> Task;
71 static ConflictResolutionPolicy kDefaultPolicy;
73 virtual ~DriveFileSyncService();
75 // Creates DriveFileSyncService.
76 static scoped_ptr<DriveFileSyncService> Create(Profile* profile);
77 static void AppendDependsOnFactories(
78 std::set<BrowserContextKeyedServiceFactory*>* factories);
80 // Creates DriveFileSyncService instance for testing.
81 // |metadata_store| must be initialized beforehand.
82 static scoped_ptr<DriveFileSyncService> CreateForTesting(
84 const base::FilePath& base_dir,
85 scoped_ptr<drive_backend::APIUtilInterface> api_util,
86 scoped_ptr<DriveMetadataStore> metadata_store);
88 // RemoteFileSyncService overrides.
89 virtual void AddServiceObserver(Observer* observer) OVERRIDE;
90 virtual void AddFileStatusObserver(FileStatusObserver* observer) OVERRIDE;
91 virtual void RegisterOrigin(const GURL& origin,
92 const SyncStatusCallback& callback) OVERRIDE;
93 virtual void EnableOrigin(const GURL& origin,
94 const SyncStatusCallback& callback) OVERRIDE;
95 virtual void DisableOrigin(const GURL& origin,
96 const SyncStatusCallback& callback) OVERRIDE;
97 virtual void UninstallOrigin(const GURL& origin,
99 const SyncStatusCallback& callback) OVERRIDE;
100 virtual void ProcessRemoteChange(const SyncFileCallback& callback) OVERRIDE;
101 virtual void SetRemoteChangeProcessor(
102 RemoteChangeProcessor* processor) OVERRIDE;
103 virtual LocalChangeProcessor* GetLocalChangeProcessor() OVERRIDE;
104 virtual bool IsConflicting(const fileapi::FileSystemURL& url) OVERRIDE;
105 virtual RemoteServiceState GetCurrentState() const OVERRIDE;
106 virtual void GetOriginStatusMap(OriginStatusMap* status_map) OVERRIDE;
107 virtual scoped_ptr<base::ListValue> DumpFiles(const GURL& origin) OVERRIDE;
108 virtual scoped_ptr<base::ListValue> DumpDatabase() OVERRIDE;
109 virtual void SetSyncEnabled(bool enabled) OVERRIDE;
110 virtual SyncStatusCode SetConflictResolutionPolicy(
111 ConflictResolutionPolicy policy) OVERRIDE;
112 virtual ConflictResolutionPolicy GetConflictResolutionPolicy() const OVERRIDE;
113 virtual void GetRemoteVersions(
114 const fileapi::FileSystemURL& url,
115 const RemoteVersionsCallback& callback) OVERRIDE;
116 virtual void DownloadRemoteVersion(
117 const fileapi::FileSystemURL& url,
118 const std::string& version_id,
119 const DownloadVersionCallback& callback) OVERRIDE;
120 virtual void PromoteDemotedChanges() OVERRIDE;
122 // LocalChangeProcessor overrides.
123 virtual void ApplyLocalChange(
124 const FileChange& change,
125 const base::FilePath& local_file_path,
126 const SyncFileMetadata& local_file_metadata,
127 const fileapi::FileSystemURL& url,
128 const SyncStatusCallback& callback) OVERRIDE;
130 // DriveFileSyncClientObserver overrides.
131 virtual void OnAuthenticated() OVERRIDE;
132 virtual void OnNetworkConnected() OVERRIDE;
134 // drive::DriveNotificationObserver implementation.
135 virtual void OnNotificationReceived() OVERRIDE;
136 virtual void OnPushNotificationEnabled(bool enabled) OVERRIDE;
138 // SyncTaskManager::Client overrides.
139 virtual void MaybeScheduleNextTask() OVERRIDE;
140 virtual void NotifyLastOperationStatus(
141 SyncStatusCode sync_status,
142 bool used_network) OVERRIDE;
144 static std::string PathToTitle(const base::FilePath& path);
145 static base::FilePath TitleToPath(const std::string& title);
146 static DriveMetadata::ResourceType SyncFileTypeToDriveMetadataResourceType(
147 SyncFileType file_type);
148 static SyncFileType DriveMetadataResourceTypeToSyncFileType(
149 DriveMetadata::ResourceType resource_type);
152 friend class SyncTaskManager;
153 friend class drive_backend::LocalSyncDelegate;
154 friend class drive_backend::RemoteSyncDelegate;
156 friend class DriveFileSyncServiceFakeTest;
157 friend class DriveFileSyncServiceSyncTest;
158 friend class DriveFileSyncServiceTest;
159 struct ApplyLocalChangeParam;
160 struct ProcessRemoteChangeParam;
162 typedef base::Callback<
163 void(SyncStatusCode status,
164 const std::string& resource_id)> ResourceIdCallback;
166 explicit DriveFileSyncService(Profile* profile);
168 void Initialize(scoped_ptr<SyncTaskManager> task_manager,
169 const SyncStatusCallback& callback);
170 void InitializeForTesting(
171 scoped_ptr<SyncTaskManager> task_manager,
172 const base::FilePath& base_dir,
173 scoped_ptr<drive_backend::APIUtilInterface> sync_client,
174 scoped_ptr<DriveMetadataStore> metadata_store,
175 const SyncStatusCallback& callback);
177 void DidInitializeMetadataStore(const SyncStatusCallback& callback,
178 SyncStatusCode status,
181 void UpdateServiceStateFromLastOperationStatus(
182 SyncStatusCode sync_status,
183 google_apis::GDataErrorCode gdata_error);
185 // Updates the service state. Also this may notify observers if the
186 // service state has been changed from the original value.
187 void UpdateServiceState(RemoteServiceState state,
188 const std::string& description);
190 void DoRegisterOrigin(
192 const SyncStatusCallback& callback);
195 const SyncStatusCallback& callback);
196 void DoDisableOrigin(
198 const SyncStatusCallback& callback);
199 void DoUninstallOrigin(
202 const SyncStatusCallback& callback);
203 void DoProcessRemoteChange(
204 const SyncFileCallback& sync_callback,
205 const SyncStatusCallback& completion_callback);
206 void DoApplyLocalChange(
207 const FileChange& change,
208 const base::FilePath& local_file_path,
209 const SyncFileMetadata& local_file_metadata,
210 const fileapi::FileSystemURL& url,
211 const SyncStatusCallback& callback);
213 void DoGetRemoteVersions(
214 const fileapi::FileSystemURL& url,
215 const RemoteVersionsCallback& callback,
216 const SyncStatusCallback& completion_callback);
217 void DidGetEntryForRemoteVersions(
218 const RemoteVersionsCallback& callback,
219 google_apis::GDataErrorCode error,
220 scoped_ptr<google_apis::ResourceEntry> entry);
222 void DoDownloadRemoteVersion(
223 const fileapi::FileSystemURL& url,
224 const std::string& version_id,
225 const DownloadVersionCallback& callback,
226 const SyncStatusCallback& completion_callback);
227 void DidDownloadVersion(
228 const DownloadVersionCallback& download_callback,
229 google_apis::GDataErrorCode error,
230 const std::string& file_md5,
232 const base::Time& last_updated,
233 webkit_blob::ScopedFile downloaded);
235 void UpdateRegisteredOrigins();
237 void StartBatchSync(const SyncStatusCallback& callback);
238 void DidGetDriveDirectoryForOrigin(const GURL& origin,
239 const SyncStatusCallback& callback,
240 SyncStatusCode status,
241 const std::string& resource_id);
242 void DidUninstallOrigin(const GURL& origin,
243 const SyncStatusCallback& callback,
244 google_apis::GDataErrorCode error);
245 void DidGetLargestChangeStampForBatchSync(
246 const SyncStatusCallback& callback,
248 const std::string& resource_id,
249 google_apis::GDataErrorCode error,
250 int64 largest_changestamp);
251 void DidGetDirectoryContentForBatchSync(
252 const SyncStatusCallback& callback,
254 const std::string& resource_id,
255 int64 largest_changestamp,
256 google_apis::GDataErrorCode error,
257 scoped_ptr<google_apis::ResourceList> feed);
259 void DidProcessRemoteChange(const SyncFileCallback& sync_callback,
260 const SyncStatusCallback& completion_callback,
261 SyncStatusCode status);
262 void DidApplyLocalChange(const SyncStatusCallback& callback,
263 SyncStatusCode status);
265 // Returns true if |pending_changes_| was updated.
266 bool AppendRemoteChange(
268 const google_apis::ResourceEntry& entry,
270 bool AppendFetchChange(
272 const base::FilePath& path,
273 const std::string& resource_id,
274 SyncFileType file_type);
275 bool AppendRemoteChangeInternal(
277 const base::FilePath& path,
279 const std::string& resource_id,
281 const std::string& remote_file_md5,
282 const base::Time& updated_time,
283 SyncFileType file_type);
284 void RemoveRemoteChange(const fileapi::FileSystemURL& url);
286 // TODO(kinuko,tzik): Move this out of DriveFileSyncService.
288 const fileapi::FileSystemURL& url,
289 DriveMetadata* drive_metadata,
290 const SyncStatusCallback& callback);
292 const fileapi::FileSystemURL& url,
293 const SyncStatusCallback& callback,
294 SyncStatusCode status);
296 // A wrapper implementation to GDataErrorCodeToSyncStatusCode which returns
297 // authentication error if the user is not signed in.
298 SyncStatusCode GDataErrorCodeToSyncStatusCodeWrapper(
299 google_apis::GDataErrorCode error);
301 base::FilePath temporary_file_dir_;
303 // May start batch sync or incremental sync.
304 // This posts either one of following tasks:
305 // - StartBatchSyncForOrigin() if it has any pending batch sync origins, or
306 // - FetchChangesForIncrementalSync() otherwise.
308 // These two methods are called only from this method.
309 void MaybeStartFetchChanges();
311 void FetchChangesForIncrementalSync(const SyncStatusCallback& callback);
312 void DidFetchChangesForIncrementalSync(
313 const SyncStatusCallback& callback,
314 bool has_new_changes,
315 google_apis::GDataErrorCode error,
316 scoped_ptr<google_apis::ResourceList> changes);
317 bool GetOriginForEntry(const google_apis::ResourceEntry& entry, GURL* origin);
318 void NotifyObserversFileStatusChanged(const fileapi::FileSystemURL& url,
319 SyncFileStatus sync_status,
320 SyncAction action_taken,
321 SyncDirection direction);
323 void EnsureSyncRootDirectory(const ResourceIdCallback& callback);
324 void DidEnsureSyncRoot(const ResourceIdCallback& callback,
325 google_apis::GDataErrorCode error,
326 const std::string& sync_root_resource_id);
327 void EnsureOriginRootDirectory(const GURL& origin,
328 const ResourceIdCallback& callback);
329 void DidEnsureSyncRootForOriginRoot(const GURL& origin,
330 const ResourceIdCallback& callback,
331 SyncStatusCode status,
332 const std::string& sync_root_resource_id);
333 void DidEnsureOriginRoot(const GURL& origin,
334 const ResourceIdCallback& callback,
335 google_apis::GDataErrorCode error,
336 const std::string& resource_id);
338 // This function returns Resouce ID for the sync root directory if available.
339 // Returns an empty string 1) when the resource ID has not been initialized
340 // yet, and 2) after the service has detected the remote sync root folder was
342 std::string sync_root_resource_id();
344 scoped_ptr<DriveMetadataStore> metadata_store_;
345 scoped_ptr<drive_backend::APIUtilInterface> api_util_;
349 scoped_ptr<SyncTaskManager> task_manager_;
351 scoped_ptr<drive_backend::LocalSyncDelegate> running_local_sync_task_;
352 scoped_ptr<drive_backend::RemoteSyncDelegate> running_remote_sync_task_;
354 // The current remote service state. This does NOT reflect the
355 // sync_enabled_ flag, while GetCurrentState() DOES reflect the flag
356 // value (i.e. it returns REMOTE_SERVICE_DISABLED when sync_enabled_
357 // is false even if state_ is REMOTE_SERVICE_OK).
358 RemoteServiceState state_;
360 // Indicates if sync is enabled or not. This flag can be turned on or
361 // off by SetSyncEnabled() method. To start synchronization
362 // this needs to be true and state_ needs to be REMOTE_SERVICE_OK.
365 int64 largest_fetched_changestamp_;
367 std::map<GURL, std::string> pending_batch_sync_origins_;
369 // Is set to true when there's a fair possibility that we have some
370 // remote changes that haven't been fetched yet.
372 // This flag is set when:
373 // - This gets invalidation notification,
374 // - The service is authenticated or becomes online, and
375 // - The polling timer is fired.
377 // This flag is cleared when:
378 // - A batch or incremental sync has been started, and
379 // - When all pending batch sync tasks have been finished.
380 bool may_have_unfetched_changes_;
382 ObserverList<Observer> service_observers_;
383 ObserverList<FileStatusObserver> file_status_observers_;
385 RemoteChangeHandler remote_change_handler_;
386 RemoteChangeProcessor* remote_change_processor_;
388 google_apis::GDataErrorCode last_gdata_error_;
390 ConflictResolutionResolver conflict_resolution_resolver_;
392 OriginOperationQueue pending_origin_operations_;
394 DISALLOW_COPY_AND_ASSIGN(DriveFileSyncService);
397 } // namespace sync_file_system
399 #endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_V1_DRIVE_FILE_SYNC_SERVICE_H_