- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync_file_system / drive_backend_v1 / drive_file_sync_service.h
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_observer.h"
20 #include "chrome/browser/sync_file_system/conflict_resolution_resolver.h"
21 #include "chrome/browser/sync_file_system/drive_backend_v1/api_util_interface.h"
22 #include "chrome/browser/sync_file_system/drive_backend_v1/drive_metadata_store.h"
23 #include "chrome/browser/sync_file_system/drive_backend_v1/local_sync_operation_resolver.h"
24 #include "chrome/browser/sync_file_system/drive_backend_v1/origin_operation_queue.h"
25 #include "chrome/browser/sync_file_system/drive_backend_v1/remote_change_handler.h"
26 #include "chrome/browser/sync_file_system/file_change.h"
27 #include "chrome/browser/sync_file_system/local_change_processor.h"
28 #include "chrome/browser/sync_file_system/remote_file_sync_service.h"
29 #include "chrome/browser/sync_file_system/sync_action.h"
30 #include "chrome/browser/sync_file_system/sync_callbacks.h"
31 #include "chrome/browser/sync_file_system/sync_direction.h"
32 #include "chrome/browser/sync_file_system/sync_file_system.pb.h"
33 #include "chrome/browser/sync_file_system/sync_status_code.h"
34 #include "chrome/browser/sync_file_system/sync_task_manager.h"
35
36 class ExtensionService;
37
38 namespace google_apis {
39 class ResourceList;
40 }
41
42 namespace tracked_objects {
43 class Location;
44 }
45
46 namespace sync_file_system {
47
48 namespace drive_backend {
49 class LocalSyncDelegate;
50 class RemoteSyncDelegate;
51 }
52
53 class SyncTaskManager;
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 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
74   // Creates DriveFileSyncService instance for testing.
75   // |metadata_store| must be initialized beforehand.
76   static scoped_ptr<DriveFileSyncService> CreateForTesting(
77       Profile* profile,
78       const base::FilePath& base_dir,
79       scoped_ptr<drive_backend::APIUtilInterface> api_util,
80       scoped_ptr<DriveMetadataStore> metadata_store);
81
82   // Destroys |sync_service| and passes the ownership of |sync_client| to caller
83   // for testing.
84   static scoped_ptr<drive_backend::APIUtilInterface>
85       DestroyAndPassAPIUtilForTesting(
86           scoped_ptr<DriveFileSyncService> sync_service);
87
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,
98                                UninstallFlag flag,
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 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
120   // LocalChangeProcessor overrides.
121   virtual void ApplyLocalChange(
122       const FileChange& change,
123       const base::FilePath& local_file_path,
124       const SyncFileMetadata& local_file_metadata,
125       const fileapi::FileSystemURL& url,
126       const SyncStatusCallback& callback) OVERRIDE;
127
128   // DriveFileSyncClientObserver overrides.
129   virtual void OnAuthenticated() OVERRIDE;
130   virtual void OnNetworkConnected() OVERRIDE;
131
132   // drive::DriveNotificationObserver implementation.
133   virtual void OnNotificationReceived() OVERRIDE;
134   virtual void OnPushNotificationEnabled(bool enabled) OVERRIDE;
135
136   // SyncTaskManager::Client overrides.
137   virtual void MaybeScheduleNextTask() OVERRIDE;
138   virtual void NotifyLastOperationStatus(SyncStatusCode sync_status) OVERRIDE;
139
140   static std::string PathToTitle(const base::FilePath& path);
141   static base::FilePath TitleToPath(const std::string& title);
142   static DriveMetadata::ResourceType SyncFileTypeToDriveMetadataResourceType(
143       SyncFileType file_type);
144   static SyncFileType DriveMetadataResourceTypeToSyncFileType(
145       DriveMetadata::ResourceType resource_type);
146
147  private:
148   friend class SyncTaskManager;
149   friend class drive_backend::LocalSyncDelegate;
150   friend class drive_backend::RemoteSyncDelegate;
151
152   friend class DriveFileSyncServiceFakeTest;
153   friend class DriveFileSyncServiceSyncTest;
154   friend class DriveFileSyncServiceTest;
155   struct ApplyLocalChangeParam;
156   struct ProcessRemoteChangeParam;
157
158   typedef base::Callback<
159       void(SyncStatusCode status,
160            const std::string& resource_id)> ResourceIdCallback;
161
162   explicit DriveFileSyncService(Profile* profile);
163
164   void Initialize(scoped_ptr<SyncTaskManager> task_manager,
165                   const SyncStatusCallback& callback);
166   void InitializeForTesting(
167       scoped_ptr<SyncTaskManager> task_manager,
168       const base::FilePath& base_dir,
169       scoped_ptr<drive_backend::APIUtilInterface> sync_client,
170       scoped_ptr<DriveMetadataStore> metadata_store,
171       const SyncStatusCallback& callback);
172
173   void DidInitializeMetadataStore(const SyncStatusCallback& callback,
174                                   SyncStatusCode status,
175                                   bool created);
176   void DidGetDriveRootResourceId(const SyncStatusCallback& callback,
177                                  google_apis::GDataErrorCode error,
178                                  const std::string& root_resource_id);
179
180   void UpdateServiceStateFromLastOperationStatus(
181       SyncStatusCode sync_status,
182       google_apis::GDataErrorCode gdata_error);
183
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);
188
189   void DoRegisterOrigin(
190       const GURL& origin,
191       const SyncStatusCallback& callback);
192   void DoEnableOrigin(
193       const GURL& origin,
194       const SyncStatusCallback& callback);
195   void DoDisableOrigin(
196       const GURL& origin,
197       const SyncStatusCallback& callback);
198   void DoUninstallOrigin(
199       const GURL& origin,
200       UninstallFlag flag,
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);
211
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);
220
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,
230       int64 file_size,
231       const base::Time& last_updated,
232       webkit_blob::ScopedFile downloaded);
233
234   void UpdateRegisteredOrigins();
235
236   void StartBatchSync(const SyncStatusCallback& callback);
237   void GetDriveDirectoryForOrigin(const GURL& origin,
238                                   const SyncStatusCallback& callback,
239                                   const std::string& sync_root_resource_id);
240   void DidGetDriveDirectoryForOrigin(const GURL& origin,
241                                      const SyncStatusCallback& callback,
242                                      SyncStatusCode status,
243                                      const std::string& resource_id);
244   void DidUninstallOrigin(const GURL& origin,
245                           const SyncStatusCallback& callback,
246                           google_apis::GDataErrorCode error);
247   void DidGetLargestChangeStampForBatchSync(
248       const SyncStatusCallback& callback,
249       const GURL& origin,
250       const std::string& resource_id,
251       google_apis::GDataErrorCode error,
252       int64 largest_changestamp);
253   void DidGetDirectoryContentForBatchSync(
254       const SyncStatusCallback& callback,
255       const GURL& origin,
256       const std::string& resource_id,
257       int64 largest_changestamp,
258       google_apis::GDataErrorCode error,
259       scoped_ptr<google_apis::ResourceList> feed);
260
261   void DidProcessRemoteChange(const SyncFileCallback& sync_callback,
262                               const SyncStatusCallback& completion_callback,
263                               SyncStatusCode status);
264   void DidApplyLocalChange(const SyncStatusCallback& callback,
265                            SyncStatusCode status);
266
267   // Returns true if |pending_changes_| was updated.
268   bool AppendRemoteChange(
269       const GURL& origin,
270       const google_apis::ResourceEntry& entry,
271       int64 changestamp);
272   bool AppendFetchChange(
273       const GURL& origin,
274       const base::FilePath& path,
275       const std::string& resource_id,
276       SyncFileType file_type);
277   bool AppendRemoteChangeInternal(
278       const GURL& origin,
279       const base::FilePath& path,
280       bool is_deleted,
281       const std::string& resource_id,
282       int64 changestamp,
283       const std::string& remote_file_md5,
284       const base::Time& updated_time,
285       SyncFileType file_type);
286   void RemoveRemoteChange(const fileapi::FileSystemURL& url);
287   void MaybeMarkAsIncrementalSyncOrigin(const GURL& origin);
288
289   // TODO(kinuko,tzik): Move this out of DriveFileSyncService.
290   void MarkConflict(
291       const fileapi::FileSystemURL& url,
292       DriveMetadata* drive_metadata,
293       const SyncStatusCallback& callback);
294   void NotifyConflict(
295       const fileapi::FileSystemURL& url,
296       const SyncStatusCallback& callback,
297       SyncStatusCode status);
298
299   // A wrapper implementation to GDataErrorCodeToSyncStatusCode which returns
300   // authentication error if the user is not signed in.
301   SyncStatusCode GDataErrorCodeToSyncStatusCodeWrapper(
302       google_apis::GDataErrorCode error);
303
304   base::FilePath temporary_file_dir_;
305
306   // May start batch sync or incremental sync.
307   // This posts either one of following tasks:
308   // - StartBatchSyncForOrigin() if it has any pending batch sync origins, or
309   // - FetchChangesForIncrementalSync() otherwise.
310   //
311   // These two methods are called only from this method.
312   void MaybeStartFetchChanges();
313
314   void FetchChangesForIncrementalSync(const SyncStatusCallback& callback);
315   void DidFetchChangesForIncrementalSync(
316       const SyncStatusCallback& callback,
317       bool has_new_changes,
318       google_apis::GDataErrorCode error,
319       scoped_ptr<google_apis::ResourceList> changes);
320   bool GetOriginForEntry(const google_apis::ResourceEntry& entry, GURL* origin);
321   void NotifyObserversFileStatusChanged(const fileapi::FileSystemURL& url,
322                                         SyncFileStatus sync_status,
323                                         SyncAction action_taken,
324                                         SyncDirection direction);
325
326   void HandleSyncRootDirectoryChange(const google_apis::ResourceEntry& entry);
327   void HandleOriginRootDirectoryChange(const google_apis::ResourceEntry& entry);
328
329   void EnsureSyncRootDirectory(const ResourceIdCallback& callback);
330   void DidEnsureSyncRoot(const ResourceIdCallback& callback,
331                          google_apis::GDataErrorCode error,
332                          const std::string& sync_root_resource_id);
333   void EnsureOriginRootDirectory(const GURL& origin,
334                                  const ResourceIdCallback& callback);
335   void DidEnsureSyncRootForOriginRoot(const GURL& origin,
336                                       const ResourceIdCallback& callback,
337                                       SyncStatusCode status,
338                                       const std::string& sync_root_resource_id);
339   void DidEnsureOriginRoot(const GURL& origin,
340                            const ResourceIdCallback& callback,
341                            google_apis::GDataErrorCode error,
342                            const std::string& resource_id);
343
344   // This function returns Resouce ID for the sync root directory if available.
345   // Returns an empty string 1) when the resource ID has not been initialized
346   // yet, and 2) after the service has detected the remote sync root folder was
347   // removed.
348   std::string sync_root_resource_id();
349
350   scoped_ptr<DriveMetadataStore> metadata_store_;
351   scoped_ptr<drive_backend::APIUtilInterface> api_util_;
352
353   Profile* profile_;
354
355   scoped_ptr<SyncTaskManager> task_manager_;
356
357   scoped_ptr<drive_backend::LocalSyncDelegate> running_local_sync_task_;
358   scoped_ptr<drive_backend::RemoteSyncDelegate> running_remote_sync_task_;
359
360   // The current remote service state. This does NOT reflect the
361   // sync_enabled_ flag, while GetCurrentState() DOES reflect the flag
362   // value (i.e. it returns REMOTE_SERVICE_DISABLED when sync_enabled_
363   // is false even if state_ is REMOTE_SERVICE_OK).
364   RemoteServiceState state_;
365
366   // Indicates if sync is enabled or not. This flag can be turned on or
367   // off by SetSyncEnabled() method.  To start synchronization
368   // this needs to be true and state_ needs to be REMOTE_SERVICE_OK.
369   bool sync_enabled_;
370
371   int64 largest_fetched_changestamp_;
372
373   std::map<GURL, std::string> pending_batch_sync_origins_;
374
375   // Is set to true when there's a fair possibility that we have some
376   // remote changes that haven't been fetched yet.
377   //
378   // This flag is set when:
379   // - This gets invalidation notification,
380   // - The service is authenticated or becomes online, and
381   // - The polling timer is fired.
382   //
383   // This flag is cleared when:
384   // - A batch or incremental sync has been started, and
385   // - When all pending batch sync tasks have been finished.
386   bool may_have_unfetched_changes_;
387
388   ObserverList<Observer> service_observers_;
389   ObserverList<FileStatusObserver> file_status_observers_;
390
391   RemoteChangeHandler remote_change_handler_;
392   RemoteChangeProcessor* remote_change_processor_;
393
394   google_apis::GDataErrorCode last_gdata_error_;
395
396   ConflictResolutionResolver conflict_resolution_resolver_;
397
398   OriginOperationQueue pending_origin_operations_;
399
400   DISALLOW_COPY_AND_ASSIGN(DriveFileSyncService);
401 };
402
403 }  // namespace sync_file_system
404
405 #endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_V1_DRIVE_FILE_SYNC_SERVICE_H_