Index: chrome/browser/chromeos/drive/file_system/copy_operation.cc |
diff --git a/chrome/browser/chromeos/drive/file_system/copy_operation.cc b/chrome/browser/chromeos/drive/file_system/copy_operation.cc |
deleted file mode 100644 |
index 0ab562c11e191c67b53c0c5d5006ddc5a48731ab..0000000000000000000000000000000000000000 |
--- a/chrome/browser/chromeos/drive/file_system/copy_operation.cc |
+++ /dev/null |
@@ -1,671 +0,0 @@ |
-// Copyright (c) 2012 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/chromeos/drive/file_system/copy_operation.h" |
- |
-#include <string> |
- |
-#include "base/task_runner_util.h" |
-#include "chrome/browser/chromeos/drive/drive.pb.h" |
-#include "chrome/browser/chromeos/drive/file_cache.h" |
-#include "chrome/browser/chromeos/drive/file_change.h" |
-#include "chrome/browser/chromeos/drive/file_system/create_file_operation.h" |
-#include "chrome/browser/chromeos/drive/file_system/operation_delegate.h" |
-#include "chrome/browser/chromeos/drive/file_system_core_util.h" |
-#include "chrome/browser/chromeos/drive/job_scheduler.h" |
-#include "chrome/browser/chromeos/drive/resource_entry_conversion.h" |
-#include "chrome/browser/chromeos/drive/resource_metadata.h" |
-#include "components/drive/drive_api_util.h" |
-#include "google_apis/drive/drive_api_parser.h" |
- |
-namespace drive { |
-namespace file_system { |
- |
-struct CopyOperation::CopyParams { |
- base::FilePath src_file_path; |
- base::FilePath dest_file_path; |
- bool preserve_last_modified; |
- FileOperationCallback callback; |
- ResourceEntry src_entry; |
- ResourceEntry parent_entry; |
-}; |
- |
-// Enum for categorizing where a gdoc represented by a JSON file exists. |
-enum JsonGdocLocationType { |
- NOT_IN_METADATA, |
- IS_ORPHAN, |
- HAS_PARENT, |
-}; |
- |
-struct CopyOperation::TransferJsonGdocParams { |
- TransferJsonGdocParams(const FileOperationCallback& callback, |
- const std::string& resource_id, |
- const ResourceEntry& parent_entry, |
- const std::string& new_title) |
- : callback(callback), |
- resource_id(resource_id), |
- parent_resource_id(parent_entry.resource_id()), |
- parent_local_id(parent_entry.local_id()), |
- new_title(new_title), |
- location_type(NOT_IN_METADATA) { |
- } |
- // Parameters supplied or calculated from operation arguments. |
- const FileOperationCallback callback; |
- const std::string resource_id; |
- const std::string parent_resource_id; |
- const std::string parent_local_id; |
- const std::string new_title; |
- |
- // Values computed during operation. |
- JsonGdocLocationType location_type; // types where the gdoc file is located. |
- std::string local_id; // the local_id of the file (if exists in metadata.) |
- base::FilePath changed_path; |
-}; |
- |
-namespace { |
- |
-FileError TryToCopyLocally(internal::ResourceMetadata* metadata, |
- internal::FileCache* cache, |
- CopyOperation::CopyParams* params, |
- std::vector<std::string>* updated_local_ids, |
- bool* directory_changed, |
- bool* should_copy_on_server) { |
- FileError error = metadata->GetResourceEntryByPath(params->src_file_path, |
- ¶ms->src_entry); |
- if (error != FILE_ERROR_OK) |
- return error; |
- |
- error = metadata->GetResourceEntryByPath(params->dest_file_path.DirName(), |
- ¶ms->parent_entry); |
- if (error != FILE_ERROR_OK) |
- return error; |
- |
- if (!params->parent_entry.file_info().is_directory()) |
- return FILE_ERROR_NOT_A_DIRECTORY; |
- |
- // Drive File System doesn't support recursive copy. |
- if (params->src_entry.file_info().is_directory()) |
- return FILE_ERROR_NOT_A_FILE; |
- |
- // Check destination. |
- ResourceEntry dest_entry; |
- error = metadata->GetResourceEntryByPath(params->dest_file_path, &dest_entry); |
- switch (error) { |
- case FILE_ERROR_OK: |
- // File API spec says it is an error to try to "copy a file to a path |
- // occupied by a directory". |
- if (dest_entry.file_info().is_directory()) |
- return FILE_ERROR_INVALID_OPERATION; |
- |
- // Move the existing entry to the trash. |
- dest_entry.set_parent_local_id(util::kDriveTrashDirLocalId); |
- error = metadata->RefreshEntry(dest_entry); |
- if (error != FILE_ERROR_OK) |
- return error; |
- updated_local_ids->push_back(dest_entry.local_id()); |
- *directory_changed = true; |
- break; |
- case FILE_ERROR_NOT_FOUND: |
- break; |
- default: |
- return error; |
- } |
- |
- // If the cache file is not present and the entry exists on the server, |
- // server side copy should be used. |
- if (!params->src_entry.file_specific_info().cache_state().is_present() && |
- !params->src_entry.resource_id().empty()) { |
- *should_copy_on_server = true; |
- return FILE_ERROR_OK; |
- } |
- |
- // Copy locally. |
- ResourceEntry entry; |
- const int64 now = base::Time::Now().ToInternalValue(); |
- entry.set_title(params->dest_file_path.BaseName().AsUTF8Unsafe()); |
- entry.set_parent_local_id(params->parent_entry.local_id()); |
- entry.mutable_file_specific_info()->set_content_mime_type( |
- params->src_entry.file_specific_info().content_mime_type()); |
- entry.set_metadata_edit_state(ResourceEntry::DIRTY); |
- entry.set_modification_date(base::Time::Now().ToInternalValue()); |
- entry.mutable_file_info()->set_last_modified( |
- params->preserve_last_modified ? |
- params->src_entry.file_info().last_modified() : now); |
- entry.mutable_file_info()->set_last_accessed(now); |
- |
- std::string local_id; |
- error = metadata->AddEntry(entry, &local_id); |
- if (error != FILE_ERROR_OK) |
- return error; |
- updated_local_ids->push_back(local_id); |
- *directory_changed = true; |
- |
- if (!params->src_entry.file_specific_info().cache_state().is_present()) { |
- DCHECK(params->src_entry.resource_id().empty()); |
- // Locally created empty file may have no cache file. |
- return FILE_ERROR_OK; |
- } |
- |
- base::FilePath cache_file_path; |
- error = cache->GetFile(params->src_entry.local_id(), &cache_file_path); |
- if (error != FILE_ERROR_OK) |
- return error; |
- |
- return cache->Store(local_id, std::string(), cache_file_path, |
- internal::FileCache::FILE_OPERATION_COPY); |
-} |
- |
-// Stores the entry returned from the server and returns its path. |
-FileError UpdateLocalStateForServerSideOperation( |
- internal::ResourceMetadata* metadata, |
- scoped_ptr<google_apis::FileResource> file_resource, |
- ResourceEntry* entry, |
- base::FilePath* file_path) { |
- DCHECK(file_resource); |
- |
- std::string parent_resource_id; |
- if (!ConvertFileResourceToResourceEntry( |
- *file_resource, entry, &parent_resource_id) || |
- parent_resource_id.empty()) |
- return FILE_ERROR_NOT_A_FILE; |
- |
- std::string parent_local_id; |
- FileError error = metadata->GetIdByResourceId(parent_resource_id, |
- &parent_local_id); |
- if (error != FILE_ERROR_OK) |
- return error; |
- entry->set_parent_local_id(parent_local_id); |
- |
- std::string local_id; |
- error = metadata->AddEntry(*entry, &local_id); |
- // Depending on timing, the metadata may have inserted via change list |
- // already. So, FILE_ERROR_EXISTS is not an error. |
- if (error == FILE_ERROR_EXISTS) |
- error = metadata->GetIdByResourceId(entry->resource_id(), &local_id); |
- |
- if (error != FILE_ERROR_OK) |
- return error; |
- |
- return metadata->GetFilePath(local_id, file_path); |
-} |
- |
-// Stores the file at |local_file_path| to the cache as a content of entry at |
-// |remote_dest_path|, and marks it dirty. |
-FileError UpdateLocalStateForScheduleTransfer( |
- internal::ResourceMetadata* metadata, |
- internal::FileCache* cache, |
- const base::FilePath& local_src_path, |
- const base::FilePath& remote_dest_path, |
- ResourceEntry* entry, |
- std::string* local_id) { |
- FileError error = metadata->GetIdByPath(remote_dest_path, local_id); |
- if (error != FILE_ERROR_OK) |
- return error; |
- |
- error = metadata->GetResourceEntryById(*local_id, entry); |
- if (error != FILE_ERROR_OK) |
- return error; |
- |
- return cache->Store(*local_id, std::string(), local_src_path, |
- internal::FileCache::FILE_OPERATION_COPY); |
-} |
- |
-// Gets the file size of the |local_path|, and the ResourceEntry for the parent |
-// of |remote_path| to prepare the necessary information for transfer. |
-FileError PrepareTransferFileFromLocalToRemote( |
- internal::ResourceMetadata* metadata, |
- const base::FilePath& local_src_path, |
- const base::FilePath& remote_dest_path, |
- std::string* gdoc_resource_id, |
- ResourceEntry* parent_entry) { |
- FileError error = metadata->GetResourceEntryByPath( |
- remote_dest_path.DirName(), parent_entry); |
- if (error != FILE_ERROR_OK) |
- return error; |
- |
- // The destination's parent must be a directory. |
- if (!parent_entry->file_info().is_directory()) |
- return FILE_ERROR_NOT_A_DIRECTORY; |
- |
- // Try to parse GDoc File and extract the resource id, if necessary. |
- // Failing isn't problem. It'd be handled as a regular file, then. |
- if (util::HasHostedDocumentExtension(local_src_path)) |
- *gdoc_resource_id = util::ReadResourceIdFromGDocFile(local_src_path); |
- return FILE_ERROR_OK; |
-} |
- |
-// Performs local work before server-side work for transferring JSON-represented |
-// gdoc files. |
-FileError LocalWorkForTransferJsonGdocFile( |
- internal::ResourceMetadata* metadata, |
- CopyOperation::TransferJsonGdocParams* params) { |
- std::string local_id; |
- FileError error = metadata->GetIdByResourceId(params->resource_id, &local_id); |
- if (error != FILE_ERROR_OK) { |
- params->location_type = NOT_IN_METADATA; |
- return error == FILE_ERROR_NOT_FOUND ? FILE_ERROR_OK : error; |
- } |
- |
- ResourceEntry entry; |
- error = metadata->GetResourceEntryById(local_id, &entry); |
- if (error != FILE_ERROR_OK) |
- return error; |
- params->local_id = entry.local_id(); |
- |
- if (entry.parent_local_id() == util::kDriveOtherDirLocalId) { |
- params->location_type = IS_ORPHAN; |
- entry.set_title(params->new_title); |
- entry.set_parent_local_id(params->parent_local_id); |
- entry.set_metadata_edit_state(ResourceEntry::DIRTY); |
- entry.set_modification_date(base::Time::Now().ToInternalValue()); |
- error = metadata->RefreshEntry(entry); |
- if (error != FILE_ERROR_OK) |
- return error; |
- return metadata->GetFilePath(local_id, ¶ms->changed_path); |
- } |
- |
- params->location_type = HAS_PARENT; |
- return FILE_ERROR_OK; |
-} |
- |
-} // namespace |
- |
-CopyOperation::CopyOperation(base::SequencedTaskRunner* blocking_task_runner, |
- OperationDelegate* delegate, |
- JobScheduler* scheduler, |
- internal::ResourceMetadata* metadata, |
- internal::FileCache* cache) |
- : blocking_task_runner_(blocking_task_runner), |
- delegate_(delegate), |
- scheduler_(scheduler), |
- metadata_(metadata), |
- cache_(cache), |
- create_file_operation_(new CreateFileOperation(blocking_task_runner, |
- delegate, |
- metadata)), |
- weak_ptr_factory_(this) { |
-} |
- |
-CopyOperation::~CopyOperation() { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
-} |
- |
-void CopyOperation::Copy(const base::FilePath& src_file_path, |
- const base::FilePath& dest_file_path, |
- bool preserve_last_modified, |
- const FileOperationCallback& callback) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(!callback.is_null()); |
- |
- CopyParams* params = new CopyParams; |
- params->src_file_path = src_file_path; |
- params->dest_file_path = dest_file_path; |
- params->preserve_last_modified = preserve_last_modified; |
- params->callback = callback; |
- |
- std::vector<std::string>* updated_local_ids = new std::vector<std::string>; |
- bool* directory_changed = new bool(false); |
- bool* should_copy_on_server = new bool(false); |
- base::PostTaskAndReplyWithResult( |
- blocking_task_runner_.get(), |
- FROM_HERE, |
- base::Bind(&TryToCopyLocally, metadata_, cache_, params, |
- updated_local_ids, directory_changed, should_copy_on_server), |
- base::Bind(&CopyOperation::CopyAfterTryToCopyLocally, |
- weak_ptr_factory_.GetWeakPtr(), base::Owned(params), |
- base::Owned(updated_local_ids), base::Owned(directory_changed), |
- base::Owned(should_copy_on_server))); |
-} |
- |
-void CopyOperation::CopyAfterTryToCopyLocally( |
- const CopyParams* params, |
- const std::vector<std::string>* updated_local_ids, |
- const bool* directory_changed, |
- const bool* should_copy_on_server, |
- FileError error) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(!params->callback.is_null()); |
- |
- for (const auto& id : *updated_local_ids) { |
- // Syncing for copy should be done in background, so pass the BACKGROUND |
- // context. See: crbug.com/420278. |
- delegate_->OnEntryUpdatedByOperation(ClientContext(BACKGROUND), id); |
- } |
- |
- if (*directory_changed) { |
- FileChange changed_file; |
- DCHECK(!params->src_entry.file_info().is_directory()); |
- changed_file.Update(params->dest_file_path, FileChange::FILE_TYPE_FILE, |
- FileChange::CHANGE_TYPE_ADD_OR_UPDATE); |
- delegate_->OnFileChangedByOperation(changed_file); |
- } |
- |
- if (error != FILE_ERROR_OK || !*should_copy_on_server) { |
- params->callback.Run(error); |
- return; |
- } |
- |
- if (params->parent_entry.resource_id().empty()) { |
- // Parent entry may be being synced. |
- const bool waiting = delegate_->WaitForSyncComplete( |
- params->parent_entry.local_id(), |
- base::Bind(&CopyOperation::CopyAfterParentSync, |
- weak_ptr_factory_.GetWeakPtr(), *params)); |
- if (!waiting) |
- params->callback.Run(FILE_ERROR_NOT_FOUND); |
- } else { |
- CopyAfterGetParentResourceId(*params, ¶ms->parent_entry, FILE_ERROR_OK); |
- } |
-} |
- |
-void CopyOperation::CopyAfterParentSync(const CopyParams& params, |
- FileError error) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(!params.callback.is_null()); |
- |
- if (error != FILE_ERROR_OK) { |
- params.callback.Run(error); |
- return; |
- } |
- |
- ResourceEntry* parent = new ResourceEntry; |
- base::PostTaskAndReplyWithResult( |
- blocking_task_runner_.get(), |
- FROM_HERE, |
- base::Bind(&internal::ResourceMetadata::GetResourceEntryById, |
- base::Unretained(metadata_), |
- params.parent_entry.local_id(), |
- parent), |
- base::Bind(&CopyOperation::CopyAfterGetParentResourceId, |
- weak_ptr_factory_.GetWeakPtr(), |
- params, |
- base::Owned(parent))); |
-} |
- |
-void CopyOperation::CopyAfterGetParentResourceId(const CopyParams& params, |
- const ResourceEntry* parent, |
- FileError error) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(!params.callback.is_null()); |
- |
- if (error != FILE_ERROR_OK) { |
- params.callback.Run(error); |
- return; |
- } |
- |
- base::FilePath new_title = params.dest_file_path.BaseName(); |
- if (params.src_entry.file_specific_info().is_hosted_document()) { |
- // Drop the document extension, which should not be in the title. |
- // TODO(yoshiki): Remove this code with crbug.com/223304. |
- new_title = new_title.RemoveExtension(); |
- } |
- |
- base::Time last_modified = |
- params.preserve_last_modified ? |
- base::Time::FromInternalValue( |
- params.src_entry.file_info().last_modified()) : base::Time(); |
- |
- CopyResourceOnServer( |
- params.src_entry.resource_id(), parent->resource_id(), |
- new_title.AsUTF8Unsafe(), last_modified, params.callback); |
-} |
- |
-void CopyOperation::TransferFileFromLocalToRemote( |
- const base::FilePath& local_src_path, |
- const base::FilePath& remote_dest_path, |
- const FileOperationCallback& callback) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(!callback.is_null()); |
- |
- std::string* gdoc_resource_id = new std::string; |
- ResourceEntry* parent_entry = new ResourceEntry; |
- base::PostTaskAndReplyWithResult( |
- blocking_task_runner_.get(), |
- FROM_HERE, |
- base::Bind( |
- &PrepareTransferFileFromLocalToRemote, |
- metadata_, local_src_path, remote_dest_path, |
- gdoc_resource_id, parent_entry), |
- base::Bind( |
- &CopyOperation::TransferFileFromLocalToRemoteAfterPrepare, |
- weak_ptr_factory_.GetWeakPtr(), |
- local_src_path, remote_dest_path, callback, |
- base::Owned(gdoc_resource_id), base::Owned(parent_entry))); |
-} |
- |
-void CopyOperation::TransferFileFromLocalToRemoteAfterPrepare( |
- const base::FilePath& local_src_path, |
- const base::FilePath& remote_dest_path, |
- const FileOperationCallback& callback, |
- std::string* gdoc_resource_id, |
- ResourceEntry* parent_entry, |
- FileError error) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(!callback.is_null()); |
- |
- if (error != FILE_ERROR_OK) { |
- callback.Run(error); |
- return; |
- } |
- |
- // For regular files, schedule the transfer. |
- if (gdoc_resource_id->empty()) { |
- ScheduleTransferRegularFile(local_src_path, remote_dest_path, callback); |
- return; |
- } |
- |
- // GDoc file may contain a resource ID in the old format. |
- const std::string canonicalized_resource_id = |
- util::CanonicalizeResourceId(*gdoc_resource_id); |
- |
- // Drop the document extension, which should not be in the title. |
- // TODO(yoshiki): Remove this code with crbug.com/223304. |
- const std::string new_title = |
- remote_dest_path.BaseName().RemoveExtension().AsUTF8Unsafe(); |
- |
- // This is uploading a JSON file representing a hosted document. |
- TransferJsonGdocParams* params = new TransferJsonGdocParams( |
- callback, canonicalized_resource_id, *parent_entry, new_title); |
- base::PostTaskAndReplyWithResult( |
- blocking_task_runner_.get(), |
- FROM_HERE, |
- base::Bind(&LocalWorkForTransferJsonGdocFile, metadata_, params), |
- base::Bind(&CopyOperation::TransferJsonGdocFileAfterLocalWork, |
- weak_ptr_factory_.GetWeakPtr(), base::Owned(params))); |
-} |
- |
-void CopyOperation::TransferJsonGdocFileAfterLocalWork( |
- TransferJsonGdocParams* params, |
- FileError error) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- |
- if (error != FILE_ERROR_OK) { |
- params->callback.Run(error); |
- return; |
- } |
- |
- switch (params->location_type) { |
- // When |resource_id| is found in the local metadata and it has a specific |
- // parent folder, we assume the user's intention is to copy the document and |
- // thus perform the server-side copy operation. |
- case HAS_PARENT: |
- CopyResourceOnServer(params->resource_id, |
- params->parent_resource_id, |
- params->new_title, |
- base::Time(), |
- params->callback); |
- break; |
- // When |resource_id| has no parent, we just set the new destination folder |
- // as the parent, for sharing the document between the original source. |
- // This reparenting is already done in LocalWorkForTransferJsonGdocFile(). |
- case IS_ORPHAN: { |
- DCHECK(!params->changed_path.empty()); |
- // Syncing for copy should be done in background, so pass the BACKGROUND |
- // context. See: crbug.com/420278. |
- delegate_->OnEntryUpdatedByOperation(ClientContext(BACKGROUND), |
- params->local_id); |
- |
- FileChange changed_file; |
- changed_file.Update( |
- params->changed_path, |
- FileChange::FILE_TYPE_FILE, // This must be a hosted document. |
- FileChange::CHANGE_TYPE_ADD_OR_UPDATE); |
- delegate_->OnFileChangedByOperation(changed_file); |
- params->callback.Run(error); |
- break; |
- } |
- // When the |resource_id| is not in the local metadata, assume it to be a |
- // document just now shared on the server but not synced locally. |
- // Same as the IS_ORPHAN case, we want to deal the case by setting parent, |
- // but this time we need to resort to server side operation. |
- case NOT_IN_METADATA: |
- scheduler_->UpdateResource( |
- params->resource_id, params->parent_resource_id, params->new_title, |
- base::Time(), base::Time(), google_apis::drive::Properties(), |
- ClientContext(USER_INITIATED), |
- base::Bind(&CopyOperation::UpdateAfterServerSideOperation, |
- weak_ptr_factory_.GetWeakPtr(), params->callback)); |
- break; |
- } |
-} |
- |
-void CopyOperation::CopyResourceOnServer( |
- const std::string& resource_id, |
- const std::string& parent_resource_id, |
- const std::string& new_title, |
- const base::Time& last_modified, |
- const FileOperationCallback& callback) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(!callback.is_null()); |
- |
- scheduler_->CopyResource( |
- resource_id, parent_resource_id, new_title, last_modified, |
- base::Bind(&CopyOperation::UpdateAfterServerSideOperation, |
- weak_ptr_factory_.GetWeakPtr(), |
- callback)); |
-} |
- |
-void CopyOperation::UpdateAfterServerSideOperation( |
- const FileOperationCallback& callback, |
- google_apis::DriveApiErrorCode status, |
- scoped_ptr<google_apis::FileResource> entry) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(!callback.is_null()); |
- |
- FileError error = GDataToFileError(status); |
- if (error != FILE_ERROR_OK) { |
- callback.Run(error); |
- return; |
- } |
- |
- ResourceEntry* resource_entry = new ResourceEntry; |
- |
- // The copy on the server side is completed successfully. Update the local |
- // metadata. |
- base::FilePath* file_path = new base::FilePath; |
- base::PostTaskAndReplyWithResult( |
- blocking_task_runner_.get(), |
- FROM_HERE, |
- base::Bind(&UpdateLocalStateForServerSideOperation, |
- metadata_, |
- base::Passed(&entry), |
- resource_entry, |
- file_path), |
- base::Bind(&CopyOperation::UpdateAfterLocalStateUpdate, |
- weak_ptr_factory_.GetWeakPtr(), |
- callback, |
- base::Owned(file_path), |
- base::Owned(resource_entry))); |
-} |
- |
-void CopyOperation::UpdateAfterLocalStateUpdate( |
- const FileOperationCallback& callback, |
- base::FilePath* file_path, |
- const ResourceEntry* entry, |
- FileError error) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(!callback.is_null()); |
- |
- if (error == FILE_ERROR_OK) { |
- FileChange changed_file; |
- changed_file.Update(*file_path, *entry, |
- FileChange::CHANGE_TYPE_ADD_OR_UPDATE); |
- delegate_->OnFileChangedByOperation(changed_file); |
- } |
- callback.Run(error); |
-} |
- |
-void CopyOperation::ScheduleTransferRegularFile( |
- const base::FilePath& local_src_path, |
- const base::FilePath& remote_dest_path, |
- const FileOperationCallback& callback) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(!callback.is_null()); |
- |
- create_file_operation_->CreateFile( |
- remote_dest_path, |
- false, // Not exclusive (OK even if a file already exists). |
- std::string(), // no specific mime type; CreateFile should guess it. |
- base::Bind(&CopyOperation::ScheduleTransferRegularFileAfterCreate, |
- weak_ptr_factory_.GetWeakPtr(), |
- local_src_path, remote_dest_path, callback)); |
-} |
- |
-void CopyOperation::ScheduleTransferRegularFileAfterCreate( |
- const base::FilePath& local_src_path, |
- const base::FilePath& remote_dest_path, |
- const FileOperationCallback& callback, |
- FileError error) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(!callback.is_null()); |
- |
- if (error != FILE_ERROR_OK) { |
- callback.Run(error); |
- return; |
- } |
- |
- std::string* local_id = new std::string; |
- ResourceEntry* entry = new ResourceEntry; |
- base::PostTaskAndReplyWithResult( |
- blocking_task_runner_.get(), |
- FROM_HERE, |
- base::Bind(&UpdateLocalStateForScheduleTransfer, |
- metadata_, |
- cache_, |
- local_src_path, |
- remote_dest_path, |
- entry, |
- local_id), |
- base::Bind( |
- &CopyOperation::ScheduleTransferRegularFileAfterUpdateLocalState, |
- weak_ptr_factory_.GetWeakPtr(), |
- callback, |
- remote_dest_path, |
- base::Owned(entry), |
- base::Owned(local_id))); |
-} |
- |
-void CopyOperation::ScheduleTransferRegularFileAfterUpdateLocalState( |
- const FileOperationCallback& callback, |
- const base::FilePath& remote_dest_path, |
- const ResourceEntry* entry, |
- std::string* local_id, |
- FileError error) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(!callback.is_null()); |
- |
- if (error == FILE_ERROR_OK) { |
- FileChange changed_file; |
- changed_file.Update(remote_dest_path, *entry, |
- FileChange::CHANGE_TYPE_ADD_OR_UPDATE); |
- delegate_->OnFileChangedByOperation(changed_file); |
- // Syncing for copy should be done in background, so pass the BACKGROUND |
- // context. See: crbug.com/420278. |
- delegate_->OnEntryUpdatedByOperation(ClientContext(BACKGROUND), *local_id); |
- } |
- callback.Run(error); |
-} |
- |
-} // namespace file_system |
-} // namespace drive |