Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / sync_file_system / drive_backend / remote_to_local_syncer.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_REMOTE_TO_LOCAL_SYNCER_H_
6 #define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_TO_LOCAL_SYNCER_H_
7
8 #include <string>
9 #include <vector>
10
11 #include "base/memory/scoped_vector.h"
12 #include "base/memory/weak_ptr.h"
13 #include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
14 #include "chrome/browser/sync_file_system/drive_backend/sync_task.h"
15 #include "chrome/browser/sync_file_system/remote_change_processor.h"
16 #include "chrome/browser/sync_file_system/sync_action.h"
17 #include "chrome/browser/sync_file_system/sync_callbacks.h"
18 #include "chrome/browser/sync_file_system/sync_file_metadata.h"
19 #include "google_apis/drive/gdata_errorcode.h"
20 #include "webkit/browser/fileapi/file_system_url.h"
21
22 namespace drive {
23 class DriveServiceInterface;
24 }
25
26 namespace google_apis {
27 class FileList;
28 class FileResource;
29 class ResourceEntry;
30 }
31
32 namespace webkit_blob {
33 class ScopedFile;
34 }
35
36 namespace sync_file_system {
37 namespace drive_backend {
38
39 class MetadataDatabase;
40 class SyncEngineContext;
41
42 class RemoteToLocalSyncer : public SyncTask {
43  public:
44   // Conflicting trackers will have low priority for RemoteToLocalSyncer so that
45   // it should be resolved by LocatToRemoteSyncer.
46   explicit RemoteToLocalSyncer(SyncEngineContext* sync_context);
47   virtual ~RemoteToLocalSyncer();
48
49   virtual void RunPreflight(scoped_ptr<SyncTaskToken> token) OVERRIDE;
50   void RunExclusive(scoped_ptr<SyncTaskToken> token);
51
52   const fileapi::FileSystemURL& url() const { return url_; }
53   SyncAction sync_action() const { return sync_action_; }
54
55   bool is_sync_root_deletion() const { return sync_root_deletion_; }
56
57  private:
58   typedef std::vector<std::string> FileIDList;
59
60   // TODO(tzik): Update documentation here.
61   //
62   // Dispatches remote change to handlers or to SyncCompleted() directly.
63   // This function uses information only in MetadataDatabase.
64   //
65   // If the tracker doesn't have remote metadata:
66   //   # The file is listed in a folder right before this operation.
67   //   - Dispatch to HandleMissingRemoteMetadata to fetch remote metadata.
68   // Else, if the tracker is not active or the dominating app-root is disabled:
69   //   # Assume the file has remote metadata.
70   //   - Update the tracker with |missing| flag and empty |md5|.
71   //   Note: MetadataDatabase may activate the tracker if possible.
72   // Else, if the tracker doesn't have synced metadata:
73   //   # Assume the tracker has remote metadata and the tracker is active.
74   //   # The tracker is not yet synced ever.
75   //   - If the file is remotely deleted, do nothing to local file and dispatch
76   //     directly to SyncCompleted().
77   //   - Else, if the file is a regular file, dispatch to HandleNewFile().
78   //   - Else, if the file is a folder, dispatch to HandleFolderUpdate().
79   //   - Else, the file should be an unsupported active file. This should not
80   //     happen.
81   // Else, if the remote metadata is marked as deleted:
82   //   # Most of the remote metadata is missing including title, kind and md5.
83   //   - Dispatch to HandleDeletion().
84   // Else, if the tracker has different titles between its synced metadata and
85   // remote metadata:
86   //   # Assume the tracker is active and has remote metetadata and synced
87   //     metadata.
88   //   # The file is remotely renamed.
89   //   # Maybe, this can be decomposed to delete and update.
90   //   - Dispatch to HandleRemoteRename().
91   // Else, if the tracker's parent is not a parent of the remote metadata:
92   //   # The file has reorganized.
93   //   # Maybe, this can be decomposed to delete and update.
94   //   - Dispatch to HandreReorganize().
95   // Else, if the folder is a regular file and the md5 in remote metadata does
96   // not match the md5 in synced metadata:
97   //   # The file is modified remotely.
98   //   - Dispatch to HandleContentUpdate().
99   // Else, if the tracker is a folder and it has needs_folder_listing flag:
100   //   - Dispatch to HandleFolderContentListing()
101   // Else, there should be no change to sync.
102   //   - Dispatch to HandleOfflineSolvable()
103   void ResolveRemoteChange(scoped_ptr<SyncTaskToken> token);
104
105   // Handles missing remote metadata case.
106   // Fetches remote metadata and updates MetadataDatabase by that.  The sync
107   // operation itself will be deferred to the next sync round.
108   // Note: if the file is not found, it should be handled as if deleted.
109   void HandleMissingRemoteMetadata(scoped_ptr<SyncTaskToken> token);
110   void DidGetRemoteMetadata(scoped_ptr<SyncTaskToken> token,
111                             google_apis::GDataErrorCode error,
112                             scoped_ptr<google_apis::FileResource> entry);
113   void DidUpdateDatabaseForRemoteMetadata(scoped_ptr<SyncTaskToken> token,
114                                           SyncStatusCode status);
115
116   // This implements the body of the HandleNewFile and HandleContentUpdate.
117   // If the file doesn't have corresponding local file:
118   //   - Dispatch to DownloadFile.
119   // Else, if the local file doesn't have local change:
120   //   - Dispatch to DownloadFile if the local file is a regular file.
121   //   - If the local file is a folder, handle this case as a conflict.  Lower
122   //     the priority of the tracker, and defer further handling to
123   //     local-to-remote change.
124   // Else:
125   //  # The file has local modification.
126   //  - Handle this case as a conflict.  Lower the priority of the tracker, and
127   //    defer further handling to local-to-remote change.
128   void DidPrepareForAddOrUpdateFile(scoped_ptr<SyncTaskToken> token,
129                                     SyncStatusCode status);
130
131   // Handles remotely added folder.  Needs Prepare() call.
132   // TODO(tzik): Write details and implement this.
133   void HandleFolderUpdate(scoped_ptr<SyncTaskToken> token);
134   void DidPrepareForFolderUpdate(scoped_ptr<SyncTaskToken> token,
135                                  SyncStatusCode status);
136
137   void HandleSyncRootDeletion(scoped_ptr<SyncTaskToken> token);
138
139   // Handles deleted remote file.  Needs Prepare() call.
140   // If the deleted tracker is the sync-root:
141   //  - TODO(tzik): Needs special handling.
142   // Else, if the deleted tracker is a app-root:
143   //  - TODO(tzik): Needs special handling.
144   // Else, if the local file is already deleted:
145   //  - Do nothing anymore to the local, call SyncCompleted().
146   // Else, if the local file is modified:
147   //  - Do nothing to the local file, call SyncCompleted().
148   // Else, if the local file is not modified:
149   //  - Delete local file.
150   //  # Note: if the local file is a folder, delete recursively.
151   void HandleDeletion(scoped_ptr<SyncTaskToken> token);
152   void DidPrepareForDeletion(scoped_ptr<SyncTaskToken> token,
153                              SyncStatusCode status);
154
155   // Handles new file.  Needs Prepare() call.
156   void HandleContentUpdate(scoped_ptr<SyncTaskToken> token);
157
158   void ListFolderContent(scoped_ptr<SyncTaskToken> token);
159   void DidListFolderContent(
160       scoped_ptr<SyncTaskToken> token,
161       scoped_ptr<FileIDList> children,
162       google_apis::GDataErrorCode error,
163       scoped_ptr<google_apis::FileList> file_list);
164
165   void SyncCompleted(scoped_ptr<SyncTaskToken> token, SyncStatusCode status);
166   void FinalizeSync(scoped_ptr<SyncTaskToken> token, SyncStatusCode status);
167
168   void Prepare(const SyncStatusCallback& callback);
169   void DidPrepare(const SyncStatusCallback& callback,
170                   SyncStatusCode status,
171                   const SyncFileMetadata& metadata,
172                   const FileChangeList& changes);
173
174   void DeleteLocalFile(scoped_ptr<SyncTaskToken> token);
175   void DownloadFile(scoped_ptr<SyncTaskToken> token);
176   void DidDownloadFile(scoped_ptr<SyncTaskToken> token,
177                        webkit_blob::ScopedFile file,
178                        google_apis::GDataErrorCode error,
179                        const base::FilePath&);
180   void DidApplyDownload(scoped_ptr<SyncTaskToken> token,
181                         webkit_blob::ScopedFile,
182                         SyncStatusCode status);
183
184   void CreateFolder(scoped_ptr<SyncTaskToken> token);
185
186   // TODO(tzik): After we convert all callbacks to token-passing style,
187   // drop this function.
188   SyncStatusCallback SyncCompletedCallback(scoped_ptr<SyncTaskToken> token);
189
190   drive::DriveServiceInterface* drive_service();
191   MetadataDatabase* metadata_database();
192   RemoteChangeProcessor* remote_change_processor();
193
194   SyncEngineContext* sync_context_;  // Not owned.
195
196   scoped_ptr<FileTracker> dirty_tracker_;
197   scoped_ptr<FileMetadata> remote_metadata_;
198
199   fileapi::FileSystemURL url_;
200   SyncAction sync_action_;
201
202   bool prepared_;
203   bool sync_root_deletion_;
204
205   scoped_ptr<SyncFileMetadata> local_metadata_;
206   scoped_ptr<FileChangeList> local_changes_;
207
208   base::WeakPtrFactory<RemoteToLocalSyncer> weak_ptr_factory_;
209
210   DISALLOW_COPY_AND_ASSIGN(RemoteToLocalSyncer);
211 };
212
213 }  // namespace drive_backend
214 }  // namespace sync_file_system
215
216 #endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_TO_LOCAL_SYNCER_H_