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 "content/public/test/test_file_system_backend.h"
6
7 #include <set>
8 #include <string>
9 #include <vector>
10
11 #include "base/file_util.h"
12 #include "base/sequenced_task_runner.h"
13 #include "webkit/browser/blob/file_stream_reader.h"
14 #include "webkit/browser/fileapi/copy_or_move_file_validator.h"
15 #include "webkit/browser/fileapi/file_observers.h"
16 #include "webkit/browser/fileapi/file_system_operation.h"
17 #include "webkit/browser/fileapi/file_system_operation_context.h"
18 #include "webkit/browser/fileapi/file_system_quota_util.h"
19 #include "webkit/browser/fileapi/local_file_util.h"
20 #include "webkit/browser/fileapi/native_file_util.h"
21 #include "webkit/browser/fileapi/quota/quota_reservation.h"
22 #include "webkit/browser/fileapi/sandbox_file_stream_writer.h"
23 #include "webkit/browser/quota/quota_manager.h"
24 #include "webkit/common/fileapi/file_system_util.h"
25
26 using fileapi::FileSystemContext;
27 using fileapi::FileSystemOperation;
28 using fileapi::FileSystemOperationContext;
29 using fileapi::FileSystemURL;
30
31 namespace content {
32
33 namespace {
34
35 class TestFileUtil : public fileapi::LocalFileUtil {
36 public:
TestFileUtil(const base::FilePath & base_path)37 explicit TestFileUtil(const base::FilePath& base_path)
38 : base_path_(base_path) {}
~TestFileUtil()39 virtual ~TestFileUtil() {}
40
41 // LocalFileUtil overrides.
GetLocalFilePath(FileSystemOperationContext * context,const FileSystemURL & file_system_url,base::FilePath * local_file_path)42 virtual base::File::Error GetLocalFilePath(
43 FileSystemOperationContext* context,
44 const FileSystemURL& file_system_url,
45 base::FilePath* local_file_path) OVERRIDE {
46 *local_file_path = base_path_.Append(file_system_url.path());
47 return base::File::FILE_OK;
48 }
49
50 private:
51 base::FilePath base_path_;
52 };
53
54 } // namespace
55
56 // This only supports single origin.
57 class TestFileSystemBackend::QuotaUtil
58 : public fileapi::FileSystemQuotaUtil,
59 public fileapi::FileUpdateObserver {
60 public:
QuotaUtil(base::SequencedTaskRunner * task_runner)61 explicit QuotaUtil(base::SequencedTaskRunner* task_runner)
62 : usage_(0),
63 task_runner_(task_runner) {
64 update_observers_ = update_observers_.AddObserver(this, task_runner_.get());
65 }
~QuotaUtil()66 virtual ~QuotaUtil() {}
67
68 // FileSystemQuotaUtil overrides.
DeleteOriginDataOnFileTaskRunner(FileSystemContext * context,quota::QuotaManagerProxy * proxy,const GURL & origin_url,fileapi::FileSystemType type)69 virtual base::File::Error DeleteOriginDataOnFileTaskRunner(
70 FileSystemContext* context,
71 quota::QuotaManagerProxy* proxy,
72 const GURL& origin_url,
73 fileapi::FileSystemType type) OVERRIDE {
74 NOTREACHED();
75 return base::File::FILE_OK;
76 }
77
78 virtual scoped_refptr<fileapi::QuotaReservation>
CreateQuotaReservationOnFileTaskRunner(const GURL & origin_url,fileapi::FileSystemType type)79 CreateQuotaReservationOnFileTaskRunner(
80 const GURL& origin_url,
81 fileapi::FileSystemType type) OVERRIDE {
82 NOTREACHED();
83 return scoped_refptr<fileapi::QuotaReservation>();
84 }
85
GetOriginsForTypeOnFileTaskRunner(fileapi::FileSystemType type,std::set<GURL> * origins)86 virtual void GetOriginsForTypeOnFileTaskRunner(
87 fileapi::FileSystemType type,
88 std::set<GURL>* origins) OVERRIDE {
89 NOTREACHED();
90 }
91
GetOriginsForHostOnFileTaskRunner(fileapi::FileSystemType type,const std::string & host,std::set<GURL> * origins)92 virtual void GetOriginsForHostOnFileTaskRunner(
93 fileapi::FileSystemType type,
94 const std::string& host,
95 std::set<GURL>* origins) OVERRIDE {
96 NOTREACHED();
97 }
98
GetOriginUsageOnFileTaskRunner(FileSystemContext * context,const GURL & origin_url,fileapi::FileSystemType type)99 virtual int64 GetOriginUsageOnFileTaskRunner(
100 FileSystemContext* context,
101 const GURL& origin_url,
102 fileapi::FileSystemType type) OVERRIDE {
103 return usage_;
104 }
105
AddFileUpdateObserver(fileapi::FileSystemType type,FileUpdateObserver * observer,base::SequencedTaskRunner * task_runner)106 virtual void AddFileUpdateObserver(
107 fileapi::FileSystemType type,
108 FileUpdateObserver* observer,
109 base::SequencedTaskRunner* task_runner) OVERRIDE {
110 NOTIMPLEMENTED();
111 }
112
AddFileChangeObserver(fileapi::FileSystemType type,fileapi::FileChangeObserver * observer,base::SequencedTaskRunner * task_runner)113 virtual void AddFileChangeObserver(
114 fileapi::FileSystemType type,
115 fileapi::FileChangeObserver* observer,
116 base::SequencedTaskRunner* task_runner) OVERRIDE {
117 change_observers_ = change_observers_.AddObserver(observer, task_runner);
118 }
119
AddFileAccessObserver(fileapi::FileSystemType type,fileapi::FileAccessObserver * observer,base::SequencedTaskRunner * task_runner)120 virtual void AddFileAccessObserver(
121 fileapi::FileSystemType type,
122 fileapi::FileAccessObserver* observer,
123 base::SequencedTaskRunner* task_runner) OVERRIDE {
124 NOTIMPLEMENTED();
125 }
126
GetUpdateObservers(fileapi::FileSystemType type) const127 virtual const fileapi::UpdateObserverList* GetUpdateObservers(
128 fileapi::FileSystemType type) const OVERRIDE {
129 return &update_observers_;
130 }
131
GetChangeObservers(fileapi::FileSystemType type) const132 virtual const fileapi::ChangeObserverList* GetChangeObservers(
133 fileapi::FileSystemType type) const OVERRIDE {
134 return &change_observers_;
135 }
136
GetAccessObservers(fileapi::FileSystemType type) const137 virtual const fileapi::AccessObserverList* GetAccessObservers(
138 fileapi::FileSystemType type) const OVERRIDE {
139 return NULL;
140 }
141
142 // FileUpdateObserver overrides.
OnStartUpdate(const FileSystemURL & url)143 virtual void OnStartUpdate(const FileSystemURL& url) OVERRIDE {}
OnUpdate(const FileSystemURL & url,int64 delta)144 virtual void OnUpdate(const FileSystemURL& url, int64 delta) OVERRIDE {
145 usage_ += delta;
146 }
OnEndUpdate(const FileSystemURL & url)147 virtual void OnEndUpdate(const FileSystemURL& url) OVERRIDE {}
148
task_runner()149 base::SequencedTaskRunner* task_runner() { return task_runner_.get(); }
150
151 private:
152 int64 usage_;
153
154 scoped_refptr<base::SequencedTaskRunner> task_runner_;
155
156 fileapi::UpdateObserverList update_observers_;
157 fileapi::ChangeObserverList change_observers_;
158 };
159
TestFileSystemBackend(base::SequencedTaskRunner * task_runner,const base::FilePath & base_path)160 TestFileSystemBackend::TestFileSystemBackend(
161 base::SequencedTaskRunner* task_runner,
162 const base::FilePath& base_path)
163 : base_path_(base_path),
164 file_util_(
165 new fileapi::AsyncFileUtilAdapter(new TestFileUtil(base_path))),
166 quota_util_(new QuotaUtil(task_runner)),
167 require_copy_or_move_validator_(false) {
168 }
169
~TestFileSystemBackend()170 TestFileSystemBackend::~TestFileSystemBackend() {
171 }
172
CanHandleType(fileapi::FileSystemType type) const173 bool TestFileSystemBackend::CanHandleType(fileapi::FileSystemType type) const {
174 return (type == fileapi::kFileSystemTypeTest);
175 }
176
Initialize(FileSystemContext * context)177 void TestFileSystemBackend::Initialize(FileSystemContext* context) {
178 }
179
ResolveURL(const FileSystemURL & url,fileapi::OpenFileSystemMode mode,const OpenFileSystemCallback & callback)180 void TestFileSystemBackend::ResolveURL(const FileSystemURL& url,
181 fileapi::OpenFileSystemMode mode,
182 const OpenFileSystemCallback& callback) {
183 callback.Run(GetFileSystemRootURI(url.origin(), url.type()),
184 GetFileSystemName(url.origin(), url.type()),
185 base::File::FILE_OK);
186 }
187
GetAsyncFileUtil(fileapi::FileSystemType type)188 fileapi::AsyncFileUtil* TestFileSystemBackend::GetAsyncFileUtil(
189 fileapi::FileSystemType type) {
190 return file_util_.get();
191 }
192
193 fileapi::CopyOrMoveFileValidatorFactory*
GetCopyOrMoveFileValidatorFactory(fileapi::FileSystemType type,base::File::Error * error_code)194 TestFileSystemBackend::GetCopyOrMoveFileValidatorFactory(
195 fileapi::FileSystemType type,
196 base::File::Error* error_code) {
197 DCHECK(error_code);
198 *error_code = base::File::FILE_OK;
199 if (require_copy_or_move_validator_) {
200 if (!copy_or_move_file_validator_factory_)
201 *error_code = base::File::FILE_ERROR_SECURITY;
202 return copy_or_move_file_validator_factory_.get();
203 }
204 return NULL;
205 }
206
InitializeCopyOrMoveFileValidatorFactory(scoped_ptr<fileapi::CopyOrMoveFileValidatorFactory> factory)207 void TestFileSystemBackend::InitializeCopyOrMoveFileValidatorFactory(
208 scoped_ptr<fileapi::CopyOrMoveFileValidatorFactory> factory) {
209 if (!copy_or_move_file_validator_factory_)
210 copy_or_move_file_validator_factory_ = factory.Pass();
211 }
212
CreateFileSystemOperation(const FileSystemURL & url,FileSystemContext * context,base::File::Error * error_code) const213 FileSystemOperation* TestFileSystemBackend::CreateFileSystemOperation(
214 const FileSystemURL& url,
215 FileSystemContext* context,
216 base::File::Error* error_code) const {
217 scoped_ptr<FileSystemOperationContext> operation_context(
218 new FileSystemOperationContext(context));
219 operation_context->set_update_observers(*GetUpdateObservers(url.type()));
220 operation_context->set_change_observers(
221 *quota_util_->GetChangeObservers(url.type()));
222 return FileSystemOperation::Create(url, context, operation_context.Pass());
223 }
224
SupportsStreaming(const fileapi::FileSystemURL & url) const225 bool TestFileSystemBackend::SupportsStreaming(
226 const fileapi::FileSystemURL& url) const {
227 return false;
228 }
229
230 scoped_ptr<webkit_blob::FileStreamReader>
CreateFileStreamReader(const FileSystemURL & url,int64 offset,const base::Time & expected_modification_time,FileSystemContext * context) const231 TestFileSystemBackend::CreateFileStreamReader(
232 const FileSystemURL& url,
233 int64 offset,
234 const base::Time& expected_modification_time,
235 FileSystemContext* context) const {
236 return scoped_ptr<webkit_blob::FileStreamReader>(
237 webkit_blob::FileStreamReader::CreateForFileSystemFile(
238 context, url, offset, expected_modification_time));
239 }
240
241 scoped_ptr<fileapi::FileStreamWriter>
CreateFileStreamWriter(const FileSystemURL & url,int64 offset,FileSystemContext * context) const242 TestFileSystemBackend::CreateFileStreamWriter(
243 const FileSystemURL& url,
244 int64 offset,
245 FileSystemContext* context) const {
246 return scoped_ptr<fileapi::FileStreamWriter>(
247 new fileapi::SandboxFileStreamWriter(context, url, offset,
248 *GetUpdateObservers(url.type())));
249 }
250
GetQuotaUtil()251 fileapi::FileSystemQuotaUtil* TestFileSystemBackend::GetQuotaUtil() {
252 return quota_util_.get();
253 }
254
GetUpdateObservers(fileapi::FileSystemType type) const255 const fileapi::UpdateObserverList* TestFileSystemBackend::GetUpdateObservers(
256 fileapi::FileSystemType type) const {
257 return quota_util_->GetUpdateObservers(type);
258 }
259
AddFileChangeObserver(fileapi::FileChangeObserver * observer)260 void TestFileSystemBackend::AddFileChangeObserver(
261 fileapi::FileChangeObserver* observer) {
262 quota_util_->AddFileChangeObserver(
263 fileapi::kFileSystemTypeTest, observer, quota_util_->task_runner());
264 }
265
266 } // namespace content
267