Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(98)

Side by Side Diff: webkit/fileapi/external_mount_points.cc

Issue 11648027: Extract external file systems handling from isolated context. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 #include "webkit/fileapi/external_mount_points.h"
6
7 #include "base/file_path.h"
8 #include "base/lazy_instance.h"
9 #include "base/path_service.h"
10 #include "base/stl_util.h"
11 #include "webkit/fileapi/remote_file_system_proxy.h"
12
13 namespace fileapi {
14
15 static base::LazyInstance<scoped_refptr<ExternalMountPoints> >::Leaky
16 g_external_mount_points = LAZY_INSTANCE_INITIALIZER;
17
18 class ExternalMountPoints::Instance {
19 public:
20 // |remote_proxy| is allowed only for drive file system.
21 Instance(FileSystemType type,
22 const FilePath& path,
23 RemoteFileSystemProxyInterface* remote_proxy);
24
25 ~Instance();
26
27 FileSystemType type() const { return type_; }
28 const FilePath& path() const { return path_; }
29 RemoteFileSystemProxyInterface* remote_proxy() const {
30 return remote_proxy_.get();
31 }
32
33 private:
34 const FileSystemType type_;
35 const FilePath path_;
36
37 // For file systems that have a remote file system proxy.
38 scoped_refptr<RemoteFileSystemProxyInterface> remote_proxy_;
39
40 DISALLOW_COPY_AND_ASSIGN(Instance);
41 };
42
43 ExternalMountPoints::Instance::Instance(FileSystemType type,
44 const FilePath& path,
45 RemoteFileSystemProxyInterface* proxy)
46 : type_(type),
47 path_(path),
48 remote_proxy_(proxy) {
49 DCHECK(!proxy || (kFileSystemTypeDrive == type_));
50 }
51
52 ExternalMountPoints::Instance::~Instance() {}
53
54 //--------------------------------------------------------------------------
55
56 // static
57 ExternalMountPoints* ExternalMountPoints::GetSystemInstance() {
58 if (!g_external_mount_points.Pointer()->get())
59 g_external_mount_points.Get() = new ExternalMountPoints(true);
60 return g_external_mount_points.Pointer()->get();
kinuko 2013/01/08 12:22:43 Hmm, this is not thread safe and we seem to be los
tbarzic 2013/01/09 01:26:34 Yeah, I was concerned about that too. I think the
61 }
62
63 // static
64 scoped_refptr<ExternalMountPoints> ExternalMountPoints::CreateRefCounted() {
65 return new ExternalMountPoints(false);
66 }
67
68 bool ExternalMountPoints::RegisterFileSystem(
69 const std::string& mount_name,
70 FileSystemType type,
71 const FilePath& path) {
72 return RegisterRemoteFileSystem(mount_name, type, NULL, path);
73 }
74
75 bool ExternalMountPoints::RegisterRemoteFileSystem(
76 const std::string& mount_name,
77 FileSystemType type,
78 RemoteFileSystemProxyInterface* remote_proxy,
79 const FilePath& path) {
80 base::AutoLock locker(lock_);
81
82 if (!ValidateNewMountPoint(mount_name, path))
83 return false;
84
85 instance_map_[mount_name] = new Instance(type, path, remote_proxy);
86 if (!path.empty())
87 path_to_name_map_.insert(std::make_pair(path, mount_name));
88 return true;
89 }
90
91 RemoteFileSystemProxyInterface* ExternalMountPoints::GetRemoteFileSystemProxy(
92 const std::string& mount_name) const {
93 base::AutoLock locker(lock_);
94 NameToInstance::const_iterator found = instance_map_.find(mount_name);
95 if (found == instance_map_.end())
96 return NULL;
97 return found->second->remote_proxy();
98 }
99
100 void ExternalMountPoints::AppendMountPoints(
101 std::vector<MountPointInfo>* mount_points) const {
102 base::AutoLock locker(lock_);
103 DCHECK(mount_points);
104 for (NameToInstance::const_iterator iter = instance_map_.begin();
105 iter != instance_map_.end(); ++iter) {
106 mount_points->push_back(MountPointInfo(iter->first, iter->second->path()));
107 }
108 }
109
110 bool ExternalMountPoints::CanCrackMountType(FileSystemType type) const {
111 return type == kFileSystemTypeExternal;
112 }
113
114 bool ExternalMountPoints::GetRegisteredPath(
115 const std::string& filesystem_id, FilePath* path) const {
116 DCHECK(path);
117 base::AutoLock locker(lock_);
118 NameToInstance::const_iterator found = instance_map_.find(filesystem_id);
119 if (found == instance_map_.end())
120 return false;
121 *path = found->second->path();
122 return true;
123 }
124
125 bool ExternalMountPoints::RevokeFileSystem(const std::string& mount_name) {
126 base::AutoLock locker(lock_);
127 NameToInstance::iterator found = instance_map_.find(mount_name);
128 if (found == instance_map_.end())
129 return false;
130 Instance* instance = found->second;
131 path_to_name_map_.erase(instance->path());
132 delete found->second;
133 instance_map_.erase(found);
134 return true;
135 }
136
137 FilePath ExternalMountPoints::CreateVirtualRootPath(
138 const std::string& mount_name) const {
139 return FilePath().AppendASCII(mount_name);
140 }
141
142 ExternalMountPoints::ExternalMountPoints(bool is_system_instance) {
kinuko 2013/01/08 12:22:43 Can we avoid using boolean here? (It's discouraged
tbarzic 2013/01/09 01:26:34 Done.
143 #if defined(OS_CHROMEOS)
144 // Add default system mount points.
145 if (is_system_instance) {
146 RegisterFileSystem("archive",
147 kFileSystemTypeNativeLocal,
148 FilePath(FILE_PATH_LITERAL("/media/archive")));
149 RegisterFileSystem("removable",
150 kFileSystemTypeNativeLocal,
151 FilePath(FILE_PATH_LITERAL("/media/removable")));
152 RegisterFileSystem("oem",
153 kFileSystemTypeRestrictedNativeLocal,
154 FilePath(FILE_PATH_LITERAL("/usr/share/oem")));
155
156 // TODO(tbarzic): Move this out of here.
157 FilePath home_path;
158 if (PathService::Get(base::DIR_HOME, &home_path)) {
159 RegisterFileSystem("Downloads",
160 kFileSystemTypeNativeLocal,
161 home_path.AppendASCII("Downloads"));
162 }
163 }
164 #endif // defined(OS_CHROMEOS)
165 }
166
167 ExternalMountPoints::~ExternalMountPoints() {
168 STLDeleteContainerPairSecondPointers(instance_map_.begin(),
169 instance_map_.end());
170 }
171
172 bool ExternalMountPoints::ValidateNewMountPoint(const std::string& mount_name,
173 const FilePath& path) {
174 // Mount name must not be empty.
175 if (mount_name.empty())
176 return false;
177
178 // Verify there is no registered mount point with the same name.
179 NameToInstance::iterator found = instance_map_.find(mount_name);
180 if (found != instance_map_.end())
181 return false;
182
183 // Allow empty paths.
184 if (path.empty())
185 return true;
186
187 // Verify path is legal.
188 if (path.ReferencesParent() || !path.IsAbsolute())
189 return false;
190
191 // Check there the new path does not overlap with one of the existing ones.
192 std::map<FilePath, std::string>::reverse_iterator potential_parent(
193 path_to_name_map_.upper_bound(path));
194 if (potential_parent != path_to_name_map_.rend()) {
195 if (potential_parent->first == path ||
196 potential_parent->first.IsParent(path)) {
197 return false;
198 }
199 }
200
201 std::map<FilePath, std::string>::iterator potential_child =
202 path_to_name_map_.upper_bound(path);
203 if (potential_child == path_to_name_map_.end())
204 return true;
205 return !(potential_child->first == path) &&
206 !path.IsParent(potential_child->first);
207 }
208
209 bool ExternalMountPoints::GetVirtualPath(const FilePath& absolute_path,
210 FilePath* virtual_path) {
211 DCHECK(virtual_path);
212 base::AutoLock locker(lock_);
213 std::map<FilePath, std::string>::reverse_iterator iter(
214 path_to_name_map_.upper_bound(absolute_path));
215 if (iter == path_to_name_map_.rend())
216 return false;
217
218 *virtual_path = CreateVirtualRootPath(iter->second);
219 if (iter->first == absolute_path)
220 return true;
221 return iter->first.AppendRelativePath(absolute_path, virtual_path);
222 }
223
224 bool ExternalMountPoints::CrackExternalPath(const FilePath& virtual_path,
225 std::string* mount_name,
226 FileSystemType* type,
227 FilePath* path) const {
228 DCHECK(mount_name);
229 DCHECK(path);
230
231 // This should not contain any '..' references.
232 if (virtual_path.ReferencesParent())
233 return false;
234
235 // The virtual_path should comprise <mount_name> and <relative_path> parts.
236 std::vector<FilePath::StringType> components;
237 virtual_path.GetComponents(&components);
238 if (components.size() < 1)
239 return false;
240
241 std::vector<FilePath::StringType>::iterator component_iter =
242 components.begin();
243 std::string maybe_mount_name = FilePath(*component_iter++).MaybeAsASCII();
244 if (maybe_mount_name.empty())
245 return false;
246
247 FilePath cracked_path;
248 {
249 base::AutoLock locker(lock_);
250 NameToInstance::const_iterator found_instance =
251 instance_map_.find(maybe_mount_name);
252 if (found_instance == instance_map_.end())
253 return false;
254
255 *mount_name = maybe_mount_name;
256 const Instance* instance = found_instance->second;
257 if (type)
258 *type = instance->type();
259 cracked_path = instance->path();
260 }
261
262 for (; component_iter != components.end(); ++component_iter)
263 cracked_path = cracked_path.Append(*component_iter);
264 *path = cracked_path;
265 return true;
266 }
267
268 ScopedExternalFileSystem::ScopedExternalFileSystem(
269 const std::string& mount_name,
270 FileSystemType type,
271 const FilePath& path)
272 : mount_name_(mount_name) {
273 ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
274 mount_name, type, path);
275 }
276
277 FilePath ScopedExternalFileSystem::GetVirtualRootPath() const {
278 return ExternalMountPoints::GetSystemInstance()->
279 CreateVirtualRootPath(mount_name_);
280 }
281
282 ScopedExternalFileSystem::~ScopedExternalFileSystem() {
283 ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(mount_name_);
284 }
285
286 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698