| 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
|
|
|