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