1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef WEBKIT_BROWSER_FILEAPI_SANDBOX_FILE_SYSTEM_BACKEND_DELEGATE_H_
6#define WEBKIT_BROWSER_FILEAPI_SANDBOX_FILE_SYSTEM_BACKEND_DELEGATE_H_
7
8#include <map>
9#include <set>
10#include <string>
11#include <utility>
12
13#include "base/files/file_path.h"
14#include "base/gtest_prod_util.h"
15#include "base/memory/ref_counted.h"
16#include "base/memory/scoped_ptr.h"
17#include "base/memory/weak_ptr.h"
18#include "base/threading/thread_checker.h"
19#include "base/time/time.h"
20#include "webkit/browser/fileapi/file_system_backend.h"
21#include "webkit/browser/fileapi/file_system_options.h"
22#include "webkit/browser/fileapi/file_system_quota_util.h"
23#include "webkit/browser/webkit_storage_browser_export.h"
24
25namespace base {
26class SequencedTaskRunner;
27}
28
29namespace content {
30class SandboxFileSystemBackendDelegateTest;
31class SandboxFileSystemTestHelper;
32}
33
34namespace quota {
35class QuotaManagerProxy;
36class SpecialStoragePolicy;
37}
38
39namespace webkit_blob {
40class FileStreamReader;
41}
42
43namespace fileapi {
44
45class AsyncFileUtil;
46class FileStreamWriter;
47class FileSystemFileUtil;
48class FileSystemOperationContext;
49class FileSystemURL;
50class FileSystemUsageCache;
51class ObfuscatedFileUtil;
52class QuotaReservationManager;
53class SandboxFileSystemBackend;
54class SandboxQuotaObserver;
55
56// Delegate implementation of the some methods in Sandbox/SyncFileSystemBackend.
57// An instance of this class is created and owned by FileSystemContext.
58class WEBKIT_STORAGE_BROWSER_EXPORT SandboxFileSystemBackendDelegate
59    : public FileSystemQuotaUtil {
60 public:
61  typedef FileSystemBackend::OpenFileSystemCallback OpenFileSystemCallback;
62
63  // The FileSystem directory name.
64  static const base::FilePath::CharType kFileSystemDirectory[];
65
66  // Origin enumerator interface.
67  // An instance of this interface is assumed to be called on the file thread.
68  class OriginEnumerator {
69   public:
70    virtual ~OriginEnumerator() {}
71
72    // Returns the next origin.  Returns empty if there are no more origins.
73    virtual GURL Next() = 0;
74
75    // Returns the current origin's information.
76    virtual bool HasFileSystemType(FileSystemType type) const = 0;
77  };
78
79  // Returns the type directory name in sandbox directory for given |type|.
80  static std::string GetTypeString(FileSystemType type);
81
82  SandboxFileSystemBackendDelegate(
83      quota::QuotaManagerProxy* quota_manager_proxy,
84      base::SequencedTaskRunner* file_task_runner,
85      const base::FilePath& profile_path,
86      quota::SpecialStoragePolicy* special_storage_policy,
87      const FileSystemOptions& file_system_options);
88
89  virtual ~SandboxFileSystemBackendDelegate();
90
91  // Returns an origin enumerator of sandbox filesystem.
92  // This method can only be called on the file thread.
93  OriginEnumerator* CreateOriginEnumerator();
94
95  // Gets a base directory path of the sandboxed filesystem that is
96  // specified by |origin_url| and |type|.
97  // (The path is similar to the origin's root path but doesn't contain
98  // the 'unique' part.)
99  // Returns an empty path if the given type is invalid.
100  // This method can only be called on the file thread.
101  base::FilePath GetBaseDirectoryForOriginAndType(
102      const GURL& origin_url,
103      FileSystemType type,
104      bool create);
105
106  // FileSystemBackend helpers.
107  void OpenFileSystem(
108      const GURL& origin_url,
109      FileSystemType type,
110      OpenFileSystemMode mode,
111      const OpenFileSystemCallback& callback,
112      const GURL& root_url);
113  scoped_ptr<FileSystemOperationContext> CreateFileSystemOperationContext(
114      const FileSystemURL& url,
115      FileSystemContext* context,
116      base::File::Error* error_code) const;
117  scoped_ptr<webkit_blob::FileStreamReader> CreateFileStreamReader(
118      const FileSystemURL& url,
119      int64 offset,
120      const base::Time& expected_modification_time,
121      FileSystemContext* context) const;
122  scoped_ptr<FileStreamWriter> CreateFileStreamWriter(
123      const FileSystemURL& url,
124      int64 offset,
125      FileSystemContext* context,
126      FileSystemType type) const;
127
128  // FileSystemQuotaUtil overrides.
129  virtual base::File::Error DeleteOriginDataOnFileTaskRunner(
130      FileSystemContext* context,
131      quota::QuotaManagerProxy* proxy,
132      const GURL& origin_url,
133      FileSystemType type) OVERRIDE;
134  virtual void GetOriginsForTypeOnFileTaskRunner(
135      FileSystemType type,
136      std::set<GURL>* origins) OVERRIDE;
137  virtual void GetOriginsForHostOnFileTaskRunner(
138      FileSystemType type,
139      const std::string& host,
140      std::set<GURL>* origins) OVERRIDE;
141  virtual int64 GetOriginUsageOnFileTaskRunner(
142      FileSystemContext* context,
143      const GURL& origin_url,
144      FileSystemType type) OVERRIDE;
145  virtual scoped_refptr<QuotaReservation>
146      CreateQuotaReservationOnFileTaskRunner(
147          const GURL& origin_url,
148          FileSystemType type) OVERRIDE;
149  virtual void AddFileUpdateObserver(
150      FileSystemType type,
151      FileUpdateObserver* observer,
152      base::SequencedTaskRunner* task_runner) OVERRIDE;
153  virtual void AddFileChangeObserver(
154      FileSystemType type,
155      FileChangeObserver* observer,
156      base::SequencedTaskRunner* task_runner) OVERRIDE;
157  virtual void AddFileAccessObserver(
158      FileSystemType type,
159      FileAccessObserver* observer,
160      base::SequencedTaskRunner* task_runner) OVERRIDE;
161  virtual const UpdateObserverList* GetUpdateObservers(
162      FileSystemType type) const OVERRIDE;
163  virtual const ChangeObserverList* GetChangeObservers(
164      FileSystemType type) const OVERRIDE;
165  virtual const AccessObserverList* GetAccessObservers(
166      FileSystemType type) const OVERRIDE;
167
168  // Registers quota observer for file updates on filesystem of |type|.
169  void RegisterQuotaUpdateObserver(FileSystemType type);
170
171  void InvalidateUsageCache(const GURL& origin_url,
172                            FileSystemType type);
173  void StickyInvalidateUsageCache(const GURL& origin_url,
174                                  FileSystemType type);
175
176  void CollectOpenFileSystemMetrics(base::File::Error error_code);
177
178  base::SequencedTaskRunner* file_task_runner() {
179    return file_task_runner_.get();
180  }
181
182  AsyncFileUtil* file_util() { return sandbox_file_util_.get(); }
183  FileSystemUsageCache* usage_cache() { return file_system_usage_cache_.get(); }
184  SandboxQuotaObserver* quota_observer() { return quota_observer_.get(); }
185
186  quota::SpecialStoragePolicy* special_storage_policy() {
187    return special_storage_policy_.get();
188  }
189
190  const FileSystemOptions& file_system_options() const {
191    return file_system_options_;
192  }
193
194  FileSystemFileUtil* sync_file_util();
195
196 private:
197  friend class QuotaBackendImpl;
198  friend class SandboxQuotaObserver;
199  friend class content::SandboxFileSystemBackendDelegateTest;
200  friend class content::SandboxFileSystemTestHelper;
201
202  // Performs API-specific validity checks on the given path |url|.
203  // Returns true if access to |url| is valid in this filesystem.
204  bool IsAccessValid(const FileSystemURL& url) const;
205
206  // Returns true if the given |url|'s scheme is allowed to access
207  // filesystem.
208  bool IsAllowedScheme(const GURL& url) const;
209
210  // Returns a path to the usage cache file.
211  base::FilePath GetUsageCachePathForOriginAndType(
212      const GURL& origin_url,
213      FileSystemType type);
214
215  // Returns a path to the usage cache file (static version).
216  static base::FilePath GetUsageCachePathForOriginAndType(
217      ObfuscatedFileUtil* sandbox_file_util,
218      const GURL& origin_url,
219      FileSystemType type,
220      base::File::Error* error_out);
221
222  int64 RecalculateUsage(FileSystemContext* context,
223                         const GURL& origin,
224                         FileSystemType type);
225
226  ObfuscatedFileUtil* obfuscated_file_util();
227
228  scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
229
230  scoped_ptr<AsyncFileUtil> sandbox_file_util_;
231  scoped_ptr<FileSystemUsageCache> file_system_usage_cache_;
232  scoped_ptr<SandboxQuotaObserver> quota_observer_;
233  scoped_ptr<QuotaReservationManager> quota_reservation_manager_;
234
235  scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
236
237  FileSystemOptions file_system_options_;
238
239  bool is_filesystem_opened_;
240  base::ThreadChecker io_thread_checker_;
241
242  // Accessed only on the file thread.
243  std::set<GURL> visited_origins_;
244
245  std::set<std::pair<GURL, FileSystemType> > sticky_dirty_origins_;
246
247  std::map<FileSystemType, UpdateObserverList> update_observers_;
248  std::map<FileSystemType, ChangeObserverList> change_observers_;
249  std::map<FileSystemType, AccessObserverList> access_observers_;
250
251  base::Time next_release_time_for_open_filesystem_stat_;
252
253  base::WeakPtrFactory<SandboxFileSystemBackendDelegate> weak_factory_;
254
255  DISALLOW_COPY_AND_ASSIGN(SandboxFileSystemBackendDelegate);
256};
257
258}  // namespace fileapi
259
260#endif  // WEBKIT_BROWSER_FILEAPI_SANDBOX_FILE_SYSTEM_BACKEND_DELEGATE_H_
261