diff options
4 files changed, 275 insertions, 78 deletions
diff --git a/chrome/browser/sync_file_system/drive_file_sync_client.cc b/chrome/browser/sync_file_system/drive_file_sync_client.cc index 9d24a85..2909dec 100644 --- a/chrome/browser/sync_file_system/drive_file_sync_client.cc +++ b/chrome/browser/sync_file_system/drive_file_sync_client.cc @@ -691,7 +691,7 @@ void DriveFileSyncClient::UploadExistingFileInternal( // If remote file's hash value is different from the expected one, conflict // might have occurred. - if (remote_file_md5 != entry->file_md5()) { + if (!remote_file_md5.empty() && remote_file_md5 != entry->file_md5()) { DVLOG(2) << "Conflict detected before uploading existing file"; callback.Run(google_apis::HTTP_CONFLICT, std::string(), std::string()); return; diff --git a/chrome/browser/sync_file_system/drive_file_sync_service.cc b/chrome/browser/sync_file_system/drive_file_sync_service.cc index c7dff98..b1785ed 100644 --- a/chrome/browser/sync_file_system/drive_file_sync_service.cc +++ b/chrome/browser/sync_file_system/drive_file_sync_service.cc @@ -176,6 +176,7 @@ struct DriveFileSyncService::ProcessRemoteChangeParam { SyncFileCallback callback; DriveMetadata drive_metadata; + SyncFileMetadata local_metadata; bool metadata_updated; base::FilePath temporary_file_path; std::string md5_checksum; @@ -197,6 +198,7 @@ struct DriveFileSyncService::ProcessRemoteChangeParam { struct DriveFileSyncService::ApplyLocalChangeParam { scoped_ptr<TaskToken> token; FileSystemURL url; + FileChange local_change; base::FilePath local_path; SyncFileMetadata local_metadata; DriveMetadata drive_metadata; @@ -205,11 +207,13 @@ struct DriveFileSyncService::ApplyLocalChangeParam { ApplyLocalChangeParam(scoped_ptr<TaskToken> token, const FileSystemURL& url, + const FileChange& local_change, const base::FilePath& local_path, const SyncFileMetadata& local_metadata, const SyncStatusCallback& callback) : token(token.Pass()), url(url), + local_change(local_change), local_path(local_path), local_metadata(local_metadata), has_drive_metadata(false), @@ -255,6 +259,7 @@ DriveFileSyncService::RemoteChange::RemoteChange( int64 changestamp, const std::string& resource_id, const std::string& md5_checksum, + const base::Time& updated_time, RemoteSyncType sync_type, const FileSystemURL& url, const FileChange& change, @@ -262,6 +267,7 @@ DriveFileSyncService::RemoteChange::RemoteChange( : changestamp(changestamp), resource_id(resource_id), md5_checksum(md5_checksum), + updated_time(updated_time), sync_type(sync_type), url(url), change(change), @@ -592,7 +598,8 @@ void DriveFileSyncService::ApplyLocalChange( } scoped_ptr<ApplyLocalChangeParam> param(new ApplyLocalChangeParam( - token.Pass(), url, local_file_path, local_file_metadata, callback)); + token.Pass(), url, + local_file_change, local_file_path, local_file_metadata, callback)); DriveFileSyncService::LocalSyncOperationType operation = ResolveLocalSyncOperationType(local_file_change, url, param.get()); DriveMetadata& drive_metadata = param->drive_metadata; @@ -632,7 +639,8 @@ void DriveFileSyncService::ApplyLocalChange( } case LOCAL_SYNC_OPERATION_NONE_CONFLICTED: // The file is already conflicted. - // (Fall through) + HandleConflictForLocalSync(param.Pass()); + return; case LOCAL_SYNC_OPERATION_NONE: FinalizeLocalSync(param->token.Pass(), callback, SYNC_STATUS_OK); return; @@ -640,16 +648,7 @@ void DriveFileSyncService::ApplyLocalChange( HandleConflictForLocalSync(param.Pass()); return; case LOCAL_SYNC_OPERATION_RESOLVE_TO_REMOTE: { - // Mark the file as to-be-fetched. - DCHECK(param->has_drive_metadata); - drive_metadata.set_conflicted(false); - drive_metadata.set_to_be_fetched(true); - metadata_store_->UpdateEntry( - url, drive_metadata, - base::Bind(&DriveFileSyncService::DidResolveConflictToRemoteChange, - AsWeakPtr(), base::Passed(¶m))); - // The synced notification will be dispatched when the remote file is - // downloaded. + ResolveConflictToRemoteForLocalSync(param.Pass()); return; } case LOCAL_SYNC_OPERATION_FAIL: { @@ -1350,30 +1349,98 @@ void DriveFileSyncService::HandleConflictForLocalSync( scoped_ptr<ApplyLocalChangeParam> param) { DCHECK(param); const FileSystemURL& url = param->url; - // Mark the file as conflicted. - if (param->has_drive_metadata) { - // If the file is not in the metadata store we must have a pending - // remote change entry. - RemoteChange remote_change; - const bool has_remote_change = - GetPendingChangeForFileSystemURL(url, &remote_change); - DCHECK(has_remote_change); - param->drive_metadata.set_resource_id(remote_change.resource_id); - param->drive_metadata.set_md5_checksum(std::string()); - param->has_drive_metadata = true; + DriveMetadata& drive_metadata = param->drive_metadata; + if (conflict_resolution_ == CONFLICT_RESOLUTION_MANUAL) { + if (drive_metadata.conflicted()) { + // It's already conflicting; no need to update metadata. + FinalizeLocalSync(param->token.Pass(), + param->callback, SYNC_STATUS_FAILED); + return; + } + MarkConflict(url, &drive_metadata, + base::Bind(&DriveFileSyncService::DidApplyLocalChange, + AsWeakPtr(), base::Passed(¶m), + google_apis::HTTP_CONFLICT)); + return; + } + + DCHECK_EQ(CONFLICT_RESOLUTION_LAST_WRITE_WIN, conflict_resolution_); + + GetRemoteFileMetadata( + url, base::Bind( + &DriveFileSyncService::DidGetRemoteFileMetadataForRemoteUpdatedTime, + AsWeakPtr(), + base::Bind(&DriveFileSyncService::ResolveConflictForLocalSync, + AsWeakPtr(), base::Passed(¶m)))); +} + +void DriveFileSyncService::ResolveConflictForLocalSync( + scoped_ptr<ApplyLocalChangeParam> param, + const base::Time& remote_updated_time, + SyncStatusCode status) { + DCHECK(param); + const FileSystemURL& url = param->url; + DriveMetadata& drive_metadata = param->drive_metadata; + SyncFileMetadata& local_metadata = param->local_metadata; + if (status != SYNC_STATUS_OK) { + FinalizeLocalSync(param->token.Pass(), param->callback, status); + return; + } + + if (local_metadata.last_modified >= remote_updated_time) { + // Local win case. + // Make sure we reset the conflict flag and start over the local sync + // with empty remote changes. + DVLOG(1) << "Resolving conflict for local sync:" + << url.DebugString() << ": LOCAL WIN"; + drive_metadata.set_md5_checksum(std::string()); + drive_metadata.set_conflicted(false); + drive_metadata.set_to_be_fetched(false); + metadata_store_->UpdateEntry( + url, drive_metadata, + base::Bind(&DriveFileSyncService::StartOverLocalSync, AsWeakPtr(), + base::Passed(¶m))); + return; } - param->drive_metadata.set_conflicted(true); - param->drive_metadata.set_to_be_fetched(false); - const DriveMetadata& metadata = param->drive_metadata; + // Remote win case. + DVLOG(1) << "Resolving conflict for local sync:" + << url.DebugString() << ": REMOTE WIN"; + ResolveConflictToRemoteForLocalSync(param.Pass()); +} + +void DriveFileSyncService::ResolveConflictToRemoteForLocalSync( + scoped_ptr<ApplyLocalChangeParam> param) { + DCHECK(param); + DCHECK(param->has_drive_metadata); + const FileSystemURL& url = param->url; + DriveMetadata& drive_metadata = param->drive_metadata; + // Mark the file as to-be-fetched. + drive_metadata.set_conflicted(false); + drive_metadata.set_to_be_fetched(true); metadata_store_->UpdateEntry( - url, metadata, - base::Bind(&DriveFileSyncService::DidApplyLocalChange, - AsWeakPtr(), base::Passed(¶m), - google_apis::HTTP_CONFLICT)); - NotifyObserversFileStatusChanged(url, - SYNC_FILE_STATUS_CONFLICTING, - SYNC_ACTION_NONE, - SYNC_DIRECTION_NONE); + url, drive_metadata, + base::Bind(&DriveFileSyncService::DidResolveConflictToRemoteChange, + AsWeakPtr(), base::Passed(¶m))); + // The synced notification will be dispatched when the remote file is + // downloaded. +} + +void DriveFileSyncService::StartOverLocalSync( + scoped_ptr<ApplyLocalChangeParam> param, + SyncStatusCode status) { + DCHECK(param); + if (status != SYNC_STATUS_OK) { + FinalizeLocalSync(param->token.Pass(), param->callback, status); + return; + } + RemoveRemoteChange(param->url); + pending_tasks_.push_front(base::Bind( + &DriveFileSyncService::ApplyLocalChange, + AsWeakPtr(), + param->local_change, param->local_path, param->local_metadata, + param->url, param->callback)); + param->token->ResetTask(FROM_HERE); + NotifyTaskDone(status, param->token.Pass()); } void DriveFileSyncService::DidPrepareForProcessRemoteChange( @@ -1386,6 +1453,7 @@ void DriveFileSyncService::DidPrepareForProcessRemoteChange( return; } + param->local_metadata = metadata; const FileSystemURL& url = param->remote_change.url; const DriveMetadata& drive_metadata = param->drive_metadata; const FileChange& remote_file_change = param->remote_change.change; @@ -1432,14 +1500,7 @@ void DriveFileSyncService::DidPrepareForProcessRemoteChange( DCHECK(!missing_local_file); if (remote_file_change.IsAddOrUpdate()) { - param->sync_action = SYNC_ACTION_NONE; - param->drive_metadata.set_conflicted(true); - param->drive_metadata.set_to_be_fetched(false); - - metadata_store_->UpdateEntry( - url, drive_metadata, - base::Bind(&DriveFileSyncService::CompleteRemoteSync, AsWeakPtr(), - base::Passed(¶m))); + HandleConflictForRemoteSync(param.Pass(), base::Time(), SYNC_STATUS_OK); return; } @@ -1450,14 +1511,7 @@ void DriveFileSyncService::DidPrepareForProcessRemoteChange( << " remote_change: " << remote_file_change.DebugString() << " ==> operation: ResolveConflictToLocalChange"; - param->sync_action = SYNC_ACTION_NONE; - param->clear_local_changes = false; - - remote_change_processor_->RecordFakeLocalChange( - url, - FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, SYNC_FILE_TYPE_FILE), - base::Bind(&DriveFileSyncService::DidResolveConflictToLocalChange, - AsWeakPtr(), base::Passed(¶m))); + ResolveConflictToLocalForRemoteSync(param.Pass()); return; } @@ -1478,17 +1532,7 @@ void DriveFileSyncService::DidPrepareForProcessRemoteChange( DCHECK(!local_changes.empty()); if (local_changes.list().back().IsAddOrUpdate()) { - param->drive_metadata.set_conflicted(true); - param->drive_metadata.set_to_be_fetched(false); - - metadata_store_->UpdateEntry( - url, drive_metadata, - base::Bind(&DriveFileSyncService::CompleteRemoteSync, AsWeakPtr(), - base::Passed(¶m))); - NotifyObserversFileStatusChanged(url, - SYNC_FILE_STATUS_CONFLICTING, - SYNC_ACTION_NONE, - SYNC_DIRECTION_NONE); + HandleConflictForRemoteSync(param.Pass(), base::Time(), SYNC_STATUS_OK); return; } @@ -1538,15 +1582,29 @@ void DriveFileSyncService::DidResolveConflictToLocalChange( scoped_ptr<ProcessRemoteChangeParam> param, SyncStatusCode status) { if (status != SYNC_STATUS_OK) { + DCHECK_NE(SYNC_STATUS_HAS_CONFLICT, status); AbortRemoteSync(param.Pass(), status); return; } const FileSystemURL& url = param->remote_change.url; - metadata_store_->DeleteEntry( - url, - base::Bind(&DriveFileSyncService::CompleteRemoteSync, - AsWeakPtr(), base::Passed(¶m))); + if (param->remote_change.change.IsDelete()) { + metadata_store_->DeleteEntry( + url, + base::Bind(&DriveFileSyncService::CompleteRemoteSync, + AsWeakPtr(), base::Passed(¶m))); + } else { + DriveMetadata& drive_metadata = param->drive_metadata; + DCHECK(!param->remote_change.resource_id.empty()); + drive_metadata.set_resource_id(param->remote_change.resource_id); + drive_metadata.set_conflicted(false); + drive_metadata.set_to_be_fetched(false); + drive_metadata.set_md5_checksum(std::string()); + metadata_store_->UpdateEntry( + url, drive_metadata, + base::Bind(&DriveFileSyncService::CompleteRemoteSync, + AsWeakPtr(), base::Passed(¶m))); + } } void DriveFileSyncService::DownloadForRemoteSync( @@ -1708,14 +1766,7 @@ void DriveFileSyncService::FinalizeRemoteSync( if (!param->temporary_file_path.empty()) DeleteTemporaryFile(param->temporary_file_path); NotifyTaskDone(status, param->token.Pass()); - if (status == SYNC_STATUS_HAS_CONFLICT || - param->drive_metadata.conflicted()) { - NotifyObserversFileStatusChanged(param->remote_change.url, - SYNC_FILE_STATUS_CONFLICTING, - SYNC_ACTION_NONE, - SYNC_DIRECTION_NONE); - } else if (status == SYNC_STATUS_OK && - param->sync_action != SYNC_ACTION_NONE) { + if (status == SYNC_STATUS_OK && param->sync_action != SYNC_ACTION_NONE) { NotifyObserversFileStatusChanged(param->remote_change.url, SYNC_FILE_STATUS_SYNCED, param->sync_action, @@ -1724,6 +1775,86 @@ void DriveFileSyncService::FinalizeRemoteSync( param->callback.Run(status, param->remote_change.url); } +void DriveFileSyncService::HandleConflictForRemoteSync( + scoped_ptr<ProcessRemoteChangeParam> param, + const base::Time& remote_updated_time, + SyncStatusCode status) { + if (status != SYNC_STATUS_OK) { + AbortRemoteSync(param.Pass(), status); + return; + } + if (!remote_updated_time.is_null()) + param->remote_change.updated_time = remote_updated_time; + DCHECK(param); + const FileSystemURL& url = param->remote_change.url; + SyncFileMetadata& local_metadata = param->local_metadata; + DriveMetadata& drive_metadata = param->drive_metadata; + if (conflict_resolution_ == CONFLICT_RESOLUTION_MANUAL) { + param->sync_action = SYNC_ACTION_NONE; + MarkConflict(url, &drive_metadata, + base::Bind(&DriveFileSyncService::CompleteRemoteSync, + AsWeakPtr(), base::Passed(¶m))); + return; + } + + DCHECK_EQ(CONFLICT_RESOLUTION_LAST_WRITE_WIN, conflict_resolution_); + if (param->remote_change.updated_time.is_null()) { + // Get remote file time and call this method again. + GetRemoteFileMetadata( + url, base::Bind( + &DriveFileSyncService::DidGetRemoteFileMetadataForRemoteUpdatedTime, + AsWeakPtr(), + base::Bind(&DriveFileSyncService::HandleConflictForRemoteSync, + AsWeakPtr(), base::Passed(¶m)))); + return; + } + if (local_metadata.last_modified >= param->remote_change.updated_time) { + // Local win case. + DVLOG(1) << "Resolving conflict for remote sync:" + << url.DebugString() << ": LOCAL WIN"; + ResolveConflictToLocalForRemoteSync(param.Pass()); + return; + } + // Remote win case. + // Make sure we reset the conflict flag and start over the remote sync + // with empty local changes. + DVLOG(1) << "Resolving conflict for remote sync:" + << url.DebugString() << ": REMOTE WIN"; + drive_metadata.set_conflicted(false); + drive_metadata.set_to_be_fetched(false); + metadata_store_->UpdateEntry( + url, drive_metadata, + base::Bind(&DriveFileSyncService::StartOverRemoteSync, + AsWeakPtr(), base::Passed(¶m))); + return; +} + +void DriveFileSyncService::ResolveConflictToLocalForRemoteSync( + scoped_ptr<ProcessRemoteChangeParam> param) { + DCHECK(param); + const FileSystemURL& url = param->remote_change.url; + param->sync_action = SYNC_ACTION_NONE; + param->clear_local_changes = false; + remote_change_processor_->RecordFakeLocalChange( + url, + FileChange(FileChange::FILE_CHANGE_ADD_OR_UPDATE, SYNC_FILE_TYPE_FILE), + base::Bind(&DriveFileSyncService::DidResolveConflictToLocalChange, + AsWeakPtr(), base::Passed(¶m))); +} + +void DriveFileSyncService::StartOverRemoteSync( + scoped_ptr<ProcessRemoteChangeParam> param, + SyncStatusCode status) { + DCHECK(param); + SyncFileMetadata& local_metadata = param->local_metadata; + pending_tasks_.push_front(base::Bind( + &DriveFileSyncService::DidPrepareForProcessRemoteChange, + AsWeakPtr(), base::Passed(¶m), status, + local_metadata, FileChangeList())); + param->token->ResetTask(FROM_HERE); + NotifyTaskDone(status, param->token.Pass()); +} + bool DriveFileSyncService::AppendRemoteChange( const GURL& origin, const google_apis::ResourceEntry& entry, @@ -1737,7 +1868,7 @@ bool DriveFileSyncService::AppendRemoteChange( origin, path, entry.deleted(), entry.resource_id(), changestamp, entry.deleted() ? std::string() : entry.file_md5(), - sync_type); + entry.updated_time(), sync_type); } bool DriveFileSyncService::AppendFetchChange( @@ -1750,6 +1881,7 @@ bool DriveFileSyncService::AppendFetchChange( resource_id, 0, // changestamp std::string(), // remote_file_md5 + base::Time(), // updated_time REMOTE_SYNC_TYPE_FETCH); } @@ -1760,6 +1892,7 @@ bool DriveFileSyncService::AppendRemoteChangeInternal( const std::string& remote_resource_id, int64 changestamp, const std::string& remote_file_md5, + const base::Time& updated_time, RemoteSyncType sync_type) { fileapi::FileSystemURL url( CreateSyncableFileSystemURL(origin, kServiceName, path)); @@ -1826,7 +1959,7 @@ bool DriveFileSyncService::AppendRemoteChangeInternal( (*path_to_change)[path] = RemoteChange( changestamp, remote_resource_id, remote_file_md5, - sync_type, url, file_change, + updated_time, sync_type, url, file_change, inserted_to_queue.first); } @@ -1876,6 +2009,37 @@ bool DriveFileSyncService::GetPendingChangeForFileSystemURL( return true; } +void DriveFileSyncService::MarkConflict( + const fileapi::FileSystemURL& url, + DriveMetadata* drive_metadata, + const SyncStatusCallback& callback) { + DCHECK(drive_metadata); + if (drive_metadata->resource_id().empty()) { + // If the file does not have valid drive_metadata in the metadata store + // we must have a pending remote change entry. + RemoteChange remote_change; + const bool has_remote_change = + GetPendingChangeForFileSystemURL(url, &remote_change); + DCHECK(has_remote_change); + drive_metadata->set_resource_id(remote_change.resource_id); + drive_metadata->set_md5_checksum(std::string()); + } + drive_metadata->set_conflicted(true); + drive_metadata->set_to_be_fetched(false); + metadata_store_->UpdateEntry(url, *drive_metadata, callback); + NotifyObserversFileStatusChanged(url, + SYNC_FILE_STATUS_CONFLICTING, + SYNC_ACTION_NONE, + SYNC_DIRECTION_NONE); +} + +void DriveFileSyncService::DidGetRemoteFileMetadataForRemoteUpdatedTime( + const UpdatedTimeCallback& callback, + SyncStatusCode status, + const SyncFileMetadata& metadata) { + callback.Run(metadata.last_modified, status); +} + SyncStatusCode DriveFileSyncService::GDataErrorCodeToSyncStatusCodeWrapper( google_apis::GDataErrorCode error) const { SyncStatusCode status = GDataErrorCodeToSyncStatusCode(error); diff --git a/chrome/browser/sync_file_system/drive_file_sync_service.h b/chrome/browser/sync_file_system/drive_file_sync_service.h index 5980893..2334306 100644 --- a/chrome/browser/sync_file_system/drive_file_sync_service.h +++ b/chrome/browser/sync_file_system/drive_file_sync_service.h @@ -151,6 +151,7 @@ class DriveFileSyncService int64 changestamp; std::string resource_id; std::string md5_checksum; + base::Time updated_time; RemoteSyncType sync_type; fileapi::FileSystemURL url; FileChange change; @@ -160,6 +161,7 @@ class DriveFileSyncService RemoteChange(int64 changestamp, const std::string& resource_id, const std::string& md5_checksum, + const base::Time& updated_time, RemoteSyncType sync_type, const fileapi::FileSystemURL& url, const FileChange& change, @@ -199,6 +201,9 @@ class DriveFileSyncService LOCAL_SYNC_OPERATION_FAIL, }; + typedef base::Callback<void(const base::Time& time, + SyncStatusCode status)> UpdatedTimeCallback; + DriveFileSyncService(Profile* profile, const base::FilePath& base_dir, scoped_ptr<DriveFileSyncClientInterface> sync_client, @@ -254,6 +259,15 @@ class DriveFileSyncService google_apis::GDataErrorCode error); void HandleConflictForLocalSync( scoped_ptr<ApplyLocalChangeParam> param); + void ResolveConflictForLocalSync( + scoped_ptr<ApplyLocalChangeParam> param, + const base::Time& remote_updated_time, + SyncStatusCode status); + void StartOverLocalSync( + scoped_ptr<ApplyLocalChangeParam> param, + SyncStatusCode status); + void ResolveConflictToRemoteForLocalSync( + scoped_ptr<ApplyLocalChangeParam> param); void DidInitializeMetadataStore(scoped_ptr<TaskToken> token, SyncStatusCode status, @@ -335,6 +349,15 @@ class DriveFileSyncService void FinalizeRemoteSync( scoped_ptr<ProcessRemoteChangeParam> param, SyncStatusCode status); + void HandleConflictForRemoteSync( + scoped_ptr<ProcessRemoteChangeParam> param, + const base::Time& remote_updated_time, + SyncStatusCode status); + void ResolveConflictToLocalForRemoteSync( + scoped_ptr<ProcessRemoteChangeParam> param); + void StartOverRemoteSync( + scoped_ptr<ProcessRemoteChangeParam> param, + SyncStatusCode status); // Returns true if |pending_changes_| was updated. bool AppendRemoteChange(const GURL& origin, @@ -350,10 +373,20 @@ class DriveFileSyncService const std::string& resource_id, int64 changestamp, const std::string& remote_file_md5, + const base::Time& updated_time, RemoteSyncType sync_type); void RemoveRemoteChange(const fileapi::FileSystemURL& url); void MaybeMarkAsIncrementalSyncOrigin(const GURL& origin); + void MarkConflict( + const fileapi::FileSystemURL& url, + DriveMetadata* drive_metadata, + const SyncStatusCallback& callback); + void DidGetRemoteFileMetadataForRemoteUpdatedTime( + const UpdatedTimeCallback& callback, + SyncStatusCode status, + const SyncFileMetadata& metadata); + // This returns false if no change is found for the |url|. bool GetPendingChangeForFileSystemURL(const fileapi::FileSystemURL& url, RemoteChange* change) const; diff --git a/chrome/browser/sync_file_system/drive_file_sync_service_mock_unittest.cc b/chrome/browser/sync_file_system/drive_file_sync_service_mock_unittest.cc index 1445be0..f590956 100644 --- a/chrome/browser/sync_file_system/drive_file_sync_service_mock_unittest.cc +++ b/chrome/browser/sync_file_system/drive_file_sync_service_mock_unittest.cc @@ -356,7 +356,7 @@ class DriveFileSyncServiceMockTest : public testing::Test { &sync_service_->origin_to_changes_map_[url.origin()]; (*path_to_change)[url.path()] = DriveFileSyncService::RemoteChange( changestamp, resource_id, md5_checksum, - sync_type, url, file_change, + base::Time(), sync_type, url, file_change, inserted_to_queue.first); } @@ -458,7 +458,7 @@ class DriveFileSyncServiceMockTest : public testing::Test { const std::string& remote_file_md5) { return sync_service_->AppendRemoteChangeInternal( origin, path, is_deleted, resource_id, - changestamp, remote_file_md5, + changestamp, remote_file_md5, base::Time(), DriveFileSyncService::REMOTE_SYNC_TYPE_INCREMENTAL); } |