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/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"
39 namespace google_apis {
43 namespace tracked_objects {
47 namespace sync_file_system {
49 namespace drive_backend {
50 class LocalSyncDelegate;
51 class RemoteSyncDelegate;
52 class SyncTaskManager;
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 {
65 typedef base::Callback<void(const SyncStatusCallback& callback)> Task;
67 static ConflictResolutionPolicy kDefaultPolicy;
69 virtual ~DriveFileSyncService();
71 // Creates DriveFileSyncService.
72 static scoped_ptr<DriveFileSyncService> Create(Profile* profile);
73 static void AppendDependsOnFactories(
74 std::set<BrowserContextKeyedServiceFactory*>* factories);
76 // Creates DriveFileSyncService instance for testing.
77 // |metadata_store| must be initialized beforehand.
78 static scoped_ptr<DriveFileSyncService> CreateForTesting(
80 const base::FilePath& base_dir,
81 scoped_ptr<drive_backend::APIUtilInterface> api_util,
82 scoped_ptr<DriveMetadataStore> metadata_store);
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,
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(const base::Closure& callback) OVERRIDE;
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;
116 // DriveFileSyncClientObserver overrides.
117 virtual void OnAuthenticated() OVERRIDE;
118 virtual void OnNetworkConnected() OVERRIDE;
120 // drive::DriveNotificationObserver implementation.
121 virtual void OnNotificationReceived() OVERRIDE;
122 virtual void OnPushNotificationEnabled(bool enabled) OVERRIDE;
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;
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);
139 friend class SyncTaskManager;
140 friend class drive_backend::LocalSyncDelegate;
141 friend class drive_backend::RemoteSyncDelegate;
143 friend class DriveFileSyncServiceFakeTest;
144 friend class DriveFileSyncServiceSyncTest;
145 friend class DriveFileSyncServiceTest;
146 struct ApplyLocalChangeParam;
147 struct ProcessRemoteChangeParam;
149 typedef base::Callback<
150 void(SyncStatusCode status,
151 const std::string& resource_id)> ResourceIdCallback;
153 explicit DriveFileSyncService(Profile* profile);
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);
164 void DidInitializeMetadataStore(const SyncStatusCallback& callback,
165 SyncStatusCode status,
168 void UpdateServiceStateFromLastOperationStatus(
169 SyncStatusCode sync_status,
170 google_apis::GDataErrorCode gdata_error);
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);
177 void DoRegisterOrigin(
179 const SyncStatusCallback& callback);
182 const SyncStatusCallback& callback);
183 void DoDisableOrigin(
185 const SyncStatusCallback& callback);
186 void DoUninstallOrigin(
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);
200 void UpdateRegisteredOrigins();
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,
213 const std::string& resource_id,
214 google_apis::GDataErrorCode error,
215 int64 largest_changestamp);
216 void DidGetDirectoryContentForBatchSync(
217 const SyncStatusCallback& callback,
219 const std::string& resource_id,
220 int64 largest_changestamp,
221 google_apis::GDataErrorCode error,
222 scoped_ptr<google_apis::ResourceList> feed);
224 void DidProcessRemoteChange(const SyncFileCallback& sync_callback,
225 const SyncStatusCallback& completion_callback,
226 SyncStatusCode status);
227 void DidApplyLocalChange(const SyncStatusCallback& callback,
228 SyncStatusCode status);
230 // Returns true if |pending_changes_| was updated.
231 bool AppendRemoteChange(
233 const google_apis::ResourceEntry& entry,
235 bool AppendFetchChange(
237 const base::FilePath& path,
238 const std::string& resource_id,
239 SyncFileType file_type);
240 bool AppendRemoteChangeInternal(
242 const base::FilePath& path,
244 const std::string& resource_id,
246 const std::string& remote_file_md5,
247 const base::Time& updated_time,
248 SyncFileType file_type);
249 void RemoveRemoteChange(const fileapi::FileSystemURL& url);
251 // TODO(kinuko,tzik): Move this out of DriveFileSyncService.
253 const fileapi::FileSystemURL& url,
254 DriveMetadata* drive_metadata,
255 const SyncStatusCallback& callback);
257 const fileapi::FileSystemURL& url,
258 const SyncStatusCallback& callback,
259 SyncStatusCode status);
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);
266 base::FilePath temporary_file_dir_;
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.
273 // These two methods are called only from this method.
274 void MaybeStartFetchChanges();
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);
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);
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
307 std::string sync_root_resource_id();
309 scoped_ptr<DriveMetadataStore> metadata_store_;
310 scoped_ptr<drive_backend::APIUtilInterface> api_util_;
314 scoped_ptr<drive_backend::SyncTaskManager> task_manager_;
316 scoped_ptr<drive_backend::LocalSyncDelegate> running_local_sync_task_;
317 scoped_ptr<drive_backend::RemoteSyncDelegate> running_remote_sync_task_;
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_;
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.
330 int64 largest_fetched_changestamp_;
332 std::map<GURL, std::string> pending_batch_sync_origins_;
334 // Is set to true when there's a fair possibility that we have some
335 // remote changes that haven't been fetched yet.
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.
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_;
347 ObserverList<Observer> service_observers_;
348 ObserverList<FileStatusObserver> file_status_observers_;
350 RemoteChangeHandler remote_change_handler_;
351 RemoteChangeProcessor* remote_change_processor_;
353 google_apis::GDataErrorCode last_gdata_error_;
355 ConflictResolutionResolver conflict_resolution_resolver_;
357 OriginOperationQueue pending_origin_operations_;
359 DISALLOW_COPY_AND_ASSIGN(DriveFileSyncService);
362 } // namespace sync_file_system
364 #endif // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_V1_DRIVE_FILE_SYNC_SERVICE_H_