Chromium Code Reviews| Index: chrome/browser/sync_file_system/drive/apply_local_change_delegate.cc |
| diff --git a/chrome/browser/sync_file_system/drive/apply_local_change_delegate.cc b/chrome/browser/sync_file_system/drive/apply_local_change_delegate.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..183177e4c460828a4a1ec131d2e8b9337bc83f8b |
| --- /dev/null |
| +++ b/chrome/browser/sync_file_system/drive/apply_local_change_delegate.cc |
| @@ -0,0 +1,612 @@ |
| +// Copyright 2013 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "chrome/browser/sync_file_system/drive/apply_local_change_delegate.h" |
| + |
| +#include "base/bind.h" |
| +#include "base/callback.h" |
| +#include "chrome/browser/sync_file_system/drive/api_util.h" |
| +#include "chrome/browser/sync_file_system/drive_file_sync_service.h" |
| +#include "chrome/browser/sync_file_system/drive_metadata_store.h" |
| +#include "webkit/fileapi/syncable/syncable_file_system_util.h" |
| + |
| +namespace sync_file_system { |
| +namespace drive { |
| + |
| +namespace { |
| + |
| +void OwnDelegateInstance(ApplyLocalChangeDelegate* delegate, |
| + const SyncStatusCallback& callback, |
| + SyncStatusCode status) { |
| + callback.Run(status); |
| +} |
| + |
| +} // namespace |
| + |
| +ApplyLocalChangeDelegate::~ApplyLocalChangeDelegate() {} |
| + |
| +ApplyLocalChangeDelegate::ApplyLocalChangeDelegate( |
|
kinuko
2013/05/16 06:57:49
nit: method order different from .h
tzik
2013/05/16 11:06:14
Done.
|
| + base::WeakPtr<DriveFileSyncService> sync_service, |
| + const FileChange& local_change, |
| + const base::FilePath& local_path, |
| + const SyncFileMetadata& local_metadata, |
| + const fileapi::FileSystemURL& url) |
| + : sync_service_(sync_service), |
| + url_(url), |
| + local_change_(local_change), |
| + local_path_(local_path), |
| + local_metadata_(local_metadata), |
| + has_drive_metadata_(false), |
| + has_remote_change_(false), |
| + weak_factory_(this) {} |
| + |
| +void ApplyLocalChangeDelegate::ApplyLocalChange( |
| + base::WeakPtr<DriveFileSyncService> sync_service, |
| + const FileChange& local_change, |
| + const base::FilePath& local_path, |
| + const SyncFileMetadata& local_metadata, |
| + const fileapi::FileSystemURL& url, |
| + const SyncStatusCallback& callback) { |
| + if (!sync_service) |
| + return; |
| + |
| + ApplyLocalChangeDelegate* delegate = new ApplyLocalChangeDelegate( |
| + sync_service, local_change, local_path, local_metadata, url); |
| + SyncStatusCallback completion_callback = |
| + base::Bind(&OwnDelegateInstance, base::Owned(delegate), callback); |
|
kinuko
2013/05/16 06:57:49
I understand this class's very self-contained and
tzik
2013/05/16 11:06:14
Done. I added |running_local_sync_task_| to DriveF
|
| + delegate->Run(completion_callback); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::Run(const SyncStatusCallback& callback) { |
| + if (!sync_service_) |
| + return; |
| + |
| + // TODO(nhiroki): support directory operations (http://crbug.com/161442). |
| + DCHECK(IsSyncDirectoryOperationEnabled() || !local_change_.IsDirectory()); |
| + |
| + has_drive_metadata_ = |
| + metadata_store()->ReadEntry(url_, &drive_metadata_) == SYNC_STATUS_OK; |
| + |
| + if (!has_drive_metadata_) |
| + drive_metadata_.set_md5_checksum(std::string()); |
| + |
| + sync_service_->EnsureOriginRootDirectory( |
| + url_.origin(), |
| + base::Bind(&ApplyLocalChangeDelegate::DidGetOriginRoot, |
| + weak_factory_.GetWeakPtr(), |
| + callback)); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::DidGetOriginRoot( |
| + const SyncStatusCallback& callback, |
| + SyncStatusCode status, |
| + const std::string& origin_resource_id) { |
| + if (!sync_service_) |
| + return; |
| + |
| + if (status != SYNC_STATUS_OK) { |
| + callback.Run(status); |
| + return; |
| + } |
| + |
| + origin_resource_id_ = origin_resource_id; |
| + |
| + has_remote_change_ = |
| + remote_change_handler()->GetChangeForURL(url_, &remote_change_); |
| + if (has_remote_change_ && drive_metadata_.resource_id().empty()) |
| + drive_metadata_.set_resource_id(remote_change_.resource_id); |
| + |
| + LocalSyncOperationType operation = LocalSyncOperationResolver::Resolve( |
| + local_change_, |
| + has_remote_change_ ? &remote_change_.change : NULL, |
| + has_drive_metadata_ ? &drive_metadata_ : NULL); |
| + |
| + DVLOG(1) << "ApplyLocalChange for " << url_.DebugString() |
| + << " local_change:" << local_change_.DebugString() |
| + << " ==> operation:" << operation; |
| + |
| + switch (operation) { |
| + case LOCAL_SYNC_OPERATION_ADD_FILE: |
| + UploadNewFile(callback); |
| + return; |
| + case LOCAL_SYNC_OPERATION_ADD_DIRECTORY: |
| + CreateDirectory(callback); |
| + return; |
| + case LOCAL_SYNC_OPERATION_UPDATE_FILE: |
| + UploadExistingFile(callback); |
| + return; |
| + case LOCAL_SYNC_OPERATION_DELETE_FILE: |
| + DeleteFile(callback); |
| + return; |
| + case LOCAL_SYNC_OPERATION_DELETE_DIRECTORY: |
| + DeleteDirectory(callback); |
| + return; |
| + case LOCAL_SYNC_OPERATION_NONE: |
| + callback.Run(SYNC_STATUS_OK); |
| + return; |
| + case LOCAL_SYNC_OPERATION_CONFLICT: |
| + HandleConflict(callback); |
| + return; |
| + case LOCAL_SYNC_OPERATION_RESOLVE_TO_LOCAL: |
| + ResolveToLocal(callback); |
| + return; |
| + case LOCAL_SYNC_OPERATION_RESOLVE_TO_REMOTE: |
| + ResolveToRemote(callback); |
| + return; |
| + case LOCAL_SYNC_OPERATION_DELETE_METADATA: |
| + DeleteMetadata(base::Bind( |
| + &ApplyLocalChangeDelegate::DidApplyLocalChange, |
| + weak_factory_.GetWeakPtr(), callback, google_apis::HTTP_SUCCESS)); |
| + return; |
| + case LOCAL_SYNC_OPERATION_FAIL: { |
| + callback.Run(SYNC_STATUS_FAILED); |
| + return; |
| + } |
| + } |
| + NOTREACHED(); |
| + callback.Run(SYNC_STATUS_FAILED); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::UploadNewFile( |
| + const SyncStatusCallback& callback) { |
| + if (!sync_service_) |
| + return; |
| + |
| + api_util()->UploadNewFile( |
| + origin_resource_id_, |
| + local_path_, |
| + DriveFileSyncService::PathToTitle(url_.path()), |
| + base::Bind(&ApplyLocalChangeDelegate::DidUploadNewFile, |
| + weak_factory_.GetWeakPtr(), callback)); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::DidUploadNewFile( |
| + const SyncStatusCallback& callback, |
| + google_apis::GDataErrorCode error, |
| + const std::string& resource_id, |
| + const std::string& md5) { |
| + if (!sync_service_) |
| + return; |
| + |
| + switch (error) { |
| + case google_apis::HTTP_CREATED: |
| + UpdateMetadata( |
| + resource_id, md5, DriveMetadata::RESOURCE_TYPE_FILE, |
| + base::Bind(&ApplyLocalChangeDelegate::DidApplyLocalChange, |
| + weak_factory_.GetWeakPtr(), callback, error)); |
| + sync_service_->NotifyObserversFileStatusChanged( |
| + url_, |
| + SYNC_FILE_STATUS_SYNCED, |
| + SYNC_ACTION_ADDED, |
| + SYNC_DIRECTION_LOCAL_TO_REMOTE); |
| + return; |
| + case google_apis::HTTP_CONFLICT: |
| + HandleCreationConflict(resource_id, DriveMetadata::RESOURCE_TYPE_FILE, |
| + callback); |
| + return; |
| + default: |
| + callback.Run(GDataErrorCodeToSyncStatusCodeWrapper(error)); |
| + } |
| +} |
| + |
| +void ApplyLocalChangeDelegate::CreateDirectory( |
| + const SyncStatusCallback& callback) { |
| + if (!sync_service_) |
| + return; |
| + |
| + DCHECK(IsSyncDirectoryOperationEnabled()); |
| + api_util()->CreateDirectory( |
| + origin_resource_id_, |
| + DriveFileSyncService::PathToTitle(url_.path()), |
| + base::Bind(&ApplyLocalChangeDelegate::DidCreateDirectory, |
| + weak_factory_.GetWeakPtr(), callback)); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::DidCreateDirectory( |
| + const SyncStatusCallback& callback, |
| + google_apis::GDataErrorCode error, |
| + const std::string& resource_id) { |
| + if (!sync_service_) |
| + return; |
| + |
| + switch (error) { |
| + case google_apis::HTTP_SUCCESS: |
| + case google_apis::HTTP_CREATED: { |
| + UpdateMetadata( |
| + resource_id, std::string(), DriveMetadata::RESOURCE_TYPE_FOLDER, |
| + base::Bind(&ApplyLocalChangeDelegate::DidApplyLocalChange, |
| + weak_factory_.GetWeakPtr(), callback, error)); |
| + sync_service_->NotifyObserversFileStatusChanged( |
| + url_, |
| + SYNC_FILE_STATUS_SYNCED, |
| + SYNC_ACTION_ADDED, |
| + SYNC_DIRECTION_LOCAL_TO_REMOTE); |
| + return; |
| + } |
| + |
| + case google_apis::HTTP_CONFLICT: |
| + // There were conflicts and a file was left. |
| + // TODO(kinuko): Handle the latter case (http://crbug.com/237090). |
| + // Fall-through |
| + |
| + default: |
| + callback.Run(GDataErrorCodeToSyncStatusCodeWrapper(error)); |
| + } |
| +} |
| + |
| +void ApplyLocalChangeDelegate::UploadExistingFile( |
| + const SyncStatusCallback& callback) { |
| + if (!sync_service_) |
| + return; |
| + |
| + DCHECK(has_drive_metadata_); |
| + api_util()->UploadExistingFile( |
| + drive_metadata_.resource_id(), |
| + drive_metadata_.md5_checksum(), |
| + local_path_, |
| + base::Bind(&ApplyLocalChangeDelegate::DidUploadExistingFile, |
| + weak_factory_.GetWeakPtr(), callback)); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::DidUploadExistingFile( |
| + const SyncStatusCallback& callback, |
| + google_apis::GDataErrorCode error, |
| + const std::string& resource_id, |
| + const std::string& md5) { |
| + if (!sync_service_) |
| + return; |
| + |
| + DCHECK(has_drive_metadata_); |
| + switch (error) { |
| + case google_apis::HTTP_SUCCESS: |
| + UpdateMetadata( |
| + resource_id, md5, DriveMetadata::RESOURCE_TYPE_FILE, |
| + base::Bind(&ApplyLocalChangeDelegate::DidApplyLocalChange, |
| + weak_factory_.GetWeakPtr(), callback, error)); |
| + sync_service_->NotifyObserversFileStatusChanged( |
| + url_, |
| + SYNC_FILE_STATUS_SYNCED, |
| + SYNC_ACTION_UPDATED, |
| + SYNC_DIRECTION_LOCAL_TO_REMOTE); |
| + return; |
| + case google_apis::HTTP_CONFLICT: { |
| + HandleConflict(callback); |
| + return; |
| + } |
| + case google_apis::HTTP_NOT_MODIFIED: { |
| + DidApplyLocalChange(callback, |
| + google_apis::HTTP_SUCCESS, SYNC_STATUS_OK); |
| + return; |
| + } |
| + case google_apis::HTTP_NOT_FOUND: { |
| + UploadNewFile(callback); |
| + return; |
| + } |
| + default: { |
| + const SyncStatusCode status = |
| + GDataErrorCodeToSyncStatusCodeWrapper(error); |
| + DCHECK_NE(SYNC_STATUS_OK, status); |
| + callback.Run(status); |
| + return; |
| + } |
| + } |
| +} |
| + |
| +void ApplyLocalChangeDelegate::DeleteFile( |
| + const SyncStatusCallback& callback) { |
| + if (!sync_service_) |
| + return; |
| + |
| + DCHECK(has_drive_metadata_); |
| + api_util()->DeleteFile( |
| + drive_metadata_.resource_id(), |
| + drive_metadata_.md5_checksum(), |
| + base::Bind(&ApplyLocalChangeDelegate::DidDeleteFile, |
| + weak_factory_.GetWeakPtr(), callback)); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::DeleteDirectory( |
| + const SyncStatusCallback& callback) { |
| + if (!sync_service_) |
| + return; |
| + |
| + DCHECK(IsSyncDirectoryOperationEnabled()); |
| + DCHECK(has_drive_metadata_); |
| + // This does not handle recursive directory deletion |
| + // (which should not happen other than after a restart). |
| + api_util()->DeleteFile( |
| + drive_metadata_.resource_id(), |
| + std::string(), // empty md5 |
| + base::Bind(&ApplyLocalChangeDelegate::DidDeleteFile, |
| + weak_factory_.GetWeakPtr(), callback)); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::DidDeleteFile( |
| + const SyncStatusCallback& callback, |
| + google_apis::GDataErrorCode error) { |
| + if (!sync_service_) |
| + return; |
| + |
| + DCHECK(has_drive_metadata_); |
| + |
| + switch (error) { |
| + // Regardless of whether the deletion has succeeded (HTTP_SUCCESS) or |
| + // has failed with ETag conflict error (HTTP_PRECONDITION or HTTP_CONFLICT) |
| + // we should just delete the drive_metadata. |
| + // In the former case the file should be just gone now, and |
| + // in the latter case the remote change will be applied in a future |
| + // remote sync. |
| + case google_apis::HTTP_SUCCESS: |
| + case google_apis::HTTP_PRECONDITION: |
| + case google_apis::HTTP_CONFLICT: |
| + DeleteMetadata(base::Bind(&ApplyLocalChangeDelegate::DidApplyLocalChange, |
| + weak_factory_.GetWeakPtr(), callback, error)); |
| + sync_service_->NotifyObserversFileStatusChanged( |
| + url_, |
| + SYNC_FILE_STATUS_SYNCED, |
| + SYNC_ACTION_DELETED, |
| + SYNC_DIRECTION_LOCAL_TO_REMOTE); |
| + return; |
| + case google_apis::HTTP_NOT_FOUND: |
| + DidApplyLocalChange(callback, |
| + google_apis::HTTP_SUCCESS, SYNC_STATUS_OK); |
| + return; |
| + default: { |
| + const SyncStatusCode status = |
| + GDataErrorCodeToSyncStatusCodeWrapper(error); |
| + DCHECK_NE(SYNC_STATUS_OK, status); |
| + callback.Run(status); |
| + return; |
| + } |
| + } |
| +} |
| + |
| +void ApplyLocalChangeDelegate::ResolveToLocal( |
| + const SyncStatusCallback& callback) { |
| + if (!sync_service_) |
| + return; |
| + |
| + api_util()->DeleteFile( |
| + drive_metadata_.resource_id(), |
| + drive_metadata_.md5_checksum(), |
| + base::Bind( |
| + &ApplyLocalChangeDelegate::DidDeleteFileToResolveToLocal, |
| + weak_factory_.GetWeakPtr(), callback)); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::DidDeleteFileToResolveToLocal( |
| + const SyncStatusCallback& callback, |
| + google_apis::GDataErrorCode error) { |
| + if (!sync_service_) |
| + return; |
| + |
| + if (error != google_apis::HTTP_SUCCESS && |
| + error != google_apis::HTTP_NOT_FOUND) { |
| + remote_change_handler()->RemoveChangeForURL(url_); |
| + callback.Run(GDataErrorCodeToSyncStatusCodeWrapper(error)); |
| + return; |
| + } |
| + |
| + DCHECK_NE(SYNC_FILE_TYPE_UNKNOWN, local_metadata_.file_type); |
| + if (local_metadata_.file_type == SYNC_FILE_TYPE_FILE) { |
| + UploadNewFile(callback); |
| + return; |
| + } |
| + |
| + DCHECK(IsSyncDirectoryOperationEnabled()); |
| + DCHECK_EQ(SYNC_FILE_TYPE_DIRECTORY, local_metadata_.file_type); |
| + CreateDirectory(callback); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::ResolveToRemote( |
| + const SyncStatusCallback& callback) { |
| + if (!sync_service_) |
| + return; |
| + |
| + // Mark the file as to-be-fetched. |
| + DCHECK(!drive_metadata_.resource_id().empty()); |
| + |
| + SyncFileType type = remote_change_.change.file_type(); |
| + SetToBeFetched( |
| + drive_metadata_.resource_id(), |
| + DriveFileSyncService::SyncFileTypeToDriveMetadataResourceType(type), |
| + base::Bind(&ApplyLocalChangeDelegate::DidResolveToRemote, |
| + weak_factory_.GetWeakPtr(), callback)); |
| + // The synced notification will be dispatched when the remote file is |
| + // downloaded. |
| +} |
| + |
| +void ApplyLocalChangeDelegate::DidResolveToRemote( |
| + const SyncStatusCallback& callback, |
| + SyncStatusCode status) { |
| + if (!sync_service_) |
| + return; |
| + |
| + DCHECK(has_drive_metadata_); |
| + if (status != SYNC_STATUS_OK) { |
| + callback.Run(status); |
| + return; |
| + } |
| + |
| + SyncFileType file_type = SYNC_FILE_TYPE_FILE; |
| + if (drive_metadata_.type() == DriveMetadata::RESOURCE_TYPE_FOLDER) |
| + file_type = SYNC_FILE_TYPE_DIRECTORY; |
| + sync_service_->AppendFetchChange( |
| + url_.origin(), url_.path(), drive_metadata_.resource_id(), file_type); |
| + callback.Run(status); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::DidApplyLocalChange( |
| + const SyncStatusCallback& callback, |
| + const google_apis::GDataErrorCode error, |
| + SyncStatusCode status) { |
| + if (!sync_service_) |
| + return; |
| + |
| + if (status == SYNC_STATUS_OK) { |
| + remote_change_handler()->RemoveChangeForURL(url_); |
| + status = GDataErrorCodeToSyncStatusCodeWrapper(error); |
| + } |
| + callback.Run(status); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::UpdateMetadata( |
| + const std::string& resource_id, |
| + const std::string& md5, |
| + DriveMetadata::ResourceType type, |
| + const SyncStatusCallback& callback) { |
| + if (!sync_service_) |
| + return; |
| + |
| + drive_metadata_.set_resource_id(resource_id); |
| + drive_metadata_.set_md5_checksum(md5); |
| + drive_metadata_.set_conflicted(false); |
| + drive_metadata_.set_to_be_fetched(false); |
| + drive_metadata_.set_type(type); |
| + metadata_store()->UpdateEntry(url_, drive_metadata_, callback); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::SetToBeFetched( |
| + const std::string& resource_id, |
| + DriveMetadata::ResourceType type, |
| + const SyncStatusCallback& callback) { |
| + if (!sync_service_) |
| + return; |
| + |
| + drive_metadata_.set_resource_id(resource_id); |
| + drive_metadata_.set_md5_checksum(std::string()); |
| + drive_metadata_.set_conflicted(false); |
| + drive_metadata_.set_to_be_fetched(true); |
| + drive_metadata_.set_type(type); |
| + metadata_store()->UpdateEntry(url_, drive_metadata_, callback); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::SetConflict( |
| + const std::string& resource_id, |
| + const std::string& md5, |
| + DriveMetadata::ResourceType type, |
| + const SyncStatusCallback& callback) { |
| + if (!sync_service_) |
| + return; |
| + |
| + drive_metadata_.set_resource_id(resource_id); |
| + drive_metadata_.set_md5_checksum(md5); |
| + drive_metadata_.set_conflicted(true); |
| + drive_metadata_.set_to_be_fetched(false); |
| + drive_metadata_.set_type(type); |
| + metadata_store()->UpdateEntry(url_, drive_metadata_, callback); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::DeleteMetadata( |
| + const SyncStatusCallback& callback) { |
| + metadata_store()->DeleteEntry(url_, callback); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::HandleCreationConflict( |
| + const std::string& resource_id, |
| + DriveMetadata::ResourceType type, |
| + const SyncStatusCallback& callback) { |
| + if (!sync_service_) |
| + return; |
| + |
| + // File-file conflict is found. |
| + // Populates a fake drive_metadata and set has_drive_metadata = true. |
| + // In HandleConflictLocalSync: |
| + // - If conflict_resolution is manual, we'll change conflicted to true |
| + // and save the metadata. |
| + // - Otherwise we'll save the metadata with empty md5 and will start |
| + // over local sync as UploadExistingFile. |
| + drive_metadata_.set_resource_id(resource_id); |
| + drive_metadata_.set_md5_checksum(std::string()); |
| + drive_metadata_.set_conflicted(false); |
| + drive_metadata_.set_to_be_fetched(false); |
| + drive_metadata_.set_type(type); |
| + has_drive_metadata_ = true; |
| + HandleConflict(callback); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::HandleConflict( |
| + const SyncStatusCallback& callback) { |
| + if (!sync_service_) |
| + return; |
| + |
| + DCHECK(!drive_metadata_.resource_id().empty()); |
| + |
| + api_util()->GetResourceEntry( |
| + drive_metadata_.resource_id(), |
| + base::Bind( |
| + &ApplyLocalChangeDelegate::DidGetEntryForConflictResolution, |
| + weak_factory_.GetWeakPtr(), callback)); |
| +} |
| + |
| +void ApplyLocalChangeDelegate::DidGetEntryForConflictResolution( |
| + const SyncStatusCallback& callback, |
| + google_apis::GDataErrorCode error, |
| + scoped_ptr<google_apis::ResourceEntry> entry) { |
| + if (!sync_service_) |
| + return; |
| + |
| + SyncFileType local_file_type = local_metadata_.file_type; |
| + base::Time local_modification_time = local_metadata_.last_modified; |
| + |
| + SyncFileType remote_file_type; |
| + base::Time remote_modification_time = entry->updated_time(); |
| + if (entry->is_file()) |
| + remote_file_type = SYNC_FILE_TYPE_FILE; |
| + else if (entry->is_folder()) |
| + remote_file_type = SYNC_FILE_TYPE_DIRECTORY; |
| + else |
| + remote_file_type = SYNC_FILE_TYPE_UNKNOWN; |
| + |
| + switch (sync_service_->ResolveConflictForLocalSync( |
| + local_file_type, local_modification_time, |
| + remote_file_type, remote_modification_time)) { |
| + case DriveFileSyncService::CONFLICT_RESOLUTION_MARK_CONFLICT: |
| + if (drive_metadata_.conflicted()) { |
| + callback.Run(SYNC_STATUS_HAS_CONFLICT); |
| + return; |
| + } |
| + |
| + SetConflict(drive_metadata_.resource_id(), |
| + drive_metadata_.md5_checksum(), |
| + DriveFileSyncService::SyncFileTypeToDriveMetadataResourceType( |
| + local_file_type), |
| + base::Bind(&ApplyLocalChangeDelegate::DidApplyLocalChange, |
| + weak_factory_.GetWeakPtr(), callback, |
| + google_apis::HTTP_SUCCESS)); |
| + return; |
| + case DriveFileSyncService::CONFLICT_RESOLUTION_LOCAL_WIN: |
| + DVLOG(1) << "Resolving conflict for local sync:" |
| + << url_.DebugString() << ": LOCAL WIN"; |
| + ResolveToLocal(callback); |
| + return; |
| + case DriveFileSyncService::CONFLICT_RESOLUTION_REMOTE_WIN: |
| + DVLOG(1) << "Resolving conflict for local sync:" |
| + << url_.DebugString() << ": REMOTE WIN"; |
| + ResolveToRemote(callback); |
| + return; |
| + } |
| + NOTREACHED(); |
| + callback.Run(SYNC_STATUS_FAILED); |
| +} |
| + |
| +SyncStatusCode ApplyLocalChangeDelegate::GDataErrorCodeToSyncStatusCodeWrapper( |
| + google_apis::GDataErrorCode error) { |
| + return sync_service_->GDataErrorCodeToSyncStatusCodeWrapper(error); |
| +} |
| + |
| +DriveMetadataStore* ApplyLocalChangeDelegate::metadata_store() { |
| + return sync_service_->metadata_store_.get(); |
| +} |
| + |
| +APIUtilInterface* ApplyLocalChangeDelegate::api_util() { |
| + return sync_service_->api_util_.get(); |
| +} |
| + |
| +RemoteChangeHandler* ApplyLocalChangeDelegate::remote_change_handler() { |
| + return &sync_service_->remote_change_handler_; |
| +} |
| + |
| +} // drive |
| +} // namespace sync_file_system |