15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_TO_LOCAL_SYNCER_H_
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_TO_LOCAL_SYNCER_H_
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/weak_ptr.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync_file_system/remote_change_processor.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync_file_system/sync_action.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync_file_system/sync_callbacks.h"
17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/sync_file_system/sync_file_metadata.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/sync_file_system/sync_task.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "google_apis/drive/gdata_errorcode.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "webkit/browser/fileapi/file_system_url.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace drive {
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class DriveServiceInterface;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
26eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace google_apis {
27d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class FileResource;
28d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class ResourceEntry;
29d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class ResourceList;
30d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)}
31d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
32eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace webkit_blob {
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass ScopedFile;
34eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
35eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
36eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace sync_file_system {
37eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace drive_backend {
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
39eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass MetadataDatabase;
40d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class SyncEngineContext;
41d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
42d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)class RemoteToLocalSyncer : public SyncTask {
43eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch public:
44eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Conflicting trackers will have low priority for RemoteToLocalSyncer so that
45eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // it should be resolved by LocatToRemoteSyncer.
46eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  explicit RemoteToLocalSyncer(SyncEngineContext* sync_context);
47eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual ~RemoteToLocalSyncer();
48eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
49eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  virtual void Run(const SyncStatusCallback& callback) OVERRIDE;
50eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
51eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const fileapi::FileSystemURL& url() const { return url_; }
52eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  SyncAction sync_action() const { return sync_action_; }
53eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
54eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  bool is_sync_root_deletion() const { return sync_root_deletion_; }
55d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
56d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) private:
57d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  typedef std::vector<std::string> FileIDList;
58d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
59d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // TODO(tzik): Update documentation here.
60eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //
61eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Dispatches remote change to handlers or to SyncCompleted() directly.
62eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // This function uses information only in MetadataDatabase.
63eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //
64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // If the tracker doesn't have remote metadata:
65d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //   # The file is listed in a folder right before this operation.
66d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //   - Dispatch to HandleMissingRemoteMetadata to fetch remote metadata.
67d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Else, if the tracker is not active or the dominating app-root is disabled:
68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //   # Assume the file has remote metadata.
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //   - Update the tracker with |missing| flag and empty |md5|.
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   Note: MetadataDatabase may activate the tracker if possible.
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Else, if the tracker doesn't have synced metadata:
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   # Assume the tracker has remote metadata and the tracker is active.
73d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //   # The tracker is not yet synced ever.
74d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //   - If the file is remotely deleted, do nothing to local file and dispatch
75d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //     directly to SyncCompleted().
76d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //   - Else, if the file is a regular file, dispatch to HandleNewFile().
77eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   - Else, if the file is a folder, dispatch to HandleFolderUpdate().
78eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   - Else, the file should be an unsupported active file. This should not
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //     happen.
80d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  // Else, if the remote metadata is marked as deleted:
81d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //   # Most of the remote metadata is missing including title, kind and md5.
82d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  //   - Dispatch to HandleDeletion().
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // Else, if the tracker has different titles between its synced metadata and
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  // remote metadata:
85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   # Assume the tracker is active and has remote metetadata and synced
86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //     metadata.
87eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   # The file is remotely renamed.
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   # Maybe, this can be decomposed to delete and update.
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  //   - Dispatch to HandleRemoteRename().
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Else, if the tracker's parent is not a parent of the remote metadata:
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   # The file has reorganized.
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   # Maybe, this can be decomposed to delete and update.
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  //   - Dispatch to HandreReorganize().
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Else, if the folder is a regular file and the md5 in remote metadata does
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // not match the md5 in synced metadata:
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   # The file is modified remotely.
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   - Dispatch to HandleContentUpdate().
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Else, if the tracker is a folder and it has needs_folder_listing flag:
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   - Dispatch to HandleFolderContentListing()
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Else, there should be no change to sync.
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   - Dispatch to HandleOfflineSolvable()
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ResolveRemoteChange(const SyncStatusCallback& callback);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles missing remote metadata case.
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fetches remote metadata and updates MetadataDatabase by that.  The sync
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // operation itself will be deferred to the next sync round.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Note: if the file is not found, it should be handled as if deleted.
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleMissingRemoteMetadata(const SyncStatusCallback& callback);
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidGetRemoteMetadata(const SyncStatusCallback& callback,
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            google_apis::GDataErrorCode error,
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            scoped_ptr<google_apis::ResourceEntry> entry);
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidUpdateDatabaseForRemoteMetadata(const SyncStatusCallback& callback,
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                          SyncStatusCode status);
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This implements the body of the HandleNewFile and HandleContentUpdate.
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the file doesn't have corresponding local file:
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   - Dispatch to DownloadFile.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Else, if the local file doesn't have local change:
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   - Dispatch to DownloadFile if the local file is a regular file.
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //   - If the local file is a folder, handle this case as a conflict.  Lower
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     the priority of the tracker, and defer further handling to
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //     local-to-remote change.
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Else:
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  # The file has local modification.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  - Handle this case as a conflict.  Lower the priority of the tracker, and
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //    defer further handling to local-to-remote change.
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidPrepareForAddOrUpdateFile(const SyncStatusCallback& callback,
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    SyncStatusCode status);
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles remotely added folder.  Needs Prepare() call.
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(tzik): Write details and implement this.
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleFolderUpdate(const SyncStatusCallback& callback);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidPrepareForFolderUpdate(const SyncStatusCallback& callback,
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 SyncStatusCode status);
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleSyncRootDeletion(const SyncStatusCallback& callback);
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles deleted remote file.  Needs Prepare() call.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the deleted tracker is the sync-root:
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  - TODO(tzik): Needs special handling.
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Else, if the deleted tracker is a app-root:
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  - TODO(tzik): Needs special handling.
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Else, if the local file is already deleted:
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  - Do nothing anymore to the local, call SyncCompleted().
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Else, if the local file is modified:
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  - Do nothing to the local file, call SyncCompleted().
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Else, if the local file is not modified:
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  - Delete local file.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  //  # Note: if the local file is a folder, delete recursively.
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void HandleDeletion(const SyncStatusCallback& callback);
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void DidPrepareForDeletion(const SyncStatusCallback& callback,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                             SyncStatusCode status);
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Handles new file.  Needs Prepare() call.
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void HandleContentUpdate(const SyncStatusCallback& callback);
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void ListFolderContent(const SyncStatusCallback& callback);
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidListFolderContent(
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const SyncStatusCallback& callback,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<FileIDList> children,
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      google_apis::GDataErrorCode error,
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      scoped_ptr<google_apis::ResourceList> resource_list);
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SyncCompleted(const SyncStatusCallback& callback, SyncStatusCode status);
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FinalizeSync(const SyncStatusCallback& callback, SyncStatusCode status);
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void Prepare(const SyncStatusCallback& callback);
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void DidPrepare(const SyncStatusCallback& callback,
170                  SyncStatusCode status,
171                  const SyncFileMetadata& metadata,
172                  const FileChangeList& changes);
173
174  void DeleteLocalFile(const SyncStatusCallback& callback);
175  void DownloadFile(const SyncStatusCallback& callback);
176  void DidCreateTemporaryFileForDownload(const SyncStatusCallback& callback,
177                                         webkit_blob::ScopedFile file);
178  void DidDownloadFile(const SyncStatusCallback& callback,
179                       webkit_blob::ScopedFile file,
180                       google_apis::GDataErrorCode error,
181                       const base::FilePath&);
182  void DidCalculateMD5ForDownload(const SyncStatusCallback& callback,
183                                  webkit_blob::ScopedFile file,
184                                  const std::string& md5);
185  void DidApplyDownload(const SyncStatusCallback& callback,
186                        webkit_blob::ScopedFile,
187                        SyncStatusCode status);
188
189  void CreateFolder(const SyncStatusCallback& callback);
190
191  drive::DriveServiceInterface* drive_service();
192  MetadataDatabase* metadata_database();
193  RemoteChangeProcessor* remote_change_processor();
194
195  SyncEngineContext* sync_context_;  // Not owned.
196
197  scoped_ptr<FileTracker> dirty_tracker_;
198  scoped_ptr<FileMetadata> remote_metadata_;
199
200  fileapi::FileSystemURL url_;
201  SyncAction sync_action_;
202
203  bool prepared_;
204  bool sync_root_deletion_;
205
206  scoped_ptr<SyncFileMetadata> local_metadata_;
207  scoped_ptr<FileChangeList> local_changes_;
208
209  base::WeakPtrFactory<RemoteToLocalSyncer> weak_ptr_factory_;
210
211  DISALLOW_COPY_AND_ASSIGN(RemoteToLocalSyncer);
212};
213
214}  // namespace drive_backend
215}  // namespace sync_file_system
216
217#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_TO_LOCAL_SYNCER_H_
218