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