Index: chrome/browser/chromeos/drive/file_system/download_operation.cc |
diff --git a/chrome/browser/chromeos/drive/file_system/download_operation.cc b/chrome/browser/chromeos/drive/file_system/download_operation.cc |
deleted file mode 100644 |
index 2032a490fce8b1e882d36055ee8b6f9511b0782d..0000000000000000000000000000000000000000 |
--- a/chrome/browser/chromeos/drive/file_system/download_operation.cc |
+++ /dev/null |
@@ -1,540 +0,0 @@ |
-// 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/chromeos/drive/file_system/download_operation.h" |
- |
-#include "base/callback_helpers.h" |
-#include "base/files/file_path.h" |
-#include "base/files/file_util.h" |
-#include "base/logging.h" |
-#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_errors.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_metadata.h" |
-#include "google_apis/drive/drive_api_error_codes.h" |
- |
-namespace drive { |
-namespace file_system { |
-namespace { |
- |
-// Generates an unused file path with |extension| to |out_path|, as a descendant |
-// of |dir|, with its parent directory created. |
-bool GeneratesUniquePathWithExtension( |
- const base::FilePath& dir, |
- const base::FilePath::StringType& extension, |
- base::FilePath* out_path) { |
- base::FilePath subdir; |
- if (!base::CreateTemporaryDirInDir(dir, base::FilePath::StringType(), |
- &subdir)) { |
- return false; |
- } |
- *out_path = subdir.Append(FILE_PATH_LITERAL("tmp") + extension); |
- return true; |
-} |
- |
-// Prepares for downloading the file. Allocates the enough space for the file |
-// in the cache. |
-// If succeeded, returns FILE_ERROR_OK with |temp_download_file| storing the |
-// path to the file in the cache. |
-FileError PrepareForDownloadFile(internal::FileCache* cache, |
- int64 expected_file_size, |
- const base::FilePath& temporary_file_directory, |
- base::FilePath* temp_download_file) { |
- DCHECK(cache); |
- DCHECK(temp_download_file); |
- |
- // Ensure enough space in the cache. |
- if (!cache->FreeDiskSpaceIfNeededFor(expected_file_size)) |
- return FILE_ERROR_NO_LOCAL_SPACE; |
- |
- return base::CreateTemporaryFileInDir( |
- temporary_file_directory, |
- temp_download_file) ? FILE_ERROR_OK : FILE_ERROR_FAILED; |
-} |
- |
-// If the resource is a hosted document, creates a JSON file representing the |
-// resource locally, and returns FILE_ERROR_OK with |cache_file_path| storing |
-// the path to the JSON file. |
-// If the resource is a regular file and its local cache is available, |
-// returns FILE_ERROR_OK with |cache_file_path| storing the path to the |
-// cache file. |
-// If the resource is a regular file but its local cache is NOT available, |
-// returns FILE_ERROR_OK, but |cache_file_path| is kept empty. |
-// Otherwise returns error code. |
-FileError CheckPreConditionForEnsureFileDownloaded( |
- internal::ResourceMetadata* metadata, |
- internal::FileCache* cache, |
- const base::FilePath& temporary_file_directory, |
- const std::string& local_id, |
- ResourceEntry* entry, |
- base::FilePath* cache_file_path, |
- base::FilePath* temp_download_file_path) { |
- DCHECK(metadata); |
- DCHECK(cache); |
- DCHECK(cache_file_path); |
- |
- FileError error = metadata->GetResourceEntryById(local_id, entry); |
- if (error != FILE_ERROR_OK) |
- return error; |
- |
- if (entry->file_info().is_directory()) |
- return FILE_ERROR_NOT_A_FILE; |
- |
- // For a hosted document, we create a special JSON file to represent the |
- // document instead of fetching the document content in one of the exported |
- // formats. The JSON file contains the edit URL and resource ID of the |
- // document. |
- if (entry->file_specific_info().is_hosted_document()) { |
- base::FilePath::StringType extension = base::FilePath::FromUTF8Unsafe( |
- entry->file_specific_info().document_extension()).value(); |
- base::FilePath gdoc_file_path; |
- base::File::Info file_info; |
- // We add the gdoc file extension in the temporary file, so that in cross |
- // profile drag-and-drop between Drive folders, the destination profiles's |
- // CopyOperation can detect the special JSON file only by the path. |
- if (!GeneratesUniquePathWithExtension(temporary_file_directory, |
- extension, |
- &gdoc_file_path) || |
- !util::CreateGDocFile(gdoc_file_path, |
- GURL(entry->file_specific_info().alternate_url()), |
- entry->resource_id()) || |
- !base::GetFileInfo(gdoc_file_path, |
- reinterpret_cast<base::File::Info*>(&file_info))) |
- return FILE_ERROR_FAILED; |
- |
- *cache_file_path = gdoc_file_path; |
- entry->mutable_file_info()->set_size(file_info.size); |
- return FILE_ERROR_OK; |
- } |
- |
- if (!entry->file_specific_info().cache_state().is_present()) { |
- // This file has no cache file. |
- if (!entry->resource_id().empty()) { |
- // This entry exists on the server, leave |cache_file_path| empty to |
- // start download. |
- return PrepareForDownloadFile(cache, entry->file_info().size(), |
- temporary_file_directory, |
- temp_download_file_path); |
- } |
- |
- // This entry does not exist on the server, store an empty file and mark it |
- // as dirty. |
- base::FilePath empty_file; |
- if (!base::CreateTemporaryFileInDir(temporary_file_directory, &empty_file)) |
- return FILE_ERROR_FAILED; |
- error = cache->Store(local_id, std::string(), empty_file, |
- internal::FileCache::FILE_OPERATION_MOVE); |
- if (error != FILE_ERROR_OK) |
- return error; |
- |
- error = metadata->GetResourceEntryById(local_id, entry); |
- if (error != FILE_ERROR_OK) |
- return error; |
- } |
- |
- // Leave |cache_file_path| empty when the stored file is obsolete and has no |
- // local modification. |
- if (!entry->file_specific_info().cache_state().is_dirty() && |
- entry->file_specific_info().md5() != |
- entry->file_specific_info().cache_state().md5()) { |
- return PrepareForDownloadFile(cache, entry->file_info().size(), |
- temporary_file_directory, |
- temp_download_file_path); |
- } |
- |
- // Fill |cache_file_path| with the path to the cached file. |
- error = cache->GetFile(local_id, cache_file_path); |
- if (error != FILE_ERROR_OK) |
- return error; |
- |
- // If the cache file is to be returned as the download result, the file info |
- // of the cache needs to be returned via |entry|. |
- // TODO(kinaba): crbug.com/246469. The logic below is similar to that in |
- // drive::FileSystem::CheckLocalModificationAndRun. We should merge them. |
- base::File::Info file_info; |
- if (base::GetFileInfo(*cache_file_path, &file_info)) |
- entry->mutable_file_info()->set_size(file_info.size); |
- |
- return FILE_ERROR_OK; |
-} |
- |
-struct CheckPreconditionForEnsureFileDownloadedParams { |
- internal::ResourceMetadata* metadata; |
- internal::FileCache* cache; |
- base::FilePath temporary_file_directory; |
-}; |
- |
-// Calls CheckPreConditionForEnsureFileDownloaded() with the entry specified by |
-// the given ID. Also fills |drive_file_path| with the path of the entry. |
-FileError CheckPreConditionForEnsureFileDownloadedByLocalId( |
- const CheckPreconditionForEnsureFileDownloadedParams& params, |
- const std::string& local_id, |
- base::FilePath* drive_file_path, |
- base::FilePath* cache_file_path, |
- base::FilePath* temp_download_file_path, |
- ResourceEntry* entry) { |
- FileError error = params.metadata->GetFilePath(local_id, drive_file_path); |
- if (error != FILE_ERROR_OK) |
- return error; |
- return CheckPreConditionForEnsureFileDownloaded( |
- params.metadata, params.cache, params.temporary_file_directory, local_id, |
- entry, cache_file_path, temp_download_file_path); |
-} |
- |
-// Calls CheckPreConditionForEnsureFileDownloaded() with the entry specified by |
-// the given file path. |
-FileError CheckPreConditionForEnsureFileDownloadedByPath( |
- const CheckPreconditionForEnsureFileDownloadedParams& params, |
- const base::FilePath& file_path, |
- base::FilePath* cache_file_path, |
- base::FilePath* temp_download_file_path, |
- ResourceEntry* entry) { |
- std::string local_id; |
- FileError error = params.metadata->GetIdByPath(file_path, &local_id); |
- if (error != FILE_ERROR_OK) |
- return error; |
- return CheckPreConditionForEnsureFileDownloaded( |
- params.metadata, params.cache, params.temporary_file_directory, local_id, |
- entry, cache_file_path, temp_download_file_path); |
-} |
- |
-// Stores the downloaded file at |downloaded_file_path| into |cache|. |
-// If succeeded, returns FILE_ERROR_OK with |cache_file_path| storing the |
-// path to the cache file. |
-// If failed, returns an error code with deleting |downloaded_file_path|. |
-FileError UpdateLocalStateForDownloadFile( |
- internal::ResourceMetadata* metadata, |
- internal::FileCache* cache, |
- const ResourceEntry& entry_before_download, |
- google_apis::DriveApiErrorCode gdata_error, |
- const base::FilePath& downloaded_file_path, |
- ResourceEntry* entry_after_update, |
- base::FilePath* cache_file_path) { |
- DCHECK(cache); |
- |
- // Downloaded file should be deleted on errors. |
- base::ScopedClosureRunner file_deleter(base::Bind( |
- base::IgnoreResult(&base::DeleteFile), |
- downloaded_file_path, false /* recursive */)); |
- |
- FileError error = GDataToFileError(gdata_error); |
- if (error != FILE_ERROR_OK) |
- return error; |
- |
- const std::string& local_id = entry_before_download.local_id(); |
- |
- // Do not overwrite locally edited file with server side contents. |
- ResourceEntry entry; |
- error = metadata->GetResourceEntryById(local_id, &entry); |
- if (error != FILE_ERROR_OK) |
- return error; |
- if (entry.file_specific_info().cache_state().is_dirty()) |
- return FILE_ERROR_IN_USE; |
- |
- // Here the download is completed successfully, so store it into the cache. |
- error = cache->Store(local_id, |
- entry_before_download.file_specific_info().md5(), |
- downloaded_file_path, |
- internal::FileCache::FILE_OPERATION_MOVE); |
- if (error != FILE_ERROR_OK) |
- return error; |
- base::Closure unused_file_deleter_closure = file_deleter.Release(); |
- |
- error = metadata->GetResourceEntryById(local_id, entry_after_update); |
- if (error != FILE_ERROR_OK) |
- return error; |
- |
- return cache->GetFile(local_id, cache_file_path); |
-} |
- |
-} // namespace |
- |
-class DownloadOperation::DownloadParams { |
- public: |
- DownloadParams( |
- const GetFileContentInitializedCallback initialized_callback, |
- const google_apis::GetContentCallback get_content_callback, |
- const GetFileCallback completion_callback, |
- scoped_ptr<ResourceEntry> entry) |
- : initialized_callback_(initialized_callback), |
- get_content_callback_(get_content_callback), |
- completion_callback_(completion_callback), |
- entry_(entry.Pass()), |
- was_cancelled_(false), |
- weak_ptr_factory_(this) { |
- DCHECK(!completion_callback_.is_null()); |
- DCHECK(entry_); |
- } |
- |
- base::Closure GetCancelClosure() { |
- return base::Bind(&DownloadParams::Cancel, weak_ptr_factory_.GetWeakPtr()); |
- } |
- |
- void OnCacheFileFound(const base::FilePath& cache_file_path) { |
- if (!initialized_callback_.is_null()) { |
- initialized_callback_.Run(FILE_ERROR_OK, cache_file_path, |
- make_scoped_ptr(new ResourceEntry(*entry_))); |
- } |
- completion_callback_.Run(FILE_ERROR_OK, cache_file_path, entry_.Pass()); |
- } |
- |
- void OnStartDownloading(const base::Closure& cancel_download_closure) { |
- cancel_download_closure_ = cancel_download_closure; |
- if (initialized_callback_.is_null()) { |
- return; |
- } |
- |
- DCHECK(entry_); |
- initialized_callback_.Run(FILE_ERROR_OK, base::FilePath(), |
- make_scoped_ptr(new ResourceEntry(*entry_))); |
- } |
- |
- void OnError(FileError error) const { |
- completion_callback_.Run( |
- error, base::FilePath(), scoped_ptr<ResourceEntry>()); |
- } |
- |
- void OnDownloadCompleted(const base::FilePath& cache_file_path, |
- scoped_ptr<ResourceEntry> entry) const { |
- completion_callback_.Run(FILE_ERROR_OK, cache_file_path, entry.Pass()); |
- } |
- |
- const google_apis::GetContentCallback& get_content_callback() const { |
- return get_content_callback_; |
- } |
- |
- const ResourceEntry& entry() const { return *entry_; } |
- |
- bool was_cancelled() const { return was_cancelled_; } |
- |
- private: |
- void Cancel() { |
- was_cancelled_ = true; |
- if (!cancel_download_closure_.is_null()) |
- cancel_download_closure_.Run(); |
- } |
- |
- const GetFileContentInitializedCallback initialized_callback_; |
- const google_apis::GetContentCallback get_content_callback_; |
- const GetFileCallback completion_callback_; |
- |
- scoped_ptr<ResourceEntry> entry_; |
- base::Closure cancel_download_closure_; |
- bool was_cancelled_; |
- |
- base::WeakPtrFactory<DownloadParams> weak_ptr_factory_; |
- DISALLOW_COPY_AND_ASSIGN(DownloadParams); |
-}; |
- |
-DownloadOperation::DownloadOperation( |
- base::SequencedTaskRunner* blocking_task_runner, |
- OperationDelegate* delegate, |
- JobScheduler* scheduler, |
- internal::ResourceMetadata* metadata, |
- internal::FileCache* cache, |
- const base::FilePath& temporary_file_directory) |
- : blocking_task_runner_(blocking_task_runner), |
- delegate_(delegate), |
- scheduler_(scheduler), |
- metadata_(metadata), |
- cache_(cache), |
- temporary_file_directory_(temporary_file_directory), |
- weak_ptr_factory_(this) { |
-} |
- |
-DownloadOperation::~DownloadOperation() { |
-} |
- |
-base::Closure DownloadOperation::EnsureFileDownloadedByLocalId( |
- const std::string& local_id, |
- const ClientContext& context, |
- const GetFileContentInitializedCallback& initialized_callback, |
- const google_apis::GetContentCallback& get_content_callback, |
- const GetFileCallback& completion_callback) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(!completion_callback.is_null()); |
- |
- CheckPreconditionForEnsureFileDownloadedParams params; |
- params.metadata = metadata_; |
- params.cache = cache_; |
- params.temporary_file_directory = temporary_file_directory_; |
- base::FilePath* drive_file_path = new base::FilePath; |
- base::FilePath* cache_file_path = new base::FilePath; |
- base::FilePath* temp_download_file_path = new base::FilePath; |
- ResourceEntry* entry = new ResourceEntry; |
- scoped_ptr<DownloadParams> download_params(new DownloadParams( |
- initialized_callback, get_content_callback, completion_callback, |
- make_scoped_ptr(entry))); |
- base::Closure cancel_closure = download_params->GetCancelClosure(); |
- base::PostTaskAndReplyWithResult( |
- blocking_task_runner_.get(), |
- FROM_HERE, |
- base::Bind(&CheckPreConditionForEnsureFileDownloadedByLocalId, |
- params, |
- local_id, |
- drive_file_path, |
- cache_file_path, |
- temp_download_file_path, |
- entry), |
- base::Bind(&DownloadOperation::EnsureFileDownloadedAfterCheckPreCondition, |
- weak_ptr_factory_.GetWeakPtr(), |
- base::Passed(&download_params), |
- context, |
- base::Owned(drive_file_path), |
- base::Owned(cache_file_path), |
- base::Owned(temp_download_file_path))); |
- return cancel_closure; |
-} |
- |
-base::Closure DownloadOperation::EnsureFileDownloadedByPath( |
- const base::FilePath& file_path, |
- const ClientContext& context, |
- const GetFileContentInitializedCallback& initialized_callback, |
- const google_apis::GetContentCallback& get_content_callback, |
- const GetFileCallback& completion_callback) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(!completion_callback.is_null()); |
- |
- CheckPreconditionForEnsureFileDownloadedParams params; |
- params.metadata = metadata_; |
- params.cache = cache_; |
- params.temporary_file_directory = temporary_file_directory_; |
- base::FilePath* drive_file_path = new base::FilePath(file_path); |
- base::FilePath* cache_file_path = new base::FilePath; |
- base::FilePath* temp_download_file_path = new base::FilePath; |
- ResourceEntry* entry = new ResourceEntry; |
- scoped_ptr<DownloadParams> download_params(new DownloadParams( |
- initialized_callback, get_content_callback, completion_callback, |
- make_scoped_ptr(entry))); |
- base::Closure cancel_closure = download_params->GetCancelClosure(); |
- base::PostTaskAndReplyWithResult( |
- blocking_task_runner_.get(), |
- FROM_HERE, |
- base::Bind(&CheckPreConditionForEnsureFileDownloadedByPath, |
- params, |
- file_path, |
- cache_file_path, |
- temp_download_file_path, |
- entry), |
- base::Bind(&DownloadOperation::EnsureFileDownloadedAfterCheckPreCondition, |
- weak_ptr_factory_.GetWeakPtr(), |
- base::Passed(&download_params), |
- context, |
- base::Owned(drive_file_path), |
- base::Owned(cache_file_path), |
- base::Owned(temp_download_file_path))); |
- return cancel_closure; |
-} |
- |
-void DownloadOperation::EnsureFileDownloadedAfterCheckPreCondition( |
- scoped_ptr<DownloadParams> params, |
- const ClientContext& context, |
- base::FilePath* drive_file_path, |
- base::FilePath* cache_file_path, |
- base::FilePath* temp_download_file_path, |
- FileError error) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- DCHECK(params); |
- DCHECK(drive_file_path); |
- DCHECK(cache_file_path); |
- |
- if (error != FILE_ERROR_OK) { |
- // During precondition check, an error is found. |
- params->OnError(error); |
- return; |
- } |
- |
- if (!cache_file_path->empty()) { |
- // The cache file is found. |
- params->OnCacheFileFound(*cache_file_path); |
- return; |
- } |
- |
- if (params->was_cancelled()) { |
- params->OnError(FILE_ERROR_ABORT); |
- return; |
- } |
- |
- DCHECK(!params->entry().resource_id().empty()); |
- DownloadParams* params_ptr = params.get(); |
- JobID id = scheduler_->DownloadFile( |
- *drive_file_path, |
- params_ptr->entry().file_info().size(), |
- *temp_download_file_path, |
- params_ptr->entry().resource_id(), |
- context, |
- base::Bind(&DownloadOperation::EnsureFileDownloadedAfterDownloadFile, |
- weak_ptr_factory_.GetWeakPtr(), |
- *drive_file_path, |
- base::Passed(¶ms)), |
- params_ptr->get_content_callback()); |
- |
- // Notify via |initialized_callback| if necessary. |
- params_ptr->OnStartDownloading( |
- base::Bind(&DownloadOperation::CancelJob, |
- weak_ptr_factory_.GetWeakPtr(), id)); |
-} |
- |
-void DownloadOperation::EnsureFileDownloadedAfterDownloadFile( |
- const base::FilePath& drive_file_path, |
- scoped_ptr<DownloadParams> params, |
- google_apis::DriveApiErrorCode gdata_error, |
- const base::FilePath& downloaded_file_path) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- |
- DownloadParams* params_ptr = params.get(); |
- ResourceEntry* entry_after_update = new ResourceEntry; |
- base::FilePath* cache_file_path = new base::FilePath; |
- base::PostTaskAndReplyWithResult( |
- blocking_task_runner_.get(), |
- FROM_HERE, |
- base::Bind(&UpdateLocalStateForDownloadFile, |
- metadata_, |
- cache_, |
- params_ptr->entry(), |
- gdata_error, |
- downloaded_file_path, |
- entry_after_update, |
- cache_file_path), |
- base::Bind(&DownloadOperation::EnsureFileDownloadedAfterUpdateLocalState, |
- weak_ptr_factory_.GetWeakPtr(), |
- drive_file_path, |
- base::Passed(¶ms), |
- base::Passed(make_scoped_ptr(entry_after_update)), |
- base::Owned(cache_file_path))); |
-} |
- |
-void DownloadOperation::EnsureFileDownloadedAfterUpdateLocalState( |
- const base::FilePath& file_path, |
- scoped_ptr<DownloadParams> params, |
- scoped_ptr<ResourceEntry> entry_after_update, |
- base::FilePath* cache_file_path, |
- FileError error) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
- |
- if (error != FILE_ERROR_OK) { |
- params->OnError(error); |
- return; |
- } |
- DCHECK(!entry_after_update->file_info().is_directory()); |
- |
- FileChange changed_files; |
- changed_files.Update(file_path, FileChange::FILE_TYPE_FILE, |
- FileChange::CHANGE_TYPE_ADD_OR_UPDATE); |
- // Storing to cache changes the "offline available" status, hence notify. |
- delegate_->OnFileChangedByOperation(changed_files); |
- params->OnDownloadCompleted(*cache_file_path, entry_after_update.Pass()); |
-} |
- |
-void DownloadOperation::CancelJob(JobID job_id) { |
- scheduler_->CancelJob(job_id); |
-} |
- |
-} // namespace file_system |
-} // namespace drive |