| 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 "webkit/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/path_service.h" | 9 #include "base/path_service.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| 11 #include "webkit/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: |
| 21 // "/a/b/c" < "/a/b/c(1)" < "/a/b/c/"). | 21 // "/a/b/c" < "/a/b/c(1)" < "/a/b/c/"). |
| 22 base::FilePath NormalizeFilePath(const base::FilePath& path) { | 22 base::FilePath NormalizeFilePath(const base::FilePath& path) { |
| 23 if (path.empty()) | 23 if (path.empty()) |
| 24 return path; | 24 return path; |
| 25 | 25 |
| 26 base::FilePath::StringType path_str = path.StripTrailingSeparators().value(); | 26 base::FilePath::StringType path_str = path.StripTrailingSeparators().value(); |
| 27 if (!base::FilePath::IsSeparator(path_str[path_str.length() - 1])) | 27 if (!base::FilePath::IsSeparator(path_str[path_str.length() - 1])) |
| 28 path_str.append(FILE_PATH_LITERAL("/")); | 28 path_str.append(FILE_PATH_LITERAL("/")); |
| 29 | 29 |
| 30 return base::FilePath(path_str).NormalizePathSeparators(); | 30 return base::FilePath(path_str).NormalizePathSeparators(); |
| 31 } | 31 } |
| 32 | 32 |
| 33 bool IsOverlappingMountPathForbidden(fileapi::FileSystemType type) { | 33 bool IsOverlappingMountPathForbidden(storage::FileSystemType type) { |
| 34 return type != fileapi::kFileSystemTypeNativeMedia && | 34 return type != storage::kFileSystemTypeNativeMedia && |
| 35 type != fileapi::kFileSystemTypeDeviceMedia; | 35 type != storage::kFileSystemTypeDeviceMedia; |
| 36 } | 36 } |
| 37 | 37 |
| 38 // Wrapper around ref-counted ExternalMountPoints that will be used to lazily | 38 // Wrapper around ref-counted ExternalMountPoints that will be used to lazily |
| 39 // create and initialize LazyInstance system ExternalMountPoints. | 39 // create and initialize LazyInstance system ExternalMountPoints. |
| 40 class SystemMountPointsLazyWrapper { | 40 class SystemMountPointsLazyWrapper { |
| 41 public: | 41 public: |
| 42 SystemMountPointsLazyWrapper() | 42 SystemMountPointsLazyWrapper() |
| 43 : system_mount_points_(fileapi::ExternalMountPoints::CreateRefCounted()) { | 43 : system_mount_points_(storage::ExternalMountPoints::CreateRefCounted()) { |
| 44 } | 44 } |
| 45 | 45 |
| 46 ~SystemMountPointsLazyWrapper() {} | 46 ~SystemMountPointsLazyWrapper() {} |
| 47 | 47 |
| 48 fileapi::ExternalMountPoints* get() { | 48 storage::ExternalMountPoints* get() { return system_mount_points_.get(); } |
| 49 return system_mount_points_.get(); | |
| 50 } | |
| 51 | 49 |
| 52 private: | 50 private: |
| 53 scoped_refptr<fileapi::ExternalMountPoints> system_mount_points_; | 51 scoped_refptr<storage::ExternalMountPoints> system_mount_points_; |
| 54 }; | 52 }; |
| 55 | 53 |
| 56 base::LazyInstance<SystemMountPointsLazyWrapper>::Leaky | 54 base::LazyInstance<SystemMountPointsLazyWrapper>::Leaky |
| 57 g_external_mount_points = LAZY_INSTANCE_INITIALIZER; | 55 g_external_mount_points = LAZY_INSTANCE_INITIALIZER; |
| 58 | 56 |
| 59 } // namespace | 57 } // namespace |
| 60 | 58 |
| 61 namespace fileapi { | 59 namespace storage { |
| 62 | 60 |
| 63 class ExternalMountPoints::Instance { | 61 class ExternalMountPoints::Instance { |
| 64 public: | 62 public: |
| 65 Instance(FileSystemType type, | 63 Instance(FileSystemType type, |
| 66 const base::FilePath& path, | 64 const base::FilePath& path, |
| 67 const FileSystemMountOption& mount_option) | 65 const FileSystemMountOption& mount_option) |
| 68 : type_(type), | 66 : type_(type), |
| 69 path_(path.StripTrailingSeparators()), | 67 path_(path.StripTrailingSeparators()), |
| 70 mount_option_(mount_option) {} | 68 mount_option_(mount_option) {} |
| 71 ~Instance() {} | 69 ~Instance() {} |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 if (found == instance_map_.end()) | 125 if (found == instance_map_.end()) |
| 128 return false; | 126 return false; |
| 129 Instance* instance = found->second; | 127 Instance* instance = found->second; |
| 130 if (IsOverlappingMountPathForbidden(instance->type())) | 128 if (IsOverlappingMountPathForbidden(instance->type())) |
| 131 path_to_name_map_.erase(NormalizeFilePath(instance->path())); | 129 path_to_name_map_.erase(NormalizeFilePath(instance->path())); |
| 132 delete found->second; | 130 delete found->second; |
| 133 instance_map_.erase(found); | 131 instance_map_.erase(found); |
| 134 return true; | 132 return true; |
| 135 } | 133 } |
| 136 | 134 |
| 137 bool ExternalMountPoints::GetRegisteredPath( | 135 bool ExternalMountPoints::GetRegisteredPath(const std::string& filesystem_id, |
| 138 const std::string& filesystem_id, base::FilePath* path) const { | 136 base::FilePath* path) const { |
| 139 DCHECK(path); | 137 DCHECK(path); |
| 140 base::AutoLock locker(lock_); | 138 base::AutoLock locker(lock_); |
| 141 NameToInstance::const_iterator found = instance_map_.find(filesystem_id); | 139 NameToInstance::const_iterator found = instance_map_.find(filesystem_id); |
| 142 if (found == instance_map_.end()) | 140 if (found == instance_map_.end()) |
| 143 return false; | 141 return false; |
| 144 *path = found->second->path(); | 142 *path = found->second->path(); |
| 145 return true; | 143 return true; |
| 146 } | 144 } |
| 147 | 145 |
| 148 bool ExternalMountPoints::CrackVirtualPath( | 146 bool ExternalMountPoints::CrackVirtualPath( |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 206 FileSystemType type, | 204 FileSystemType type, |
| 207 const base::FilePath& path) const { | 205 const base::FilePath& path) const { |
| 208 return CrackFileSystemURL(FileSystemURL(origin, type, path)); | 206 return CrackFileSystemURL(FileSystemURL(origin, type, path)); |
| 209 } | 207 } |
| 210 | 208 |
| 211 void ExternalMountPoints::AddMountPointInfosTo( | 209 void ExternalMountPoints::AddMountPointInfosTo( |
| 212 std::vector<MountPointInfo>* mount_points) const { | 210 std::vector<MountPointInfo>* mount_points) const { |
| 213 base::AutoLock locker(lock_); | 211 base::AutoLock locker(lock_); |
| 214 DCHECK(mount_points); | 212 DCHECK(mount_points); |
| 215 for (NameToInstance::const_iterator iter = instance_map_.begin(); | 213 for (NameToInstance::const_iterator iter = instance_map_.begin(); |
| 216 iter != instance_map_.end(); ++iter) { | 214 iter != instance_map_.end(); |
| 215 ++iter) { |
| 217 mount_points->push_back(MountPointInfo(iter->first, iter->second->path())); | 216 mount_points->push_back(MountPointInfo(iter->first, iter->second->path())); |
| 218 } | 217 } |
| 219 } | 218 } |
| 220 | 219 |
| 221 bool ExternalMountPoints::GetVirtualPath(const base::FilePath& path_in, | 220 bool ExternalMountPoints::GetVirtualPath(const base::FilePath& path_in, |
| 222 base::FilePath* virtual_path) const { | 221 base::FilePath* virtual_path) const { |
| 223 DCHECK(virtual_path); | 222 DCHECK(virtual_path); |
| 224 | 223 |
| 225 base::AutoLock locker(lock_); | 224 base::AutoLock locker(lock_); |
| 226 | 225 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 240 const std::string& mount_name) const { | 239 const std::string& mount_name) const { |
| 241 return base::FilePath().AppendASCII(mount_name); | 240 return base::FilePath().AppendASCII(mount_name); |
| 242 } | 241 } |
| 243 | 242 |
| 244 FileSystemURL ExternalMountPoints::CreateExternalFileSystemURL( | 243 FileSystemURL ExternalMountPoints::CreateExternalFileSystemURL( |
| 245 const GURL& origin, | 244 const GURL& origin, |
| 246 const std::string& mount_name, | 245 const std::string& mount_name, |
| 247 const base::FilePath& path) const { | 246 const base::FilePath& path) const { |
| 248 return CreateCrackedFileSystemURL( | 247 return CreateCrackedFileSystemURL( |
| 249 origin, | 248 origin, |
| 250 fileapi::kFileSystemTypeExternal, | 249 storage::kFileSystemTypeExternal, |
| 251 // Avoid using FilePath::Append as path may be an absolute path. | 250 // Avoid using FilePath::Append as path may be an absolute path. |
| 252 base::FilePath( | 251 base::FilePath(CreateVirtualRootPath(mount_name).value() + |
| 253 CreateVirtualRootPath(mount_name).value() + | 252 base::FilePath::kSeparators[0] + path.value())); |
| 254 base::FilePath::kSeparators[0] + path.value())); | |
| 255 } | 253 } |
| 256 | 254 |
| 257 void ExternalMountPoints::RevokeAllFileSystems() { | 255 void ExternalMountPoints::RevokeAllFileSystems() { |
| 258 NameToInstance instance_map_copy; | 256 NameToInstance instance_map_copy; |
| 259 { | 257 { |
| 260 base::AutoLock locker(lock_); | 258 base::AutoLock locker(lock_); |
| 261 instance_map_copy = instance_map_; | 259 instance_map_copy = instance_map_; |
| 262 instance_map_.clear(); | 260 instance_map_.clear(); |
| 263 path_to_name_map_.clear(); | 261 path_to_name_map_.clear(); |
| 264 } | 262 } |
| 265 STLDeleteContainerPairSecondPointers(instance_map_copy.begin(), | 263 STLDeleteContainerPairSecondPointers(instance_map_copy.begin(), |
| 266 instance_map_copy.end()); | 264 instance_map_copy.end()); |
| 267 } | 265 } |
| 268 | 266 |
| 269 ExternalMountPoints::ExternalMountPoints() {} | 267 ExternalMountPoints::ExternalMountPoints() { |
| 268 } |
| 270 | 269 |
| 271 ExternalMountPoints::~ExternalMountPoints() { | 270 ExternalMountPoints::~ExternalMountPoints() { |
| 272 STLDeleteContainerPairSecondPointers(instance_map_.begin(), | 271 STLDeleteContainerPairSecondPointers(instance_map_.begin(), |
| 273 instance_map_.end()); | 272 instance_map_.end()); |
| 274 } | 273 } |
| 275 | 274 |
| 276 FileSystemURL ExternalMountPoints::CrackFileSystemURL( | 275 FileSystemURL ExternalMountPoints::CrackFileSystemURL( |
| 277 const FileSystemURL& url) const { | 276 const FileSystemURL& url) const { |
| 278 if (!HandlesFileSystemMountType(url.type())) | 277 if (!HandlesFileSystemMountType(url.type())) |
| 279 return FileSystemURL(); | 278 return FileSystemURL(); |
| 280 | 279 |
| 281 base::FilePath virtual_path = url.path(); | 280 base::FilePath virtual_path = url.path(); |
| 282 if (url.type() == kFileSystemTypeNativeForPlatformApp) { | 281 if (url.type() == kFileSystemTypeNativeForPlatformApp) { |
| 283 #if defined(OS_CHROMEOS) | 282 #if defined(OS_CHROMEOS) |
| 284 // On Chrome OS, find a mount point and virtual path for the external fs. | 283 // On Chrome OS, find a mount point and virtual path for the external fs. |
| 285 if (!GetVirtualPath(url.path(), &virtual_path)) | 284 if (!GetVirtualPath(url.path(), &virtual_path)) |
| 286 return FileSystemURL(); | 285 return FileSystemURL(); |
| 287 #else | 286 #else |
| 288 // On other OS, it is simply a native local path. | 287 // On other OS, it is simply a native local path. |
| 289 return FileSystemURL( | 288 return FileSystemURL(url.origin(), |
| 290 url.origin(), url.mount_type(), url.virtual_path(), | 289 url.mount_type(), |
| 291 url.mount_filesystem_id(), kFileSystemTypeNativeLocal, | 290 url.virtual_path(), |
| 292 url.path(), url.filesystem_id(), url.mount_option()); | 291 url.mount_filesystem_id(), |
| 292 kFileSystemTypeNativeLocal, |
| 293 url.path(), |
| 294 url.filesystem_id(), |
| 295 url.mount_option()); |
| 293 #endif | 296 #endif |
| 294 } | 297 } |
| 295 | 298 |
| 296 std::string mount_name; | 299 std::string mount_name; |
| 297 FileSystemType cracked_type; | 300 FileSystemType cracked_type; |
| 298 std::string cracked_id; | 301 std::string cracked_id; |
| 299 base::FilePath cracked_path; | 302 base::FilePath cracked_path; |
| 300 FileSystemMountOption cracked_mount_option; | 303 FileSystemMountOption cracked_mount_option; |
| 301 | 304 |
| 302 if (!CrackVirtualPath(virtual_path, &mount_name, &cracked_type, | 305 if (!CrackVirtualPath(virtual_path, |
| 303 &cracked_id, &cracked_path, &cracked_mount_option)) { | 306 &mount_name, |
| 307 &cracked_type, |
| 308 &cracked_id, |
| 309 &cracked_path, |
| 310 &cracked_mount_option)) { |
| 304 return FileSystemURL(); | 311 return FileSystemURL(); |
| 305 } | 312 } |
| 306 | 313 |
| 307 return FileSystemURL( | 314 return FileSystemURL( |
| 308 url.origin(), url.mount_type(), url.virtual_path(), | 315 url.origin(), |
| 316 url.mount_type(), |
| 317 url.virtual_path(), |
| 309 !url.filesystem_id().empty() ? url.filesystem_id() : mount_name, | 318 !url.filesystem_id().empty() ? url.filesystem_id() : mount_name, |
| 310 cracked_type, cracked_path, | 319 cracked_type, |
| 311 cracked_id.empty() ? mount_name : cracked_id, cracked_mount_option); | 320 cracked_path, |
| 321 cracked_id.empty() ? mount_name : cracked_id, |
| 322 cracked_mount_option); |
| 312 } | 323 } |
| 313 | 324 |
| 314 bool ExternalMountPoints::ValidateNewMountPoint(const std::string& mount_name, | 325 bool ExternalMountPoints::ValidateNewMountPoint(const std::string& mount_name, |
| 315 FileSystemType type, | 326 FileSystemType type, |
| 316 const base::FilePath& path) { | 327 const base::FilePath& path) { |
| 317 lock_.AssertAcquired(); | 328 lock_.AssertAcquired(); |
| 318 | 329 |
| 319 // Mount name must not be empty. | 330 // Mount name must not be empty. |
| 320 if (mount_name.empty()) | 331 if (mount_name.empty()) |
| 321 return false; | 332 return false; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 350 if (potential_child->first == path || | 361 if (potential_child->first == path || |
| 351 path.IsParent(potential_child->first)) { | 362 path.IsParent(potential_child->first)) { |
| 352 return false; | 363 return false; |
| 353 } | 364 } |
| 354 } | 365 } |
| 355 } | 366 } |
| 356 | 367 |
| 357 return true; | 368 return true; |
| 358 } | 369 } |
| 359 | 370 |
| 360 } // namespace fileapi | 371 } // namespace storage |
| OLD | NEW |