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