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: 37 explicit TestFileUtil(const base::FilePath& base_path) 38 : base_path_(base_path) {} 39 virtual ~TestFileUtil() {} 40 41 // LocalFileUtil overrides. 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: 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 } 66 virtual ~QuotaUtil() {} 67 68 // FileSystemQuotaUtil overrides. 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> 79 CreateQuotaReservationOnFileTaskRunner( 80 const GURL& origin_url, 81 fileapi::FileSystemType type) OVERRIDE { 82 NOTREACHED(); 83 return scoped_refptr<fileapi::QuotaReservation>(); 84 } 85 86 virtual void GetOriginsForTypeOnFileTaskRunner( 87 fileapi::FileSystemType type, 88 std::set<GURL>* origins) OVERRIDE { 89 NOTREACHED(); 90 } 91 92 virtual void GetOriginsForHostOnFileTaskRunner( 93 fileapi::FileSystemType type, 94 const std::string& host, 95 std::set<GURL>* origins) OVERRIDE { 96 NOTREACHED(); 97 } 98 99 virtual int64 GetOriginUsageOnFileTaskRunner( 100 FileSystemContext* context, 101 const GURL& origin_url, 102 fileapi::FileSystemType type) OVERRIDE { 103 return usage_; 104 } 105 106 virtual void AddFileUpdateObserver( 107 fileapi::FileSystemType type, 108 FileUpdateObserver* observer, 109 base::SequencedTaskRunner* task_runner) OVERRIDE { 110 NOTIMPLEMENTED(); 111 } 112 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 120 virtual void AddFileAccessObserver( 121 fileapi::FileSystemType type, 122 fileapi::FileAccessObserver* observer, 123 base::SequencedTaskRunner* task_runner) OVERRIDE { 124 NOTIMPLEMENTED(); 125 } 126 127 virtual const fileapi::UpdateObserverList* GetUpdateObservers( 128 fileapi::FileSystemType type) const OVERRIDE { 129 return &update_observers_; 130 } 131 132 virtual const fileapi::ChangeObserverList* GetChangeObservers( 133 fileapi::FileSystemType type) const OVERRIDE { 134 return &change_observers_; 135 } 136 137 virtual const fileapi::AccessObserverList* GetAccessObservers( 138 fileapi::FileSystemType type) const OVERRIDE { 139 return NULL; 140 } 141 142 // FileUpdateObserver overrides. 143 virtual void OnStartUpdate(const FileSystemURL& url) OVERRIDE {} 144 virtual void OnUpdate(const FileSystemURL& url, int64 delta) OVERRIDE { 145 usage_ += delta; 146 } 147 virtual void OnEndUpdate(const FileSystemURL& url) OVERRIDE {} 148 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 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 170 TestFileSystemBackend::~TestFileSystemBackend() { 171 } 172 173 bool TestFileSystemBackend::CanHandleType(fileapi::FileSystemType type) const { 174 return (type == fileapi::kFileSystemTypeTest); 175 } 176 177 void TestFileSystemBackend::Initialize(FileSystemContext* context) { 178 } 179 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 188 fileapi::AsyncFileUtil* TestFileSystemBackend::GetAsyncFileUtil( 189 fileapi::FileSystemType type) { 190 return file_util_.get(); 191 } 192 193 fileapi::CopyOrMoveFileValidatorFactory* 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 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 213 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 225 bool TestFileSystemBackend::SupportsStreaming( 226 const fileapi::FileSystemURL& url) const { 227 return false; 228 } 229 230 scoped_ptr<webkit_blob::FileStreamReader> 231 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> 242 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 251 fileapi::FileSystemQuotaUtil* TestFileSystemBackend::GetQuotaUtil() { 252 return quota_util_.get(); 253 } 254 255 const fileapi::UpdateObserverList* TestFileSystemBackend::GetUpdateObservers( 256 fileapi::FileSystemType type) const { 257 return quota_util_->GetUpdateObservers(type); 258 } 259 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