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
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/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"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/files/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"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/blob/file_stream_reader.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/async_file_util_adapter.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_context.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_operation_context.h"
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_url.h"
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/file_system_usage_cache.h"
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/obfuscated_file_util.h"
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/quota/quota_backend_impl.h"
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/quota/quota_reservation.h"
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/quota/quota_reservation_manager.h"
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/sandbox_file_stream_writer.h"
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/sandbox_file_system_backend.h"
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/fileapi/sandbox_quota_observer.h"
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/browser/quota/quota_manager_proxy.h"
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "storage/common/fileapi/file_system_util.h"
307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
3103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)namespace storage {
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(
17303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::QuotaManagerProxy* quota_manager_proxy,
1747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    base::SequencedTaskRunner* file_task_runner,
1757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    const base::FilePath& profile_path,
17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::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(
18003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          new ObfuscatedFileUtil(special_storage_policy,
18103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                 profile_path.Append(kFileSystemDirectory),
18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                 file_system_options.env_override(),
18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                 file_task_runner,
18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                 base::Bind(&GetTypeStringForURL),
18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                 GetKnownTypeStrings(),
18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                 this))),
1877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch      file_system_usage_cache_(new FileSystemUsageCache(file_task_runner)),
18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      quota_observer_(new SandboxQuotaObserver(quota_manager_proxy,
18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                               file_task_runner,
19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                               obfuscated_file_util(),
19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                               usage_cache())),
192f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      quota_reservation_manager_(new QuotaReservationManager(
193f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)          scoped_ptr<QuotaReservationManager::QuotaBackend>(
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              new QuotaBackendImpl(file_task_runner_.get(),
195f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   obfuscated_file_util(),
196f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   usage_cache(),
197f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                                   quota_manager_proxy)))),
198558790d6acca3451cf3a6b497803a5f07d0bec58Ben Murdoch      special_storage_policy_(special_storage_policy),
199a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      file_system_options_(file_system_options),
2003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      is_filesystem_opened_(false),
201a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      weak_factory_(this) {
2021e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // Prepopulate database only if it can run asynchronously (i.e. the current
2031e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // thread is not file_task_runner). Usually this is the case but may not
2041e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  // in test code.
205f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  if (!file_system_options.is_incognito() &&
206f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)      !file_task_runner_->RunsTasksOnCurrentThread()) {
2071e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    std::vector<std::string> types_to_prepopulate(
2081e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        &kPrepopulateTypes[0],
2091e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        &kPrepopulateTypes[arraysize(kPrepopulateTypes)]);
2101e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    file_task_runner_->PostTask(
2111e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        FROM_HERE,
2121e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)        base::Bind(&ObfuscatedFileUtil::MaybePrepopulateDatabase,
2131e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                  base::Unretained(obfuscated_file_util()),
2141e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                  types_to_prepopulate));
2151e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  }
2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::~SandboxFileSystemBackendDelegate() {
219424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  io_thread_checker_.DetachFromThread();
2201e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)
2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (!file_task_runner_->RunsTasksOnCurrentThread()) {
222f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    DeleteSoon(file_task_runner_.get(), quota_reservation_manager_.release());
2231e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DeleteSoon(file_task_runner_.get(), sandbox_file_util_.release());
2241e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DeleteSoon(file_task_runner_.get(), quota_observer_.release());
2251e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)    DeleteSoon(file_task_runner_.get(), file_system_usage_cache_.release());
2267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  }
2277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
2293551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::OriginEnumerator*
2303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::CreateOriginEnumerator() {
2313551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return new ObfuscatedOriginEnumerator(obfuscated_file_util());
232a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
233a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)base::FilePath
2353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::GetBaseDirectoryForOriginAndType(
2363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const GURL& origin_url,
2373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type,
2383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    bool create) {
2395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
2403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  base::FilePath path = obfuscated_file_util()->GetDirectoryForOriginAndType(
2418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      origin_url, GetTypeString(type), create, &error);
2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (error != base::File::FILE_OK)
243a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return base::FilePath();
244a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return path;
245a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
246a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SandboxFileSystemBackendDelegate::OpenFileSystem(
248a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& origin_url,
2493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type,
250a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    OpenFileSystemMode mode,
251a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const OpenFileSystemCallback& callback,
252a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& root_url) {
253a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!IsAllowedScheme(origin_url)) {
2545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    callback.Run(GURL(), std::string(), base::File::FILE_ERROR_SECURITY);
255a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
256a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
257a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
258a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  std::string name = GetFileSystemName(origin_url, type);
259a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error* error_ptr = new base::File::Error;
261a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  file_task_runner_->PostTaskAndReply(
262a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      FROM_HERE,
2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::Bind(&OpenFileSystemOnFileTaskRunner,
2643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)                 obfuscated_file_util(), origin_url, type, mode,
265a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 base::Unretained(error_ptr)),
266a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base::Bind(&DidOpenFileSystem,
267a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 weak_factory_.GetWeakPtr(),
268a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 base::Bind(callback, root_url, name),
269a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                 base::Owned(error_ptr)));
2703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
271424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  io_thread_checker_.DetachFromThread();
2723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  is_filesystem_opened_ = true;
2733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
2743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<FileSystemOperationContext>
2763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::CreateFileSystemOperationContext(
2773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const FileSystemURL& url,
2783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemContext* context,
2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error* error_code) const {
2803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!IsAccessValid(url)) {
2815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    *error_code = base::File::FILE_ERROR_SECURITY;
2823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<FileSystemOperationContext>();
2833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
2843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const UpdateObserverList* update_observers = GetUpdateObservers(url.type());
2863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const ChangeObserverList* change_observers = GetChangeObservers(url.type());
2873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(update_observers);
2883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  scoped_ptr<FileSystemOperationContext> operation_context(
2903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new FileSystemOperationContext(context));
2913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  operation_context->set_update_observers(*update_observers);
2923551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  operation_context->set_change_observers(
2933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      change_observers ? *change_observers : ChangeObserverList());
2943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
2953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return operation_context.Pass();
296a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
297a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
29803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_ptr<storage::FileStreamReader>
2993551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::CreateFileStreamReader(
3003551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const FileSystemURL& url,
3013551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    int64 offset,
3023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const base::Time& expected_modification_time,
3033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemContext* context) const {
3043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!IsAccessValid(url))
30503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return scoped_ptr<storage::FileStreamReader>();
30603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return scoped_ptr<storage::FileStreamReader>(
30703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      storage::FileStreamReader::CreateForFileSystemFile(
3083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          context, url, offset, expected_modification_time));
3093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<FileStreamWriter>
3123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::CreateFileStreamWriter(
3133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const FileSystemURL& url,
3143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    int64 offset,
3153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemContext* context,
3163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) const {
3173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (!IsAccessValid(url))
3183551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return scoped_ptr<FileStreamWriter>();
3193551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  const UpdateObserverList* observers = GetUpdateObservers(type);
3203551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  DCHECK(observers);
3213551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return scoped_ptr<FileStreamWriter>(
3223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      new SandboxFileStreamWriter(context, url, offset, *observers));
3233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3243551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::File::Error
3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SandboxFileSystemBackendDelegate::DeleteOriginDataOnFileTaskRunner(
327a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    FileSystemContext* file_system_context,
32803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::QuotaManagerProxy* proxy,
329a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& origin_url,
3303551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) {
3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  int64 usage = GetOriginUsageOnFileTaskRunner(
333a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      file_system_context, origin_url, type);
334a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  usage_cache()->CloseCacheFiles();
3353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  bool result = obfuscated_file_util()->DeleteDirectoryForOriginAndType(
3368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      origin_url, GetTypeString(type));
337a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (result && proxy) {
33803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    proxy->NotifyStorageModified(storage::QuotaClient::kFileSystem,
33903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                 origin_url,
34003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                 FileSystemTypeToQuotaStorageType(type),
34103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                                 -usage);
342a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
343a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
344a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (result)
3455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    return base::File::FILE_OK;
3465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::File::FILE_ERROR_FAILED;
347a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
348a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SandboxFileSystemBackendDelegate::GetOriginsForTypeOnFileTaskRunner(
3503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type, std::set<GURL>* origins) {
3515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
352a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(origins);
353a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator());
354a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GURL origin;
355a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  while (!(origin = enumerator->Next()).is_empty()) {
356a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (enumerator->HasFileSystemType(type))
357a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      origins->insert(origin);
358a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  switch (type) {
3603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case kFileSystemTypeTemporary:
3613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      UMA_HISTOGRAM_COUNTS(kTemporaryOriginsCountLabel, origins->size());
3623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
3633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    case kFileSystemTypePersistent:
3643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      UMA_HISTOGRAM_COUNTS(kPersistentOriginsCountLabel, origins->size());
3653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
3663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    default:
3673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      break;
3683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  }
369a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
370a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SandboxFileSystemBackendDelegate::GetOriginsForHostOnFileTaskRunner(
3723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type, const std::string& host,
373a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    std::set<GURL>* origins) {
3745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
375a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(origins);
376a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator());
377a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  GURL origin;
378a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  while (!(origin = enumerator->Next()).is_empty()) {
379a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    if (host == net::GetHostOrSpecFromURL(origin) &&
380a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        enumerator->HasFileSystemType(type))
381a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      origins->insert(origin);
382a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
383a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
384a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
3855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)int64 SandboxFileSystemBackendDelegate::GetOriginUsageOnFileTaskRunner(
386a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    FileSystemContext* file_system_context,
387a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& origin_url,
3883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) {
3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
391a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Don't use usage cache and return recalculated usage for sticky invalidated
392a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // origins.
393a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (ContainsKey(sticky_dirty_origins_, std::make_pair(origin_url, type)))
394a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return RecalculateUsage(file_system_context, origin_url, type);
395a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
396a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::FilePath base_path =
397a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      GetBaseDirectoryForOriginAndType(origin_url, type, false);
398a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (base_path.empty() || !base::DirectoryExists(base_path))
399a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return 0;
400a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::FilePath usage_file_path =
401a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      base_path.Append(FileSystemUsageCache::kUsageFileName);
402a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
403a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool is_valid = usage_cache()->IsValid(usage_file_path);
404a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  uint32 dirty_status = 0;
405a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool dirty_status_available =
406a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      usage_cache()->GetDirty(usage_file_path, &dirty_status);
407a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool visited = !visited_origins_.insert(origin_url).second;
408a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (is_valid && (dirty_status == 0 || (dirty_status_available && visited))) {
409a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // The usage cache is clean (dirty == 0) or the origin is already
410a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    // initialized and running.  Read the cache file to get the usage.
411a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    int64 usage = 0;
412a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return usage_cache()->GetUsage(usage_file_path, &usage) ? usage : -1;
413a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
414a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // The usage cache has not been initialized or the cache is dirty.
415a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // Get the directory size now and update the cache.
416a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  usage_cache()->Delete(usage_file_path);
417a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
418a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int64 usage = RecalculateUsage(file_system_context, origin_url, type);
419a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
420a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  // This clears the dirty flag too.
421a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  usage_cache()->UpdateUsage(usage_file_path, usage);
422a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return usage;
423a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
424a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
425f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)scoped_refptr<QuotaReservation>
426f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)SandboxFileSystemBackendDelegate::CreateQuotaReservationOnFileTaskRunner(
427f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    const GURL& origin,
428f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    FileSystemType type) {
429f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(file_task_runner_->RunsTasksOnCurrentThread());
430f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  DCHECK(quota_reservation_manager_);
431f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return quota_reservation_manager_->CreateReservation(origin, type);
432f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
433f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
4343551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SandboxFileSystemBackendDelegate::AddFileUpdateObserver(
4353551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type,
4363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileUpdateObserver* observer,
4373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::SequencedTaskRunner* task_runner) {
438424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!is_filesystem_opened_ || io_thread_checker_.CalledOnValidThread());
4393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  update_observers_[type] =
4403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      update_observers_[type].AddObserver(observer, task_runner);
4413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SandboxFileSystemBackendDelegate::AddFileChangeObserver(
4443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type,
4453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileChangeObserver* observer,
4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::SequencedTaskRunner* task_runner) {
447424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!is_filesystem_opened_ || io_thread_checker_.CalledOnValidThread());
4483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  change_observers_[type] =
4493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      change_observers_[type].AddObserver(observer, task_runner);
4503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SandboxFileSystemBackendDelegate::AddFileAccessObserver(
4533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type,
4543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileAccessObserver* observer,
4553551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    base::SequencedTaskRunner* task_runner) {
456424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)  DCHECK(!is_filesystem_opened_ || io_thread_checker_.CalledOnValidThread());
4573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  access_observers_[type] =
4583551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      access_observers_[type].AddObserver(observer, task_runner);
4593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4603551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4613551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const UpdateObserverList* SandboxFileSystemBackendDelegate::GetUpdateObservers(
4623551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) const {
4633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::map<FileSystemType, UpdateObserverList>::const_iterator iter =
4643551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      update_observers_.find(type);
4653551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (iter == update_observers_.end())
4663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return NULL;
4673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return &iter->second;
4683551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4693551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4703551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const ChangeObserverList* SandboxFileSystemBackendDelegate::GetChangeObservers(
4713551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) const {
4723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::map<FileSystemType, ChangeObserverList>::const_iterator iter =
4733551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      change_observers_.find(type);
4743551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (iter == change_observers_.end())
4753551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return NULL;
4763551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return &iter->second;
4773551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4783551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)const AccessObserverList* SandboxFileSystemBackendDelegate::GetAccessObservers(
4803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) const {
4813551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  std::map<FileSystemType, AccessObserverList>::const_iterator iter =
4823551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      access_observers_.find(type);
4833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (iter == access_observers_.end())
4843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    return NULL;
4853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return &iter->second;
4863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
4873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
4888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void SandboxFileSystemBackendDelegate::RegisterQuotaUpdateObserver(
4898bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    FileSystemType type) {
4908bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  AddFileUpdateObserver(type, quota_observer_.get(), file_task_runner_.get());
4918bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
4928bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
4933551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SandboxFileSystemBackendDelegate::InvalidateUsageCache(
494a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& origin,
4953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) {
4965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error = base::File::FILE_OK;
497a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::FilePath usage_file_path = GetUsageCachePathForOriginAndType(
4983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      obfuscated_file_util(), origin, type, &error);
4995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (error != base::File::FILE_OK)
500a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return;
501a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  usage_cache()->IncrementDirty(usage_file_path);
502a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
503a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5043551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SandboxFileSystemBackendDelegate::StickyInvalidateUsageCache(
505a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& origin,
5063551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) {
507a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  sticky_dirty_origins_.insert(std::make_pair(origin, type));
508a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  quota_observer()->SetUsageCacheEnabled(origin, type, false);
509a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  InvalidateUsageCache(origin, type);
510a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
511a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)FileSystemFileUtil* SandboxFileSystemBackendDelegate::sync_file_util() {
5133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return static_cast<AsyncFileUtilAdapter*>(file_util())->sync_file_util();
5143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
5153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
5168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SandboxFileSystemBackendDelegate::IsAccessValid(
5178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const FileSystemURL& url) const {
5188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (!IsAllowedScheme(url.origin()))
5198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
5208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (url.path().ReferencesParent())
5228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return false;
5238bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Return earlier if the path is '/', because VirtualPath::BaseName()
5258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // returns '/' for '/' and we fail the "basename != '/'" check below.
5268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // (We exclude '.' because it's disallowed by spec.)
5278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (VirtualPath::IsRootPath(url.path()) &&
5288bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      url.path() != base::FilePath(base::FilePath::kCurrentDirectory))
5298bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return true;
5308bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5318bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Restricted names specified in
5328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions
5338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  base::FilePath filename = VirtualPath::BaseName(url.path());
5348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // See if the name is allowed to create.
5358bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) {
5368bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (filename.value() == kRestrictedNames[i])
5378bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return false;
5388bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5398bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (size_t i = 0; i < arraysize(kRestrictedChars); ++i) {
5408bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (filename.value().find(kRestrictedChars[i]) !=
5418bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)        base::FilePath::StringType::npos)
5428bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return false;
5438bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5448bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5458bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return true;
5468bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5478bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5488bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)bool SandboxFileSystemBackendDelegate::IsAllowedScheme(const GURL& url) const {
5498bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // Basically we only accept http or https. We allow file:// URLs
5508bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  // only if --allow-file-access-from-files flag is given.
5518bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (url.SchemeIsHTTPOrHTTPS())
5528bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return true;
5538bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  if (url.SchemeIsFileSystem())
5548bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    return url.inner_url() && IsAllowedScheme(*url.inner_url());
5558bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5568bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  for (size_t i = 0;
5578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)       i < file_system_options_.additional_allowed_schemes().size();
5588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)       ++i) {
5598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    if (url.SchemeIs(
5608bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)            file_system_options_.additional_allowed_schemes()[i].c_str()))
5618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      return true;
5628bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  }
5638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return false;
5648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
5658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
5663551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)base::FilePath
5673551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::GetUsageCachePathForOriginAndType(
568a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& origin_url,
569a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    FileSystemType type) {
5705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::File::Error error;
571a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::FilePath path = GetUsageCachePathForOriginAndType(
5723551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      obfuscated_file_util(), origin_url, type, &error);
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (error != base::File::FILE_OK)
574a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return base::FilePath();
575a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return path;
576a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
577a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
578a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)// static
5793551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)base::FilePath
5803551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)SandboxFileSystemBackendDelegate::GetUsageCachePathForOriginAndType(
581a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    ObfuscatedFileUtil* sandbox_file_util,
582a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    const GURL& origin_url,
5833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type,
5845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error* error_out) {
585a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  DCHECK(error_out);
5865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  *error_out = base::File::FILE_OK;
587a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::FilePath base_path = sandbox_file_util->GetDirectoryForOriginAndType(
5888bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)      origin_url, GetTypeString(type), false /* create */, error_out);
5895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (*error_out != base::File::FILE_OK)
590a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    return base::FilePath();
591a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return base_path.Append(FileSystemUsageCache::kUsageFileName);
592a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
593a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
5943551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)int64 SandboxFileSystemBackendDelegate::RecalculateUsage(
5953551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemContext* context,
5963551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    const GURL& origin,
5973551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)    FileSystemType type) {
598a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  FileSystemOperationContext operation_context(context);
599a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  FileSystemURL url = context->CreateCrackedFileSystemURL(
600a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      origin, type, base::FilePath());
601a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator(
6023551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)      obfuscated_file_util()->CreateFileEnumerator(
6033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)          &operation_context, url, true));
604a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
605a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::FilePath file_path_each;
606a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  int64 usage = 0;
607a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
608a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  while (!(file_path_each = enumerator->Next()).empty()) {
609a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    usage += enumerator->Size();
610a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    usage += ObfuscatedFileUtil::ComputeFilePathCost(file_path_each);
611a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
612a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
613a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  return usage;
614a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
615a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void SandboxFileSystemBackendDelegate::CollectOpenFileSystemMetrics(
6175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::File::Error error_code) {
618a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  base::Time now = base::Time::Now();
619a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  bool throttled = now < next_release_time_for_open_filesystem_stat_;
620a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!throttled) {
621a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    next_release_time_for_open_filesystem_stat_ =
622a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)        now + base::TimeDelta::FromHours(kMinimumStatsCollectionIntervalHours);
623a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
624a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
625a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#define REPORT(report_value)                                            \
626a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemDetailLabel,                 \
627a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                            (report_value),                             \
628a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                            kFileSystemErrorMax);                       \
629a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  if (!throttled) {                                                     \
630a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemDetailNonThrottledLabel,   \
631a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                              (report_value),                           \
632a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)                              kFileSystemErrorMax);                     \
633a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
634a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
635a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  switch (error_code) {
6365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_OK:
637a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      REPORT(kOK);
638a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
6395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_INVALID_URL:
640a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      REPORT(kInvalidSchemeError);
641a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
6425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_NOT_FOUND:
643a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      REPORT(kNotFound);
644a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
6455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    case base::File::FILE_ERROR_FAILED:
646a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)    default:
647a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      REPORT(kUnknownError);
648a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)      break;
649a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)  }
650a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)#undef REPORT
651a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)}
652a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles)
6533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)ObfuscatedFileUtil* SandboxFileSystemBackendDelegate::obfuscated_file_util() {
6543551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  return static_cast<ObfuscatedFileUtil*>(sync_file_util());
6557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch}
6567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch
6578bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// Declared in obfuscated_file_util.h.
6588bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)// static
6598bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)ObfuscatedFileUtil* ObfuscatedFileUtil::CreateForTesting(
66003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    storage::SpecialStoragePolicy* special_storage_policy,
6618bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    const base::FilePath& file_system_directory,
6625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    leveldb::Env* env_override,
6638bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)    base::SequencedTaskRunner* file_task_runner) {
6648bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)  return new ObfuscatedFileUtil(special_storage_policy,
6658bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                file_system_directory,
6665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                                env_override,
6678bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                file_task_runner,
6688bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)                                base::Bind(&GetTypeStringForURL),
6691e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                GetKnownTypeStrings(),
6701e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)                                NULL);
6718bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)}
6728bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)
67303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}  // namespace storage
674