Chromium Code Reviews| 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 (auto iter = instance_map_.begin(); iter != instance_map_.end(); ++iter) { |
|
danakj
2016/09/16 19:49:14
can this be a for (const auto& pair : instance_map
Avi (use Gerrit)
2016/09/16 20:08:50
Done.
| |
| 208 iter != instance_map_.end(); ++iter) { | |
| 209 mount_points->push_back(MountPointInfo(iter->first, iter->second->path())); | 207 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 |
| (...skipping 23 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 instance_map_copy.swap(instance_map_); |
|
danakj
2016/09/16 19:49:14
Can you leave a comment saying we're moving these
Avi (use Gerrit)
2016/09/16 20:08:51
Done.
| |
| 253 instance_map_.clear(); | |
| 254 path_to_name_map_.clear(); | 251 path_to_name_map_.clear(); |
| 255 } | 252 } |
| 256 base::STLDeleteContainerPairSecondPointers(instance_map_copy.begin(), | |
| 257 instance_map_copy.end()); | |
| 258 } | 253 } |
| 259 | 254 |
| 260 ExternalMountPoints::ExternalMountPoints() {} | 255 ExternalMountPoints::ExternalMountPoints() {} |
|
danakj
2016/09/16 19:49:14
= default while you're here?
Avi (use Gerrit)
2016/09/16 20:08:51
Done.
| |
| 261 | 256 |
| 262 ExternalMountPoints::~ExternalMountPoints() { | 257 ExternalMountPoints::~ExternalMountPoints() {} |
|
danakj
2016/09/16 19:49:14
= default?
Avi (use Gerrit)
2016/09/16 20:08:50
Done.
| |
| 263 base::STLDeleteContainerPairSecondPointers(instance_map_.begin(), | |
| 264 instance_map_.end()); | |
| 265 } | |
| 266 | 258 |
| 267 FileSystemURL ExternalMountPoints::CrackFileSystemURL( | 259 FileSystemURL ExternalMountPoints::CrackFileSystemURL( |
| 268 const FileSystemURL& url) const { | 260 const FileSystemURL& url) const { |
| 269 if (!HandlesFileSystemMountType(url.type())) | 261 if (!HandlesFileSystemMountType(url.type())) |
| 270 return FileSystemURL(); | 262 return FileSystemURL(); |
| 271 | 263 |
| 272 base::FilePath virtual_path = url.path(); | 264 base::FilePath virtual_path = url.path(); |
| 273 if (url.type() == kFileSystemTypeNativeForPlatformApp) { | 265 if (url.type() == kFileSystemTypeNativeForPlatformApp) { |
| 274 #if defined(OS_CHROMEOS) | 266 #if defined(OS_CHROMEOS) |
| 275 // On Chrome OS, find a mount point and virtual path for the external fs. | 267 // 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, | 297 bool ExternalMountPoints::ValidateNewMountPoint(const std::string& mount_name, |
| 306 FileSystemType type, | 298 FileSystemType type, |
| 307 const base::FilePath& path) { | 299 const base::FilePath& path) { |
| 308 lock_.AssertAcquired(); | 300 lock_.AssertAcquired(); |
| 309 | 301 |
| 310 // Mount name must not be empty. | 302 // Mount name must not be empty. |
| 311 if (mount_name.empty()) | 303 if (mount_name.empty()) |
| 312 return false; | 304 return false; |
| 313 | 305 |
| 314 // Verify there is no registered mount point with the same name. | 306 // Verify there is no registered mount point with the same name. |
| 315 NameToInstance::iterator found = instance_map_.find(mount_name); | 307 auto found = instance_map_.find(mount_name); |
| 316 if (found != instance_map_.end()) | 308 if (found != instance_map_.end()) |
| 317 return false; | 309 return false; |
| 318 | 310 |
| 319 // Allow empty paths. | 311 // Allow empty paths. |
| 320 if (path.empty()) | 312 if (path.empty()) |
| 321 return true; | 313 return true; |
| 322 | 314 |
| 323 // Verify path is legal. | 315 // Verify path is legal. |
| 324 if (path.ReferencesParent() || !path.IsAbsolute()) | 316 if (path.ReferencesParent() || !path.IsAbsolute()) |
| 325 return false; | 317 return false; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 342 path.IsParent(potential_child->first)) { | 334 path.IsParent(potential_child->first)) { |
| 343 return false; | 335 return false; |
| 344 } | 336 } |
| 345 } | 337 } |
| 346 } | 338 } |
| 347 | 339 |
| 348 return true; | 340 return true; |
| 349 } | 341 } |
| 350 | 342 |
| 351 } // namespace storage | 343 } // namespace storage |
| OLD | NEW |