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

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

Issue 442383002: Move storage-related files from webkit/ to new top-level directory storage/ (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 6 years, 4 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
« no previous file with comments | « webkit/browser/fileapi/external_mount_points.h ('k') | webkit/browser/fileapi/file_observers.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright (c) 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 #include "webkit/browser/fileapi/external_mount_points.h"
6
7 #include "base/files/file_path.h"
8 #include "base/lazy_instance.h"
9 #include "base/path_service.h"
10 #include "base/stl_util.h"
11 #include "webkit/browser/fileapi/file_system_url.h"
12
13 namespace {
14
15 // Normalizes file path so it has normalized separators and ends with exactly
16 // one separator. Paths have to be normalized this way for use in
17 // GetVirtualPath method. Separators cannot be completely stripped, or
18 // GetVirtualPath could not working in some edge cases.
19 // For example, /a/b/c(1)/d would be erroneously resolved as c/d if the
20 // following mount points were registered: "/a/b/c", "/a/b/c(1)". (Note:
21 // "/a/b/c" < "/a/b/c(1)" < "/a/b/c/").
22 base::FilePath NormalizeFilePath(const base::FilePath& path) {
23 if (path.empty())
24 return path;
25
26 base::FilePath::StringType path_str = path.StripTrailingSeparators().value();
27 if (!base::FilePath::IsSeparator(path_str[path_str.length() - 1]))
28 path_str.append(FILE_PATH_LITERAL("/"));
29
30 return base::FilePath(path_str).NormalizePathSeparators();
31 }
32
33 bool IsOverlappingMountPathForbidden(fileapi::FileSystemType type) {
34 return type != fileapi::kFileSystemTypeNativeMedia &&
35 type != fileapi::kFileSystemTypeDeviceMedia;
36 }
37
38 // Wrapper around ref-counted ExternalMountPoints that will be used to lazily
39 // create and initialize LazyInstance system ExternalMountPoints.
40 class SystemMountPointsLazyWrapper {
41 public:
42 SystemMountPointsLazyWrapper()
43 : system_mount_points_(fileapi::ExternalMountPoints::CreateRefCounted()) {
44 }
45
46 ~SystemMountPointsLazyWrapper() {}
47
48 fileapi::ExternalMountPoints* get() {
49 return system_mount_points_.get();
50 }
51
52 private:
53 scoped_refptr<fileapi::ExternalMountPoints> system_mount_points_;
54 };
55
56 base::LazyInstance<SystemMountPointsLazyWrapper>::Leaky
57 g_external_mount_points = LAZY_INSTANCE_INITIALIZER;
58
59 } // namespace
60
61 namespace fileapi {
62
63 class ExternalMountPoints::Instance {
64 public:
65 Instance(FileSystemType type,
66 const base::FilePath& path,
67 const FileSystemMountOption& mount_option)
68 : type_(type),
69 path_(path.StripTrailingSeparators()),
70 mount_option_(mount_option) {}
71 ~Instance() {}
72
73 FileSystemType type() const { return type_; }
74 const base::FilePath& path() const { return path_; }
75 const FileSystemMountOption& mount_option() const { return mount_option_; }
76
77 private:
78 const FileSystemType type_;
79 const base::FilePath path_;
80 const FileSystemMountOption mount_option_;
81
82 DISALLOW_COPY_AND_ASSIGN(Instance);
83 };
84
85 //--------------------------------------------------------------------------
86
87 // static
88 ExternalMountPoints* ExternalMountPoints::GetSystemInstance() {
89 return g_external_mount_points.Pointer()->get();
90 }
91
92 // static
93 scoped_refptr<ExternalMountPoints> ExternalMountPoints::CreateRefCounted() {
94 return new ExternalMountPoints();
95 }
96
97 bool ExternalMountPoints::RegisterFileSystem(
98 const std::string& mount_name,
99 FileSystemType type,
100 const FileSystemMountOption& mount_option,
101 const base::FilePath& path_in) {
102 // COPY_SYNC_OPTION_SYNC is only applicable to native local file system.
103 DCHECK(type == kFileSystemTypeNativeLocal ||
104 mount_option.copy_sync_option() != COPY_SYNC_OPTION_SYNC);
105
106 base::AutoLock locker(lock_);
107
108 base::FilePath path = NormalizeFilePath(path_in);
109 if (!ValidateNewMountPoint(mount_name, type, path))
110 return false;
111
112 instance_map_[mount_name] = new Instance(type, path, mount_option);
113 if (!path.empty() && IsOverlappingMountPathForbidden(type))
114 path_to_name_map_.insert(std::make_pair(path, mount_name));
115 return true;
116 }
117
118 bool ExternalMountPoints::HandlesFileSystemMountType(
119 FileSystemType type) const {
120 return type == kFileSystemTypeExternal ||
121 type == kFileSystemTypeNativeForPlatformApp;
122 }
123
124 bool ExternalMountPoints::RevokeFileSystem(const std::string& mount_name) {
125 base::AutoLock locker(lock_);
126 NameToInstance::iterator found = instance_map_.find(mount_name);
127 if (found == instance_map_.end())
128 return false;
129 Instance* instance = found->second;
130 if (IsOverlappingMountPathForbidden(instance->type()))
131 path_to_name_map_.erase(NormalizeFilePath(instance->path()));
132 delete found->second;
133 instance_map_.erase(found);
134 return true;
135 }
136
137 bool ExternalMountPoints::GetRegisteredPath(
138 const std::string& filesystem_id, base::FilePath* path) const {
139 DCHECK(path);
140 base::AutoLock locker(lock_);
141 NameToInstance::const_iterator found = instance_map_.find(filesystem_id);
142 if (found == instance_map_.end())
143 return false;
144 *path = found->second->path();
145 return true;
146 }
147
148 bool ExternalMountPoints::CrackVirtualPath(
149 const base::FilePath& virtual_path,
150 std::string* mount_name,
151 FileSystemType* type,
152 std::string* cracked_id,
153 base::FilePath* path,
154 FileSystemMountOption* mount_option) const {
155 DCHECK(mount_name);
156 DCHECK(path);
157
158 // The path should not contain any '..' references.
159 if (virtual_path.ReferencesParent())
160 return false;
161
162 // The virtual_path should comprise of <mount_name> and <relative_path> parts.
163 std::vector<base::FilePath::StringType> components;
164 virtual_path.GetComponents(&components);
165 if (components.size() < 1)
166 return false;
167
168 std::vector<base::FilePath::StringType>::iterator component_iter =
169 components.begin();
170 std::string maybe_mount_name =
171 base::FilePath(*component_iter++).MaybeAsASCII();
172 if (maybe_mount_name.empty())
173 return false;
174
175 base::FilePath cracked_path;
176 {
177 base::AutoLock locker(lock_);
178 NameToInstance::const_iterator found_instance =
179 instance_map_.find(maybe_mount_name);
180 if (found_instance == instance_map_.end())
181 return false;
182
183 *mount_name = maybe_mount_name;
184 const Instance* instance = found_instance->second;
185 if (type)
186 *type = instance->type();
187 cracked_path = instance->path();
188 *mount_option = instance->mount_option();
189 }
190
191 for (; component_iter != components.end(); ++component_iter)
192 cracked_path = cracked_path.Append(*component_iter);
193 *path = cracked_path;
194 return true;
195 }
196
197 FileSystemURL ExternalMountPoints::CrackURL(const GURL& url) const {
198 FileSystemURL filesystem_url = FileSystemURL(url);
199 if (!filesystem_url.is_valid())
200 return FileSystemURL();
201 return CrackFileSystemURL(filesystem_url);
202 }
203
204 FileSystemURL ExternalMountPoints::CreateCrackedFileSystemURL(
205 const GURL& origin,
206 FileSystemType type,
207 const base::FilePath& path) const {
208 return CrackFileSystemURL(FileSystemURL(origin, type, path));
209 }
210
211 void ExternalMountPoints::AddMountPointInfosTo(
212 std::vector<MountPointInfo>* mount_points) const {
213 base::AutoLock locker(lock_);
214 DCHECK(mount_points);
215 for (NameToInstance::const_iterator iter = instance_map_.begin();
216 iter != instance_map_.end(); ++iter) {
217 mount_points->push_back(MountPointInfo(iter->first, iter->second->path()));
218 }
219 }
220
221 bool ExternalMountPoints::GetVirtualPath(const base::FilePath& path_in,
222 base::FilePath* virtual_path) const {
223 DCHECK(virtual_path);
224
225 base::AutoLock locker(lock_);
226
227 base::FilePath path = NormalizeFilePath(path_in);
228 std::map<base::FilePath, std::string>::const_reverse_iterator iter(
229 path_to_name_map_.upper_bound(path));
230 if (iter == path_to_name_map_.rend())
231 return false;
232
233 *virtual_path = CreateVirtualRootPath(iter->second);
234 if (iter->first == path)
235 return true;
236 return iter->first.AppendRelativePath(path, virtual_path);
237 }
238
239 base::FilePath ExternalMountPoints::CreateVirtualRootPath(
240 const std::string& mount_name) const {
241 return base::FilePath().AppendASCII(mount_name);
242 }
243
244 FileSystemURL ExternalMountPoints::CreateExternalFileSystemURL(
245 const GURL& origin,
246 const std::string& mount_name,
247 const base::FilePath& path) const {
248 return CreateCrackedFileSystemURL(
249 origin,
250 fileapi::kFileSystemTypeExternal,
251 // Avoid using FilePath::Append as path may be an absolute path.
252 base::FilePath(
253 CreateVirtualRootPath(mount_name).value() +
254 base::FilePath::kSeparators[0] + path.value()));
255 }
256
257 void ExternalMountPoints::RevokeAllFileSystems() {
258 NameToInstance instance_map_copy;
259 {
260 base::AutoLock locker(lock_);
261 instance_map_copy = instance_map_;
262 instance_map_.clear();
263 path_to_name_map_.clear();
264 }
265 STLDeleteContainerPairSecondPointers(instance_map_copy.begin(),
266 instance_map_copy.end());
267 }
268
269 ExternalMountPoints::ExternalMountPoints() {}
270
271 ExternalMountPoints::~ExternalMountPoints() {
272 STLDeleteContainerPairSecondPointers(instance_map_.begin(),
273 instance_map_.end());
274 }
275
276 FileSystemURL ExternalMountPoints::CrackFileSystemURL(
277 const FileSystemURL& url) const {
278 if (!HandlesFileSystemMountType(url.type()))
279 return FileSystemURL();
280
281 base::FilePath virtual_path = url.path();
282 if (url.type() == kFileSystemTypeNativeForPlatformApp) {
283 #if defined(OS_CHROMEOS)
284 // On Chrome OS, find a mount point and virtual path for the external fs.
285 if (!GetVirtualPath(url.path(), &virtual_path))
286 return FileSystemURL();
287 #else
288 // On other OS, it is simply a native local path.
289 return FileSystemURL(
290 url.origin(), url.mount_type(), url.virtual_path(),
291 url.mount_filesystem_id(), kFileSystemTypeNativeLocal,
292 url.path(), url.filesystem_id(), url.mount_option());
293 #endif
294 }
295
296 std::string mount_name;
297 FileSystemType cracked_type;
298 std::string cracked_id;
299 base::FilePath cracked_path;
300 FileSystemMountOption cracked_mount_option;
301
302 if (!CrackVirtualPath(virtual_path, &mount_name, &cracked_type,
303 &cracked_id, &cracked_path, &cracked_mount_option)) {
304 return FileSystemURL();
305 }
306
307 return FileSystemURL(
308 url.origin(), url.mount_type(), url.virtual_path(),
309 !url.filesystem_id().empty() ? url.filesystem_id() : mount_name,
310 cracked_type, cracked_path,
311 cracked_id.empty() ? mount_name : cracked_id, cracked_mount_option);
312 }
313
314 bool ExternalMountPoints::ValidateNewMountPoint(const std::string& mount_name,
315 FileSystemType type,
316 const base::FilePath& path) {
317 lock_.AssertAcquired();
318
319 // Mount name must not be empty.
320 if (mount_name.empty())
321 return false;
322
323 // Verify there is no registered mount point with the same name.
324 NameToInstance::iterator found = instance_map_.find(mount_name);
325 if (found != instance_map_.end())
326 return false;
327
328 // Allow empty paths.
329 if (path.empty())
330 return true;
331
332 // Verify path is legal.
333 if (path.ReferencesParent() || !path.IsAbsolute())
334 return false;
335
336 if (IsOverlappingMountPathForbidden(type)) {
337 // Check there the new path does not overlap with one of the existing ones.
338 std::map<base::FilePath, std::string>::reverse_iterator potential_parent(
339 path_to_name_map_.upper_bound(path));
340 if (potential_parent != path_to_name_map_.rend()) {
341 if (potential_parent->first == path ||
342 potential_parent->first.IsParent(path)) {
343 return false;
344 }
345 }
346
347 std::map<base::FilePath, std::string>::iterator potential_child =
348 path_to_name_map_.upper_bound(path);
349 if (potential_child != path_to_name_map_.end()) {
350 if (potential_child->first == path ||
351 path.IsParent(potential_child->first)) {
352 return false;
353 }
354 }
355 }
356
357 return true;
358 }
359
360 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/browser/fileapi/external_mount_points.h ('k') | webkit/browser/fileapi/file_observers.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698