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