summaryrefslogtreecommitdiffstats
path: root/chrome/browser/chromeos/drive
diff options
context:
space:
mode:
authorkinaba@chromium.org <kinaba@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-08 11:19:57 +0000
committerkinaba@chromium.org <kinaba@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-08-08 11:19:57 +0000
commit67d35b02236148e5b696b38ea9aceb77de9d16a4 (patch)
treef39da1746850cca8fed0d45749ce0df043f7b585 /chrome/browser/chromeos/drive
parent3aacc9c9ec7d8c3124c8263d0f70bcf3c2cb2866 (diff)
downloadchromium_src-67d35b02236148e5b696b38ea9aceb77de9d16a4.zip
chromium_src-67d35b02236148e5b696b38ea9aceb77de9d16a4.tar.gz
chromium_src-67d35b02236148e5b696b38ea9aceb77de9d16a4.tar.bz2
Add drive::FileSystem::GetFileByPathForSaving().
This is a part of the effort to enable Drive in the Save-As dialog of Chrome OS for every call site. For that, we need to care about existing callers that just simply write to local file paths returned by the dialog. By calling the newly added method, Drive file system will return a local cache whose modification is monitored for syncing. BUG=140425 Review URL: https://chromiumcodereview.appspot.com/22335004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@216377 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/chromeos/drive')
-rw-r--r--chrome/browser/chromeos/drive/dummy_file_system.h3
-rw-r--r--chrome/browser/chromeos/drive/fake_file_system.cc5
-rw-r--r--chrome/browser/chromeos/drive/fake_file_system.h2
-rw-r--r--chrome/browser/chromeos/drive/file_system.cc18
-rw-r--r--chrome/browser/chromeos/drive/file_system.h5
-rw-r--r--chrome/browser/chromeos/drive/file_system/get_file_for_saving_operation.cc146
-rw-r--r--chrome/browser/chromeos/drive/file_system/get_file_for_saving_operation.h92
-rw-r--r--chrome/browser/chromeos/drive/file_system/get_file_for_saving_operation_unittest.cc158
-rw-r--r--chrome/browser/chromeos/drive/file_system/operation_test_base.cc4
-rw-r--r--chrome/browser/chromeos/drive/file_system/operation_test_base.h1
-rw-r--r--chrome/browser/chromeos/drive/file_system_interface.h18
-rw-r--r--chrome/browser/chromeos/drive/file_write_watcher.h2
12 files changed, 447 insertions, 7 deletions
diff --git a/chrome/browser/chromeos/drive/dummy_file_system.h b/chrome/browser/chromeos/drive/dummy_file_system.h
index 191be66..c0fe931 100644
--- a/chrome/browser/chromeos/drive/dummy_file_system.h
+++ b/chrome/browser/chromeos/drive/dummy_file_system.h
@@ -58,6 +58,9 @@ class DummyFileSystem : public FileSystemInterface {
const FileOperationCallback& callback) OVERRIDE {}
virtual void GetFileByPath(const base::FilePath& file_path,
const GetFileCallback& callback) OVERRIDE {}
+ virtual void GetFileByPathForSaving(
+ const base::FilePath& file_path,
+ const GetFileCallback& callback) OVERRIDE {}
virtual void GetFileContentByPath(
const base::FilePath& file_path,
const GetFileContentInitializedCallback& initialized_callback,
diff --git a/chrome/browser/chromeos/drive/fake_file_system.cc b/chrome/browser/chromeos/drive/fake_file_system.cc
index 4b6f6e4..6211872 100644
--- a/chrome/browser/chromeos/drive/fake_file_system.cc
+++ b/chrome/browser/chromeos/drive/fake_file_system.cc
@@ -134,6 +134,11 @@ void FakeFileSystem::GetFileByPath(const base::FilePath& file_path,
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
}
+void FakeFileSystem::GetFileByPathForSaving(const base::FilePath& file_path,
+ const GetFileCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+}
+
void FakeFileSystem::GetFileContentByPath(
const base::FilePath& file_path,
const GetFileContentInitializedCallback& initialized_callback,
diff --git a/chrome/browser/chromeos/drive/fake_file_system.h b/chrome/browser/chromeos/drive/fake_file_system.h
index da005db..6b20d34 100644
--- a/chrome/browser/chromeos/drive/fake_file_system.h
+++ b/chrome/browser/chromeos/drive/fake_file_system.h
@@ -91,6 +91,8 @@ class FakeFileSystem : public FileSystemInterface {
const FileOperationCallback& callback) OVERRIDE;
virtual void GetFileByPath(const base::FilePath& file_path,
const GetFileCallback& callback) OVERRIDE;
+ virtual void GetFileByPathForSaving(const base::FilePath& file_path,
+ const GetFileCallback& callback) OVERRIDE;
virtual void GetFileContentByPath(
const base::FilePath& file_path,
const GetFileContentInitializedCallback& initialized_callback,
diff --git a/chrome/browser/chromeos/drive/file_system.cc b/chrome/browser/chromeos/drive/file_system.cc
index 6b89008..b6f4e93 100644
--- a/chrome/browser/chromeos/drive/file_system.cc
+++ b/chrome/browser/chromeos/drive/file_system.cc
@@ -20,6 +20,7 @@
#include "chrome/browser/chromeos/drive/file_system/create_directory_operation.h"
#include "chrome/browser/chromeos/drive/file_system/create_file_operation.h"
#include "chrome/browser/chromeos/drive/file_system/download_operation.h"
+#include "chrome/browser/chromeos/drive/file_system/get_file_for_saving_operation.h"
#include "chrome/browser/chromeos/drive/file_system/move_operation.h"
#include "chrome/browser/chromeos/drive/file_system/open_file_operation.h"
#include "chrome/browser/chromeos/drive/file_system/remove_operation.h"
@@ -208,13 +209,20 @@ void FileSystem::Initialize() {
cache_));
search_operation_.reset(new file_system::SearchOperation(
blocking_task_runner_.get(), scheduler_, resource_metadata_));
+ get_file_for_saving_operation_.reset(
+ new file_system::GetFileForSavingOperation(blocking_task_runner_.get(),
+ observer,
+ scheduler_,
+ resource_metadata_,
+ cache_,
+ temporary_file_directory_));
+
sync_client_.reset(new internal::SyncClient(blocking_task_runner_.get(),
observer,
scheduler_,
resource_metadata_,
cache_,
temporary_file_directory_));
-
hide_hosted_docs_ =
pref_service_->GetBoolean(prefs::kDisableDriveHostedFiles);
@@ -491,6 +499,14 @@ void FileSystem::GetFileByPath(const base::FilePath& file_path,
callback);
}
+void FileSystem::GetFileByPathForSaving(const base::FilePath& file_path,
+ const GetFileCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(!callback.is_null());
+
+ get_file_for_saving_operation_->GetFileForSaving(file_path, callback);
+}
+
void FileSystem::GetFileContentByPath(
const base::FilePath& file_path,
const GetFileContentInitializedCallback& initialized_callback,
diff --git a/chrome/browser/chromeos/drive/file_system.h b/chrome/browser/chromeos/drive/file_system.h
index 5bb1ca8..dacc522 100644
--- a/chrome/browser/chromeos/drive/file_system.h
+++ b/chrome/browser/chromeos/drive/file_system.h
@@ -46,6 +46,7 @@ class CopyOperation;
class CreateDirectoryOperation;
class CreateFileOperation;
class DownloadOperation;
+class GetFileForSavingOperation;
class MoveOperation;
class OpenFileOperation;
class OperationObserver;
@@ -122,6 +123,8 @@ class FileSystem : public FileSystemInterface,
const FileOperationCallback& callback) OVERRIDE;
virtual void GetFileByPath(const base::FilePath& file_path,
const GetFileCallback& callback) OVERRIDE;
+ virtual void GetFileByPathForSaving(const base::FilePath& file_path,
+ const GetFileCallback& callback) OVERRIDE;
virtual void GetFileContentByPath(
const base::FilePath& file_path,
const GetFileContentInitializedCallback& initialized_callback,
@@ -319,6 +322,8 @@ class FileSystem : public FileSystemInterface,
scoped_ptr<file_system::DownloadOperation> download_operation_;
scoped_ptr<file_system::UpdateOperation> update_operation_;
scoped_ptr<file_system::SearchOperation> search_operation_;
+ scoped_ptr<file_system::GetFileForSavingOperation>
+ get_file_for_saving_operation_;
// Note: This should remain the last member so it'll be destroyed and
// invalidate the weak pointers before any other members are destroyed.
diff --git a/chrome/browser/chromeos/drive/file_system/get_file_for_saving_operation.cc b/chrome/browser/chromeos/drive/file_system/get_file_for_saving_operation.cc
new file mode 100644
index 0000000..7964876
--- /dev/null
+++ b/chrome/browser/chromeos/drive/file_system/get_file_for_saving_operation.cc
@@ -0,0 +1,146 @@
+// 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/get_file_for_saving_operation.h"
+
+#include "base/bind.h"
+#include "chrome/browser/chromeos/drive/file_system/create_file_operation.h"
+#include "chrome/browser/chromeos/drive/file_system/download_operation.h"
+#include "chrome/browser/chromeos/drive/file_write_watcher.h"
+#include "content/public/browser/browser_thread.h"
+
+using content::BrowserThread;
+
+namespace drive {
+namespace file_system {
+
+GetFileForSavingOperation::GetFileForSavingOperation(
+ base::SequencedTaskRunner* blocking_task_runner,
+ OperationObserver* observer,
+ JobScheduler* scheduler,
+ internal::ResourceMetadata* metadata,
+ internal::FileCache* cache,
+ const base::FilePath& temporary_file_directory)
+ : create_file_operation_(new CreateFileOperation(blocking_task_runner,
+ observer,
+ scheduler,
+ metadata,
+ cache)),
+ download_operation_(new DownloadOperation(blocking_task_runner,
+ observer,
+ scheduler,
+ metadata,
+ cache,
+ temporary_file_directory)),
+ file_write_watcher_(new internal::FileWriteWatcher(observer)),
+ cache_(cache),
+ weak_ptr_factory_(this) {
+}
+
+GetFileForSavingOperation::~GetFileForSavingOperation() {
+}
+
+void GetFileForSavingOperation::GetFileForSaving(
+ const base::FilePath& file_path,
+ const GetFileCallback& callback) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(!callback.is_null());
+
+ create_file_operation_->CreateFile(
+ file_path,
+ false, // error_if_already_exists
+ base::Bind(&GetFileForSavingOperation::GetFileForSavingAfterCreate,
+ weak_ptr_factory_.GetWeakPtr(),
+ file_path,
+ callback));
+}
+
+void GetFileForSavingOperation::GetFileForSavingAfterCreate(
+ const base::FilePath& file_path,
+ const GetFileCallback& callback,
+ FileError error) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(!callback.is_null());
+
+ if (error != FILE_ERROR_OK) {
+ callback.Run(error, base::FilePath(), scoped_ptr<ResourceEntry>());
+ return;
+ }
+
+ download_operation_->EnsureFileDownloadedByPath(
+ file_path,
+ ClientContext(USER_INITIATED),
+ GetFileContentInitializedCallback(),
+ google_apis::GetContentCallback(),
+ base::Bind(&GetFileForSavingOperation::GetFileForSavingAfterDownload,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback));
+}
+
+void GetFileForSavingOperation::GetFileForSavingAfterDownload(
+ const GetFileCallback& callback,
+ FileError error,
+ const base::FilePath& cache_path,
+ scoped_ptr<ResourceEntry> entry) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(!callback.is_null());
+
+ if (error != FILE_ERROR_OK) {
+ callback.Run(error, base::FilePath(), scoped_ptr<ResourceEntry>());
+ return;
+ }
+
+ const std::string& resource_id = entry->resource_id();
+ cache_->MarkDirtyOnUIThread(
+ resource_id,
+ base::Bind(&GetFileForSavingOperation::GetFileForSavingAfterMarkDirty,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback,
+ cache_path,
+ base::Passed(&entry)));
+}
+
+void GetFileForSavingOperation::GetFileForSavingAfterMarkDirty(
+ const GetFileCallback& callback,
+ const base::FilePath& cache_path,
+ scoped_ptr<ResourceEntry> entry,
+ FileError error) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(!callback.is_null());
+
+ if (error != FILE_ERROR_OK) {
+ callback.Run(error, base::FilePath(), scoped_ptr<ResourceEntry>());
+ return;
+ }
+
+ const std::string& resource_id = entry->resource_id();
+ file_write_watcher_->StartWatch(
+ cache_path,
+ resource_id,
+ base::Bind(&GetFileForSavingOperation::GetFileForSavingAfterWatch,
+ weak_ptr_factory_.GetWeakPtr(),
+ callback,
+ cache_path,
+ base::Passed(&entry)));
+}
+
+void GetFileForSavingOperation::GetFileForSavingAfterWatch(
+ const GetFileCallback& callback,
+ const base::FilePath& cache_path,
+ scoped_ptr<ResourceEntry> entry,
+ bool success) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ DCHECK(!callback.is_null());
+
+ if (!success) {
+ callback.Run(FILE_ERROR_FAILED,
+ base::FilePath(), scoped_ptr<ResourceEntry>());
+ return;
+ }
+
+ callback.Run(FILE_ERROR_OK, cache_path, entry.Pass());
+}
+
+} // namespace file_system
+} // namespace drive
diff --git a/chrome/browser/chromeos/drive/file_system/get_file_for_saving_operation.h b/chrome/browser/chromeos/drive/file_system/get_file_for_saving_operation.h
new file mode 100644
index 0000000..3215cc2
--- /dev/null
+++ b/chrome/browser/chromeos/drive/file_system/get_file_for_saving_operation.h
@@ -0,0 +1,92 @@
+// 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.
+
+#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_GET_FILE_FOR_SAVING_OPERATION_H_
+#define CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_GET_FILE_FOR_SAVING_OPERATION_H_
+
+#include "base/basictypes.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/memory/weak_ptr.h"
+#include "chrome/browser/chromeos/drive/file_errors.h"
+#include "chrome/browser/chromeos/drive/file_system_interface.h"
+
+namespace base {
+class FilePath;
+class SequencedTaskRunner;
+} // namespace base
+
+namespace drive {
+namespace internal {
+class FileCache;
+class FileWriteWatcher;
+class ResourceMetadata;
+} // namespace internal
+
+class JobScheduler;
+class ResourceEntry;
+
+namespace file_system {
+
+class CreateFileOperation;
+class DownloadOperation;
+class OperationObserver;
+
+// Implements GetFileForSaving() operation that prepares a local cache for
+// a Drive file whose next modification is monitored and notified to the
+// OperationObserver.
+// TODO(kinaba): crbug.com/269424: we might want to monitor all the changes
+// to the cache directory, not just the one immediately after the save dialog.
+class GetFileForSavingOperation {
+ public:
+ GetFileForSavingOperation(base::SequencedTaskRunner* blocking_task_runner,
+ OperationObserver* observer,
+ JobScheduler* scheduler,
+ internal::ResourceMetadata* metadata,
+ internal::FileCache* cache,
+ const base::FilePath& temporary_file_directory);
+ ~GetFileForSavingOperation();
+
+ // Makes sure that |file_path| in the file system is available in the local
+ // cache, and marks it as dirty. The next modification to the cache file is
+ // watched and is automatically notified to the observer. If the entry is not
+ // present in the file system, it is created.
+ void GetFileForSaving(const base::FilePath& file_path,
+ const GetFileCallback& callback);
+
+ internal::FileWriteWatcher* file_write_watcher_for_testing() {
+ return file_write_watcher_.get();
+ }
+
+ private:
+ void GetFileForSavingAfterCreate(const base::FilePath& file_path,
+ const GetFileCallback& callback,
+ FileError error);
+ void GetFileForSavingAfterDownload(const GetFileCallback& callback,
+ FileError error,
+ const base::FilePath& cache_path,
+ scoped_ptr<ResourceEntry> entry);
+ void GetFileForSavingAfterMarkDirty(const GetFileCallback& callback,
+ const base::FilePath& cache_path,
+ scoped_ptr<ResourceEntry> entry,
+ FileError error);
+ void GetFileForSavingAfterWatch(const GetFileCallback& callback,
+ const base::FilePath& cache_path,
+ scoped_ptr<ResourceEntry> entry,
+ bool success);
+
+ scoped_ptr<CreateFileOperation> create_file_operation_;
+ scoped_ptr<DownloadOperation> download_operation_;
+ scoped_ptr<internal::FileWriteWatcher> file_write_watcher_;
+ internal::FileCache* cache_;
+
+ // Note: This should remain the last member so it'll be destroyed and
+ // invalidate the weak pointers before any other members are destroyed.
+ base::WeakPtrFactory<GetFileForSavingOperation> weak_ptr_factory_;
+ DISALLOW_COPY_AND_ASSIGN(GetFileForSavingOperation);
+};
+
+} // namespace file_system
+} // namespace drive
+
+#endif // CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_GET_FILE_FOR_SAVING_OPERATION_H_
diff --git a/chrome/browser/chromeos/drive/file_system/get_file_for_saving_operation_unittest.cc b/chrome/browser/chromeos/drive/file_system/get_file_for_saving_operation_unittest.cc
new file mode 100644
index 0000000..08918e6
--- /dev/null
+++ b/chrome/browser/chromeos/drive/file_system/get_file_for_saving_operation_unittest.cc
@@ -0,0 +1,158 @@
+// 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/get_file_for_saving_operation.h"
+
+#include "base/callback.h"
+#include "base/file_util.h"
+#include "base/files/file_path.h"
+#include "base/run_loop.h"
+#include "chrome/browser/chromeos/drive/drive.pb.h"
+#include "chrome/browser/chromeos/drive/file_errors.h"
+#include "chrome/browser/chromeos/drive/file_system/operation_test_base.h"
+#include "chrome/browser/chromeos/drive/file_write_watcher.h"
+#include "chrome/browser/google_apis/test_util.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace drive {
+namespace file_system {
+
+namespace {
+
+// If OnCacheFileUploadNeededByOperation is called, records the resource ID and
+// calls |quit_closure|.
+class TestObserver : public OperationObserver {
+ public:
+ void set_quit_closure(const base::Closure& quit_closure) {
+ quit_closure_ = quit_closure;
+ }
+
+ const std::string& observerd_resource_id() const {
+ return observed_resource_id_;
+ }
+
+ // OperationObserver overrides.
+ virtual void OnDirectoryChangedByOperation(
+ const base::FilePath& path) OVERRIDE {}
+
+ virtual void OnCacheFileUploadNeededByOperation(
+ const std::string& resource_id) OVERRIDE {
+ observed_resource_id_ = resource_id;
+ quit_closure_.Run();
+ }
+
+ private:
+ std::string observed_resource_id_;
+ base::Closure quit_closure_;
+};
+
+} // namespace
+
+class GetFileForSavingOperationTest : public OperationTestBase {
+ protected:
+ // FileWriteWatcher requires TYPE_IO message loop to run.
+ GetFileForSavingOperationTest()
+ : OperationTestBase(content::TestBrowserThreadBundle::IO_MAINLOOP) {
+ }
+
+ virtual void SetUp() OVERRIDE {
+ OperationTestBase::SetUp();
+
+ operation_.reset(new GetFileForSavingOperation(
+ blocking_task_runner(), &observer_, scheduler(), metadata(), cache(),
+ temp_dir()));
+ operation_->file_write_watcher_for_testing()->DisableDelayForTesting();
+ }
+
+ TestObserver observer_;
+ scoped_ptr<GetFileForSavingOperation> operation_;
+};
+
+TEST_F(GetFileForSavingOperationTest, GetFileForSaving_Exist) {
+ base::FilePath drive_path(FILE_PATH_LITERAL("drive/root/File 1.txt"));
+ ResourceEntry src_entry;
+ ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(drive_path, &src_entry));
+
+ // Run the operation.
+ FileError error = FILE_ERROR_FAILED;
+ scoped_ptr<ResourceEntry> entry;
+ base::FilePath local_path;
+ operation_->GetFileForSaving(
+ drive_path,
+ google_apis::test_util::CreateCopyResultCallback(
+ &error, &local_path, &entry));
+ test_util::RunBlockingPoolTask();
+
+ // Checks that the file is retrieved.
+ EXPECT_EQ(FILE_ERROR_OK, error);
+ ASSERT_TRUE(entry);
+ EXPECT_EQ(src_entry.resource_id(), entry->resource_id());
+
+ // Checks that it presents in cache and marked dirty.
+ bool success = false;
+ FileCacheEntry cache_entry;
+ cache()->GetCacheEntryOnUIThread(
+ src_entry.resource_id(),
+ google_apis::test_util::CreateCopyResultCallback(&success, &cache_entry));
+ test_util::RunBlockingPoolTask();
+ EXPECT_TRUE(success);
+ EXPECT_TRUE(cache_entry.is_present());
+ EXPECT_TRUE(cache_entry.is_dirty());
+
+ // Write something to the cache and checks that the event is reported.
+ {
+ base::RunLoop run_loop;
+ observer_.set_quit_closure(run_loop.QuitClosure());
+ google_apis::test_util::WriteStringToFile(local_path, "hello");
+ run_loop.Run();
+ EXPECT_EQ(entry->resource_id(), observer_.observerd_resource_id());
+ }
+}
+
+TEST_F(GetFileForSavingOperationTest, GetFileForSaving_NotExist) {
+ base::FilePath drive_path(FILE_PATH_LITERAL("drive/root/NotExist.txt"));
+ ResourceEntry src_entry;
+ ASSERT_EQ(FILE_ERROR_NOT_FOUND,
+ GetLocalResourceEntry(drive_path, &src_entry));
+
+ // Run the operation.
+ FileError error = FILE_ERROR_FAILED;
+ scoped_ptr<ResourceEntry> entry;
+ base::FilePath local_path;
+ operation_->GetFileForSaving(
+ drive_path,
+ google_apis::test_util::CreateCopyResultCallback(
+ &error, &local_path, &entry));
+ test_util::RunBlockingPoolTask();
+
+ // Checks that the file is created and retrieved.
+ EXPECT_EQ(FILE_ERROR_OK, error);
+ EXPECT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(drive_path, &src_entry));
+ int64 size = -1;
+ EXPECT_TRUE(file_util::GetFileSize(local_path, &size));
+ EXPECT_EQ(0, size);
+}
+
+TEST_F(GetFileForSavingOperationTest, GetFileForSaving_Directory) {
+ base::FilePath drive_path(FILE_PATH_LITERAL("drive/root/Directory 1"));
+ ResourceEntry src_entry;
+ ASSERT_EQ(FILE_ERROR_OK, GetLocalResourceEntry(drive_path, &src_entry));
+ ASSERT_TRUE(src_entry.file_info().is_directory());
+
+ // Run the operation.
+ FileError error = FILE_ERROR_FAILED;
+ scoped_ptr<ResourceEntry> entry;
+ base::FilePath local_path;
+ operation_->GetFileForSaving(
+ drive_path,
+ google_apis::test_util::CreateCopyResultCallback(
+ &error, &local_path, &entry));
+ test_util::RunBlockingPoolTask();
+
+ // Checks that an error is returned.
+ EXPECT_EQ(FILE_ERROR_EXISTS, error);
+}
+
+} // namespace file_system
+} // namespace drive
diff --git a/chrome/browser/chromeos/drive/file_system/operation_test_base.cc b/chrome/browser/chromeos/drive/file_system/operation_test_base.cc
index ad1fb09..324858d 100644
--- a/chrome/browser/chromeos/drive/file_system/operation_test_base.cc
+++ b/chrome/browser/chromeos/drive/file_system/operation_test_base.cc
@@ -39,6 +39,10 @@ void OperationTestBase::LoggingObserver::OnCacheFileUploadNeededByOperation(
OperationTestBase::OperationTestBase() {
}
+OperationTestBase::OperationTestBase(int test_thread_bundle_options)
+ : thread_bundle_(test_thread_bundle_options) {
+}
+
OperationTestBase::~OperationTestBase() {
}
diff --git a/chrome/browser/chromeos/drive/file_system/operation_test_base.h b/chrome/browser/chromeos/drive/file_system/operation_test_base.h
index b8b26cc..4056455 100644
--- a/chrome/browser/chromeos/drive/file_system/operation_test_base.h
+++ b/chrome/browser/chromeos/drive/file_system/operation_test_base.h
@@ -67,6 +67,7 @@ class OperationTestBase : public testing::Test {
};
OperationTestBase();
+ explicit OperationTestBase(int test_thread_bundle_options);
virtual ~OperationTestBase();
// testing::Test overrides.
diff --git a/chrome/browser/chromeos/drive/file_system_interface.h b/chrome/browser/chromeos/drive/file_system_interface.h
index 1c5865e..4df3c8f 100644
--- a/chrome/browser/chromeos/drive/file_system_interface.h
+++ b/chrome/browser/chromeos/drive/file_system_interface.h
@@ -318,15 +318,23 @@ class FileSystemInterface {
virtual void Unpin(const base::FilePath& file_path,
const FileOperationCallback& callback) = 0;
- // Gets |file_path| from the file system. The file entry represented by
- // |file_path| needs to be present in in-memory representation of the file
- // system in order to be retrieved. If the file is not cached, the file
- // will be downloaded through GData API or Drive V2 API.
+ // Makes sure that |file_path| in the file system is available in the local
+ // cache. If the file is not cached, the file will be downloaded. The entry
+ // needs to be present in the file system.
//
- // |callback| must not be null.
+ // Returns the cache path and entry info to |callback|. It must not be null.
virtual void GetFileByPath(const base::FilePath& file_path,
const GetFileCallback& callback) = 0;
+ // Makes sure that |file_path| in the file system is available in the local
+ // cache, and mark it as dirty. The next modification to the cache file is
+ // watched and is automatically uploaded to the server. If the entry is not
+ // present in the file system, it is created.
+ //
+ // Returns the cache path and entry info to |callback|. It must not be null.
+ virtual void GetFileByPathForSaving(const base::FilePath& file_path,
+ const GetFileCallback& callback) = 0;
+
// Gets a file by the given |file_path|.
// Calls |initialized_callback| when either:
// 1) The cached file (or JSON file for hosted file) is found, or
diff --git a/chrome/browser/chromeos/drive/file_write_watcher.h b/chrome/browser/chromeos/drive/file_write_watcher.h
index 91c947d..13523df 100644
--- a/chrome/browser/chromeos/drive/file_write_watcher.h
+++ b/chrome/browser/chromeos/drive/file_write_watcher.h
@@ -46,7 +46,7 @@ class FileWriteWatcher {
// 5 seconds has passed after the last write operation is detected.
//
// TODO(kinaba): investigate the possibility to continuously watch the whole
- // cache directory.
+ // cache directory. http://crbug.com/269424
void StartWatch(const base::FilePath& path,
const std::string& resource_id,
const StartWatchCallback& callback);