OLD | NEW |
1 // Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "storage/browser/fileapi/external_mount_points.h" | 5 #include "storage/browser/fileapi/external_mount_points.h" |
6 | 6 |
7 #include "base/files/file_path.h" | 7 #include "base/files/file_path.h" |
8 #include "base/lazy_instance.h" | 8 #include "base/lazy_instance.h" |
9 #include "base/macros.h" | 9 #include "base/macros.h" |
10 #include "base/stl_util.h" | 10 #include "base/memory/ptr_util.h" |
11 #include "storage/browser/fileapi/file_system_url.h" | 11 #include "storage/browser/fileapi/file_system_url.h" |
12 | 12 |
13 namespace { | 13 namespace { |
14 | 14 |
15 // Normalizes file path so it has normalized separators and ends with exactly | 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 | 16 // one separator. Paths have to be normalized this way for use in |
17 // GetVirtualPath method. Separators cannot be completely stripped, or | 17 // GetVirtualPath method. Separators cannot be completely stripped, or |
18 // GetVirtualPath could not working in some edge cases. | 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 | 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: | 20 // following mount points were registered: "/a/b/c", "/a/b/c(1)". (Note: |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 const std::string& mount_name, | 96 const std::string& mount_name, |
97 FileSystemType type, | 97 FileSystemType type, |
98 const FileSystemMountOption& mount_option, | 98 const FileSystemMountOption& mount_option, |
99 const base::FilePath& path_in) { | 99 const base::FilePath& path_in) { |
100 base::AutoLock locker(lock_); | 100 base::AutoLock locker(lock_); |
101 | 101 |
102 base::FilePath path = NormalizeFilePath(path_in); | 102 base::FilePath path = NormalizeFilePath(path_in); |
103 if (!ValidateNewMountPoint(mount_name, type, path)) | 103 if (!ValidateNewMountPoint(mount_name, type, path)) |
104 return false; | 104 return false; |
105 | 105 |
106 instance_map_[mount_name] = new Instance(type, path, mount_option); | 106 instance_map_[mount_name] = |
| 107 base::MakeUnique<Instance>(type, path, mount_option); |
107 if (!path.empty() && IsOverlappingMountPathForbidden(type)) | 108 if (!path.empty() && IsOverlappingMountPathForbidden(type)) |
108 path_to_name_map_.insert(std::make_pair(path, mount_name)); | 109 path_to_name_map_.insert(std::make_pair(path, mount_name)); |
109 return true; | 110 return true; |
110 } | 111 } |
111 | 112 |
112 bool ExternalMountPoints::HandlesFileSystemMountType( | 113 bool ExternalMountPoints::HandlesFileSystemMountType( |
113 FileSystemType type) const { | 114 FileSystemType type) const { |
114 return type == kFileSystemTypeExternal || | 115 return type == kFileSystemTypeExternal || |
115 type == kFileSystemTypeNativeForPlatformApp; | 116 type == kFileSystemTypeNativeForPlatformApp; |
116 } | 117 } |
117 | 118 |
118 bool ExternalMountPoints::RevokeFileSystem(const std::string& mount_name) { | 119 bool ExternalMountPoints::RevokeFileSystem(const std::string& mount_name) { |
119 base::AutoLock locker(lock_); | 120 base::AutoLock locker(lock_); |
120 NameToInstance::iterator found = instance_map_.find(mount_name); | 121 auto found = instance_map_.find(mount_name); |
121 if (found == instance_map_.end()) | 122 if (found == instance_map_.end()) |
122 return false; | 123 return false; |
123 Instance* instance = found->second; | 124 Instance* instance = found->second.get(); |
124 if (IsOverlappingMountPathForbidden(instance->type())) | 125 if (IsOverlappingMountPathForbidden(instance->type())) |
125 path_to_name_map_.erase(NormalizeFilePath(instance->path())); | 126 path_to_name_map_.erase(NormalizeFilePath(instance->path())); |
126 delete found->second; | |
127 instance_map_.erase(found); | 127 instance_map_.erase(found); |
128 return true; | 128 return true; |
129 } | 129 } |
130 | 130 |
131 bool ExternalMountPoints::GetRegisteredPath( | 131 bool ExternalMountPoints::GetRegisteredPath( |
132 const std::string& filesystem_id, base::FilePath* path) const { | 132 const std::string& filesystem_id, base::FilePath* path) const { |
133 DCHECK(path); | 133 DCHECK(path); |
134 base::AutoLock locker(lock_); | 134 base::AutoLock locker(lock_); |
135 NameToInstance::const_iterator found = instance_map_.find(filesystem_id); | 135 auto found = instance_map_.find(filesystem_id); |
136 if (found == instance_map_.end()) | 136 if (found == instance_map_.end()) |
137 return false; | 137 return false; |
138 *path = found->second->path(); | 138 *path = found->second->path(); |
139 return true; | 139 return true; |
140 } | 140 } |
141 | 141 |
142 bool ExternalMountPoints::CrackVirtualPath( | 142 bool ExternalMountPoints::CrackVirtualPath( |
143 const base::FilePath& virtual_path, | 143 const base::FilePath& virtual_path, |
144 std::string* mount_name, | 144 std::string* mount_name, |
145 FileSystemType* type, | 145 FileSystemType* type, |
(...skipping 14 matching lines...) Expand all Loading... |
160 return false; | 160 return false; |
161 | 161 |
162 std::vector<base::FilePath::StringType>::iterator component_iter = | 162 std::vector<base::FilePath::StringType>::iterator component_iter = |
163 components.begin(); | 163 components.begin(); |
164 std::string maybe_mount_name = | 164 std::string maybe_mount_name = |
165 base::FilePath(*component_iter++).AsUTF8Unsafe(); | 165 base::FilePath(*component_iter++).AsUTF8Unsafe(); |
166 | 166 |
167 base::FilePath cracked_path; | 167 base::FilePath cracked_path; |
168 { | 168 { |
169 base::AutoLock locker(lock_); | 169 base::AutoLock locker(lock_); |
170 NameToInstance::const_iterator found_instance = | 170 auto found_instance = instance_map_.find(maybe_mount_name); |
171 instance_map_.find(maybe_mount_name); | |
172 if (found_instance == instance_map_.end()) | 171 if (found_instance == instance_map_.end()) |
173 return false; | 172 return false; |
174 | 173 |
175 *mount_name = maybe_mount_name; | 174 *mount_name = maybe_mount_name; |
176 const Instance* instance = found_instance->second; | 175 const Instance* instance = found_instance->second.get(); |
177 if (type) | 176 if (type) |
178 *type = instance->type(); | 177 *type = instance->type(); |
179 cracked_path = instance->path(); | 178 cracked_path = instance->path(); |
180 *mount_option = instance->mount_option(); | 179 *mount_option = instance->mount_option(); |
181 } | 180 } |
182 | 181 |
183 for (; component_iter != components.end(); ++component_iter) | 182 for (; component_iter != components.end(); ++component_iter) |
184 cracked_path = cracked_path.Append(*component_iter); | 183 cracked_path = cracked_path.Append(*component_iter); |
185 *path = cracked_path; | 184 *path = cracked_path; |
186 return true; | 185 return true; |
(...skipping 10 matching lines...) Expand all Loading... |
197 const GURL& origin, | 196 const GURL& origin, |
198 FileSystemType type, | 197 FileSystemType type, |
199 const base::FilePath& path) const { | 198 const base::FilePath& path) const { |
200 return CrackFileSystemURL(FileSystemURL(origin, type, path)); | 199 return CrackFileSystemURL(FileSystemURL(origin, type, path)); |
201 } | 200 } |
202 | 201 |
203 void ExternalMountPoints::AddMountPointInfosTo( | 202 void ExternalMountPoints::AddMountPointInfosTo( |
204 std::vector<MountPointInfo>* mount_points) const { | 203 std::vector<MountPointInfo>* mount_points) const { |
205 base::AutoLock locker(lock_); | 204 base::AutoLock locker(lock_); |
206 DCHECK(mount_points); | 205 DCHECK(mount_points); |
207 for (NameToInstance::const_iterator iter = instance_map_.begin(); | 206 for (const auto& pair : instance_map_) { |
208 iter != instance_map_.end(); ++iter) { | 207 mount_points->push_back(MountPointInfo(pair.first, pair.second->path())); |
209 mount_points->push_back(MountPointInfo(iter->first, iter->second->path())); | |
210 } | 208 } |
211 } | 209 } |
212 | 210 |
213 bool ExternalMountPoints::GetVirtualPath(const base::FilePath& path_in, | 211 bool ExternalMountPoints::GetVirtualPath(const base::FilePath& path_in, |
214 base::FilePath* virtual_path) const { | 212 base::FilePath* virtual_path) const { |
215 DCHECK(virtual_path); | 213 DCHECK(virtual_path); |
216 | 214 |
217 base::AutoLock locker(lock_); | 215 base::AutoLock locker(lock_); |
218 | 216 |
219 base::FilePath path = NormalizeFilePath(path_in); | 217 base::FilePath path = NormalizeFilePath(path_in); |
(...skipping 22 matching lines...) Expand all Loading... |
242 storage::kFileSystemTypeExternal, | 240 storage::kFileSystemTypeExternal, |
243 // Avoid using FilePath::Append as path may be an absolute path. | 241 // Avoid using FilePath::Append as path may be an absolute path. |
244 base::FilePath(CreateVirtualRootPath(mount_name).value() + | 242 base::FilePath(CreateVirtualRootPath(mount_name).value() + |
245 base::FilePath::kSeparators[0] + path.value())); | 243 base::FilePath::kSeparators[0] + path.value())); |
246 } | 244 } |
247 | 245 |
248 void ExternalMountPoints::RevokeAllFileSystems() { | 246 void ExternalMountPoints::RevokeAllFileSystems() { |
249 NameToInstance instance_map_copy; | 247 NameToInstance instance_map_copy; |
250 { | 248 { |
251 base::AutoLock locker(lock_); | 249 base::AutoLock locker(lock_); |
252 instance_map_copy = instance_map_; | 250 // This swap moves the contents of instance_map_ to the local variable so |
253 instance_map_.clear(); | 251 // they can be freed outside the lock. |
| 252 instance_map_copy.swap(instance_map_); |
254 path_to_name_map_.clear(); | 253 path_to_name_map_.clear(); |
255 } | 254 } |
256 base::STLDeleteContainerPairSecondPointers(instance_map_copy.begin(), | |
257 instance_map_copy.end()); | |
258 } | 255 } |
259 | 256 |
260 ExternalMountPoints::ExternalMountPoints() {} | 257 ExternalMountPoints::ExternalMountPoints() = default; |
261 | 258 |
262 ExternalMountPoints::~ExternalMountPoints() { | 259 ExternalMountPoints::~ExternalMountPoints() = default; |
263 base::STLDeleteContainerPairSecondPointers(instance_map_.begin(), | |
264 instance_map_.end()); | |
265 } | |
266 | 260 |
267 FileSystemURL ExternalMountPoints::CrackFileSystemURL( | 261 FileSystemURL ExternalMountPoints::CrackFileSystemURL( |
268 const FileSystemURL& url) const { | 262 const FileSystemURL& url) const { |
269 if (!HandlesFileSystemMountType(url.type())) | 263 if (!HandlesFileSystemMountType(url.type())) |
270 return FileSystemURL(); | 264 return FileSystemURL(); |
271 | 265 |
272 base::FilePath virtual_path = url.path(); | 266 base::FilePath virtual_path = url.path(); |
273 if (url.type() == kFileSystemTypeNativeForPlatformApp) { | 267 if (url.type() == kFileSystemTypeNativeForPlatformApp) { |
274 #if defined(OS_CHROMEOS) | 268 #if defined(OS_CHROMEOS) |
275 // On Chrome OS, find a mount point and virtual path for the external fs. | 269 // On Chrome OS, find a mount point and virtual path for the external fs. |
(...skipping 29 matching lines...) Expand all Loading... |
305 bool ExternalMountPoints::ValidateNewMountPoint(const std::string& mount_name, | 299 bool ExternalMountPoints::ValidateNewMountPoint(const std::string& mount_name, |
306 FileSystemType type, | 300 FileSystemType type, |
307 const base::FilePath& path) { | 301 const base::FilePath& path) { |
308 lock_.AssertAcquired(); | 302 lock_.AssertAcquired(); |
309 | 303 |
310 // Mount name must not be empty. | 304 // Mount name must not be empty. |
311 if (mount_name.empty()) | 305 if (mount_name.empty()) |
312 return false; | 306 return false; |
313 | 307 |
314 // Verify there is no registered mount point with the same name. | 308 // Verify there is no registered mount point with the same name. |
315 NameToInstance::iterator found = instance_map_.find(mount_name); | 309 auto found = instance_map_.find(mount_name); |
316 if (found != instance_map_.end()) | 310 if (found != instance_map_.end()) |
317 return false; | 311 return false; |
318 | 312 |
319 // Allow empty paths. | 313 // Allow empty paths. |
320 if (path.empty()) | 314 if (path.empty()) |
321 return true; | 315 return true; |
322 | 316 |
323 // Verify path is legal. | 317 // Verify path is legal. |
324 if (path.ReferencesParent() || !path.IsAbsolute()) | 318 if (path.ReferencesParent() || !path.IsAbsolute()) |
325 return false; | 319 return false; |
(...skipping 16 matching lines...) Expand all Loading... |
342 path.IsParent(potential_child->first)) { | 336 path.IsParent(potential_child->first)) { |
343 return false; | 337 return false; |
344 } | 338 } |
345 } | 339 } |
346 } | 340 } |
347 | 341 |
348 return true; | 342 return true; |
349 } | 343 } |
350 | 344 |
351 } // namespace storage | 345 } // namespace storage |
OLD | NEW |