| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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/fileapi/isolated_context.h" | 5 #include "webkit/fileapi/isolated_context.h" |
| 6 | 6 |
| 7 #include "base/file_path.h" | 7 #include "base/file_path.h" |
| 8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/rand_util.h" | 10 #include "base/rand_util.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 46 case kFileSystemTypeDragged: | 46 case kFileSystemTypeDragged: |
| 47 return false; | 47 return false; |
| 48 | 48 |
| 49 // Regular file systems. | 49 // Regular file systems. |
| 50 case kFileSystemTypeIsolated: | 50 case kFileSystemTypeIsolated: |
| 51 case kFileSystemTypeNativeMedia: | 51 case kFileSystemTypeNativeMedia: |
| 52 case kFileSystemTypeDeviceMedia: | 52 case kFileSystemTypeDeviceMedia: |
| 53 case kFileSystemTypeTemporary: | 53 case kFileSystemTypeTemporary: |
| 54 case kFileSystemTypePersistent: | 54 case kFileSystemTypePersistent: |
| 55 case kFileSystemTypeExternal: | 55 case kFileSystemTypeExternal: |
| 56 case kFileSystemTypeNativeLocal: |
| 57 case kFileSystemTypeGData: |
| 56 case kFileSystemTypeTest: | 58 case kFileSystemTypeTest: |
| 57 return true; | 59 return true; |
| 58 | 60 |
| 59 case kFileSystemTypeUnknown: | 61 case kFileSystemTypeUnknown: |
| 60 NOTREACHED(); | 62 NOTREACHED(); |
| 61 return true; | 63 return true; |
| 62 } | 64 } |
| 63 NOTREACHED(); | 65 NOTREACHED(); |
| 64 return true; | 66 return true; |
| 65 } | 67 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 // The given path should not contain any '..' and should be absolute. | 109 // The given path should not contain any '..' and should be absolute. |
| 108 if (path.ReferencesParent() || !path.IsAbsolute()) | 110 if (path.ReferencesParent() || !path.IsAbsolute()) |
| 109 return false; | 111 return false; |
| 110 return fileset_.insert(FileInfo(name, path.NormalizePathSeparators())).second; | 112 return fileset_.insert(FileInfo(name, path.NormalizePathSeparators())).second; |
| 111 } | 113 } |
| 112 | 114 |
| 113 //-------------------------------------------------------------------------- | 115 //-------------------------------------------------------------------------- |
| 114 | 116 |
| 115 IsolatedContext::Instance::Instance(FileSystemType type, | 117 IsolatedContext::Instance::Instance(FileSystemType type, |
| 116 const FileInfo& file_info) | 118 const FileInfo& file_info) |
| 117 : type_(type), | 119 : instance_type_(ISOLATED), |
| 120 type_(type), |
| 118 file_info_(file_info), | 121 file_info_(file_info), |
| 119 ref_counts_(0) { | 122 ref_counts_(0) { |
| 120 DCHECK(IsSinglePathIsolatedFileSystem(type_)); | 123 DCHECK(IsSinglePathIsolatedFileSystem(type_)); |
| 121 } | 124 } |
| 122 | 125 |
| 123 IsolatedContext::Instance::Instance(FileSystemType type, | 126 IsolatedContext::Instance::Instance(FileSystemType type, |
| 124 const std::set<FileInfo>& files) | 127 const std::set<FileInfo>& files) |
| 125 : type_(type), | 128 : instance_type_(ISOLATED), |
| 129 type_(type), |
| 126 files_(files), | 130 files_(files), |
| 127 ref_counts_(0) { | 131 ref_counts_(0) { |
| 128 DCHECK(!IsSinglePathIsolatedFileSystem(type_)); | 132 DCHECK(!IsSinglePathIsolatedFileSystem(type_)); |
| 129 } | 133 } |
| 130 | 134 |
| 135 IsolatedContext::Instance::Instance(FileSystemType type, |
| 136 const FilePath& path) |
| 137 : instance_type_(EXTERNAL), |
| 138 type_(type), |
| 139 file_info_(FileInfo("", path)), |
| 140 ref_counts_(0) { |
| 141 DCHECK(IsSinglePathIsolatedFileSystem(type_)); |
| 142 } |
| 143 |
| 131 IsolatedContext::Instance::~Instance() {} | 144 IsolatedContext::Instance::~Instance() {} |
| 132 | 145 |
| 133 bool IsolatedContext::Instance::ResolvePathForName(const std::string& name, | 146 bool IsolatedContext::Instance::ResolvePathForName(const std::string& name, |
| 134 FilePath* path) const { | 147 FilePath* path) const { |
| 135 if (IsSinglePathIsolatedFileSystem(type_)) { | 148 if (IsSinglePathIsolatedFileSystem(type_)) { |
| 136 *path = file_info_.path; | 149 *path = file_info_.path; |
| 137 return file_info_.name == name; | 150 return file_info_.name == name; |
| 138 } | 151 } |
| 139 std::set<FileInfo>::const_iterator found = files_.find( | 152 std::set<FileInfo>::const_iterator found = files_.find( |
| 140 FileInfo(name, FilePath())); | 153 FileInfo(name, FilePath())); |
| 141 if (found == files_.end()) | 154 if (found == files_.end()) |
| 142 return false; | 155 return false; |
| 143 *path = found->path; | 156 *path = found->path; |
| 144 return true; | 157 return true; |
| 145 } | 158 } |
| 146 | 159 |
| 147 bool IsolatedContext::Instance::IsSinglePathInstance() const { | 160 bool IsolatedContext::Instance::IsSinglePathInstance() const { |
| 148 return IsSinglePathIsolatedFileSystem(type_); | 161 return IsSinglePathIsolatedFileSystem(type_); |
| 149 } | 162 } |
| 150 | 163 |
| 151 //-------------------------------------------------------------------------- | 164 //-------------------------------------------------------------------------- |
| 152 | 165 |
| 153 // static | 166 // static |
| 154 IsolatedContext* IsolatedContext::GetInstance() { | 167 IsolatedContext* IsolatedContext::GetInstance() { |
| 155 return g_isolated_context.Pointer(); | 168 return g_isolated_context.Pointer(); |
| 156 } | 169 } |
| 157 | 170 |
| 171 // static |
| 172 bool IsolatedContext::IsIsolatedType(FileSystemType type) { |
| 173 return type == kFileSystemTypeIsolated || type == kFileSystemTypeExternal; |
| 174 } |
| 175 |
| 158 std::string IsolatedContext::RegisterDraggedFileSystem( | 176 std::string IsolatedContext::RegisterDraggedFileSystem( |
| 159 const FileInfoSet& files) { | 177 const FileInfoSet& files) { |
| 160 base::AutoLock locker(lock_); | 178 base::AutoLock locker(lock_); |
| 161 std::string filesystem_id = GetNewFileSystemId(); | 179 std::string filesystem_id = GetNewFileSystemId(); |
| 162 instance_map_[filesystem_id] = new Instance( | 180 instance_map_[filesystem_id] = new Instance( |
| 163 kFileSystemTypeDragged, files.fileset()); | 181 kFileSystemTypeDragged, files.fileset()); |
| 164 return filesystem_id; | 182 return filesystem_id; |
| 165 } | 183 } |
| 166 | 184 |
| 167 std::string IsolatedContext::RegisterFileSystemForPath( | 185 std::string IsolatedContext::RegisterFileSystemForPath( |
| (...skipping 11 matching lines...) Expand all Loading... |
| 179 register_name->assign(name); | 197 register_name->assign(name); |
| 180 } | 198 } |
| 181 | 199 |
| 182 base::AutoLock locker(lock_); | 200 base::AutoLock locker(lock_); |
| 183 std::string filesystem_id = GetNewFileSystemId(); | 201 std::string filesystem_id = GetNewFileSystemId(); |
| 184 instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path)); | 202 instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path)); |
| 185 path_to_id_map_[path].insert(filesystem_id); | 203 path_to_id_map_[path].insert(filesystem_id); |
| 186 return filesystem_id; | 204 return filesystem_id; |
| 187 } | 205 } |
| 188 | 206 |
| 207 #if defined(OS_CHROMEOS) |
| 208 bool IsolatedContext::RegisterExternalFileSystem(const std::string& mount_name, |
| 209 FileSystemType type, |
| 210 const FilePath& path) { |
| 211 base::AutoLock locker(lock_); |
| 212 IDToInstance::iterator found = instance_map_.find(mount_name); |
| 213 if (found != instance_map_.end()) |
| 214 return false; |
| 215 instance_map_[mount_name] = new Instance(type, path); |
| 216 path_to_id_map_[path].insert(mount_name); |
| 217 return true; |
| 218 } |
| 219 |
| 220 std::vector<IsolatedContext::FileInfo> |
| 221 IsolatedContext::GetExternalMountPoints() const { |
| 222 base::AutoLock locker(lock_); |
| 223 std::vector<FileInfo> files; |
| 224 for (IDToInstance::const_iterator iter = instance_map_.begin(); |
| 225 iter != instance_map_.end(); |
| 226 ++iter) { |
| 227 if (iter->second->instance_type() == Instance::EXTERNAL) |
| 228 files.push_back(FileInfo(iter->first, iter->second->file_info().path)); |
| 229 } |
| 230 return files; |
| 231 } |
| 232 #endif |
| 233 |
| 189 bool IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) { | 234 bool IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) { |
| 190 base::AutoLock locker(lock_); | 235 base::AutoLock locker(lock_); |
| 191 return UnregisterFileSystem(filesystem_id); | 236 return UnregisterFileSystem(filesystem_id); |
| 192 } | 237 } |
| 193 | 238 |
| 194 void IsolatedContext::RevokeFileSystemByPath(const FilePath& path_in) { | 239 void IsolatedContext::RevokeFileSystemByPath(const FilePath& path_in) { |
| 195 base::AutoLock locker(lock_); | 240 base::AutoLock locker(lock_); |
| 196 FilePath path(path_in.NormalizePathSeparators()); | 241 FilePath path(path_in.NormalizePathSeparators()); |
| 197 PathToID::iterator ids_iter = path_to_id_map_.find(path); | 242 PathToID::iterator ids_iter = path_to_id_map_.find(path); |
| 198 if (ids_iter == path_to_id_map_.end()) | 243 if (ids_iter == path_to_id_map_.end()) |
| (...skipping 19 matching lines...) Expand all Loading... |
| 218 void IsolatedContext::RemoveReference(const std::string& filesystem_id) { | 263 void IsolatedContext::RemoveReference(const std::string& filesystem_id) { |
| 219 base::AutoLock locker(lock_); | 264 base::AutoLock locker(lock_); |
| 220 // This could get called for non-existent filesystem if it has been | 265 // This could get called for non-existent filesystem if it has been |
| 221 // already deleted by RevokeFileSystemByPath. | 266 // already deleted by RevokeFileSystemByPath. |
| 222 IDToInstance::iterator found = instance_map_.find(filesystem_id); | 267 IDToInstance::iterator found = instance_map_.find(filesystem_id); |
| 223 if (found == instance_map_.end()) | 268 if (found == instance_map_.end()) |
| 224 return; | 269 return; |
| 225 Instance* instance = found->second; | 270 Instance* instance = found->second; |
| 226 DCHECK(instance->ref_counts() > 0); | 271 DCHECK(instance->ref_counts() > 0); |
| 227 instance->RemoveRef(); | 272 instance->RemoveRef(); |
| 228 if (instance->ref_counts() == 0) { | 273 if (instance->ref_counts() == 0 && |
| 274 instance->instance_type() != Instance::EXTERNAL) { |
| 229 bool deleted = UnregisterFileSystem(filesystem_id); | 275 bool deleted = UnregisterFileSystem(filesystem_id); |
| 230 DCHECK(deleted); | 276 DCHECK(deleted); |
| 231 } | 277 } |
| 232 } | 278 } |
| 233 | 279 |
| 234 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, | 280 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, |
| 235 std::string* filesystem_id, | 281 std::string* id_or_name, |
| 236 FileSystemType* type, | 282 FileSystemType* type, |
| 237 FilePath* path) const { | 283 FilePath* path) const { |
| 238 DCHECK(filesystem_id); | 284 DCHECK(id_or_name); |
| 239 DCHECK(path); | 285 DCHECK(path); |
| 240 | 286 |
| 241 // This should not contain any '..' references. | 287 // This should not contain any '..' references. |
| 242 if (virtual_path.ReferencesParent()) | 288 if (virtual_path.ReferencesParent()) |
| 243 return false; | 289 return false; |
| 244 | 290 |
| 245 // The virtual_path should comprise <filesystem_id> and <relative_path> parts. | 291 // The virtual_path should comprise <id_or_name> and <relative_path> parts. |
| 246 std::vector<FilePath::StringType> components; | 292 std::vector<FilePath::StringType> components; |
| 247 virtual_path.GetComponents(&components); | 293 virtual_path.GetComponents(&components); |
| 248 if (components.size() < 1) | 294 if (components.size() < 1) |
| 249 return false; | 295 return false; |
| 250 | 296 std::vector<FilePath::StringType>::iterator component_iter = |
| 251 base::AutoLock locker(lock_); | 297 components.begin(); |
| 252 std::string fsid = FilePath(components[0]).MaybeAsASCII(); | 298 std::string fsid = FilePath(*component_iter++).MaybeAsASCII(); |
| 253 if (fsid.empty()) | 299 if (fsid.empty()) |
| 254 return false; | 300 return false; |
| 255 IDToInstance::const_iterator found_instance = instance_map_.find(fsid); | 301 |
| 256 if (found_instance == instance_map_.end()) | 302 FilePath cracked_path; |
| 257 return false; | 303 { |
| 258 *filesystem_id = fsid; | 304 base::AutoLock locker(lock_); |
| 259 if (type) | 305 IDToInstance::const_iterator found_instance = instance_map_.find(fsid); |
| 260 *type = found_instance->second->type(); | 306 if (found_instance == instance_map_.end()) |
| 261 if (components.size() == 1) { | 307 return false; |
| 262 path->clear(); | 308 *id_or_name = fsid; |
| 263 return true; | 309 const Instance* instance = found_instance->second; |
| 310 if (type) |
| 311 *type = instance->type(); |
| 312 switch (instance->instance_type()) { |
| 313 case Instance::ISOLATED: { |
| 314 if (component_iter == components.end()) { |
| 315 // The virtual root case. |
| 316 path->clear(); |
| 317 return true; |
| 318 } |
| 319 // *component_iter should be a name of the registered path. |
| 320 std::string name = FilePath(*component_iter++).AsUTF8Unsafe(); |
| 321 if (!instance->ResolvePathForName(name, &cracked_path)) |
| 322 return false; |
| 323 break; |
| 324 } |
| 325 case Instance::EXTERNAL: |
| 326 cracked_path = instance->file_info().path; |
| 327 break; |
| 328 } |
| 264 } | 329 } |
| 265 // components[1] should be a name of the registered paths. | |
| 266 FilePath cracked_path; | |
| 267 std::string name = FilePath(components[1]).AsUTF8Unsafe(); | |
| 268 if (!found_instance->second->ResolvePathForName(name, &cracked_path)) | |
| 269 return false; | |
| 270 | 330 |
| 271 for (size_t i = 2; i < components.size(); ++i) | 331 for (; component_iter != components.end(); ++component_iter) |
| 272 cracked_path = cracked_path.Append(components[i]); | 332 cracked_path = cracked_path.Append(*component_iter); |
| 273 *path = cracked_path; | 333 *path = cracked_path; |
| 274 return true; | 334 return true; |
| 275 } | 335 } |
| 276 | 336 |
| 277 bool IsolatedContext::GetDraggedFileInfo( | 337 bool IsolatedContext::GetDraggedFileInfo( |
| 278 const std::string& filesystem_id, std::vector<FileInfo>* files) const { | 338 const std::string& filesystem_id, std::vector<FileInfo>* files) const { |
| 279 DCHECK(files); | 339 DCHECK(files); |
| 280 base::AutoLock locker(lock_); | 340 base::AutoLock locker(lock_); |
| 281 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); | 341 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); |
| 282 if (found == instance_map_.end() || | 342 if (found == instance_map_.end() || |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 uint32 random_data[4]; | 396 uint32 random_data[4]; |
| 337 std::string id; | 397 std::string id; |
| 338 do { | 398 do { |
| 339 base::RandBytes(random_data, sizeof(random_data)); | 399 base::RandBytes(random_data, sizeof(random_data)); |
| 340 id = base::HexEncode(random_data, sizeof(random_data)); | 400 id = base::HexEncode(random_data, sizeof(random_data)); |
| 341 } while (instance_map_.find(id) != instance_map_.end()); | 401 } while (instance_map_.find(id) != instance_map_.end()); |
| 342 return id; | 402 return id; |
| 343 } | 403 } |
| 344 | 404 |
| 345 } // namespace fileapi | 405 } // namespace fileapi |
| OLD | NEW |