blob: 82c4781e537444663acedc54c40239a3f9adf397 [file] [log] [blame]
// 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 "content/public/test/test_file_system_backend.h"
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "base/files/file.h"
#include "base/files/file_util.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/observer_list.h"
#include "base/sequenced_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "storage/browser/fileapi/copy_or_move_file_validator.h"
#include "storage/browser/fileapi/file_observers.h"
#include "storage/browser/fileapi/file_stream_reader.h"
#include "storage/browser/fileapi/file_system_operation.h"
#include "storage/browser/fileapi/file_system_operation_context.h"
#include "storage/browser/fileapi/file_system_quota_util.h"
#include "storage/browser/fileapi/local_file_util.h"
#include "storage/browser/fileapi/native_file_util.h"
#include "storage/browser/fileapi/quota/quota_reservation.h"
#include "storage/browser/fileapi/sandbox_file_stream_writer.h"
#include "storage/browser/quota/quota_manager.h"
#include "storage/common/fileapi/file_system_util.h"
using storage::FileSystemContext;
using storage::FileSystemOperation;
using storage::FileSystemOperationContext;
using storage::FileSystemURL;
namespace content {
namespace {
// Stub implementation of storage::LocalFileUtil.
class TestFileUtil : public storage::LocalFileUtil {
public:
explicit TestFileUtil(const base::FilePath& base_path)
: base_path_(base_path) {}
~TestFileUtil() override {}
// LocalFileUtil overrides.
base::File::Error GetLocalFilePath(FileSystemOperationContext* context,
const FileSystemURL& file_system_url,
base::FilePath* local_file_path) override {
*local_file_path = base_path_.Append(file_system_url.path());
return base::File::FILE_OK;
}
private:
base::FilePath base_path_;
};
} // namespace
// This only supports single origin.
class TestFileSystemBackend::QuotaUtil : public storage::FileSystemQuotaUtil,
public storage::FileUpdateObserver {
public:
QuotaUtil() : usage_(0) {}
~QuotaUtil() override {}
// FileSystemQuotaUtil overrides.
base::File::Error DeleteOriginDataOnFileTaskRunner(
FileSystemContext* context,
storage::QuotaManagerProxy* proxy,
const GURL& origin_url,
storage::FileSystemType type) override {
NOTREACHED();
return base::File::FILE_OK;
}
scoped_refptr<storage::QuotaReservation>
CreateQuotaReservationOnFileTaskRunner(
const GURL& origin_url,
storage::FileSystemType type) override {
NOTREACHED();
return scoped_refptr<storage::QuotaReservation>();
}
void GetOriginsForTypeOnFileTaskRunner(storage::FileSystemType type,
std::set<GURL>* origins) override {
NOTREACHED();
}
void GetOriginsForHostOnFileTaskRunner(storage::FileSystemType type,
const std::string& host,
std::set<GURL>* origins) override {
NOTREACHED();
}
int64_t GetOriginUsageOnFileTaskRunner(
FileSystemContext* context,
const GURL& origin_url,
storage::FileSystemType type) override {
return usage_;
}
// FileUpdateObserver overrides.
void OnStartUpdate(const FileSystemURL& url) override {}
void OnUpdate(const FileSystemURL& url, int64_t delta) override {
usage_ += delta;
}
void OnEndUpdate(const FileSystemURL& url) override {}
private:
int64_t usage_;
DISALLOW_COPY_AND_ASSIGN(QuotaUtil);
};
TestFileSystemBackend::TestFileSystemBackend(
base::SequencedTaskRunner* task_runner,
const base::FilePath& base_path)
: base_path_(base_path),
task_runner_(task_runner),
file_util_(
new storage::AsyncFileUtilAdapter(new TestFileUtil(base_path))),
quota_util_(new QuotaUtil),
require_copy_or_move_validator_(false) {
update_observers_ =
update_observers_.AddObserver(quota_util_.get(), task_runner_.get());
}
TestFileSystemBackend::~TestFileSystemBackend() {
}
bool TestFileSystemBackend::CanHandleType(storage::FileSystemType type) const {
return (type == storage::kFileSystemTypeTest);
}
void TestFileSystemBackend::Initialize(FileSystemContext* context) {
}
void TestFileSystemBackend::ResolveURL(const FileSystemURL& url,
storage::OpenFileSystemMode mode,
const OpenFileSystemCallback& callback) {
callback.Run(GetFileSystemRootURI(url.origin(), url.type()),
GetFileSystemName(url.origin(), url.type()),
base::File::FILE_OK);
}
storage::AsyncFileUtil* TestFileSystemBackend::GetAsyncFileUtil(
storage::FileSystemType type) {
return file_util_.get();
}
storage::WatcherManager* TestFileSystemBackend::GetWatcherManager(
storage::FileSystemType type) {
return nullptr;
}
storage::CopyOrMoveFileValidatorFactory*
TestFileSystemBackend::GetCopyOrMoveFileValidatorFactory(
storage::FileSystemType type,
base::File::Error* error_code) {
DCHECK(error_code);
*error_code = base::File::FILE_OK;
if (require_copy_or_move_validator_) {
if (!copy_or_move_file_validator_factory_)
*error_code = base::File::FILE_ERROR_SECURITY;
return copy_or_move_file_validator_factory_.get();
}
return nullptr;
}
void TestFileSystemBackend::InitializeCopyOrMoveFileValidatorFactory(
std::unique_ptr<storage::CopyOrMoveFileValidatorFactory> factory) {
if (!copy_or_move_file_validator_factory_)
copy_or_move_file_validator_factory_ = std::move(factory);
}
FileSystemOperation* TestFileSystemBackend::CreateFileSystemOperation(
const FileSystemURL& url,
FileSystemContext* context,
base::File::Error* error_code) const {
std::unique_ptr<FileSystemOperationContext> operation_context(
new FileSystemOperationContext(context));
operation_context->set_update_observers(*GetUpdateObservers(url.type()));
operation_context->set_change_observers(*GetChangeObservers(url.type()));
return FileSystemOperation::Create(url, context,
std::move(operation_context));
}
bool TestFileSystemBackend::SupportsStreaming(
const storage::FileSystemURL& url) const {
return false;
}
bool TestFileSystemBackend::HasInplaceCopyImplementation(
storage::FileSystemType type) const {
return true;
}
std::unique_ptr<storage::FileStreamReader>
TestFileSystemBackend::CreateFileStreamReader(
const FileSystemURL& url,
int64_t offset,
int64_t max_bytes_to_read,
const base::Time& expected_modification_time,
FileSystemContext* context) const {
return std::unique_ptr<storage::FileStreamReader>(
storage::FileStreamReader::CreateForFileSystemFile(
context, url, offset, expected_modification_time));
}
std::unique_ptr<storage::FileStreamWriter>
TestFileSystemBackend::CreateFileStreamWriter(
const FileSystemURL& url,
int64_t offset,
FileSystemContext* context) const {
return std::unique_ptr<storage::FileStreamWriter>(
new storage::SandboxFileStreamWriter(context, url, offset,
*GetUpdateObservers(url.type())));
}
storage::FileSystemQuotaUtil* TestFileSystemBackend::GetQuotaUtil() {
return quota_util_.get();
}
const storage::UpdateObserverList* TestFileSystemBackend::GetUpdateObservers(
storage::FileSystemType type) const {
return &update_observers_;
}
const storage::ChangeObserverList* TestFileSystemBackend::GetChangeObservers(
storage::FileSystemType type) const {
return &change_observers_;
}
const storage::AccessObserverList* TestFileSystemBackend::GetAccessObservers(
storage::FileSystemType type) const {
return nullptr;
}
void TestFileSystemBackend::AddFileChangeObserver(
storage::FileChangeObserver* observer) {
change_observers_ =
change_observers_.AddObserver(observer, task_runner_.get());
}
} // namespace content