diff options
-rw-r--r-- | chrome/browser/chromeos/drive/file_system/download_operation.cc | 34 | ||||
-rw-r--r-- | chrome/browser/chromeos/drive/file_system/download_operation_unittest.cc | 43 |
2 files changed, 71 insertions, 6 deletions
diff --git a/chrome/browser/chromeos/drive/file_system/download_operation.cc b/chrome/browser/chromeos/drive/file_system/download_operation.cc index 0df9748..6bb88ac 100644 --- a/chrome/browser/chromeos/drive/file_system/download_operation.cc +++ b/chrome/browser/chromeos/drive/file_system/download_operation.cc @@ -4,6 +4,7 @@ #include "chrome/browser/chromeos/drive/file_system/download_operation.h" +#include "base/callback_helpers.h" #include "base/file_util.h" #include "base/files/file_path.h" #include "base/logging.h" @@ -52,9 +53,6 @@ FileError CheckPreConditionForEnsureFileDownloaded( if (entry->file_info().is_directory()) return FILE_ERROR_NOT_A_FILE; - // The file's entry should have its file specific info. - DCHECK(entry->has_file_specific_info()); - // 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 @@ -77,10 +75,32 @@ FileError CheckPreConditionForEnsureFileDownloaded( return FILE_ERROR_OK; } - // Leave |cache_file_path| empty when no cache entry is found. FileCacheEntry cache_entry; - if (!cache->GetCacheEntry(local_id, &cache_entry)) - return FILE_ERROR_OK; + if (!cache->GetCacheEntry(local_id, &cache_entry) || + !cache_entry.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 FILE_ERROR_OK; + } + + // 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, base::MD5String(""), empty_file, + internal::FileCache::FILE_OPERATION_MOVE); + if (error != FILE_ERROR_OK) + return error; + scoped_ptr<base::ScopedClosureRunner> file_closer; + error = cache->OpenForWrite(entry->local_id(), &file_closer); + if (error != FILE_ERROR_OK) + return error; + + if (!cache->GetCacheEntry(local_id, &cache_entry)) + return FILE_ERROR_NOT_FOUND; + } // Leave |cache_file_path| empty when the stored file is obsolete and has no // local modification. @@ -383,6 +403,8 @@ void DownloadOperation::EnsureFileDownloadedAfterCheckPreCondition( return; } + DCHECK(!params->entry().resource_id().empty()); + // If cache file is not found, try to download the file from the server // instead. Check if we have enough space, based on the expected file size. // - if we don't have enough space, try to free up the disk space diff --git a/chrome/browser/chromeos/drive/file_system/download_operation_unittest.cc b/chrome/browser/chromeos/drive/file_system/download_operation_unittest.cc index 5aaedfc..a706a37 100644 --- a/chrome/browser/chromeos/drive/file_system/download_operation_unittest.cc +++ b/chrome/browser/chromeos/drive/file_system/download_operation_unittest.cc @@ -469,5 +469,48 @@ TEST_F(DownloadOperationTest, EnsureFileDownloadedByPath_DirtyCache) { EXPECT_EQ(static_cast<int64>(dirty_size), entry->file_info().size()); } +TEST_F(DownloadOperationTest, EnsureFileDownloadedByPath_LocallyCreatedFile) { + // Add a new file with an empty resource ID. + base::FilePath file_path(FILE_PATH_LITERAL("drive/root/New File.txt")); + ResourceEntry parent; + ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(file_path.DirName(), &parent)); + + ResourceEntry new_file; + new_file.set_title("New File.txt"); + new_file.set_parent_local_id(parent.local_id()); + + FileError error = FILE_ERROR_FAILED; + std::string local_id; + base::PostTaskAndReplyWithResult( + blocking_task_runner(), + FROM_HERE, + base::Bind(&internal::ResourceMetadata::AddEntry, + base::Unretained(metadata()), + new_file, + &local_id), + google_apis::test_util::CreateCopyResultCallback(&error)); + test_util::RunBlockingPoolTask(); + EXPECT_EQ(FILE_ERROR_OK, error); + + // Empty cache file should be returned. + base::FilePath cache_file_path; + scoped_ptr<ResourceEntry> entry; + operation_->EnsureFileDownloadedByPath( + file_path, + ClientContext(USER_INITIATED), + GetFileContentInitializedCallback(), + google_apis::GetContentCallback(), + google_apis::test_util::CreateCopyResultCallback( + &error, &cache_file_path, &entry)); + test_util::RunBlockingPoolTask(); + EXPECT_EQ(FILE_ERROR_OK, error); + + int64 cache_file_size = 0; + EXPECT_TRUE(base::GetFileSize(cache_file_path, &cache_file_size)); + EXPECT_EQ(static_cast<int64>(0), cache_file_size); + ASSERT_TRUE(entry); + EXPECT_EQ(cache_file_size, entry->file_info().size()); +} + } // namespace file_system } // namespace drive |