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

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 {
14
15 // Wrapper around ref-counted ExternalMountPoints that will be used to lazily
16 // create and initialize LazyInstance system ExternalMountPoints.
17 class SystemMountPointsLazyWrapper {
18 public:
19 SystemMountPointsLazyWrapper()
20 : system_mount_points_(fileapi::ExternalMountPoints::CreateRefCounted()) {
21 RegisterDefaultMountPoints();
22 }
23
24 ~SystemMountPointsLazyWrapper() {}
25
26 fileapi::ExternalMountPoints* get() {
27 return system_mount_points_.get();
28 }
29
30 private:
31 void RegisterDefaultMountPoints() {
32 #if defined(OS_CHROMEOS)
33 // Add default system mount points.
34 system_mount_points_->RegisterFileSystem(
35 "archive",
36 fileapi::kFileSystemTypeNativeLocal,
37 FilePath(FILE_PATH_LITERAL("/media/archive")));
38 system_mount_points_->RegisterFileSystem(
39 "removable",
40 fileapi::kFileSystemTypeNativeLocal,
41 FilePath(FILE_PATH_LITERAL("/media/removable")));
42 system_mount_points_->RegisterFileSystem(
43 "oem",
44 fileapi::kFileSystemTypeRestrictedNativeLocal,
45 FilePath(FILE_PATH_LITERAL("/usr/share/oem")));
46
47 // TODO(tbarzic): Move this out of here.
48 FilePath home_path;
49 if (PathService::Get(base::DIR_HOME, &home_path)) {
50 system_mount_points_->RegisterFileSystem(
51 "Downloads",
52 fileapi::kFileSystemTypeNativeLocal,
53 home_path.AppendASCII("Downloads"));
54 }
55 #endif // defined(OS_CHROMEOS)
56 }
57
58 scoped_refptr<fileapi::ExternalMountPoints> system_mount_points_;
59 };
60
61 base::LazyInstance<SystemMountPointsLazyWrapper>::Leaky
62 g_external_mount_points = LAZY_INSTANCE_INITIALIZER;
63
64 } // namespace
65
66 namespace fileapi {
67
68 class ExternalMountPoints::Instance {
69 public:
70 // |remote_proxy| is allowed only for drive file system.
kinuko 2013/01/09 16:37:12 nit: allowed only for -> used only by?
tbarzic 2013/01/10 00:39:56 Done.
71 Instance(FileSystemType type,
72 const FilePath& path,
73 RemoteFileSystemProxyInterface* remote_proxy);
74
75 ~Instance();
76
77 FileSystemType type() const { return type_; }
78 const FilePath& path() const { return path_; }
79 RemoteFileSystemProxyInterface* remote_proxy() const {
80 return remote_proxy_.get();
81 }
82
83 private:
84 const FileSystemType type_;
85 const FilePath path_;
86
87 // For file systems that have a remote file system proxy.
88 scoped_refptr<RemoteFileSystemProxyInterface> remote_proxy_;
89
90 DISALLOW_COPY_AND_ASSIGN(Instance);
91 };
92
93 ExternalMountPoints::Instance::Instance(FileSystemType type,
94 const FilePath& path,
95 RemoteFileSystemProxyInterface* proxy)
96 : type_(type),
97 path_(path),
98 remote_proxy_(proxy) {
99 DCHECK(!proxy || (kFileSystemTypeDrive == type_));
100 }
101
102 ExternalMountPoints::Instance::~Instance() {}
103
104 //--------------------------------------------------------------------------
105
106 // static
107 ExternalMountPoints* ExternalMountPoints::GetSystemInstance() {
108 return g_external_mount_points.Pointer()->get();
109 }
110
111 // static
112 scoped_refptr<ExternalMountPoints> ExternalMountPoints::CreateRefCounted() {
113 return new ExternalMountPoints();
114 }
115
116 bool ExternalMountPoints::RegisterFileSystem(
117 const std::string& mount_name,
118 FileSystemType type,
119 const FilePath& path) {
120 return RegisterRemoteFileSystem(mount_name, type, NULL, path);
121 }
122
123 bool ExternalMountPoints::RegisterRemoteFileSystem(
124 const std::string& mount_name,
125 FileSystemType type,
126 RemoteFileSystemProxyInterface* remote_proxy,
127 const FilePath& path) {
128 base::AutoLock locker(lock_);
129
130 if (!ValidateNewMountPoint(mount_name, path))
131 return false;
132
133 instance_map_[mount_name] = new Instance(type, path, remote_proxy);
134 if (!path.empty())
135 path_to_name_map_.insert(std::make_pair(path, mount_name));
136 return true;
137 }
138
139 RemoteFileSystemProxyInterface* ExternalMountPoints::GetRemoteFileSystemProxy(
140 const std::string& mount_name) const {
141 base::AutoLock locker(lock_);
142 NameToInstance::const_iterator found = instance_map_.find(mount_name);
143 if (found == instance_map_.end())
144 return NULL;
145 return found->second->remote_proxy();
146 }
147
148 void ExternalMountPoints::AddMountPointInfosTo(
149 std::vector<MountPointInfo>* mount_points) const {
150 base::AutoLock locker(lock_);
151 DCHECK(mount_points);
152 for (NameToInstance::const_iterator iter = instance_map_.begin();
153 iter != instance_map_.end(); ++iter) {
154 mount_points->push_back(MountPointInfo(iter->first, iter->second->path()));
155 }
156 }
157
158 bool ExternalMountPoints::CanCrackMountType(FileSystemType type) const {
159 return type == kFileSystemTypeExternal;
160 }
161
162 bool ExternalMountPoints::GetRegisteredPath(
163 const std::string& filesystem_id, FilePath* path) const {
164 DCHECK(path);
165 base::AutoLock locker(lock_);
166 NameToInstance::const_iterator found = instance_map_.find(filesystem_id);
167 if (found == instance_map_.end())
168 return false;
169 *path = found->second->path();
170 return true;
171 }
172
173 bool ExternalMountPoints::RevokeFileSystem(const std::string& mount_name) {
174 base::AutoLock locker(lock_);
175 NameToInstance::iterator found = instance_map_.find(mount_name);
176 if (found == instance_map_.end())
177 return false;
178 Instance* instance = found->second;
179 path_to_name_map_.erase(instance->path());
180 delete found->second;
181 instance_map_.erase(found);
182 return true;
183 }
184
185 FilePath ExternalMountPoints::CreateVirtualRootPath(
186 const std::string& mount_name) const {
187 return FilePath().AppendASCII(mount_name);
188 }
189
190 ExternalMountPoints::ExternalMountPoints() { }
191
192 ExternalMountPoints::~ExternalMountPoints() {
193 STLDeleteContainerPairSecondPointers(instance_map_.begin(),
194 instance_map_.end());
195 }
196
197 bool ExternalMountPoints::ValidateNewMountPoint(const std::string& mount_name,
198 const FilePath& path) {
199 // Mount name must not be empty.
200 if (mount_name.empty())
201 return false;
202
203 // Verify there is no registered mount point with the same name.
204 NameToInstance::iterator found = instance_map_.find(mount_name);
205 if (found != instance_map_.end())
206 return false;
207
208 // Allow empty paths.
209 if (path.empty())
210 return true;
211
212 // Verify path is legal.
213 if (path.ReferencesParent() || !path.IsAbsolute())
214 return false;
215
216 // Check there the new path does not overlap with one of the existing ones.
217 std::map<FilePath, std::string>::reverse_iterator potential_parent(
218 path_to_name_map_.upper_bound(path));
219 if (potential_parent != path_to_name_map_.rend()) {
220 if (potential_parent->first == path ||
221 potential_parent->first.IsParent(path)) {
222 return false;
223 }
224 }
225
226 std::map<FilePath, std::string>::iterator potential_child =
227 path_to_name_map_.upper_bound(path);
228 if (potential_child == path_to_name_map_.end())
229 return true;
230 return !(potential_child->first == path) &&
231 !path.IsParent(potential_child->first);
232 }
233
234 bool ExternalMountPoints::GetVirtualPath(const FilePath& absolute_path,
235 FilePath* virtual_path) {
236 DCHECK(virtual_path);
237 base::AutoLock locker(lock_);
238 std::map<FilePath, std::string>::reverse_iterator iter(
239 path_to_name_map_.upper_bound(absolute_path));
240 if (iter == path_to_name_map_.rend())
241 return false;
242
243 *virtual_path = CreateVirtualRootPath(iter->second);
244 if (iter->first == absolute_path)
245 return true;
246 return iter->first.AppendRelativePath(absolute_path, virtual_path);
247 }
248
249 bool ExternalMountPoints::CrackExternalPath(const FilePath& virtual_path,
kinuko 2013/01/09 16:37:12 Maybe this should be named CrackVirtualPath (to be
tbarzic 2013/01/10 00:39:56 Done. Also added to MountPoints interface (and ch
250 std::string* mount_name,
251 FileSystemType* type,
252 FilePath* path) const {
253 DCHECK(mount_name);
254 DCHECK(path);
255
256 // This should not contain any '..' references.
257 if (virtual_path.ReferencesParent())
258 return false;
259
260 // The virtual_path should comprise <mount_name> and <relative_path> parts.
261 std::vector<FilePath::StringType> components;
262 virtual_path.GetComponents(&components);
263 if (components.size() < 1)
264 return false;
265
266 std::vector<FilePath::StringType>::iterator component_iter =
267 components.begin();
268 std::string maybe_mount_name = FilePath(*component_iter++).MaybeAsASCII();
269 if (maybe_mount_name.empty())
270 return false;
271
272 FilePath cracked_path;
273 {
274 base::AutoLock locker(lock_);
275 NameToInstance::const_iterator found_instance =
276 instance_map_.find(maybe_mount_name);
277 if (found_instance == instance_map_.end())
278 return false;
279
280 *mount_name = maybe_mount_name;
281 const Instance* instance = found_instance->second;
282 if (type)
283 *type = instance->type();
284 cracked_path = instance->path();
285 }
286
287 for (; component_iter != components.end(); ++component_iter)
288 cracked_path = cracked_path.Append(*component_iter);
289 *path = cracked_path;
290 return true;
291 }
292
293 ScopedExternalFileSystem::ScopedExternalFileSystem(
294 const std::string& mount_name,
295 FileSystemType type,
296 const FilePath& path)
297 : mount_name_(mount_name) {
298 ExternalMountPoints::GetSystemInstance()->RegisterFileSystem(
299 mount_name, type, path);
300 }
301
302 FilePath ScopedExternalFileSystem::GetVirtualRootPath() const {
303 return ExternalMountPoints::GetSystemInstance()->
304 CreateVirtualRootPath(mount_name_);
305 }
306
307 ScopedExternalFileSystem::~ScopedExternalFileSystem() {
308 ExternalMountPoints::GetSystemInstance()->RevokeFileSystem(mount_name_);
309 }
310
311 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698