OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 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 "webkit/fileapi/file_system_context.h" | |
6 | |
7 #include "base/bind.h" | |
8 #include "base/single_thread_task_runner.h" | |
9 #include "base/stl_util.h" | |
10 #include "googleurl/src/gurl.h" | |
11 #include "webkit/blob/file_stream_reader.h" | |
12 #include "webkit/browser/fileapi/copy_or_move_file_validator.h" | |
13 #include "webkit/browser/fileapi/external_mount_points.h" | |
14 #include "webkit/browser/fileapi/file_system_file_util.h" | |
15 #include "webkit/browser/fileapi/file_system_quota_client.h" | |
16 #include "webkit/browser/fileapi/file_system_task_runners.h" | |
17 #include "webkit/browser/fileapi/isolated_context.h" | |
18 #include "webkit/browser/fileapi/isolated_mount_point_provider.h" | |
19 #include "webkit/browser/fileapi/mount_points.h" | |
20 #include "webkit/browser/fileapi/sandbox_mount_point_provider.h" | |
21 #include "webkit/fileapi/file_stream_writer.h" | |
22 #include "webkit/fileapi/file_system_operation.h" | |
23 #include "webkit/fileapi/file_system_options.h" | |
24 #include "webkit/fileapi/file_system_url.h" | |
25 #include "webkit/fileapi/file_system_util.h" | |
26 #include "webkit/fileapi/syncable/local_file_change_tracker.h" | |
27 #include "webkit/fileapi/syncable/local_file_sync_context.h" | |
28 #include "webkit/fileapi/syncable/syncable_file_system_util.h" | |
29 #include "webkit/fileapi/test_mount_point_provider.h" | |
30 #include "webkit/quota/quota_manager.h" | |
31 #include "webkit/quota/special_storage_policy.h" | |
32 | |
33 #if defined(OS_CHROMEOS) | |
34 #include "webkit/chromeos/fileapi/cros_mount_point_provider.h" | |
35 #endif | |
36 | |
37 using quota::QuotaClient; | |
38 | |
39 namespace fileapi { | |
40 | |
41 namespace { | |
42 | |
43 QuotaClient* CreateQuotaClient( | |
44 FileSystemContext* context, | |
45 bool is_incognito) { | |
46 return new FileSystemQuotaClient(context, is_incognito); | |
47 } | |
48 | |
49 void DidOpenFileSystem( | |
50 const FileSystemContext::OpenFileSystemCallback& callback, | |
51 const GURL& filesystem_root, | |
52 const std::string& filesystem_name, | |
53 base::PlatformFileError error) { | |
54 callback.Run(error, filesystem_name, filesystem_root); | |
55 } | |
56 | |
57 } // namespace | |
58 | |
59 FileSystemContext::FileSystemContext( | |
60 scoped_ptr<FileSystemTaskRunners> task_runners, | |
61 ExternalMountPoints* external_mount_points, | |
62 quota::SpecialStoragePolicy* special_storage_policy, | |
63 quota::QuotaManagerProxy* quota_manager_proxy, | |
64 ScopedVector<FileSystemMountPointProvider> additional_providers, | |
65 const base::FilePath& partition_path, | |
66 const FileSystemOptions& options) | |
67 : task_runners_(task_runners.Pass()), | |
68 quota_manager_proxy_(quota_manager_proxy), | |
69 sandbox_provider_( | |
70 new SandboxMountPointProvider( | |
71 quota_manager_proxy, | |
72 task_runners_->file_task_runner(), | |
73 partition_path, | |
74 options, | |
75 special_storage_policy)), | |
76 isolated_provider_(new IsolatedMountPointProvider()), | |
77 additional_providers_(additional_providers.Pass()), | |
78 external_mount_points_(external_mount_points), | |
79 partition_path_(partition_path) { | |
80 DCHECK(task_runners_.get()); | |
81 | |
82 if (quota_manager_proxy) { | |
83 quota_manager_proxy->RegisterClient(CreateQuotaClient( | |
84 this, options.is_incognito())); | |
85 } | |
86 | |
87 RegisterMountPointProvider(sandbox_provider_.get()); | |
88 RegisterMountPointProvider(isolated_provider_.get()); | |
89 | |
90 #if defined(OS_CHROMEOS) | |
91 // TODO(kinuko): Move this out of webkit/fileapi layer. | |
92 DCHECK(external_mount_points); | |
93 external_provider_.reset( | |
94 new chromeos::CrosMountPointProvider( | |
95 special_storage_policy, | |
96 external_mount_points, | |
97 ExternalMountPoints::GetSystemInstance())); | |
98 RegisterMountPointProvider(external_provider_.get()); | |
99 #endif | |
100 | |
101 for (ScopedVector<FileSystemMountPointProvider>::const_iterator iter = | |
102 additional_providers_.begin(); | |
103 iter != additional_providers_.end(); ++iter) { | |
104 RegisterMountPointProvider(*iter); | |
105 } | |
106 | |
107 // Additional mount points must be added before regular system-wide | |
108 // mount points. | |
109 if (external_mount_points) | |
110 url_crackers_.push_back(external_mount_points); | |
111 url_crackers_.push_back(ExternalMountPoints::GetSystemInstance()); | |
112 url_crackers_.push_back(IsolatedContext::GetInstance()); | |
113 } | |
114 | |
115 bool FileSystemContext::DeleteDataForOriginOnFileThread( | |
116 const GURL& origin_url) { | |
117 DCHECK(task_runners_->file_task_runner()->RunsTasksOnCurrentThread()); | |
118 DCHECK(sandbox_provider()); | |
119 DCHECK(origin_url == origin_url.GetOrigin()); | |
120 | |
121 // Delete temporary and persistent data. | |
122 return | |
123 (sandbox_provider()->DeleteOriginDataOnFileThread( | |
124 this, quota_manager_proxy(), origin_url, | |
125 kFileSystemTypeTemporary) == | |
126 base::PLATFORM_FILE_OK) && | |
127 (sandbox_provider()->DeleteOriginDataOnFileThread( | |
128 this, quota_manager_proxy(), origin_url, | |
129 kFileSystemTypePersistent) == | |
130 base::PLATFORM_FILE_OK) && | |
131 (sandbox_provider()->DeleteOriginDataOnFileThread( | |
132 this, quota_manager_proxy(), origin_url, | |
133 kFileSystemTypeSyncable) == | |
134 base::PLATFORM_FILE_OK); | |
135 } | |
136 | |
137 FileSystemQuotaUtil* | |
138 FileSystemContext::GetQuotaUtil(FileSystemType type) const { | |
139 FileSystemMountPointProvider* mount_point_provider = | |
140 GetMountPointProvider(type); | |
141 if (!mount_point_provider) | |
142 return NULL; | |
143 return mount_point_provider->GetQuotaUtil(); | |
144 } | |
145 | |
146 AsyncFileUtil* FileSystemContext::GetAsyncFileUtil( | |
147 FileSystemType type) const { | |
148 FileSystemMountPointProvider* mount_point_provider = | |
149 GetMountPointProvider(type); | |
150 if (!mount_point_provider) | |
151 return NULL; | |
152 return mount_point_provider->GetAsyncFileUtil(type); | |
153 } | |
154 | |
155 FileSystemFileUtil* FileSystemContext::GetFileUtil( | |
156 FileSystemType type) const { | |
157 FileSystemMountPointProvider* mount_point_provider = | |
158 GetMountPointProvider(type); | |
159 if (!mount_point_provider) | |
160 return NULL; | |
161 return mount_point_provider->GetFileUtil(type); | |
162 } | |
163 | |
164 CopyOrMoveFileValidatorFactory* | |
165 FileSystemContext::GetCopyOrMoveFileValidatorFactory( | |
166 FileSystemType type, base::PlatformFileError* error_code) const { | |
167 DCHECK(error_code); | |
168 *error_code = base::PLATFORM_FILE_OK; | |
169 FileSystemMountPointProvider* mount_point_provider = | |
170 GetMountPointProvider(type); | |
171 if (!mount_point_provider) | |
172 return NULL; | |
173 return mount_point_provider->GetCopyOrMoveFileValidatorFactory( | |
174 type, error_code); | |
175 } | |
176 | |
177 FileSystemMountPointProvider* FileSystemContext::GetMountPointProvider( | |
178 FileSystemType type) const { | |
179 MountPointProviderMap::const_iterator found = provider_map_.find(type); | |
180 if (found != provider_map_.end()) | |
181 return found->second; | |
182 NOTREACHED() << "Unknown filesystem type: " << type; | |
183 return NULL; | |
184 } | |
185 | |
186 const UpdateObserverList* FileSystemContext::GetUpdateObservers( | |
187 FileSystemType type) const { | |
188 // Currently update observer is only available in SandboxMountPointProvider | |
189 // and TestMountPointProvider. | |
190 // TODO(kinuko): Probably GetUpdateObservers() virtual method should be | |
191 // added to FileSystemMountPointProvider interface and be called like | |
192 // other GetFoo() methods do. | |
193 if (SandboxMountPointProvider::IsSandboxType(type)) | |
194 return sandbox_provider()->GetUpdateObservers(type); | |
195 if (type != kFileSystemTypeTest) | |
196 return NULL; | |
197 FileSystemMountPointProvider* mount_point_provider = | |
198 GetMountPointProvider(type); | |
199 return static_cast<TestMountPointProvider*>( | |
200 mount_point_provider)->GetUpdateObservers(type); | |
201 } | |
202 | |
203 SandboxMountPointProvider* | |
204 FileSystemContext::sandbox_provider() const { | |
205 return sandbox_provider_.get(); | |
206 } | |
207 | |
208 ExternalFileSystemMountPointProvider* | |
209 FileSystemContext::external_provider() const { | |
210 return external_provider_.get(); | |
211 } | |
212 | |
213 void FileSystemContext::OpenFileSystem( | |
214 const GURL& origin_url, | |
215 FileSystemType type, | |
216 bool create, | |
217 const OpenFileSystemCallback& callback) { | |
218 DCHECK(!callback.is_null()); | |
219 | |
220 FileSystemMountPointProvider* mount_point_provider = | |
221 GetMountPointProvider(type); | |
222 if (!mount_point_provider) { | |
223 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY, std::string(), GURL()); | |
224 return; | |
225 } | |
226 | |
227 GURL root_url = GetFileSystemRootURI(origin_url, type); | |
228 std::string name = GetFileSystemName(origin_url, type); | |
229 | |
230 mount_point_provider->ValidateFileSystemRoot( | |
231 origin_url, type, create, | |
232 base::Bind(&DidOpenFileSystem, callback, root_url, name)); | |
233 } | |
234 | |
235 void FileSystemContext::OpenSyncableFileSystem( | |
236 const std::string& mount_name, | |
237 const GURL& origin_url, | |
238 FileSystemType type, | |
239 bool create, | |
240 const OpenFileSystemCallback& callback) { | |
241 DCHECK(!callback.is_null()); | |
242 | |
243 DCHECK(type == kFileSystemTypeSyncable); | |
244 | |
245 GURL root_url = sync_file_system::GetSyncableFileSystemRootURI( | |
246 origin_url, mount_name); | |
247 std::string name = GetFileSystemName(origin_url, kFileSystemTypeSyncable); | |
248 | |
249 FileSystemMountPointProvider* mount_point_provider = | |
250 GetMountPointProvider(type); | |
251 DCHECK(mount_point_provider); | |
252 mount_point_provider->ValidateFileSystemRoot( | |
253 origin_url, type, create, | |
254 base::Bind(&DidOpenFileSystem, callback, root_url, name)); | |
255 } | |
256 | |
257 void FileSystemContext::DeleteFileSystem( | |
258 const GURL& origin_url, | |
259 FileSystemType type, | |
260 const DeleteFileSystemCallback& callback) { | |
261 DCHECK(origin_url == origin_url.GetOrigin()); | |
262 FileSystemMountPointProvider* mount_point_provider = | |
263 GetMountPointProvider(type); | |
264 if (!mount_point_provider) { | |
265 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY); | |
266 return; | |
267 } | |
268 | |
269 mount_point_provider->DeleteFileSystem(origin_url, type, this, callback); | |
270 } | |
271 | |
272 FileSystemOperation* FileSystemContext::CreateFileSystemOperation( | |
273 const FileSystemURL& url, base::PlatformFileError* error_code) { | |
274 if (!url.is_valid()) { | |
275 if (error_code) | |
276 *error_code = base::PLATFORM_FILE_ERROR_INVALID_URL; | |
277 return NULL; | |
278 } | |
279 | |
280 FileSystemMountPointProvider* mount_point_provider = | |
281 GetMountPointProvider(url.type()); | |
282 if (!mount_point_provider) { | |
283 if (error_code) | |
284 *error_code = base::PLATFORM_FILE_ERROR_FAILED; | |
285 return NULL; | |
286 } | |
287 | |
288 base::PlatformFileError fs_error = base::PLATFORM_FILE_OK; | |
289 FileSystemOperation* operation = | |
290 mount_point_provider->CreateFileSystemOperation(url, this, &fs_error); | |
291 | |
292 if (error_code) | |
293 *error_code = fs_error; | |
294 return operation; | |
295 } | |
296 | |
297 scoped_ptr<webkit_blob::FileStreamReader> | |
298 FileSystemContext::CreateFileStreamReader( | |
299 const FileSystemURL& url, | |
300 int64 offset, | |
301 const base::Time& expected_modification_time) { | |
302 if (!url.is_valid()) | |
303 return scoped_ptr<webkit_blob::FileStreamReader>(); | |
304 FileSystemMountPointProvider* mount_point_provider = | |
305 GetMountPointProvider(url.type()); | |
306 if (!mount_point_provider) | |
307 return scoped_ptr<webkit_blob::FileStreamReader>(); | |
308 return mount_point_provider->CreateFileStreamReader( | |
309 url, offset, expected_modification_time, this); | |
310 } | |
311 | |
312 scoped_ptr<FileStreamWriter> FileSystemContext::CreateFileStreamWriter( | |
313 const FileSystemURL& url, | |
314 int64 offset) { | |
315 if (!url.is_valid()) | |
316 return scoped_ptr<FileStreamWriter>(); | |
317 FileSystemMountPointProvider* mount_point_provider = | |
318 GetMountPointProvider(url.type()); | |
319 if (!mount_point_provider) | |
320 return scoped_ptr<FileStreamWriter>(); | |
321 return mount_point_provider->CreateFileStreamWriter(url, offset, this); | |
322 } | |
323 | |
324 void FileSystemContext::SetLocalFileChangeTracker( | |
325 scoped_ptr<sync_file_system::LocalFileChangeTracker> tracker) { | |
326 DCHECK(!change_tracker_.get()); | |
327 DCHECK(tracker.get()); | |
328 change_tracker_ = tracker.Pass(); | |
329 sandbox_provider_->AddSyncableFileUpdateObserver( | |
330 change_tracker_.get(), | |
331 task_runners_->file_task_runner()); | |
332 sandbox_provider_->AddSyncableFileChangeObserver( | |
333 change_tracker_.get(), | |
334 task_runners_->file_task_runner()); | |
335 } | |
336 | |
337 void FileSystemContext::set_sync_context( | |
338 sync_file_system::LocalFileSyncContext* sync_context) { | |
339 sync_context_ = sync_context; | |
340 } | |
341 | |
342 FileSystemURL FileSystemContext::CrackURL(const GURL& url) const { | |
343 return CrackFileSystemURL(FileSystemURL(url)); | |
344 } | |
345 | |
346 FileSystemURL FileSystemContext::CreateCrackedFileSystemURL( | |
347 const GURL& origin, | |
348 FileSystemType type, | |
349 const base::FilePath& path) const { | |
350 return CrackFileSystemURL(FileSystemURL(origin, type, path)); | |
351 } | |
352 | |
353 FileSystemContext::~FileSystemContext() { | |
354 task_runners_->file_task_runner()->DeleteSoon( | |
355 FROM_HERE, change_tracker_.release()); | |
356 } | |
357 | |
358 void FileSystemContext::DeleteOnCorrectThread() const { | |
359 if (!task_runners_->io_task_runner()->RunsTasksOnCurrentThread() && | |
360 task_runners_->io_task_runner()->DeleteSoon(FROM_HERE, this)) { | |
361 return; | |
362 } | |
363 delete this; | |
364 } | |
365 | |
366 FileSystemURL FileSystemContext::CrackFileSystemURL( | |
367 const FileSystemURL& url) const { | |
368 if (!url.is_valid()) | |
369 return FileSystemURL(); | |
370 | |
371 // The returned value in case there is no crackers which can crack the url. | |
372 // This is valid situation for non isolated/external file systems. | |
373 FileSystemURL current = url; | |
374 | |
375 // File system may be mounted multiple times (e.g., an isolated filesystem on | |
376 // top of an external filesystem). Hence cracking needs to be iterated. | |
377 for (;;) { | |
378 FileSystemURL cracked = current; | |
379 for (size_t i = 0; i < url_crackers_.size(); ++i) { | |
380 if (!url_crackers_[i]->HandlesFileSystemMountType(current.type())) | |
381 continue; | |
382 cracked = url_crackers_[i]->CrackFileSystemURL(current); | |
383 if (cracked.is_valid()) | |
384 break; | |
385 } | |
386 if (cracked == current) | |
387 break; | |
388 current = cracked; | |
389 } | |
390 return current; | |
391 } | |
392 | |
393 void FileSystemContext::RegisterMountPointProvider( | |
394 FileSystemMountPointProvider* provider) { | |
395 const FileSystemType mount_types[] = { | |
396 kFileSystemTypeTemporary, | |
397 kFileSystemTypePersistent, | |
398 kFileSystemTypeIsolated, | |
399 kFileSystemTypeExternal, | |
400 }; | |
401 // Register mount point providers for public mount types. | |
402 for (size_t j = 0; j < ARRAYSIZE_UNSAFE(mount_types); ++j) { | |
403 if (provider->CanHandleType(mount_types[j])) { | |
404 const bool inserted = provider_map_.insert( | |
405 std::make_pair(mount_types[j], provider)).second; | |
406 DCHECK(inserted); | |
407 } | |
408 } | |
409 // Register mount point providers for internal types. | |
410 for (int t = kFileSystemInternalTypeEnumStart + 1; | |
411 t < kFileSystemInternalTypeEnumEnd; ++t) { | |
412 FileSystemType type = static_cast<FileSystemType>(t); | |
413 if (provider->CanHandleType(type)) { | |
414 const bool inserted = provider_map_.insert( | |
415 std::make_pair(type, provider)).second; | |
416 DCHECK(inserted); | |
417 } | |
418 } | |
419 } | |
420 | |
421 } // namespace fileapi | |
OLD | NEW |