Separate Simple Backend creation from initialization.
[chromium-blink-merge.git] / webkit / fileapi / sandbox_mount_point_provider.cc
blobb5341e96f8afc5ef0617de0af44ed0b00071aafa
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.
5 #include "webkit/fileapi/sandbox_mount_point_provider.h"
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/metrics/histogram.h"
12 #include "base/task_runner_util.h"
13 #include "googleurl/src/gurl.h"
14 #include "net/base/net_util.h"
15 #include "webkit/fileapi/async_file_util_adapter.h"
16 #include "webkit/fileapi/copy_or_move_file_validator.h"
17 #include "webkit/fileapi/file_system_context.h"
18 #include "webkit/fileapi/file_system_file_stream_reader.h"
19 #include "webkit/fileapi/file_system_operation_context.h"
20 #include "webkit/fileapi/file_system_options.h"
21 #include "webkit/fileapi/file_system_task_runners.h"
22 #include "webkit/fileapi/file_system_types.h"
23 #include "webkit/fileapi/file_system_usage_cache.h"
24 #include "webkit/fileapi/file_system_util.h"
25 #include "webkit/fileapi/local_file_system_operation.h"
26 #include "webkit/fileapi/obfuscated_file_util.h"
27 #include "webkit/fileapi/sandbox_file_stream_writer.h"
28 #include "webkit/fileapi/sandbox_quota_observer.h"
29 #include "webkit/fileapi/syncable/syncable_file_system_operation.h"
30 #include "webkit/quota/quota_manager.h"
32 using quota::QuotaManagerProxy;
34 namespace fileapi {
36 namespace {
38 const char kChromeScheme[] = "chrome";
39 const char kExtensionScheme[] = "chrome-extension";
41 const char kOpenFileSystemLabel[] = "FileSystem.OpenFileSystem";
42 const char kOpenFileSystemDetailLabel[] = "FileSystem.OpenFileSystemDetail";
43 const char kOpenFileSystemDetailNonThrottledLabel[] =
44 "FileSystem.OpenFileSystemDetailNonthrottled";
45 int64 kMinimumStatsCollectionIntervalHours = 1;
47 // A command switch to enable syncing directory operations in Sync FileSystem
48 // API. (http://crbug.com/161442)
49 // TODO(kinuko): this command-line switch should be temporary.
50 const char kEnableSyncDirectoryOperation[] = "enable-sync-directory-operation";
52 // A command line switch to disable usage tracking.
53 const char kDisableUsageTracking[] = "disable-file-system-usage-tracking";
55 enum FileSystemError {
56 kOK = 0,
57 kIncognito,
58 kInvalidSchemeError,
59 kCreateDirectoryError,
60 kNotFound,
61 kUnknownError,
62 kFileSystemErrorMax,
65 const char kTemporaryOriginsCountLabel[] = "FileSystem.TemporaryOriginsCount";
66 const char kPersistentOriginsCountLabel[] = "FileSystem.PersistentOriginsCount";
68 // Restricted names.
69 // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions
70 const base::FilePath::CharType* const kRestrictedNames[] = {
71 FILE_PATH_LITERAL("."), FILE_PATH_LITERAL(".."),
74 // Restricted chars.
75 const base::FilePath::CharType kRestrictedChars[] = {
76 FILE_PATH_LITERAL('/'), FILE_PATH_LITERAL('\\'),
79 class ObfuscatedOriginEnumerator
80 : public SandboxMountPointProvider::OriginEnumerator {
81 public:
82 explicit ObfuscatedOriginEnumerator(ObfuscatedFileUtil* file_util) {
83 enum_.reset(file_util->CreateOriginEnumerator());
85 virtual ~ObfuscatedOriginEnumerator() {}
87 virtual GURL Next() OVERRIDE {
88 return enum_->Next();
91 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE {
92 return enum_->HasFileSystemType(type);
95 private:
96 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enum_;
99 void DidValidateFileSystemRoot(
100 base::WeakPtr<SandboxMountPointProvider> mount_point_provider,
101 const FileSystemMountPointProvider::ValidateFileSystemCallback& callback,
102 base::PlatformFileError* error) {
103 if (mount_point_provider.get())
104 mount_point_provider.get()->CollectOpenFileSystemMetrics(*error);
105 callback.Run(*error);
108 void ValidateRootOnFileThread(
109 ObfuscatedFileUtil* file_util,
110 const GURL& origin_url,
111 FileSystemType type,
112 bool create,
113 base::PlatformFileError* error_ptr) {
114 DCHECK(error_ptr);
116 base::FilePath root_path =
117 file_util->GetDirectoryForOriginAndType(
118 origin_url, type, create, error_ptr);
119 if (*error_ptr != base::PLATFORM_FILE_OK) {
120 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel,
121 kCreateDirectoryError,
122 kFileSystemErrorMax);
123 } else {
124 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, kOK, kFileSystemErrorMax);
126 // The reference of file_util will be derefed on the FILE thread
127 // when the storage of this callback gets deleted regardless of whether
128 // this method is called or not.
131 } // anonymous namespace
133 const base::FilePath::CharType
134 SandboxMountPointProvider::kFileSystemDirectory[] =
135 FILE_PATH_LITERAL("File System");
137 // static
138 bool SandboxMountPointProvider::CanHandleType(FileSystemType type) {
139 return type == kFileSystemTypeTemporary ||
140 type == kFileSystemTypePersistent ||
141 type == kFileSystemTypeSyncable;
144 SandboxMountPointProvider::SandboxMountPointProvider(
145 quota::QuotaManagerProxy* quota_manager_proxy,
146 base::SequencedTaskRunner* file_task_runner,
147 const base::FilePath& profile_path,
148 const FileSystemOptions& file_system_options)
149 : file_task_runner_(file_task_runner),
150 profile_path_(profile_path),
151 file_system_options_(file_system_options),
152 sandbox_file_util_(
153 new AsyncFileUtilAdapter(
154 new ObfuscatedFileUtil(
155 profile_path.Append(kFileSystemDirectory)))),
156 file_system_usage_cache_(new FileSystemUsageCache(file_task_runner)),
157 quota_observer_(new SandboxQuotaObserver(
158 quota_manager_proxy,
159 file_task_runner,
160 sandbox_sync_file_util(),
161 file_system_usage_cache_.get())),
162 enable_sync_directory_operation_(
163 CommandLine::ForCurrentProcess()->HasSwitch(
164 kEnableSyncDirectoryOperation)),
165 enable_usage_tracking_(
166 !CommandLine::ForCurrentProcess()->HasSwitch(
167 kDisableUsageTracking)),
168 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
169 // Set quota observers.
170 UpdateObserverList::Source update_observers_src;
171 AccessObserverList::Source access_observers_src;
173 if (enable_usage_tracking_) {
174 update_observers_src.AddObserver(quota_observer_.get(), file_task_runner_);
175 access_observers_src.AddObserver(quota_observer_.get(), NULL);
178 update_observers_ = UpdateObserverList(update_observers_src);
179 access_observers_ = AccessObserverList(access_observers_src);
180 syncable_update_observers_ = UpdateObserverList(update_observers_src);
183 SandboxMountPointProvider::~SandboxMountPointProvider() {
184 if (!file_task_runner_->RunsTasksOnCurrentThread()) {
185 AsyncFileUtilAdapter* sandbox_file_util = sandbox_file_util_.release();
186 SandboxQuotaObserver* quota_observer = quota_observer_.release();
187 FileSystemUsageCache* file_system_usage_cache =
188 file_system_usage_cache_.release();
189 if (!file_task_runner_->DeleteSoon(FROM_HERE, sandbox_file_util))
190 delete sandbox_file_util;
191 if (!file_task_runner_->DeleteSoon(FROM_HERE, quota_observer))
192 delete quota_observer;
193 if (!file_task_runner_->DeleteSoon(FROM_HERE, file_system_usage_cache))
194 delete file_system_usage_cache;
198 void SandboxMountPointProvider::ValidateFileSystemRoot(
199 const GURL& origin_url, fileapi::FileSystemType type, bool create,
200 const ValidateFileSystemCallback& callback) {
201 if (file_system_options_.is_incognito()) {
202 // TODO(kinuko): return an isolated temporary directory.
203 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
204 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel,
205 kIncognito,
206 kFileSystemErrorMax);
207 return;
210 if (!IsAllowedScheme(origin_url)) {
211 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
212 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel,
213 kInvalidSchemeError,
214 kFileSystemErrorMax);
215 return;
218 base::PlatformFileError* error_ptr = new base::PlatformFileError;
219 file_task_runner_->PostTaskAndReply(
220 FROM_HERE,
221 base::Bind(&ValidateRootOnFileThread,
222 sandbox_sync_file_util(),
223 origin_url, type, create,
224 base::Unretained(error_ptr)),
225 base::Bind(&DidValidateFileSystemRoot,
226 weak_factory_.GetWeakPtr(),
227 callback, base::Owned(error_ptr)));
229 if (enable_usage_tracking_)
230 return;
232 // Schedule full usage recalculation on the next launch without
233 // --disable-file-system-usage-tracking.
234 file_task_runner_->PostTask(
235 FROM_HERE,
236 base::Bind(&SandboxMountPointProvider::InvalidateUsageCacheOnFileThread,
237 sandbox_sync_file_util(), origin_url, type,
238 file_system_usage_cache_.get()));
241 base::FilePath
242 SandboxMountPointProvider::GetFileSystemRootPathOnFileThread(
243 const FileSystemURL& url,
244 bool create) {
245 if (file_system_options_.is_incognito())
246 // TODO(kinuko): return an isolated temporary directory.
247 return base::FilePath();
249 if (!IsAllowedScheme(url.origin()))
250 return base::FilePath();
252 return GetBaseDirectoryForOriginAndType(url.origin(), url.type(), create);
255 FileSystemFileUtil* SandboxMountPointProvider::GetFileUtil(
256 FileSystemType type) {
257 DCHECK(sandbox_file_util_.get());
258 return sandbox_file_util_->sync_file_util();
261 AsyncFileUtil* SandboxMountPointProvider::GetAsyncFileUtil(
262 FileSystemType type) {
263 return sandbox_file_util_.get();
266 CopyOrMoveFileValidatorFactory*
267 SandboxMountPointProvider::GetCopyOrMoveFileValidatorFactory(
268 FileSystemType type,
269 base::PlatformFileError* error_code) {
270 DCHECK(error_code);
271 *error_code = base::PLATFORM_FILE_OK;
272 return NULL;
275 void SandboxMountPointProvider::InitializeCopyOrMoveFileValidatorFactory(
276 FileSystemType type,
277 scoped_ptr<CopyOrMoveFileValidatorFactory> factory) {
278 DCHECK(!factory);
281 FilePermissionPolicy SandboxMountPointProvider::GetPermissionPolicy(
282 const FileSystemURL& url, int permissions) const {
283 if (!CanHandleType(url.type()) || !IsAllowedScheme(url.origin()))
284 return FILE_PERMISSION_ALWAYS_DENY;
286 if (url.path().ReferencesParent())
287 return FILE_PERMISSION_ALWAYS_DENY;
289 // Any write access is disallowed on the root path.
290 if ((url.path().empty() || VirtualPath::DirName(url.path()) == url.path())
291 && (permissions & ~kReadFilePermissions))
292 return FILE_PERMISSION_ALWAYS_DENY;
294 if ((permissions & kCreateFilePermissions) == kCreateFilePermissions) {
295 base::FilePath filename = VirtualPath::BaseName(url.path());
296 // See if the name is allowed to create.
297 for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) {
298 if (filename.value() == kRestrictedNames[i])
299 return FILE_PERMISSION_ALWAYS_DENY;
301 for (size_t i = 0; i < arraysize(kRestrictedChars); ++i) {
302 if (filename.value().find(kRestrictedChars[i]) !=
303 base::FilePath::StringType::npos)
304 return FILE_PERMISSION_ALWAYS_DENY;
308 // Access to the sandbox directory (and only to the directory) should be
309 // always allowed.
310 return FILE_PERMISSION_ALWAYS_ALLOW;
313 FileSystemOperation* SandboxMountPointProvider::CreateFileSystemOperation(
314 const FileSystemURL& url,
315 FileSystemContext* context,
316 base::PlatformFileError* error_code) const {
317 scoped_ptr<FileSystemOperationContext> operation_context(
318 new FileSystemOperationContext(context));
320 // Copy the observer lists (assuming we only have small number of observers).
321 if (url.type() == kFileSystemTypeSyncable) {
322 operation_context->set_update_observers(syncable_update_observers_);
323 operation_context->set_change_observers(syncable_change_observers_);
324 operation_context->set_access_observers(access_observers_);
325 return new sync_file_system::SyncableFileSystemOperation(
326 context, operation_context.Pass());
329 // For regular sandboxed types.
330 operation_context->set_update_observers(update_observers_);
331 operation_context->set_access_observers(access_observers_);
332 return new LocalFileSystemOperation(context, operation_context.Pass());
335 scoped_ptr<webkit_blob::FileStreamReader>
336 SandboxMountPointProvider::CreateFileStreamReader(
337 const FileSystemURL& url,
338 int64 offset,
339 const base::Time& expected_modification_time,
340 FileSystemContext* context) const {
341 return scoped_ptr<webkit_blob::FileStreamReader>(
342 new FileSystemFileStreamReader(
343 context, url, offset, expected_modification_time));
346 scoped_ptr<fileapi::FileStreamWriter>
347 SandboxMountPointProvider::CreateFileStreamWriter(
348 const FileSystemURL& url,
349 int64 offset,
350 FileSystemContext* context) const {
351 return scoped_ptr<fileapi::FileStreamWriter>(
352 new SandboxFileStreamWriter(context, url, offset, update_observers_));
355 FileSystemQuotaUtil* SandboxMountPointProvider::GetQuotaUtil() {
356 return this;
359 void SandboxMountPointProvider::DeleteFileSystem(
360 const GURL& origin_url,
361 FileSystemType type,
362 FileSystemContext* context,
363 const DeleteFileSystemCallback& callback) {
364 base::PostTaskAndReplyWithResult(
365 context->task_runners()->file_task_runner(),
366 FROM_HERE,
367 // It is safe to pass Unretained(this) since context owns it.
368 base::Bind(&SandboxMountPointProvider::DeleteOriginDataOnFileThread,
369 base::Unretained(this),
370 make_scoped_refptr(context),
371 base::Unretained(context->quota_manager_proxy()),
372 origin_url,
373 type),
374 callback);
377 SandboxMountPointProvider::OriginEnumerator*
378 SandboxMountPointProvider::CreateOriginEnumerator() {
379 return new ObfuscatedOriginEnumerator(sandbox_sync_file_util());
382 base::FilePath SandboxMountPointProvider::GetBaseDirectoryForOriginAndType(
383 const GURL& origin_url, fileapi::FileSystemType type, bool create) {
385 base::PlatformFileError error = base::PLATFORM_FILE_OK;
386 base::FilePath path = sandbox_sync_file_util()->GetDirectoryForOriginAndType(
387 origin_url, type, create, &error);
388 if (error != base::PLATFORM_FILE_OK)
389 return base::FilePath();
390 return path;
393 base::PlatformFileError
394 SandboxMountPointProvider::DeleteOriginDataOnFileThread(
395 FileSystemContext* file_system_context,
396 QuotaManagerProxy* proxy,
397 const GURL& origin_url,
398 fileapi::FileSystemType type) {
400 int64 usage = GetOriginUsageOnFileThread(file_system_context,
401 origin_url, type);
403 file_system_usage_cache_->CloseCacheFiles();
404 bool result = sandbox_sync_file_util()->DeleteDirectoryForOriginAndType(
405 origin_url, type);
406 if (result && proxy) {
407 proxy->NotifyStorageModified(
408 quota::QuotaClient::kFileSystem,
409 origin_url,
410 FileSystemTypeToQuotaStorageType(type),
411 -usage);
414 if (result)
415 return base::PLATFORM_FILE_OK;
416 return base::PLATFORM_FILE_ERROR_FAILED;
419 void SandboxMountPointProvider::GetOriginsForTypeOnFileThread(
420 fileapi::FileSystemType type, std::set<GURL>* origins) {
421 DCHECK(CanHandleType(type));
422 DCHECK(origins);
423 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator());
424 GURL origin;
425 while (!(origin = enumerator->Next()).is_empty()) {
426 if (enumerator->HasFileSystemType(type))
427 origins->insert(origin);
429 switch (type) {
430 case kFileSystemTypeTemporary:
431 UMA_HISTOGRAM_COUNTS(kTemporaryOriginsCountLabel, origins->size());
432 break;
433 case kFileSystemTypePersistent:
434 UMA_HISTOGRAM_COUNTS(kPersistentOriginsCountLabel, origins->size());
435 break;
436 default:
437 break;
441 void SandboxMountPointProvider::GetOriginsForHostOnFileThread(
442 fileapi::FileSystemType type, const std::string& host,
443 std::set<GURL>* origins) {
444 DCHECK(CanHandleType(type));
445 DCHECK(origins);
446 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator());
447 GURL origin;
448 while (!(origin = enumerator->Next()).is_empty()) {
449 if (host == net::GetHostOrSpecFromURL(origin) &&
450 enumerator->HasFileSystemType(type))
451 origins->insert(origin);
455 int64 SandboxMountPointProvider::GetOriginUsageOnFileThread(
456 FileSystemContext* file_system_context,
457 const GURL& origin_url,
458 fileapi::FileSystemType type) {
459 DCHECK(CanHandleType(type));
460 if (!enable_usage_tracking_)
461 return 0;
463 base::FilePath base_path =
464 GetBaseDirectoryForOriginAndType(origin_url, type, false);
465 if (base_path.empty() || !file_util::DirectoryExists(base_path))
466 return 0;
467 base::FilePath usage_file_path =
468 base_path.Append(FileSystemUsageCache::kUsageFileName);
470 bool is_valid = file_system_usage_cache_->IsValid(usage_file_path);
471 int32 dirty_status = file_system_usage_cache_->GetDirty(usage_file_path);
472 bool visited = (visited_origins_.find(origin_url) != visited_origins_.end());
473 visited_origins_.insert(origin_url);
474 if (is_valid && (dirty_status == 0 || (dirty_status > 0 && visited))) {
475 // The usage cache is clean (dirty == 0) or the origin is already
476 // initialized and running. Read the cache file to get the usage.
477 return file_system_usage_cache_->GetUsage(usage_file_path);
479 // The usage cache has not been initialized or the cache is dirty.
480 // Get the directory size now and update the cache.
481 file_system_usage_cache_->Delete(usage_file_path);
482 FileSystemOperationContext context(file_system_context);
483 FileSystemURL url = file_system_context->CreateCrackedFileSystemURL(
484 origin_url, type, base::FilePath());
485 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator(
486 sandbox_sync_file_util()->CreateFileEnumerator(&context, url, true));
488 base::FilePath file_path_each;
489 int64 usage = 0;
491 while (!(file_path_each = enumerator->Next()).empty()) {
492 usage += enumerator->Size();
493 usage += ObfuscatedFileUtil::ComputeFilePathCost(file_path_each);
495 // This clears the dirty flag too.
496 file_system_usage_cache_->UpdateUsage(usage_file_path, usage);
497 return usage;
500 void SandboxMountPointProvider::InvalidateUsageCache(
501 const GURL& origin_url, fileapi::FileSystemType type) {
502 DCHECK(CanHandleType(type));
503 base::PlatformFileError error = base::PLATFORM_FILE_OK;
504 base::FilePath usage_file_path = GetUsageCachePathForOriginAndType(
505 sandbox_sync_file_util(), origin_url, type, &error);
506 if (error != base::PLATFORM_FILE_OK)
507 return;
508 file_system_usage_cache_->IncrementDirty(usage_file_path);
511 void SandboxMountPointProvider::CollectOpenFileSystemMetrics(
512 base::PlatformFileError error_code) {
513 base::Time now = base::Time::Now();
514 bool throttled = now < next_release_time_for_open_filesystem_stat_;
515 if (!throttled) {
516 next_release_time_for_open_filesystem_stat_ =
517 now + base::TimeDelta::FromHours(kMinimumStatsCollectionIntervalHours);
520 #define REPORT(report_value) \
521 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemDetailLabel, \
522 (report_value), \
523 kFileSystemErrorMax); \
524 if (!throttled) { \
525 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemDetailNonThrottledLabel, \
526 (report_value), \
527 kFileSystemErrorMax); \
530 switch (error_code) {
531 case base::PLATFORM_FILE_OK:
532 REPORT(kOK);
533 break;
534 case base::PLATFORM_FILE_ERROR_INVALID_URL:
535 REPORT(kInvalidSchemeError);
536 break;
537 case base::PLATFORM_FILE_ERROR_NOT_FOUND:
538 REPORT(kNotFound);
539 break;
540 case base::PLATFORM_FILE_ERROR_FAILED:
541 default:
542 REPORT(kUnknownError);
543 break;
545 #undef REPORT
548 const UpdateObserverList* SandboxMountPointProvider::GetUpdateObservers(
549 FileSystemType type) const {
550 DCHECK(CanHandleType(type));
551 if (type == kFileSystemTypeSyncable)
552 return &syncable_update_observers_;
553 return &update_observers_;
556 void SandboxMountPointProvider::AddSyncableFileUpdateObserver(
557 FileUpdateObserver* observer,
558 base::SequencedTaskRunner* task_runner) {
559 UpdateObserverList::Source observer_source =
560 syncable_update_observers_.source();
561 observer_source.AddObserver(observer, task_runner);
562 syncable_update_observers_ = UpdateObserverList(observer_source);
565 void SandboxMountPointProvider::AddSyncableFileChangeObserver(
566 FileChangeObserver* observer,
567 base::SequencedTaskRunner* task_runner) {
568 ChangeObserverList::Source observer_source =
569 syncable_change_observers_.source();
570 observer_source.AddObserver(observer, task_runner);
571 syncable_change_observers_ = ChangeObserverList(observer_source);
574 LocalFileSystemOperation*
575 SandboxMountPointProvider::CreateFileSystemOperationForSync(
576 FileSystemContext* file_system_context) {
577 scoped_ptr<FileSystemOperationContext> operation_context(
578 new FileSystemOperationContext(file_system_context));
579 operation_context->set_update_observers(update_observers_);
580 operation_context->set_access_observers(access_observers_);
581 return new LocalFileSystemOperation(file_system_context,
582 operation_context.Pass());
585 base::FilePath SandboxMountPointProvider::GetUsageCachePathForOriginAndType(
586 const GURL& origin_url,
587 FileSystemType type) {
588 base::PlatformFileError error;
589 base::FilePath path = GetUsageCachePathForOriginAndType(
590 sandbox_sync_file_util(), origin_url, type, &error);
591 if (error != base::PLATFORM_FILE_OK)
592 return base::FilePath();
593 return path;
596 // static
597 base::FilePath SandboxMountPointProvider::GetUsageCachePathForOriginAndType(
598 ObfuscatedFileUtil* sandbox_file_util,
599 const GURL& origin_url,
600 fileapi::FileSystemType type,
601 base::PlatformFileError* error_out) {
602 DCHECK(error_out);
603 *error_out = base::PLATFORM_FILE_OK;
604 base::FilePath base_path = sandbox_file_util->GetDirectoryForOriginAndType(
605 origin_url, type, false /* create */, error_out);
606 if (*error_out != base::PLATFORM_FILE_OK)
607 return base::FilePath();
608 return base_path.Append(FileSystemUsageCache::kUsageFileName);
611 bool SandboxMountPointProvider::IsAllowedScheme(const GURL& url) const {
612 // Basically we only accept http or https. We allow file:// URLs
613 // only if --allow-file-access-from-files flag is given.
614 if (url.SchemeIs("http") || url.SchemeIs("https"))
615 return true;
616 if (url.SchemeIsFileSystem())
617 return url.inner_url() && IsAllowedScheme(*url.inner_url());
619 for (size_t i = 0;
620 i < file_system_options_.additional_allowed_schemes().size();
621 ++i) {
622 if (url.SchemeIs(
623 file_system_options_.additional_allowed_schemes()[i].c_str()))
624 return true;
626 return false;
629 ObfuscatedFileUtil* SandboxMountPointProvider::sandbox_sync_file_util() {
630 DCHECK(sandbox_file_util_.get());
631 return static_cast<ObfuscatedFileUtil*>(sandbox_file_util_->sync_file_util());
634 // static
635 void SandboxMountPointProvider::InvalidateUsageCacheOnFileThread(
636 ObfuscatedFileUtil* file_util,
637 const GURL& origin,
638 FileSystemType type,
639 FileSystemUsageCache* usage_cache) {
640 base::PlatformFileError error = base::PLATFORM_FILE_OK;
641 base::FilePath usage_cache_path = GetUsageCachePathForOriginAndType(
642 file_util, origin, type, &error);
643 if (error == base::PLATFORM_FILE_OK)
644 usage_cache->IncrementDirty(usage_cache_path);
647 } // namespace fileapi