1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "storage/browser/test/test_file_system_backend.h"
6
7 #include <set>
8 #include <string>
9 #include <utility>
10 #include <vector>
11
12 #include "base/files/file.h"
13 #include "base/files/file_util.h"
14 #include "base/macros.h"
15 #include "base/memory/weak_ptr.h"
16 #include "base/observer_list.h"
17 #include "base/sequenced_task_runner.h"
18 #include "base/threading/thread_task_runner_handle.h"
19 #include "storage/browser/file_system/copy_or_move_file_validator.h"
20 #include "storage/browser/file_system/file_observers.h"
21 #include "storage/browser/file_system/file_stream_reader.h"
22 #include "storage/browser/file_system/file_system_operation.h"
23 #include "storage/browser/file_system/file_system_operation_context.h"
24 #include "storage/browser/file_system/file_system_quota_util.h"
25 #include "storage/browser/file_system/local_file_util.h"
26 #include "storage/browser/file_system/native_file_util.h"
27 #include "storage/browser/file_system/quota/quota_reservation.h"
28 #include "storage/browser/file_system/sandbox_file_stream_writer.h"
29 #include "storage/browser/quota/quota_manager.h"
30 #include "storage/common/file_system/file_system_util.h"
31
32 namespace storage {
33
34 namespace {
35
36 // Stub implementation of LocalFileUtil.
37 class TestFileUtil : public LocalFileUtil {
38 public:
TestFileUtil(const base::FilePath & base_path)39 explicit TestFileUtil(const base::FilePath& base_path)
40 : base_path_(base_path) {}
41 ~TestFileUtil() override = default;
42
43 // LocalFileUtil overrides.
GetLocalFilePath(FileSystemOperationContext * context,const FileSystemURL & file_system_url,base::FilePath * local_file_path)44 base::File::Error GetLocalFilePath(FileSystemOperationContext* context,
45 const FileSystemURL& file_system_url,
46 base::FilePath* local_file_path) override {
47 *local_file_path = base_path_.Append(file_system_url.path());
48 return base::File::FILE_OK;
49 }
50
51 private:
52 base::FilePath base_path_;
53 };
54
55 } // namespace
56
57 // This only supports single origin.
58 class TestFileSystemBackend::QuotaUtil : public FileSystemQuotaUtil,
59 public FileUpdateObserver {
60 public:
QuotaUtil()61 QuotaUtil() : usage_(0) {}
62 ~QuotaUtil() override = default;
63
64 // FileSystemQuotaUtil overrides.
DeleteOriginDataOnFileTaskRunner(FileSystemContext * context,QuotaManagerProxy * proxy,const url::Origin & origin,FileSystemType type)65 base::File::Error DeleteOriginDataOnFileTaskRunner(
66 FileSystemContext* context,
67 QuotaManagerProxy* proxy,
68 const url::Origin& origin,
69 FileSystemType type) override {
70 NOTREACHED();
71 return base::File::FILE_OK;
72 }
73
PerformStorageCleanupOnFileTaskRunner(FileSystemContext * context,QuotaManagerProxy * proxy,FileSystemType type)74 void PerformStorageCleanupOnFileTaskRunner(FileSystemContext* context,
75 QuotaManagerProxy* proxy,
76 FileSystemType type) override {}
77
CreateQuotaReservationOnFileTaskRunner(const url::Origin & origin,FileSystemType type)78 scoped_refptr<QuotaReservation> CreateQuotaReservationOnFileTaskRunner(
79 const url::Origin& origin,
80 FileSystemType type) override {
81 NOTREACHED();
82 return scoped_refptr<QuotaReservation>();
83 }
84
GetOriginsForTypeOnFileTaskRunner(FileSystemType type)85 std::vector<url::Origin> GetOriginsForTypeOnFileTaskRunner(
86 FileSystemType type) override {
87 NOTREACHED();
88 return std::vector<url::Origin>();
89 }
90
GetOriginsForHostOnFileTaskRunner(FileSystemType type,const std::string & host)91 std::vector<url::Origin> GetOriginsForHostOnFileTaskRunner(
92 FileSystemType type,
93 const std::string& host) override {
94 NOTREACHED();
95 return std::vector<url::Origin>();
96 }
97
GetOriginUsageOnFileTaskRunner(FileSystemContext * context,const url::Origin & origin,FileSystemType type)98 int64_t GetOriginUsageOnFileTaskRunner(FileSystemContext* context,
99 const url::Origin& origin,
100 FileSystemType type) override {
101 return usage_;
102 }
103
104 // FileUpdateObserver overrides.
OnStartUpdate(const FileSystemURL & url)105 void OnStartUpdate(const FileSystemURL& url) override {}
OnUpdate(const FileSystemURL & url,int64_t delta)106 void OnUpdate(const FileSystemURL& url, int64_t delta) override {
107 usage_ += delta;
108 }
OnEndUpdate(const FileSystemURL & url)109 void OnEndUpdate(const FileSystemURL& url) override {}
110
111 private:
112 int64_t usage_;
113 DISALLOW_COPY_AND_ASSIGN(QuotaUtil);
114 };
115
TestFileSystemBackend(base::SequencedTaskRunner * task_runner,const base::FilePath & base_path)116 TestFileSystemBackend::TestFileSystemBackend(
117 base::SequencedTaskRunner* task_runner,
118 const base::FilePath& base_path)
119 : base_path_(base_path),
120 task_runner_(task_runner),
121 file_util_(
122 std::make_unique<AsyncFileUtilAdapter>(new TestFileUtil(base_path))),
123 quota_util_(std::make_unique<QuotaUtil>()),
124 require_copy_or_move_validator_(false) {
125 update_observers_ =
126 update_observers_.AddObserver(quota_util_.get(), task_runner_.get());
127 }
128
129 TestFileSystemBackend::~TestFileSystemBackend() = default;
130
CanHandleType(FileSystemType type) const131 bool TestFileSystemBackend::CanHandleType(FileSystemType type) const {
132 return (type == kFileSystemTypeTest);
133 }
134
Initialize(FileSystemContext * context)135 void TestFileSystemBackend::Initialize(FileSystemContext* context) {}
136
ResolveURL(const FileSystemURL & url,OpenFileSystemMode mode,OpenFileSystemCallback callback)137 void TestFileSystemBackend::ResolveURL(const FileSystemURL& url,
138 OpenFileSystemMode mode,
139 OpenFileSystemCallback callback) {
140 std::move(callback).Run(
141 GetFileSystemRootURI(url.origin().GetURL(), url.type()),
142 GetFileSystemName(url.origin().GetURL(), url.type()),
143 base::File::FILE_OK);
144 }
145
GetAsyncFileUtil(FileSystemType type)146 AsyncFileUtil* TestFileSystemBackend::GetAsyncFileUtil(FileSystemType type) {
147 return file_util_.get();
148 }
149
GetWatcherManager(FileSystemType type)150 WatcherManager* TestFileSystemBackend::GetWatcherManager(FileSystemType type) {
151 return nullptr;
152 }
153
154 CopyOrMoveFileValidatorFactory*
GetCopyOrMoveFileValidatorFactory(FileSystemType type,base::File::Error * error_code)155 TestFileSystemBackend::GetCopyOrMoveFileValidatorFactory(
156 FileSystemType type,
157 base::File::Error* error_code) {
158 DCHECK(error_code);
159 *error_code = base::File::FILE_OK;
160 if (require_copy_or_move_validator_) {
161 if (!copy_or_move_file_validator_factory_)
162 *error_code = base::File::FILE_ERROR_SECURITY;
163 return copy_or_move_file_validator_factory_.get();
164 }
165 return nullptr;
166 }
167
InitializeCopyOrMoveFileValidatorFactory(std::unique_ptr<CopyOrMoveFileValidatorFactory> factory)168 void TestFileSystemBackend::InitializeCopyOrMoveFileValidatorFactory(
169 std::unique_ptr<CopyOrMoveFileValidatorFactory> factory) {
170 if (!copy_or_move_file_validator_factory_)
171 copy_or_move_file_validator_factory_ = std::move(factory);
172 }
173
CreateFileSystemOperation(const FileSystemURL & url,FileSystemContext * context,base::File::Error * error_code) const174 FileSystemOperation* TestFileSystemBackend::CreateFileSystemOperation(
175 const FileSystemURL& url,
176 FileSystemContext* context,
177 base::File::Error* error_code) const {
178 std::unique_ptr<FileSystemOperationContext> operation_context(
179 new FileSystemOperationContext(context));
180 operation_context->set_update_observers(*GetUpdateObservers(url.type()));
181 operation_context->set_change_observers(*GetChangeObservers(url.type()));
182 return FileSystemOperation::Create(url, context,
183 std::move(operation_context));
184 }
185
SupportsStreaming(const FileSystemURL & url) const186 bool TestFileSystemBackend::SupportsStreaming(const FileSystemURL& url) const {
187 return false;
188 }
189
HasInplaceCopyImplementation(FileSystemType type) const190 bool TestFileSystemBackend::HasInplaceCopyImplementation(
191 FileSystemType type) const {
192 return true;
193 }
194
CreateFileStreamReader(const FileSystemURL & url,int64_t offset,int64_t max_bytes_to_read,const base::Time & expected_modification_time,FileSystemContext * context) const195 std::unique_ptr<FileStreamReader> TestFileSystemBackend::CreateFileStreamReader(
196 const FileSystemURL& url,
197 int64_t offset,
198 int64_t max_bytes_to_read,
199 const base::Time& expected_modification_time,
200 FileSystemContext* context) const {
201 return FileStreamReader::CreateForFileSystemFile(context, url, offset,
202 expected_modification_time);
203 }
204
CreateFileStreamWriter(const FileSystemURL & url,int64_t offset,FileSystemContext * context) const205 std::unique_ptr<FileStreamWriter> TestFileSystemBackend::CreateFileStreamWriter(
206 const FileSystemURL& url,
207 int64_t offset,
208 FileSystemContext* context) const {
209 return std::make_unique<SandboxFileStreamWriter>(
210 context, url, offset, *GetUpdateObservers(url.type()));
211 }
212
GetQuotaUtil()213 FileSystemQuotaUtil* TestFileSystemBackend::GetQuotaUtil() {
214 return quota_util_.get();
215 }
216
GetUpdateObservers(FileSystemType type) const217 const UpdateObserverList* TestFileSystemBackend::GetUpdateObservers(
218 FileSystemType type) const {
219 return &update_observers_;
220 }
221
GetChangeObservers(FileSystemType type) const222 const ChangeObserverList* TestFileSystemBackend::GetChangeObservers(
223 FileSystemType type) const {
224 return &change_observers_;
225 }
226
GetAccessObservers(FileSystemType type) const227 const AccessObserverList* TestFileSystemBackend::GetAccessObservers(
228 FileSystemType type) const {
229 return nullptr;
230 }
231
AddFileChangeObserver(FileChangeObserver * observer)232 void TestFileSystemBackend::AddFileChangeObserver(
233 FileChangeObserver* observer) {
234 change_observers_ =
235 change_observers_.AddObserver(observer, task_runner_.get());
236 }
237
238 } // namespace storage
239