17dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Copyright 2013 The Chromium Authors. All rights reserved.
27dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// Use of this source code is governed by a BSD-style license that can be
37dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch// found in the LICENSE file.
47dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
53551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "webkit/browser/fileapi/sandbox_file_system_backend_delegate.h"
67dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
7f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include <vector>
8f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
9a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch#include "base/command_line.h"
10a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/file_util.h"
11a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/metrics/histogram.h"
12a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "base/stl_util.h"
137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "base/task_runner_util.h"
14a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "net/base/net_util.h"
15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "webkit/browser/blob/file_stream_reader.h"
167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "webkit/browser/fileapi/async_file_util_adapter.h"
17a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "webkit/browser/fileapi/file_system_context.h"
18a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "webkit/browser/fileapi/file_system_operation_context.h"
19a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "webkit/browser/fileapi/file_system_url.h"
207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "webkit/browser/fileapi/file_system_usage_cache.h"
217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "webkit/browser/fileapi/obfuscated_file_util.h"
22f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "webkit/browser/fileapi/quota/quota_backend_impl.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "webkit/browser/fileapi/quota/quota_reservation.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "webkit/browser/fileapi/quota/quota_reservation_manager.h"
253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "webkit/browser/fileapi/sandbox_file_stream_writer.h"
26a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "webkit/browser/fileapi/sandbox_file_system_backend.h"
277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "webkit/browser/fileapi/sandbox_quota_observer.h"
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "webkit/browser/quota/quota_manager_proxy.h"
29a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#include "webkit/common/fileapi/file_system_util.h"
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
317dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochnamespace fileapi {
327dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
33a3f7b4e666c476898878fa745f637129375cd889Ben Murdochnamespace {
34a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kTemporaryOriginsCountLabel[] = "FileSystem.TemporaryOriginsCount";
363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const char kPersistentOriginsCountLabel[] = "FileSystem.PersistentOriginsCount";
373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
38a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kOpenFileSystemLabel[] = "FileSystem.OpenFileSystem";
39a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kOpenFileSystemDetailLabel[] = "FileSystem.OpenFileSystemDetail";
40a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const char kOpenFileSystemDetailNonThrottledLabel[] =
41a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    "FileSystem.OpenFileSystemDetailNonthrottled";
42a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)int64 kMinimumStatsCollectionIntervalHours = 1;
43a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// For type directory names in ObfuscatedFileUtil.
458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// TODO(kinuko,nhiroki): Each type string registration should be done
468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// via its own backend.
478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kTemporaryDirectoryName[] = "t";
488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kPersistentDirectoryName[] = "p";
498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)const char kSyncableDirectoryName[] = "s";
508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
511e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)const char* kPrepopulateTypes[] = {
521e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  kPersistentDirectoryName,
531e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  kTemporaryDirectoryName
541e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)};
551e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
56a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)enum FileSystemError {
57a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  kOK = 0,
58a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  kIncognito,
59a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  kInvalidSchemeError,
60a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  kCreateDirectoryError,
61a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  kNotFound,
62a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  kUnknownError,
63a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  kFileSystemErrorMax,
64a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
65a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
66a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Restricted names.
67a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions
68a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const base::FilePath::CharType* const kRestrictedNames[] = {
69a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  FILE_PATH_LITERAL("."), FILE_PATH_LITERAL(".."),
70a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
71a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
72a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// Restricted chars.
73a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)const base::FilePath::CharType kRestrictedChars[] = {
74a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  FILE_PATH_LITERAL('/'), FILE_PATH_LITERAL('\\'),
75a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
76a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
778bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string GetTypeStringForURL(const FileSystemURL& url) {
788bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return SandboxFileSystemBackendDelegate::GetTypeString(url.type());
798bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
808bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
818bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::set<std::string> GetKnownTypeStrings() {
828bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  std::set<std::string> known_type_strings;
838bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  known_type_strings.insert(kTemporaryDirectoryName);
848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  known_type_strings.insert(kPersistentDirectoryName);
858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  known_type_strings.insert(kSyncableDirectoryName);
868bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return known_type_strings;
878bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
89a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)class ObfuscatedOriginEnumerator
903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    : public SandboxFileSystemBackendDelegate::OriginEnumerator {
91a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) public:
92a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  explicit ObfuscatedOriginEnumerator(ObfuscatedFileUtil* file_util) {
93a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    enum_.reset(file_util->CreateOriginEnumerator());
94a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
95a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual ~ObfuscatedOriginEnumerator() {}
96a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
97a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  virtual GURL Next() OVERRIDE {
98a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return enum_->Next();
99a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
100a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  virtual bool HasFileSystemType(FileSystemType type) const OVERRIDE {
1028bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return enum_->HasTypeDirectory(
1038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        SandboxFileSystemBackendDelegate::GetTypeString(type));
104a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
105a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
106a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) private:
107a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enum_;
108a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)};
109a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void OpenFileSystemOnFileTaskRunner(
111a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ObfuscatedFileUtil* file_util,
112a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& origin_url,
113a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    FileSystemType type,
114a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    OpenFileSystemMode mode,
1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error* error_ptr) {
116a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(error_ptr);
117a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  const bool create = (mode == OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT);
1188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  file_util->GetDirectoryForOriginAndType(
1198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      origin_url, SandboxFileSystemBackendDelegate::GetTypeString(type),
1208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      create, error_ptr);
1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (*error_ptr != base::File::FILE_OK) {
122a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel,
123a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                              kCreateDirectoryError,
124a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                              kFileSystemErrorMax);
125a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  } else {
126a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, kOK, kFileSystemErrorMax);
127a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
128a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // The reference of file_util will be derefed on the FILE thread
129a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // when the storage of this callback gets deleted regardless of whether
130a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // this method is called or not.
131a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
132a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
133a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)void DidOpenFileSystem(
1343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::WeakPtr<SandboxFileSystemBackendDelegate> delegate,
1355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const base::Callback<void(base::File::Error error)>& callback,
1365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error* error) {
1373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (delegate.get())
1383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    delegate.get()->CollectOpenFileSystemMetrics(*error);
139a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  callback.Run(*error);
140a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch}
141a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch
1421e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)template <typename T>
1431e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)void DeleteSoon(base::SequencedTaskRunner* runner, T* ptr) {
1441e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  if (!runner->DeleteSoon(FROM_HERE, ptr))
1451e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    delete ptr;
1461e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)}
1471e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
148a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}  // namespace
149a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdochconst base::FilePath::CharType
1513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::kFileSystemDirectory[] =
1523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FILE_PATH_LITERAL("File System");
1537dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
1548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// static
1558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)std::string SandboxFileSystemBackendDelegate::GetTypeString(
1568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    FileSystemType type) {
1578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  switch (type) {
1588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    case kFileSystemTypeTemporary:
1598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return kTemporaryDirectoryName;
1608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    case kFileSystemTypePersistent:
1618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return kPersistentDirectoryName;
1628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    case kFileSystemTypeSyncable:
1638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    case kFileSystemTypeSyncableForInternalSync:
1648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return kSyncableDirectoryName;
1658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    case kFileSystemTypeUnknown:
1668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    default:
1678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      NOTREACHED() << "Unknown filesystem type requested:" << type;
1688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return std::string();
1698bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
1708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
1718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
1723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::SandboxFileSystemBackendDelegate(
1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    quota::QuotaManagerProxy* quota_manager_proxy,
1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::SequencedTaskRunner* file_task_runner,
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::FilePath& profile_path,
176a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    quota::SpecialStoragePolicy* special_storage_policy,
177a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const FileSystemOptions& file_system_options)
1787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    : file_task_runner_(file_task_runner),
1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      sandbox_file_util_(new AsyncFileUtilAdapter(
1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          new ObfuscatedFileUtil(
1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              special_storage_policy,
1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch              profile_path.Append(kFileSystemDirectory),
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)              file_system_options.env_override(),
1848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)              file_task_runner,
1858bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)              base::Bind(&GetTypeStringForURL),
1861e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              GetKnownTypeStrings(),
1871e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)              this))),
1887dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      file_system_usage_cache_(new FileSystemUsageCache(file_task_runner)),
1897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      quota_observer_(new SandboxQuotaObserver(
1907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          quota_manager_proxy,
1917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch          file_task_runner,
1923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          obfuscated_file_util(),
193a3f7b4e666c476898878fa745f637129375cd889Ben Murdoch          usage_cache())),
194f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      quota_reservation_manager_(new QuotaReservationManager(
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          scoped_ptr<QuotaReservationManager::QuotaBackend>(
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)              new QuotaBackendImpl(file_task_runner_,
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   obfuscated_file_util(),
198f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   usage_cache(),
199f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   quota_manager_proxy)))),
200558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      special_storage_policy_(special_storage_policy),
201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      file_system_options_(file_system_options),
2023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      is_filesystem_opened_(false),
203a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      weak_factory_(this) {
2041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Prepopulate database only if it can run asynchronously (i.e. the current
2051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // thread is not file_task_runner). Usually this is the case but may not
2061e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // in test code.
207f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!file_system_options.is_incognito() &&
208f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      !file_task_runner_->RunsTasksOnCurrentThread()) {
2091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::vector<std::string> types_to_prepopulate(
2101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        &kPrepopulateTypes[0],
2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        &kPrepopulateTypes[arraysize(kPrepopulateTypes)]);
2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    file_task_runner_->PostTask(
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        FROM_HERE,
2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        base::Bind(&ObfuscatedFileUtil::MaybePrepopulateDatabase,
2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                  base::Unretained(obfuscated_file_util()),
2161e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                  types_to_prepopulate));
2171e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::~SandboxFileSystemBackendDelegate() {
221424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  io_thread_checker_.DetachFromThread();
2221e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2237dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!file_task_runner_->RunsTasksOnCurrentThread()) {
224f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DeleteSoon(file_task_runner_.get(), quota_reservation_manager_.release());
2251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DeleteSoon(file_task_runner_.get(), sandbox_file_util_.release());
2261e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DeleteSoon(file_task_runner_.get(), quota_observer_.release());
2271e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DeleteSoon(file_task_runner_.get(), file_system_usage_cache_.release());
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::OriginEnumerator*
2323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::CreateOriginEnumerator() {
2333551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return new ObfuscatedOriginEnumerator(obfuscated_file_util());
234a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
235a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)base::FilePath
2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::GetBaseDirectoryForOriginAndType(
2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const GURL& origin_url,
2393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type,
2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    bool create) {
2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
2423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::FilePath path = obfuscated_file_util()->GetDirectoryForOriginAndType(
2438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      origin_url, GetTypeString(type), create, &error);
2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (error != base::File::FILE_OK)
245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return base::FilePath();
246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return path;
247a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SandboxFileSystemBackendDelegate::OpenFileSystem(
250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& origin_url,
2513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type,
252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    OpenFileSystemMode mode,
253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const OpenFileSystemCallback& callback,
254a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& root_url) {
255a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!IsAllowedScheme(origin_url)) {
2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(GURL(), std::string(), base::File::FILE_ERROR_SECURITY);
257a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
260a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::string name = GetFileSystemName(origin_url, type);
261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error* error_ptr = new base::File::Error;
263a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  file_task_runner_->PostTaskAndReply(
264a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      FROM_HERE,
2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&OpenFileSystemOnFileTaskRunner,
2663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                 obfuscated_file_util(), origin_url, type, mode,
267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 base::Unretained(error_ptr)),
268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base::Bind(&DidOpenFileSystem,
269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
270a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 base::Bind(callback, root_url, name),
271a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 base::Owned(error_ptr)));
2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  io_thread_checker_.DetachFromThread();
2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  is_filesystem_opened_ = true;
2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<FileSystemOperationContext>
2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::CreateFileSystemOperationContext(
2793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const FileSystemURL& url,
2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemContext* context,
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error* error_code) const {
2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!IsAccessValid(url)) {
2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *error_code = base::File::FILE_ERROR_SECURITY;
2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<FileSystemOperationContext>();
2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const UpdateObserverList* update_observers = GetUpdateObservers(url.type());
2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const ChangeObserverList* change_observers = GetChangeObservers(url.type());
2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(update_observers);
2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<FileSystemOperationContext> operation_context(
2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new FileSystemOperationContext(context));
2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  operation_context->set_update_observers(*update_observers);
2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  operation_context->set_change_observers(
2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      change_observers ? *change_observers : ChangeObserverList());
2963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return operation_context.Pass();
298a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
299a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<webkit_blob::FileStreamReader>
3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::CreateFileStreamReader(
3023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const FileSystemURL& url,
3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    int64 offset,
3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const base::Time& expected_modification_time,
3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemContext* context) const {
3063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!IsAccessValid(url))
3073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<webkit_blob::FileStreamReader>();
3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return scoped_ptr<webkit_blob::FileStreamReader>(
309d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      webkit_blob::FileStreamReader::CreateForFileSystemFile(
3103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          context, url, offset, expected_modification_time));
3113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<FileStreamWriter>
3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::CreateFileStreamWriter(
3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const FileSystemURL& url,
3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    int64 offset,
3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemContext* context,
3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) const {
3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!IsAccessValid(url))
3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<FileStreamWriter>();
3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const UpdateObserverList* observers = GetUpdateObservers(type);
3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(observers);
3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return scoped_ptr<FileStreamWriter>(
3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new SandboxFileStreamWriter(context, url, offset, *observers));
3253551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3263551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::File::Error
3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SandboxFileSystemBackendDelegate::DeleteOriginDataOnFileTaskRunner(
329a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    FileSystemContext* file_system_context,
330a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    quota::QuotaManagerProxy* proxy,
331a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& origin_url,
3323551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) {
3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 usage = GetOriginUsageOnFileTaskRunner(
335a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      file_system_context, origin_url, type);
336a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  usage_cache()->CloseCacheFiles();
3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool result = obfuscated_file_util()->DeleteDirectoryForOriginAndType(
3388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      origin_url, GetTypeString(type));
339a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (result && proxy) {
340a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    proxy->NotifyStorageModified(
341a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        quota::QuotaClient::kFileSystem,
342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        origin_url,
343a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        FileSystemTypeToQuotaStorageType(type),
344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        -usage);
345a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
346a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (result)
3485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::File::FILE_OK;
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::File::FILE_ERROR_FAILED;
350a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
351a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SandboxFileSystemBackendDelegate::GetOriginsForTypeOnFileTaskRunner(
3533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type, std::set<GURL>* origins) {
3545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
355a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(origins);
356a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator());
357a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GURL origin;
358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  while (!(origin = enumerator->Next()).is_empty()) {
359a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (enumerator->HasFileSystemType(type))
360a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      origins->insert(origin);
361a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  switch (type) {
3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case kFileSystemTypeTemporary:
3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      UMA_HISTOGRAM_COUNTS(kTemporaryOriginsCountLabel, origins->size());
3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case kFileSystemTypePersistent:
3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      UMA_HISTOGRAM_COUNTS(kPersistentOriginsCountLabel, origins->size());
3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
3693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    default:
3703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
3713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
372a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
373a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SandboxFileSystemBackendDelegate::GetOriginsForHostOnFileTaskRunner(
3753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type, const std::string& host,
376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    std::set<GURL>* origins) {
3775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
378a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(origins);
379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator());
380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GURL origin;
381a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  while (!(origin = enumerator->Next()).is_empty()) {
382a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (host == net::GetHostOrSpecFromURL(origin) &&
383a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        enumerator->HasFileSystemType(type))
384a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      origins->insert(origin);
385a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
386a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
387a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int64 SandboxFileSystemBackendDelegate::GetOriginUsageOnFileTaskRunner(
389a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    FileSystemContext* file_system_context,
390a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& origin_url,
3913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) {
3925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
3935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
394a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Don't use usage cache and return recalculated usage for sticky invalidated
395a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // origins.
396a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (ContainsKey(sticky_dirty_origins_, std::make_pair(origin_url, type)))
397a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return RecalculateUsage(file_system_context, origin_url, type);
398a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
399a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::FilePath base_path =
400a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      GetBaseDirectoryForOriginAndType(origin_url, type, false);
401a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (base_path.empty() || !base::DirectoryExists(base_path))
402a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return 0;
403a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::FilePath usage_file_path =
404a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base_path.Append(FileSystemUsageCache::kUsageFileName);
405a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
406a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool is_valid = usage_cache()->IsValid(usage_file_path);
407a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  uint32 dirty_status = 0;
408a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool dirty_status_available =
409a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      usage_cache()->GetDirty(usage_file_path, &dirty_status);
410a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool visited = !visited_origins_.insert(origin_url).second;
411a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (is_valid && (dirty_status == 0 || (dirty_status_available && visited))) {
412a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // The usage cache is clean (dirty == 0) or the origin is already
413a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // initialized and running.  Read the cache file to get the usage.
414a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    int64 usage = 0;
415a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return usage_cache()->GetUsage(usage_file_path, &usage) ? usage : -1;
416a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
417a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // The usage cache has not been initialized or the cache is dirty.
418a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Get the directory size now and update the cache.
419a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  usage_cache()->Delete(usage_file_path);
420a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
421a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int64 usage = RecalculateUsage(file_system_context, origin_url, type);
422a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
423a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // This clears the dirty flag too.
424a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  usage_cache()->UpdateUsage(usage_file_path, usage);
425a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return usage;
426a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
427a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_refptr<QuotaReservation>
429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SandboxFileSystemBackendDelegate::CreateQuotaReservationOnFileTaskRunner(
430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const GURL& origin,
431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FileSystemType type) {
432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(quota_reservation_manager_);
434f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return quota_reservation_manager_->CreateReservation(origin, type);
435f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
436f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SandboxFileSystemBackendDelegate::AddFileUpdateObserver(
4383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type,
4393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileUpdateObserver* observer,
4403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::SequencedTaskRunner* task_runner) {
441424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!is_filesystem_opened_ || io_thread_checker_.CalledOnValidThread());
4423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  update_observers_[type] =
4433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      update_observers_[type].AddObserver(observer, task_runner);
4443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SandboxFileSystemBackendDelegate::AddFileChangeObserver(
4473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type,
4483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileChangeObserver* observer,
4493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::SequencedTaskRunner* task_runner) {
450424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!is_filesystem_opened_ || io_thread_checker_.CalledOnValidThread());
4513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  change_observers_[type] =
4523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      change_observers_[type].AddObserver(observer, task_runner);
4533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SandboxFileSystemBackendDelegate::AddFileAccessObserver(
4563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type,
4573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileAccessObserver* observer,
4583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::SequencedTaskRunner* task_runner) {
459424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!is_filesystem_opened_ || io_thread_checker_.CalledOnValidThread());
4603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  access_observers_[type] =
4613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      access_observers_[type].AddObserver(observer, task_runner);
4623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const UpdateObserverList* SandboxFileSystemBackendDelegate::GetUpdateObservers(
4653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) const {
4663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::map<FileSystemType, UpdateObserverList>::const_iterator iter =
4673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      update_observers_.find(type);
4683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (iter == update_observers_.end())
4693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return NULL;
4703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return &iter->second;
4713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const ChangeObserverList* SandboxFileSystemBackendDelegate::GetChangeObservers(
4743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) const {
4753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::map<FileSystemType, ChangeObserverList>::const_iterator iter =
4763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      change_observers_.find(type);
4773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (iter == change_observers_.end())
4783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return NULL;
4793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return &iter->second;
4803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const AccessObserverList* SandboxFileSystemBackendDelegate::GetAccessObservers(
4833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) const {
4843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::map<FileSystemType, AccessObserverList>::const_iterator iter =
4853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      access_observers_.find(type);
4863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (iter == access_observers_.end())
4873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return NULL;
4883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return &iter->second;
4893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SandboxFileSystemBackendDelegate::RegisterQuotaUpdateObserver(
4928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    FileSystemType type) {
4938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  AddFileUpdateObserver(type, quota_observer_.get(), file_task_runner_.get());
4948bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SandboxFileSystemBackendDelegate::InvalidateUsageCache(
497a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& origin,
4983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) {
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
500a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::FilePath usage_file_path = GetUsageCachePathForOriginAndType(
5013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      obfuscated_file_util(), origin, type, &error);
5025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (error != base::File::FILE_OK)
503a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
504a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  usage_cache()->IncrementDirty(usage_file_path);
505a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
506a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5073551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SandboxFileSystemBackendDelegate::StickyInvalidateUsageCache(
508a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& origin,
5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) {
510a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  sticky_dirty_origins_.insert(std::make_pair(origin, type));
511a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  quota_observer()->SetUsageCacheEnabled(origin, type, false);
512a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  InvalidateUsageCache(origin, type);
513a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
514a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FileSystemFileUtil* SandboxFileSystemBackendDelegate::sync_file_util() {
5163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return static_cast<AsyncFileUtilAdapter*>(file_util())->sync_file_util();
5173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SandboxFileSystemBackendDelegate::IsAccessValid(
5208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const FileSystemURL& url) const {
5218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!IsAllowedScheme(url.origin()))
5228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
5238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (url.path().ReferencesParent())
5258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
5268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Return earlier if the path is '/', because VirtualPath::BaseName()
5288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // returns '/' for '/' and we fail the "basename != '/'" check below.
5298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // (We exclude '.' because it's disallowed by spec.)
5308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (VirtualPath::IsRootPath(url.path()) &&
5318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      url.path() != base::FilePath(base::FilePath::kCurrentDirectory))
5328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return true;
5338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Restricted names specified in
5358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions
5368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::FilePath filename = VirtualPath::BaseName(url.path());
5378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // See if the name is allowed to create.
5388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) {
5398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (filename.value() == kRestrictedNames[i])
5408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return false;
5418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kRestrictedChars); ++i) {
5438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (filename.value().find(kRestrictedChars[i]) !=
5448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        base::FilePath::StringType::npos)
5458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return false;
5468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return true;
5498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SandboxFileSystemBackendDelegate::IsAllowedScheme(const GURL& url) const {
5528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Basically we only accept http or https. We allow file:// URLs
5538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // only if --allow-file-access-from-files flag is given.
5548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (url.SchemeIsHTTPOrHTTPS())
5558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return true;
5568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (url.SchemeIsFileSystem())
5578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return url.inner_url() && IsAllowedScheme(*url.inner_url());
5588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (size_t i = 0;
5608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)       i < file_system_options_.additional_allowed_schemes().size();
5618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)       ++i) {
5628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (url.SchemeIs(
5638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            file_system_options_.additional_allowed_schemes()[i].c_str()))
5648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return true;
5658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return false;
5678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)base::FilePath
5703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::GetUsageCachePathForOriginAndType(
571a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& origin_url,
572a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    FileSystemType type) {
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error;
574a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::FilePath path = GetUsageCachePathForOriginAndType(
5753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      obfuscated_file_util(), origin_url, type, &error);
5765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (error != base::File::FILE_OK)
577a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return base::FilePath();
578a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return path;
579a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
580a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
581a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
5823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)base::FilePath
5833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::GetUsageCachePathForOriginAndType(
584a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ObfuscatedFileUtil* sandbox_file_util,
585a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& origin_url,
5863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type,
5875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error* error_out) {
588a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(error_out);
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *error_out = base::File::FILE_OK;
590a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::FilePath base_path = sandbox_file_util->GetDirectoryForOriginAndType(
5918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      origin_url, GetTypeString(type), false /* create */, error_out);
5925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (*error_out != base::File::FILE_OK)
593a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return base::FilePath();
594a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return base_path.Append(FileSystemUsageCache::kUsageFileName);
595a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
596a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)int64 SandboxFileSystemBackendDelegate::RecalculateUsage(
5983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemContext* context,
5993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const GURL& origin,
6003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) {
601a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  FileSystemOperationContext operation_context(context);
602a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  FileSystemURL url = context->CreateCrackedFileSystemURL(
603a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      origin, type, base::FilePath());
604a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator(
6053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      obfuscated_file_util()->CreateFileEnumerator(
6063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          &operation_context, url, true));
607a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
608a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::FilePath file_path_each;
609a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int64 usage = 0;
610a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
611a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  while (!(file_path_each = enumerator->Next()).empty()) {
612a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    usage += enumerator->Size();
613a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    usage += ObfuscatedFileUtil::ComputeFilePathCost(file_path_each);
614a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
615a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
616a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return usage;
617a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
618a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SandboxFileSystemBackendDelegate::CollectOpenFileSystemMetrics(
6205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error_code) {
621a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::Time now = base::Time::Now();
622a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool throttled = now < next_release_time_for_open_filesystem_stat_;
623a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!throttled) {
624a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    next_release_time_for_open_filesystem_stat_ =
625a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        now + base::TimeDelta::FromHours(kMinimumStatsCollectionIntervalHours);
626a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
627a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
628a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#define REPORT(report_value)                                            \
629a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemDetailLabel,                 \
630a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                            (report_value),                             \
631a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                            kFileSystemErrorMax);                       \
632a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!throttled) {                                                     \
633a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemDetailNonThrottledLabel,   \
634a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                              (report_value),                           \
635a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                              kFileSystemErrorMax);                     \
636a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
637a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
638a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  switch (error_code) {
6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_OK:
640a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      REPORT(kOK);
641a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_INVALID_URL:
643a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      REPORT(kInvalidSchemeError);
644a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_NOT_FOUND:
646a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      REPORT(kNotFound);
647a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
6485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_FAILED:
649a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    default:
650a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      REPORT(kUnknownError);
651a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
652a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
653a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#undef REPORT
654a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
655a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6563551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ObfuscatedFileUtil* SandboxFileSystemBackendDelegate::obfuscated_file_util() {
6573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return static_cast<ObfuscatedFileUtil*>(sync_file_util());
6587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
6597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Declared in obfuscated_file_util.h.
6618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// static
6628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ObfuscatedFileUtil* ObfuscatedFileUtil::CreateForTesting(
6638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    quota::SpecialStoragePolicy* special_storage_policy,
6648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const base::FilePath& file_system_directory,
6655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    leveldb::Env* env_override,
6668bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::SequencedTaskRunner* file_task_runner) {
6678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return new ObfuscatedFileUtil(special_storage_policy,
6688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                file_system_directory,
6695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                env_override,
6708bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                file_task_runner,
6718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                base::Bind(&GetTypeStringForURL),
6721e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                GetKnownTypeStrings(),
6731e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                NULL);
6748bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
6758bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
6767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}  // namespace fileapi
677