Add LocalFileSyncContext class which is a glue class between profile-owned service and FileSystemContext(s)
BUG=154234 TEST=LocalFileSyncContextTest.* TBR=jam@chromium.org Review URL: https://codereview.chromium.org/11090019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@161556 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
@ -433,6 +433,7 @@
|
||||
'../webkit/fileapi/syncable/canned_syncable_file_system.h',
|
||||
'../webkit/fileapi/syncable/file_change_unittest.cc',
|
||||
'../webkit/fileapi/syncable/local_file_change_tracker_unittest.cc',
|
||||
'../webkit/fileapi/syncable/local_file_sync_context_unittest.cc',
|
||||
'../webkit/fileapi/syncable/local_file_sync_status_unittest.cc',
|
||||
'../webkit/fileapi/syncable/syncable_file_system_unittest.cc',
|
||||
'../webkit/fileapi/syncable/syncable_file_system_util_unittest.cc',
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "webkit/fileapi/isolated_mount_point_provider.h"
|
||||
#include "webkit/fileapi/sandbox_mount_point_provider.h"
|
||||
#include "webkit/fileapi/syncable/local_file_change_tracker.h"
|
||||
#include "webkit/fileapi/syncable/local_file_sync_context.h"
|
||||
#include "webkit/fileapi/syncable/syncable_file_system_util.h"
|
||||
#include "webkit/fileapi/test_mount_point_provider.h"
|
||||
#include "webkit/quota/quota_manager.h"
|
||||
@ -289,6 +290,11 @@ void FileSystemContext::SetLocalFileChangeTracker(
|
||||
task_runners_->file_task_runner());
|
||||
}
|
||||
|
||||
void FileSystemContext::set_sync_context(
|
||||
LocalFileSyncContext* sync_context) {
|
||||
sync_context_ = sync_context;
|
||||
}
|
||||
|
||||
FileSystemContext::~FileSystemContext() {}
|
||||
|
||||
void FileSystemContext::DeleteOnCorrectThread() const {
|
||||
|
@ -41,6 +41,7 @@ class FileSystemURL;
|
||||
class IsolatedMountPointProvider;
|
||||
class LocalFileChangeTracker;
|
||||
class SandboxMountPointProvider;
|
||||
class LocalFileSyncContext;
|
||||
|
||||
struct DefaultContextDeleter;
|
||||
|
||||
@ -165,6 +166,9 @@ class FILEAPI_EXPORT FileSystemContext
|
||||
LocalFileChangeTracker* change_tracker() { return change_tracker_.get(); }
|
||||
void SetLocalFileChangeTracker(scoped_ptr<LocalFileChangeTracker> tracker);
|
||||
|
||||
LocalFileSyncContext* sync_context() { return sync_context_.get(); }
|
||||
void set_sync_context(LocalFileSyncContext* sync_context);
|
||||
|
||||
const FilePath& partition_path() const { return partition_path_; }
|
||||
|
||||
private:
|
||||
@ -193,6 +197,7 @@ class FILEAPI_EXPORT FileSystemContext
|
||||
|
||||
// For syncable file systems.
|
||||
scoped_ptr<LocalFileChangeTracker> change_tracker_;
|
||||
scoped_refptr<LocalFileSyncContext> sync_context_;
|
||||
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(FileSystemContext);
|
||||
};
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include "webkit/fileapi/isolated_context.h"
|
||||
#include "webkit/fileapi/local_file_system_operation.h"
|
||||
#include "webkit/fileapi/mock_file_system_options.h"
|
||||
#include "webkit/fileapi/syncable/local_file_sync_context.h"
|
||||
#include "webkit/quota/mock_special_storage_policy.h"
|
||||
#include "webkit/quota/quota_manager.h"
|
||||
|
||||
@ -29,12 +30,15 @@ CannedSyncableFileSystem::CannedSyncableFileSystem(
|
||||
test_helper_(origin, kFileSystemTypeSyncable),
|
||||
result_(base::PLATFORM_FILE_OK),
|
||||
sync_status_(SYNC_STATUS_OK),
|
||||
is_filesystem_set_up_(false),
|
||||
is_filesystem_opened_(false),
|
||||
weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
|
||||
}
|
||||
|
||||
CannedSyncableFileSystem::~CannedSyncableFileSystem() {}
|
||||
|
||||
void CannedSyncableFileSystem::SetUp() {
|
||||
ASSERT_FALSE(is_filesystem_set_up_);
|
||||
ASSERT_TRUE(data_dir_.CreateUniqueTempDir());
|
||||
|
||||
scoped_refptr<quota::SpecialStoragePolicy> storage_policy =
|
||||
@ -55,6 +59,7 @@ void CannedSyncableFileSystem::SetUp() {
|
||||
CreateAllowFileAccessOptions());
|
||||
|
||||
test_helper_.SetUp(file_system_context_.get(), NULL);
|
||||
is_filesystem_set_up_ = true;
|
||||
}
|
||||
|
||||
void CannedSyncableFileSystem::TearDown() {
|
||||
@ -63,10 +68,14 @@ void CannedSyncableFileSystem::TearDown() {
|
||||
}
|
||||
|
||||
FileSystemURL CannedSyncableFileSystem::URL(const std::string& path) const {
|
||||
EXPECT_TRUE(is_filesystem_set_up_);
|
||||
EXPECT_TRUE(is_filesystem_opened_);
|
||||
return FileSystemURL(GURL(root_url_.spec() + path));
|
||||
}
|
||||
|
||||
PlatformFileError CannedSyncableFileSystem::OpenFileSystem() {
|
||||
EXPECT_TRUE(is_filesystem_set_up_);
|
||||
EXPECT_FALSE(is_filesystem_opened_);
|
||||
file_system_context_->OpenSyncableFileSystem(
|
||||
service_name_,
|
||||
test_helper_.origin(), test_helper_.type(),
|
||||
@ -77,8 +86,22 @@ PlatformFileError CannedSyncableFileSystem::OpenFileSystem() {
|
||||
return result_;
|
||||
}
|
||||
|
||||
SyncStatusCode CannedSyncableFileSystem::MaybeInitializeFileSystemContext(
|
||||
LocalFileSyncContext* sync_context) {
|
||||
DCHECK(sync_context);
|
||||
sync_status_ = SYNC_STATUS_UNKNOWN;
|
||||
sync_context->MaybeInitializeFileSystemContext(
|
||||
test_helper_.origin(),
|
||||
file_system_context_,
|
||||
base::Bind(&CannedSyncableFileSystem::DidInitializeFileSystemContext,
|
||||
base::Unretained(this)));
|
||||
MessageLoop::current()->Run();
|
||||
return sync_status_;
|
||||
}
|
||||
|
||||
PlatformFileError CannedSyncableFileSystem::CreateDirectory(
|
||||
const FileSystemURL& url) {
|
||||
EXPECT_TRUE(is_filesystem_opened_);
|
||||
result_ = base::PLATFORM_FILE_ERROR_FAILED;
|
||||
test_helper_.NewOperation()->CreateDirectory(
|
||||
url, false /* exclusive */, false /* recursive */,
|
||||
@ -90,6 +113,7 @@ PlatformFileError CannedSyncableFileSystem::CreateDirectory(
|
||||
|
||||
PlatformFileError CannedSyncableFileSystem::CreateFile(
|
||||
const FileSystemURL& url) {
|
||||
EXPECT_TRUE(is_filesystem_opened_);
|
||||
result_ = base::PLATFORM_FILE_ERROR_FAILED;
|
||||
test_helper_.NewOperation()->CreateFile(
|
||||
url, false /* exclusive */,
|
||||
@ -123,6 +147,7 @@ PlatformFileError CannedSyncableFileSystem::Move(
|
||||
|
||||
PlatformFileError CannedSyncableFileSystem::TruncateFile(
|
||||
const FileSystemURL& url, int64 size) {
|
||||
EXPECT_TRUE(is_filesystem_opened_);
|
||||
result_ = base::PLATFORM_FILE_ERROR_FAILED;
|
||||
test_helper_.NewOperation()->Truncate(
|
||||
url, size,
|
||||
@ -134,6 +159,7 @@ PlatformFileError CannedSyncableFileSystem::TruncateFile(
|
||||
|
||||
PlatformFileError CannedSyncableFileSystem::Remove(
|
||||
const FileSystemURL& url, bool recursive) {
|
||||
EXPECT_TRUE(is_filesystem_opened_);
|
||||
result_ = base::PLATFORM_FILE_ERROR_FAILED;
|
||||
test_helper_.NewOperation()->Remove(
|
||||
url, recursive,
|
||||
@ -144,6 +170,7 @@ PlatformFileError CannedSyncableFileSystem::Remove(
|
||||
}
|
||||
|
||||
PlatformFileError CannedSyncableFileSystem::DeleteFileSystem() {
|
||||
EXPECT_TRUE(is_filesystem_set_up_);
|
||||
file_system_context_->DeleteFileSystem(
|
||||
test_helper_.origin(), test_helper_.type(),
|
||||
base::Bind(&CannedSyncableFileSystem::StatusCallback,
|
||||
@ -156,6 +183,13 @@ void CannedSyncableFileSystem::DidOpenFileSystem(
|
||||
PlatformFileError result, const std::string& name, const GURL& root) {
|
||||
result_ = result;
|
||||
root_url_ = root;
|
||||
is_filesystem_opened_ = true;
|
||||
}
|
||||
|
||||
void CannedSyncableFileSystem::DidInitializeFileSystemContext(
|
||||
SyncStatusCode status) {
|
||||
sync_status_ = status;
|
||||
MessageLoop::current()->Quit();
|
||||
}
|
||||
|
||||
void CannedSyncableFileSystem::StatusCallback(PlatformFileError result) {
|
||||
|
@ -27,6 +27,7 @@ class QuotaManager;
|
||||
namespace fileapi {
|
||||
|
||||
class FileSystemContext;
|
||||
class LocalFileSyncContext;
|
||||
|
||||
// A canned syncable filesystem for testing.
|
||||
// This internally creates its own QuotaManager and FileSystemContext
|
||||
@ -45,6 +46,11 @@ class CannedSyncableFileSystem {
|
||||
// Creates a FileSystemURL for the given (utf8) path string.
|
||||
FileSystemURL URL(const std::string& path) const;
|
||||
|
||||
// Initialize this with given |sync_context| if it hasn't
|
||||
// been initialized.
|
||||
SyncStatusCode MaybeInitializeFileSystemContext(
|
||||
LocalFileSyncContext* sync_context);
|
||||
|
||||
// Opens a new syncable file system.
|
||||
base::PlatformFileError OpenFileSystem();
|
||||
|
||||
@ -60,6 +66,7 @@ class CannedSyncableFileSystem {
|
||||
}
|
||||
|
||||
// Helper routines to perform file system operations.
|
||||
// OpenFileSystem() must have been called before calling any of them.
|
||||
// (They run on the current thread and returns synchronously).
|
||||
base::PlatformFileError CreateDirectory(const FileSystemURL& url);
|
||||
base::PlatformFileError CreateFile(const FileSystemURL& url);
|
||||
@ -78,6 +85,7 @@ class CannedSyncableFileSystem {
|
||||
void DidOpenFileSystem(base::PlatformFileError result,
|
||||
const std::string& name,
|
||||
const GURL& root);
|
||||
void DidInitializeFileSystemContext(SyncStatusCode status);
|
||||
void StatusCallback(base::PlatformFileError result);
|
||||
|
||||
FileSystemOperationContext* NewOperationContext();
|
||||
@ -92,6 +100,10 @@ class CannedSyncableFileSystem {
|
||||
base::PlatformFileError result_;
|
||||
SyncStatusCode sync_status_;
|
||||
|
||||
// Boolean flags mainly for helping debug.
|
||||
bool is_filesystem_set_up_;
|
||||
bool is_filesystem_opened_;
|
||||
|
||||
base::WeakPtrFactory<CannedSyncableFileSystem> weak_factory_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(CannedSyncableFileSystem);
|
||||
|
157
webkit/fileapi/syncable/local_file_sync_context.cc
Normal file
157
webkit/fileapi/syncable/local_file_sync_context.cc
Normal file
@ -0,0 +1,157 @@
|
||||
// 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 "webkit/fileapi/syncable/local_file_sync_context.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/callback.h"
|
||||
#include "base/location.h"
|
||||
#include "base/single_thread_task_runner.h"
|
||||
#include "base/stl_util.h"
|
||||
#include "base/task_runner_util.h"
|
||||
#include "webkit/fileapi/file_system_context.h"
|
||||
#include "webkit/fileapi/file_system_task_runners.h"
|
||||
#include "webkit/fileapi/syncable/local_file_change_tracker.h"
|
||||
|
||||
namespace fileapi {
|
||||
|
||||
LocalFileSyncContext::LocalFileSyncContext(
|
||||
base::SingleThreadTaskRunner* ui_task_runner,
|
||||
base::SingleThreadTaskRunner* io_task_runner)
|
||||
: ui_task_runner_(ui_task_runner),
|
||||
io_task_runner_(io_task_runner),
|
||||
shutdown_(false) {
|
||||
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
||||
}
|
||||
|
||||
void LocalFileSyncContext::MaybeInitializeFileSystemContext(
|
||||
const GURL& source_url,
|
||||
FileSystemContext* file_system_context,
|
||||
const StatusCallback& callback) {
|
||||
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
||||
if (ContainsKey(file_system_contexts_, file_system_context)) {
|
||||
DCHECK(!ContainsKey(origin_to_contexts_, source_url) ||
|
||||
origin_to_contexts_[source_url] == file_system_context);
|
||||
origin_to_contexts_[source_url] = file_system_context;
|
||||
// The context has been already initialized. Just dispatch the callback
|
||||
// with SYNC_STATUS_OK.
|
||||
ui_task_runner_->PostTask(FROM_HERE, base::Bind(callback, SYNC_STATUS_OK));
|
||||
return;
|
||||
}
|
||||
|
||||
StatusCallbackQueue& callback_queue =
|
||||
pending_initialize_callbacks_[file_system_context];
|
||||
callback_queue.push_back(callback);
|
||||
if (callback_queue.size() > 1)
|
||||
return;
|
||||
|
||||
io_task_runner_->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&LocalFileSyncContext::InitializeFileSystemContextOnIOThread,
|
||||
this, source_url, make_scoped_refptr(file_system_context)));
|
||||
}
|
||||
|
||||
void LocalFileSyncContext::ShutdownOnUIThread() {
|
||||
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
||||
shutdown_ = true;
|
||||
io_task_runner_->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&LocalFileSyncContext::ShutdownOnIOThread,
|
||||
this));
|
||||
}
|
||||
|
||||
LocalFileSyncContext::~LocalFileSyncContext() {
|
||||
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
||||
DCHECK(shutdown_);
|
||||
}
|
||||
|
||||
void LocalFileSyncContext::ShutdownOnIOThread() {
|
||||
DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
|
||||
}
|
||||
|
||||
void LocalFileSyncContext::InitializeFileSystemContextOnIOThread(
|
||||
const GURL& source_url,
|
||||
FileSystemContext* file_system_context) {
|
||||
DCHECK(io_task_runner_->RunsTasksOnCurrentThread());
|
||||
DCHECK(file_system_context);
|
||||
if (!file_system_context->change_tracker()) {
|
||||
// Create and initialize LocalFileChangeTracker and call back this method
|
||||
// later again.
|
||||
scoped_ptr<LocalFileChangeTracker>* tracker_ptr(
|
||||
new scoped_ptr<LocalFileChangeTracker>);
|
||||
base::PostTaskAndReplyWithResult(
|
||||
file_system_context->task_runners()->file_task_runner(),
|
||||
FROM_HERE,
|
||||
base::Bind(&LocalFileSyncContext::InitializeChangeTrackerOnFileThread,
|
||||
this, tracker_ptr,
|
||||
make_scoped_refptr(file_system_context)),
|
||||
base::Bind(&LocalFileSyncContext::DidInitializeChangeTracker, this,
|
||||
base::Owned(tracker_ptr),
|
||||
source_url,
|
||||
make_scoped_refptr(file_system_context)));
|
||||
return;
|
||||
}
|
||||
file_system_context->set_sync_context(this);
|
||||
DidInitialize(source_url, file_system_context, SYNC_STATUS_OK);
|
||||
}
|
||||
|
||||
SyncStatusCode LocalFileSyncContext::InitializeChangeTrackerOnFileThread(
|
||||
scoped_ptr<LocalFileChangeTracker>* tracker_ptr,
|
||||
FileSystemContext* file_system_context) {
|
||||
DCHECK(file_system_context);
|
||||
DCHECK(tracker_ptr);
|
||||
tracker_ptr->reset(new LocalFileChangeTracker(
|
||||
file_system_context->partition_path(),
|
||||
file_system_context->task_runners()->file_task_runner()));
|
||||
// TODO(kinuko,nhiroki): Uncomment this once http://crbug.com/154028 is fixed.
|
||||
// return change_tracker->Initialize(file_system_context);
|
||||
return SYNC_STATUS_OK;
|
||||
}
|
||||
|
||||
void LocalFileSyncContext::DidInitializeChangeTracker(
|
||||
scoped_ptr<LocalFileChangeTracker>* tracker_ptr,
|
||||
const GURL& source_url,
|
||||
FileSystemContext* file_system_context,
|
||||
SyncStatusCode status) {
|
||||
DCHECK(file_system_context);
|
||||
if (status != SYNC_STATUS_OK) {
|
||||
DidInitialize(source_url, file_system_context, status);
|
||||
return;
|
||||
}
|
||||
file_system_context->SetLocalFileChangeTracker(tracker_ptr->Pass());
|
||||
InitializeFileSystemContextOnIOThread(source_url, file_system_context);
|
||||
}
|
||||
|
||||
void LocalFileSyncContext::DidInitialize(
|
||||
const GURL& source_url,
|
||||
FileSystemContext* file_system_context,
|
||||
SyncStatusCode status) {
|
||||
if (!ui_task_runner_->RunsTasksOnCurrentThread()) {
|
||||
ui_task_runner_->PostTask(
|
||||
FROM_HERE,
|
||||
base::Bind(&LocalFileSyncContext::DidInitialize,
|
||||
this, source_url,
|
||||
make_scoped_refptr(file_system_context), status));
|
||||
return;
|
||||
}
|
||||
DCHECK(ui_task_runner_->RunsTasksOnCurrentThread());
|
||||
DCHECK(!ContainsKey(file_system_contexts_, file_system_context));
|
||||
DCHECK(ContainsKey(pending_initialize_callbacks_, file_system_context));
|
||||
DCHECK(file_system_context->change_tracker());
|
||||
|
||||
file_system_contexts_.insert(file_system_context);
|
||||
|
||||
DCHECK(!ContainsKey(origin_to_contexts_, source_url));
|
||||
origin_to_contexts_[source_url] = file_system_context;
|
||||
|
||||
StatusCallbackQueue& callback_queue =
|
||||
pending_initialize_callbacks_[file_system_context];
|
||||
for (StatusCallbackQueue::iterator iter = callback_queue.begin();
|
||||
iter != callback_queue.end(); ++iter) {
|
||||
ui_task_runner_->PostTask(FROM_HERE, base::Bind(*iter, status));
|
||||
}
|
||||
pending_initialize_callbacks_.erase(file_system_context);
|
||||
}
|
||||
|
||||
} // namespace fileapi
|
105
webkit/fileapi/syncable/local_file_sync_context.h
Normal file
105
webkit/fileapi/syncable/local_file_sync_context.h
Normal file
@ -0,0 +1,105 @@
|
||||
// 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.
|
||||
|
||||
#ifndef WEBKIT_FILEAPI_SYNCABLE_LOCAL_FILE_SYNC_CONTEXT_H_
|
||||
#define WEBKIT_FILEAPI_SYNCABLE_LOCAL_FILE_SYNC_CONTEXT_H_
|
||||
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
#include "base/basictypes.h"
|
||||
#include "base/callback_forward.h"
|
||||
#include "base/file_path.h"
|
||||
#include "base/logging.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/memory/scoped_ptr.h"
|
||||
#include "googleurl/src/gurl.h"
|
||||
#include "webkit/fileapi/fileapi_export.h"
|
||||
#include "webkit/fileapi/syncable/file_change.h"
|
||||
#include "webkit/fileapi/syncable/sync_status_code.h"
|
||||
|
||||
namespace base {
|
||||
class SingleThreadTaskRunner;
|
||||
}
|
||||
|
||||
namespace fileapi {
|
||||
|
||||
class FileSystemContext;
|
||||
class LocalFileChangeTracker;
|
||||
|
||||
// This class works as a bridge between LocalFileSyncService (which is a
|
||||
// per-profile object) and FileSystemContext's (which is a per-storage-partition
|
||||
// object and may exist multiple in a profile).
|
||||
// An instance of this class is shared by FileSystemContexts and outlives
|
||||
// LocalFileSyncService.
|
||||
class FILEAPI_EXPORT LocalFileSyncContext
|
||||
: public base::RefCountedThreadSafe<LocalFileSyncContext> {
|
||||
public:
|
||||
typedef base::Callback<void(SyncStatusCode status)> StatusCallback;
|
||||
|
||||
LocalFileSyncContext(base::SingleThreadTaskRunner* ui_task_runner,
|
||||
base::SingleThreadTaskRunner* io_task_runner);
|
||||
|
||||
// Initializes |file_system_context| for syncable file operations and
|
||||
// registers the it into the internal map.
|
||||
// Calling this multiple times for the same file_system_context is valid.
|
||||
// This method must be called on UI thread.
|
||||
void MaybeInitializeFileSystemContext(const GURL& source_url,
|
||||
FileSystemContext* file_system_context,
|
||||
const StatusCallback& callback);
|
||||
|
||||
// Called when the corresponding LocalFileSyncService exits.
|
||||
// This method must be called on UI thread.
|
||||
void ShutdownOnUIThread();
|
||||
|
||||
private:
|
||||
typedef std::deque<StatusCallback> StatusCallbackQueue;
|
||||
friend class base::RefCountedThreadSafe<LocalFileSyncContext>;
|
||||
|
||||
~LocalFileSyncContext();
|
||||
|
||||
void ShutdownOnIOThread();
|
||||
|
||||
// Helper routines for MaybeInitializeFileSystemContext.
|
||||
void InitializeFileSystemContextOnIOThread(
|
||||
const GURL& source_url,
|
||||
FileSystemContext* file_system_context);
|
||||
SyncStatusCode InitializeChangeTrackerOnFileThread(
|
||||
scoped_ptr<LocalFileChangeTracker>* tracker_ptr,
|
||||
FileSystemContext* file_system_context);
|
||||
void DidInitializeChangeTracker(
|
||||
scoped_ptr<LocalFileChangeTracker>* tracker_ptr,
|
||||
const GURL& source_url,
|
||||
FileSystemContext* file_system_context,
|
||||
SyncStatusCode status);
|
||||
void DidInitialize(
|
||||
const GURL& source_url,
|
||||
FileSystemContext* file_system_context,
|
||||
SyncStatusCode status);
|
||||
|
||||
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
|
||||
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
|
||||
|
||||
// This must be accessed only on UI thread.
|
||||
bool shutdown_;
|
||||
|
||||
// Pointers to file system contexts that have been initialized for
|
||||
// synchronization (i.e. that own this instance).
|
||||
// This must be accessed only on UI thread.
|
||||
std::set<FileSystemContext*> file_system_contexts_;
|
||||
|
||||
std::map<FileSystemContext*, StatusCallbackQueue>
|
||||
pending_initialize_callbacks_;
|
||||
|
||||
// Origin to context map. (Assuming that as far as we're in the same
|
||||
// profile single origin wouldn't belong to multiple FileSystemContexts.)
|
||||
std::map<GURL, FileSystemContext*> origin_to_contexts_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(LocalFileSyncContext);
|
||||
};
|
||||
|
||||
} // namespace fileapi
|
||||
|
||||
#endif // WEBKIT_FILEAPI_SYNCABLE_LOCAL_FILE_SYNC_CONTEXT_H_
|
168
webkit/fileapi/syncable/local_file_sync_context_unittest.cc
Normal file
168
webkit/fileapi/syncable/local_file_sync_context_unittest.cc
Normal file
@ -0,0 +1,168 @@
|
||||
// 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 "webkit/fileapi/syncable/local_file_sync_context.h"
|
||||
|
||||
#include "base/bind.h"
|
||||
#include "base/file_path.h"
|
||||
#include "base/message_loop.h"
|
||||
#include "base/single_thread_task_runner.h"
|
||||
#include "base/threading/thread.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "webkit/fileapi/file_system_context.h"
|
||||
#include "webkit/fileapi/isolated_context.h"
|
||||
#include "webkit/fileapi/syncable/canned_syncable_file_system.h"
|
||||
#include "webkit/fileapi/syncable/local_file_change_tracker.h"
|
||||
#include "webkit/fileapi/syncable/sync_status_code.h"
|
||||
#include "webkit/fileapi/syncable/syncable_file_system_util.h"
|
||||
|
||||
namespace fileapi {
|
||||
|
||||
namespace {
|
||||
const char kOrigin1[] = "http://example.com";
|
||||
const char kOrigin2[] = "http://chromium.org";
|
||||
const char kServiceName[] = "test";
|
||||
const FileSystemType kSyncableType = kFileSystemTypeSyncable;
|
||||
}
|
||||
|
||||
class LocalFileSyncContextTest : public testing::Test {
|
||||
protected:
|
||||
LocalFileSyncContextTest()
|
||||
: status_(SYNC_FILE_ERROR_FAILED) {}
|
||||
|
||||
virtual void SetUp() OVERRIDE {
|
||||
EXPECT_TRUE(fileapi::RegisterSyncableFileSystem(kServiceName));
|
||||
|
||||
io_thread_.reset(new base::Thread("Thread_IO"));
|
||||
file_thread_.reset(new base::Thread("Thread_File"));
|
||||
io_thread_->Start();
|
||||
file_thread_->Start();
|
||||
|
||||
ui_task_runner_ = MessageLoop::current()->message_loop_proxy();
|
||||
io_task_runner_ = io_thread_->message_loop_proxy();
|
||||
file_task_runner_ = file_thread_->message_loop_proxy();
|
||||
}
|
||||
|
||||
virtual void TearDown() OVERRIDE {
|
||||
EXPECT_TRUE(fileapi::RevokeSyncableFileSystem(kServiceName));
|
||||
io_thread_->Stop();
|
||||
file_thread_->Stop();
|
||||
}
|
||||
|
||||
// These need to remain until the very end.
|
||||
scoped_ptr<base::Thread> io_thread_;
|
||||
scoped_ptr<base::Thread> file_thread_;
|
||||
MessageLoop loop_;
|
||||
|
||||
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner_;
|
||||
scoped_refptr<base::SingleThreadTaskRunner> file_task_runner_;
|
||||
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
|
||||
|
||||
scoped_refptr<LocalFileSyncContext> sync_context_;
|
||||
|
||||
SyncStatusCode status_;
|
||||
};
|
||||
|
||||
TEST_F(LocalFileSyncContextTest, ConstructAndDestruct) {
|
||||
sync_context_ = new LocalFileSyncContext(
|
||||
ui_task_runner_, io_task_runner_);
|
||||
sync_context_->ShutdownOnUIThread();
|
||||
}
|
||||
|
||||
TEST_F(LocalFileSyncContextTest, InitializeFileSystemContext) {
|
||||
CannedSyncableFileSystem file_system(GURL(kOrigin1), kServiceName);
|
||||
file_system.SetUp();
|
||||
|
||||
sync_context_ = new LocalFileSyncContext(ui_task_runner_, io_task_runner_);
|
||||
|
||||
// Initializes file_system using |sync_context_|.
|
||||
EXPECT_EQ(SYNC_STATUS_OK,
|
||||
file_system.MaybeInitializeFileSystemContext(sync_context_));
|
||||
|
||||
// Make sure everything's set up for file_system to be able to handle
|
||||
// syncable file system operations.
|
||||
EXPECT_TRUE(file_system.file_system_context()->sync_context() != NULL);
|
||||
EXPECT_TRUE(file_system.file_system_context()->change_tracker() != NULL);
|
||||
EXPECT_EQ(sync_context_.get(),
|
||||
file_system.file_system_context()->sync_context());
|
||||
|
||||
// Calling MaybeInitialize for the same context multiple times must be ok.
|
||||
EXPECT_EQ(SYNC_STATUS_OK,
|
||||
file_system.MaybeInitializeFileSystemContext(sync_context_));
|
||||
EXPECT_EQ(sync_context_.get(),
|
||||
file_system.file_system_context()->sync_context());
|
||||
|
||||
// Opens the file_system, perform some operation and see if the change tracker
|
||||
// correctly captures the change.
|
||||
EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.OpenFileSystem());
|
||||
|
||||
const FileSystemURL kURL(file_system.URL("foo"));
|
||||
EXPECT_EQ(base::PLATFORM_FILE_OK, file_system.CreateFile(kURL));
|
||||
|
||||
std::vector<FileSystemURL> urls;
|
||||
file_system.file_system_context()->change_tracker()->GetChangedURLs(&urls);
|
||||
ASSERT_EQ(1U, urls.size());
|
||||
EXPECT_EQ(kURL, urls[0]);
|
||||
|
||||
// Finishing the test.
|
||||
sync_context_->ShutdownOnUIThread();
|
||||
file_system.TearDown();
|
||||
}
|
||||
|
||||
TEST_F(LocalFileSyncContextTest, MultipleFileSystemContexts) {
|
||||
CannedSyncableFileSystem file_system1(GURL(kOrigin1), kServiceName);
|
||||
CannedSyncableFileSystem file_system2(GURL(kOrigin2), kServiceName);
|
||||
file_system1.SetUp();
|
||||
file_system2.SetUp();
|
||||
|
||||
sync_context_ = new LocalFileSyncContext(ui_task_runner_, io_task_runner_);
|
||||
|
||||
// Initializes file_system1 and file_system2.
|
||||
EXPECT_EQ(SYNC_STATUS_OK,
|
||||
file_system1.MaybeInitializeFileSystemContext(sync_context_));
|
||||
EXPECT_EQ(SYNC_STATUS_OK,
|
||||
file_system2.MaybeInitializeFileSystemContext(sync_context_));
|
||||
|
||||
EXPECT_EQ(base::PLATFORM_FILE_OK, file_system1.OpenFileSystem());
|
||||
EXPECT_EQ(base::PLATFORM_FILE_OK, file_system2.OpenFileSystem());
|
||||
|
||||
const FileSystemURL kURL1(file_system1.URL("foo"));
|
||||
const FileSystemURL kURL2(file_system2.URL("bar"));
|
||||
|
||||
// Creates a file in file_system1.
|
||||
EXPECT_EQ(base::PLATFORM_FILE_OK, file_system1.CreateFile(kURL1));
|
||||
|
||||
// file_system1's tracker must have recorded the change.
|
||||
std::vector<FileSystemURL> urls;
|
||||
file_system1.file_system_context()->change_tracker()->GetChangedURLs(&urls);
|
||||
ASSERT_EQ(1U, urls.size());
|
||||
EXPECT_EQ(kURL1, urls[0]);
|
||||
|
||||
// file_system1's tracker must have no change.
|
||||
urls.clear();
|
||||
file_system2.file_system_context()->change_tracker()->GetChangedURLs(&urls);
|
||||
ASSERT_TRUE(urls.empty());
|
||||
|
||||
// Creates a directory in file_system2.
|
||||
EXPECT_EQ(base::PLATFORM_FILE_OK, file_system2.CreateDirectory(kURL2));
|
||||
|
||||
// file_system1's tracker must have the change for kURL1 as before.
|
||||
urls.clear();
|
||||
file_system1.file_system_context()->change_tracker()->GetChangedURLs(&urls);
|
||||
ASSERT_EQ(1U, urls.size());
|
||||
EXPECT_EQ(kURL1, urls[0]);
|
||||
|
||||
// file_system2's tracker now must have the change for kURL2.
|
||||
urls.clear();
|
||||
file_system2.file_system_context()->change_tracker()->GetChangedURLs(&urls);
|
||||
ASSERT_EQ(1U, urls.size());
|
||||
EXPECT_EQ(kURL2, urls[0]);
|
||||
|
||||
sync_context_->ShutdownOnUIThread();
|
||||
|
||||
file_system1.TearDown();
|
||||
file_system2.TearDown();
|
||||
}
|
||||
|
||||
} // namespace fileapi
|
@ -96,6 +96,8 @@
|
||||
'syncable/file_change.h',
|
||||
'syncable/local_file_change_tracker.cc',
|
||||
'syncable/local_file_change_tracker.h',
|
||||
'syncable/local_file_sync_context.cc',
|
||||
'syncable/local_file_sync_context.h',
|
||||
'syncable/local_file_sync_status.cc',
|
||||
'syncable/local_file_sync_status.h',
|
||||
'syncable/sync_status_code.cc',
|
||||
|
Reference in New Issue
Block a user