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.
5 #include "content/public/test/test_file_system_backend.h"
11 #include "base/files/file.h"
12 #include "base/files/file_util.h"
13 #include "base/memory/weak_ptr.h"
14 #include "base/observer_list.h"
15 #include "base/sequenced_task_runner.h"
16 #include "base/thread_task_runner_handle.h"
17 #include "storage/browser/blob/file_stream_reader.h"
18 #include "storage/browser/fileapi/copy_or_move_file_validator.h"
19 #include "storage/browser/fileapi/file_observers.h"
20 #include "storage/browser/fileapi/file_system_operation.h"
21 #include "storage/browser/fileapi/file_system_operation_context.h"
22 #include "storage/browser/fileapi/file_system_quota_util.h"
23 #include "storage/browser/fileapi/local_file_util.h"
24 #include "storage/browser/fileapi/native_file_util.h"
25 #include "storage/browser/fileapi/quota/quota_reservation.h"
26 #include "storage/browser/fileapi/sandbox_file_stream_writer.h"
27 #include "storage/browser/fileapi/watcher_manager.h"
28 #include "storage/browser/quota/quota_manager.h"
29 #include "storage/common/fileapi/file_system_util.h"
31 using storage::FileSystemContext
;
32 using storage::FileSystemOperation
;
33 using storage::FileSystemOperationContext
;
34 using storage::FileSystemURL
;
40 // Stub implementation of storage::LocalFileUtil.
41 class TestFileUtil
: public storage::LocalFileUtil
{
43 explicit TestFileUtil(const base::FilePath
& base_path
)
44 : base_path_(base_path
) {}
45 virtual ~TestFileUtil() {}
47 // LocalFileUtil overrides.
48 virtual base::File::Error
GetLocalFilePath(
49 FileSystemOperationContext
* context
,
50 const FileSystemURL
& file_system_url
,
51 base::FilePath
* local_file_path
) OVERRIDE
{
52 *local_file_path
= base_path_
.Append(file_system_url
.path());
53 return base::File::FILE_OK
;
57 base::FilePath base_path_
;
60 // Stub implementation of storage::WatcherManager. Emits a fake notification
61 // after a directory watcher is set successfully.
62 class TestWatcherManager
: public storage::WatcherManager
{
64 TestWatcherManager() : weak_ptr_factory_(this) {}
65 virtual ~TestWatcherManager() {}
67 // storage::WatcherManager overrides.
68 virtual void AddObserver(Observer
* observer
) OVERRIDE
{
69 observers_
.AddObserver(observer
);
72 virtual void RemoveObserver(Observer
* observer
) OVERRIDE
{
73 observers_
.RemoveObserver(observer
);
76 virtual bool HasObserver(Observer
* observer
) const OVERRIDE
{
77 return observers_
.HasObserver(observer
);
80 virtual void WatchDirectory(const storage::FileSystemURL
& url
,
82 const StatusCallback
& callback
) OVERRIDE
{
84 base::ThreadTaskRunnerHandle::Get()->PostTask(
86 base::Bind(callback
, base::File::FILE_ERROR_INVALID_OPERATION
));
90 const GURL gurl
= url
.ToGURL();
91 if (watched_urls_
.find(gurl
) != watched_urls_
.end()) {
92 base::ThreadTaskRunnerHandle::Get()->PostTask(
93 FROM_HERE
, base::Bind(callback
, base::File::FILE_ERROR_EXISTS
));
97 watched_urls_
.insert(gurl
);
98 base::ThreadTaskRunnerHandle::Get()->PostTask(
99 FROM_HERE
, base::Bind(callback
, base::File::FILE_OK
));
101 // Send a fake changed notification.
102 base::ThreadTaskRunnerHandle::Get()->PostTask(
104 base::Bind(&TestWatcherManager::SendFakeChangeNotification
,
105 weak_ptr_factory_
.GetWeakPtr(),
108 // Send a fake removed notification.
109 base::ThreadTaskRunnerHandle::Get()->PostTask(
111 base::Bind(&TestWatcherManager::SendFakeRemoveNotification
,
112 weak_ptr_factory_
.GetWeakPtr(),
116 virtual void UnwatchEntry(const storage::FileSystemURL
& url
,
117 const StatusCallback
& callback
) OVERRIDE
{
118 const GURL gurl
= url
.ToGURL();
119 if (watched_urls_
.find(gurl
) == watched_urls_
.end()) {
120 base::ThreadTaskRunnerHandle::Get()->PostTask(
121 FROM_HERE
, base::Bind(callback
, base::File::FILE_ERROR_NOT_FOUND
));
125 watched_urls_
.erase(gurl
);
126 base::ThreadTaskRunnerHandle::Get()->PostTask(
127 FROM_HERE
, base::Bind(callback
, base::File::FILE_OK
));
131 // Sends a fake notification to each observer about a changed entry
132 // represented by |url|, as long as it is still being watched.
133 void SendFakeChangeNotification(const storage::FileSystemURL
& url
) {
134 if (watched_urls_
.find(url
.ToGURL()) == watched_urls_
.end())
137 FOR_EACH_OBSERVER(Observer
, observers_
, OnEntryChanged(url
));
140 // Sends a fake notification to each observer about a removed entry
141 // represented by |url|, as long as it is still being watched.
142 void SendFakeRemoveNotification(const storage::FileSystemURL
& url
) {
143 if (watched_urls_
.find(url
.ToGURL()) == watched_urls_
.end())
146 FOR_EACH_OBSERVER(Observer
, observers_
, OnEntryRemoved(url
));
149 ObserverList
<Observer
> observers_
;
150 std::set
<GURL
> watched_urls_
;
152 base::WeakPtrFactory
<TestWatcherManager
> weak_ptr_factory_
;
157 // This only supports single origin.
158 class TestFileSystemBackend::QuotaUtil
: public storage::FileSystemQuotaUtil
,
159 public storage::FileUpdateObserver
{
161 QuotaUtil() : usage_(0) {}
162 virtual ~QuotaUtil() {}
164 // FileSystemQuotaUtil overrides.
165 virtual base::File::Error
DeleteOriginDataOnFileTaskRunner(
166 FileSystemContext
* context
,
167 storage::QuotaManagerProxy
* proxy
,
168 const GURL
& origin_url
,
169 storage::FileSystemType type
) OVERRIDE
{
171 return base::File::FILE_OK
;
174 virtual scoped_refptr
<storage::QuotaReservation
>
175 CreateQuotaReservationOnFileTaskRunner(
176 const GURL
& origin_url
,
177 storage::FileSystemType type
) OVERRIDE
{
179 return scoped_refptr
<storage::QuotaReservation
>();
182 virtual void GetOriginsForTypeOnFileTaskRunner(
183 storage::FileSystemType type
,
184 std::set
<GURL
>* origins
) OVERRIDE
{
188 virtual void GetOriginsForHostOnFileTaskRunner(
189 storage::FileSystemType type
,
190 const std::string
& host
,
191 std::set
<GURL
>* origins
) OVERRIDE
{
195 virtual int64
GetOriginUsageOnFileTaskRunner(
196 FileSystemContext
* context
,
197 const GURL
& origin_url
,
198 storage::FileSystemType type
) OVERRIDE
{
202 // FileUpdateObserver overrides.
203 virtual void OnStartUpdate(const FileSystemURL
& url
) OVERRIDE
{}
204 virtual void OnUpdate(const FileSystemURL
& url
, int64 delta
) OVERRIDE
{
207 virtual void OnEndUpdate(const FileSystemURL
& url
) OVERRIDE
{}
211 DISALLOW_COPY_AND_ASSIGN(QuotaUtil
);
214 TestFileSystemBackend::TestFileSystemBackend(
215 base::SequencedTaskRunner
* task_runner
,
216 const base::FilePath
& base_path
)
217 : base_path_(base_path
),
218 task_runner_(task_runner
),
220 new storage::AsyncFileUtilAdapter(new TestFileUtil(base_path
))),
221 watcher_manager_(new TestWatcherManager()),
222 quota_util_(new QuotaUtil
),
223 require_copy_or_move_validator_(false) {
225 update_observers_
.AddObserver(quota_util_
.get(), task_runner_
.get());
228 TestFileSystemBackend::~TestFileSystemBackend() {
231 bool TestFileSystemBackend::CanHandleType(storage::FileSystemType type
) const {
232 return (type
== storage::kFileSystemTypeTest
);
235 void TestFileSystemBackend::Initialize(FileSystemContext
* context
) {
238 void TestFileSystemBackend::ResolveURL(const FileSystemURL
& url
,
239 storage::OpenFileSystemMode mode
,
240 const OpenFileSystemCallback
& callback
) {
241 callback
.Run(GetFileSystemRootURI(url
.origin(), url
.type()),
242 GetFileSystemName(url
.origin(), url
.type()),
243 base::File::FILE_OK
);
246 storage::AsyncFileUtil
* TestFileSystemBackend::GetAsyncFileUtil(
247 storage::FileSystemType type
) {
248 return file_util_
.get();
251 storage::WatcherManager
* TestFileSystemBackend::GetWatcherManager(
252 storage::FileSystemType type
) {
253 return watcher_manager_
.get();
256 storage::CopyOrMoveFileValidatorFactory
*
257 TestFileSystemBackend::GetCopyOrMoveFileValidatorFactory(
258 storage::FileSystemType type
,
259 base::File::Error
* error_code
) {
261 *error_code
= base::File::FILE_OK
;
262 if (require_copy_or_move_validator_
) {
263 if (!copy_or_move_file_validator_factory_
)
264 *error_code
= base::File::FILE_ERROR_SECURITY
;
265 return copy_or_move_file_validator_factory_
.get();
270 void TestFileSystemBackend::InitializeCopyOrMoveFileValidatorFactory(
271 scoped_ptr
<storage::CopyOrMoveFileValidatorFactory
> factory
) {
272 if (!copy_or_move_file_validator_factory_
)
273 copy_or_move_file_validator_factory_
= factory
.Pass();
276 FileSystemOperation
* TestFileSystemBackend::CreateFileSystemOperation(
277 const FileSystemURL
& url
,
278 FileSystemContext
* context
,
279 base::File::Error
* error_code
) const {
280 scoped_ptr
<FileSystemOperationContext
> operation_context(
281 new FileSystemOperationContext(context
));
282 operation_context
->set_update_observers(*GetUpdateObservers(url
.type()));
283 operation_context
->set_change_observers(*GetChangeObservers(url
.type()));
284 return FileSystemOperation::Create(url
, context
, operation_context
.Pass());
287 bool TestFileSystemBackend::SupportsStreaming(
288 const storage::FileSystemURL
& url
) const {
292 bool TestFileSystemBackend::HasInplaceCopyImplementation(
293 storage::FileSystemType type
) const {
297 scoped_ptr
<storage::FileStreamReader
>
298 TestFileSystemBackend::CreateFileStreamReader(
299 const FileSystemURL
& url
,
301 int64 max_bytes_to_read
,
302 const base::Time
& expected_modification_time
,
303 FileSystemContext
* context
) const {
304 return scoped_ptr
<storage::FileStreamReader
>(
305 storage::FileStreamReader::CreateForFileSystemFile(
306 context
, url
, offset
, expected_modification_time
));
309 scoped_ptr
<storage::FileStreamWriter
>
310 TestFileSystemBackend::CreateFileStreamWriter(
311 const FileSystemURL
& url
,
313 FileSystemContext
* context
) const {
314 return scoped_ptr
<storage::FileStreamWriter
>(
315 new storage::SandboxFileStreamWriter(
316 context
, url
, offset
, *GetUpdateObservers(url
.type())));
319 storage::FileSystemQuotaUtil
* TestFileSystemBackend::GetQuotaUtil() {
320 return quota_util_
.get();
323 const storage::UpdateObserverList
* TestFileSystemBackend::GetUpdateObservers(
324 storage::FileSystemType type
) const {
325 return &update_observers_
;
328 const storage::ChangeObserverList
* TestFileSystemBackend::GetChangeObservers(
329 storage::FileSystemType type
) const {
330 return &change_observers_
;
333 const storage::AccessObserverList
* TestFileSystemBackend::GetAccessObservers(
334 storage::FileSystemType type
) const {
338 void TestFileSystemBackend::AddFileChangeObserver(
339 storage::FileChangeObserver
* observer
) {
341 change_observers_
.AddObserver(observer
, task_runner_
.get());
344 } // namespace content