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