- add sources.
[platform/framework/web/crosswalk.git] / src / webkit / browser / fileapi / isolated_context.h
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #ifndef WEBKIT_BROWSER_FILEAPI_ISOLATED_CONTEXT_H_
6 #define WEBKIT_BROWSER_FILEAPI_ISOLATED_CONTEXT_H_
7
8 #include <map>
9 #include <set>
10 #include <string>
11 #include <vector>
12
13 #include "base/basictypes.h"
14 #include "base/files/file_path.h"
15 #include "base/lazy_instance.h"
16 #include "base/memory/singleton.h"
17 #include "base/synchronization/lock.h"
18 #include "webkit/browser/fileapi/mount_points.h"
19 #include "webkit/browser/webkit_storage_browser_export.h"
20 #include "webkit/common/fileapi/file_system_types.h"
21
22 namespace fileapi {
23 class FileSystemURL;
24 }
25
26 namespace fileapi {
27
28 // Manages isolated filesystem mount points which have no well-known names
29 // and are identified by a string 'filesystem ID', which usually just looks
30 // like random value.
31 // This type of filesystem can be created on the fly and may go away when it has
32 // no references from renderers.
33 // Files in an isolated filesystem are registered with corresponding names and
34 // identified by a filesystem URL like:
35 //
36 //   filesystem:<origin>/isolated/<filesystem_id>/<name>/relative/path
37 //
38 // Some methods of this class are virtual just for mocking.
39 //
40 class WEBKIT_STORAGE_BROWSER_EXPORT IsolatedContext : public MountPoints {
41  public:
42   class WEBKIT_STORAGE_BROWSER_EXPORT FileInfoSet {
43    public:
44     FileInfoSet();
45     ~FileInfoSet();
46
47     // Add the given |path| to the set and populates |registered_name| with
48     // the registered name assigned for the path. |path| needs to be
49     // absolute and should not contain parent references.
50     // Return false if the |path| is not valid and could not be added.
51     bool AddPath(const base::FilePath& path, std::string* registered_name);
52
53     // Add the given |path| with the |name|.
54     // Return false if the |name| is already registered in the set or
55     // is not valid and could not be added.
56     bool AddPathWithName(const base::FilePath& path, const std::string& name);
57
58     const std::set<MountPointInfo>& fileset() const { return fileset_; }
59
60    private:
61     std::set<MountPointInfo> fileset_;
62   };
63
64   // The instance is lazily created per browser process.
65   static IsolatedContext* GetInstance();
66
67   // Returns true if the given filesystem type is managed by IsolatedContext
68   // (i.e. if the given |type| is Isolated or External).
69   // TODO(kinuko): needs a better function name.
70   static bool IsIsolatedType(FileSystemType type);
71
72   // Registers a new isolated filesystem with the given FileInfoSet |files|
73   // and returns the new filesystem_id.  The files are registered with their
74   // register_name as their keys so that later we can resolve the full paths
75   // for the given name.  We only expose the name and the ID for the
76   // newly created filesystem to the renderer for the sake of security.
77   //
78   // The renderer will be sending filesystem requests with a virtual path like
79   // '/<filesystem_id>/<registered_name>/<relative_path_from_the_dropped_path>'
80   // for which we could crack in the browser process by calling
81   // CrackIsolatedPath to get the full path.
82   //
83   // For example: if a dropped file has a path like '/a/b/foo' and we register
84   // the path with the name 'foo' in the newly created filesystem.
85   // Later if the context is asked to crack a virtual path like '/<fsid>/foo'
86   // it can properly return the original path '/a/b/foo' by looking up the
87   // internal mapping.  Similarly if a dropped entry is a directory and its
88   // path is like '/a/b/dir' a virtual path like '/<fsid>/dir/foo' can be
89   // cracked into '/a/b/dir/foo'.
90   //
91   // Note that the path in |fileset| that contains '..' or is not an
92   // absolute path is skipped and is not registered.
93   std::string RegisterDraggedFileSystem(const FileInfoSet& files);
94
95   // Registers a new isolated filesystem for a given |path| of filesystem
96   // |type| filesystem and returns a new filesystem ID.
97   // |path| must be an absolute path which has no parent references ('..').
98   // If |register_name| is non-null and has non-empty string the path is
99   // registered as the given |register_name|, otherwise it is populated
100   // with the name internally assigned to the path.
101   std::string RegisterFileSystemForPath(FileSystemType type,
102                                         const base::FilePath& path,
103                                         std::string* register_name);
104
105   // Registers a virtual filesystem. This is different from
106   // RegisterFileSystemForPath because register_name is required, and
107   // cracked_path_prefix is allowed to be non-absolute.
108   // |register_name| is required, since we cannot infer one from the path.
109   // |cracked_path_prefix| has no parent references, but can be relative.
110   std::string RegisterFileSystemForVirtualPath(
111       FileSystemType type,
112       const std::string& register_name,
113       const base::FilePath& cracked_path_prefix);
114
115   // Revokes all filesystem(s) registered for the given path.
116   // This is assumed to be called when the registered path becomes
117   // globally invalid, e.g. when a device for the path is detached.
118   //
119   // Note that this revokes the filesystem no matter how many references it has.
120   // It is ok to call this for the path that has no associated filesystems.
121   // Note that this only works for the filesystems registered by
122   // |RegisterFileSystemForPath|.
123   void RevokeFileSystemByPath(const base::FilePath& path);
124
125   // Adds a reference to a filesystem specified by the given filesystem_id.
126   void AddReference(const std::string& filesystem_id);
127
128   // Removes a reference to a filesystem specified by the given filesystem_id.
129   // If the reference count reaches 0 the isolated context gets destroyed.
130   // It is OK to call this on the filesystem that has been already deleted
131   // (e.g. by RevokeFileSystemByPath).
132   void RemoveReference(const std::string& filesystem_id);
133
134   // Returns a set of dragged MountPointInfos registered for the
135   // |filesystem_id|.
136   // The filesystem_id must be pointing to a dragged file system
137   // (i.e. must be the one registered by RegisterDraggedFileSystem).
138   // Returns false if the |filesystem_id| is not valid.
139   bool GetDraggedFileInfo(const std::string& filesystem_id,
140                           std::vector<MountPointInfo>* files) const;
141
142   // MountPoints overrides.
143   virtual bool HandlesFileSystemMountType(FileSystemType type) const OVERRIDE;
144   virtual bool RevokeFileSystem(const std::string& filesystem_id) OVERRIDE;
145   virtual bool GetRegisteredPath(const std::string& filesystem_id,
146                                  base::FilePath* path) const OVERRIDE;
147   virtual bool CrackVirtualPath(const base::FilePath& virtual_path,
148                                 std::string* filesystem_id,
149                                 FileSystemType* type,
150                                 base::FilePath* path) const OVERRIDE;
151   virtual FileSystemURL CrackURL(const GURL& url) const OVERRIDE;
152   virtual FileSystemURL CreateCrackedFileSystemURL(
153       const GURL& origin,
154       FileSystemType type,
155       const base::FilePath& path) const OVERRIDE;
156
157   // Returns the virtual root path that looks like /<filesystem_id>.
158   base::FilePath CreateVirtualRootPath(const std::string& filesystem_id) const;
159
160  private:
161   friend struct base::DefaultLazyInstanceTraits<IsolatedContext>;
162
163   // Represents each file system instance (defined in the .cc).
164   class Instance;
165
166   typedef std::map<std::string, Instance*> IDToInstance;
167
168   // Reverse map from registered path to IDs.
169   typedef std::map<base::FilePath, std::set<std::string> > PathToID;
170
171   // Obtain an instance of this class via GetInstance().
172   IsolatedContext();
173   virtual ~IsolatedContext();
174
175   // MountPoints overrides.
176   virtual FileSystemURL CrackFileSystemURL(
177       const FileSystemURL& url) const OVERRIDE;
178
179   // Unregisters a file system of given |filesystem_id|. Must be called with
180   // lock_ held.  Returns true if the file system is unregistered.
181   bool UnregisterFileSystem(const std::string& filesystem_id);
182
183   // Returns a new filesystem_id.  Called with lock.
184   std::string GetNewFileSystemId() const;
185
186   // This lock needs to be obtained when accessing the instance_map_.
187   mutable base::Lock lock_;
188
189   IDToInstance instance_map_;
190   PathToID path_to_id_map_;
191
192   DISALLOW_COPY_AND_ASSIGN(IsolatedContext);
193 };
194
195 }  // namespace fileapi
196
197 #endif  // WEBKIT_BROWSER_FILEAPI_ISOLATED_CONTEXT_H_