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

Side by Side Diff: webkit/fileapi/isolated_context.cc

Issue 11648027: Extract external file systems handling from isolated context. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 7 years, 11 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
OLDNEW
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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 } 55 }
56 NOTREACHED(); 56 NOTREACHED();
57 return true; 57 return true;
58 } 58 }
59 59
60 } // namespace 60 } // namespace
61 61
62 static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context = 62 static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context =
63 LAZY_INSTANCE_INITIALIZER; 63 LAZY_INSTANCE_INITIALIZER;
64 64
65 IsolatedContext::FileInfo::FileInfo() {}
66 IsolatedContext::FileInfo::FileInfo(
67 const std::string& name, const FilePath& path)
68 : name(name), path(path) {}
69
70 IsolatedContext::FileInfoSet::FileInfoSet() {} 65 IsolatedContext::FileInfoSet::FileInfoSet() {}
71 IsolatedContext::FileInfoSet::~FileInfoSet() {} 66 IsolatedContext::FileInfoSet::~FileInfoSet() {}
72 67
73 bool IsolatedContext::FileInfoSet::AddPath( 68 bool IsolatedContext::FileInfoSet::AddPath(
74 const FilePath& path, std::string* registered_name) { 69 const FilePath& path, std::string* registered_name) {
75 // The given path should not contain any '..' and should be absolute. 70 // The given path should not contain any '..' and should be absolute.
76 if (path.ReferencesParent() || !path.IsAbsolute()) 71 if (path.ReferencesParent() || !path.IsAbsolute())
77 return false; 72 return false;
78 FilePath::StringType name = GetRegisterNameForPath(path); 73 FilePath::StringType name = GetRegisterNameForPath(path);
79 std::string utf8name = FilePath(name).AsUTF8Unsafe(); 74 std::string utf8name = FilePath(name).AsUTF8Unsafe();
80 FilePath normalized_path = path.NormalizePathSeparators(); 75 FilePath normalized_path = path.NormalizePathSeparators();
81 bool inserted = fileset_.insert(FileInfo(utf8name, normalized_path)).second; 76 bool inserted =
77 fileset_.insert(MountPointInfo(utf8name, normalized_path)).second;
82 if (!inserted) { 78 if (!inserted) {
83 int suffix = 1; 79 int suffix = 1;
84 std::string basepart = FilePath(name).RemoveExtension().AsUTF8Unsafe(); 80 std::string basepart = FilePath(name).RemoveExtension().AsUTF8Unsafe();
85 std::string ext = FilePath(FilePath(name).Extension()).AsUTF8Unsafe(); 81 std::string ext = FilePath(FilePath(name).Extension()).AsUTF8Unsafe();
86 while (!inserted) { 82 while (!inserted) {
87 utf8name = base::StringPrintf("%s (%d)", basepart.c_str(), suffix++); 83 utf8name = base::StringPrintf("%s (%d)", basepart.c_str(), suffix++);
88 if (!ext.empty()) 84 if (!ext.empty())
89 utf8name.append(ext); 85 utf8name.append(ext);
90 inserted = fileset_.insert(FileInfo(utf8name, normalized_path)).second; 86 inserted =
87 fileset_.insert(MountPointInfo(utf8name, normalized_path)).second;
91 } 88 }
92 } 89 }
93 if (registered_name) 90 if (registered_name)
94 *registered_name = utf8name; 91 *registered_name = utf8name;
95 return true; 92 return true;
96 } 93 }
97 94
98 bool IsolatedContext::FileInfoSet::AddPathWithName( 95 bool IsolatedContext::FileInfoSet::AddPathWithName(
99 const FilePath& path, const std::string& name) { 96 const FilePath& path, const std::string& name) {
100 // The given path should not contain any '..' and should be absolute. 97 // The given path should not contain any '..' and should be absolute.
101 if (path.ReferencesParent() || !path.IsAbsolute()) 98 if (path.ReferencesParent() || !path.IsAbsolute())
102 return false; 99 return false;
103 return fileset_.insert(FileInfo(name, path.NormalizePathSeparators())).second; 100 return fileset_.insert(
101 MountPointInfo(name, path.NormalizePathSeparators())).second;
104 } 102 }
105 103
106 //-------------------------------------------------------------------------- 104 //--------------------------------------------------------------------------
107 105
108 class IsolatedContext::Instance { 106 class IsolatedContext::Instance {
109 public: 107 public:
110 typedef FileSystemType MountType;
111
112 // For a single-path isolated file system, which could be registered by 108 // For a single-path isolated file system, which could be registered by
113 // IsolatedContext::RegisterFileSystemForPath(). 109 // IsolatedContext::RegisterFileSystemForPath().
114 // Most of isolated file system contexts should be of this type. 110 // Most of isolated file system contexts should be of this type.
115 Instance(FileSystemType type, const FileInfo& file_info); 111 Instance(FileSystemType type, const MountPointInfo& file_info);
116 112
117 // For a multi-paths isolated file system. As of writing only file system 113 // For a multi-paths isolated file system. As of writing only file system
118 // type which could have multi-paths is Dragged file system, and 114 // type which could have multi-paths is Dragged file system, and
119 // could be registered by IsolatedContext::RegisterDraggedFileSystem(). 115 // could be registered by IsolatedContext::RegisterDraggedFileSystem().
120 Instance(FileSystemType type, const std::set<FileInfo>& files); 116 Instance(FileSystemType type, const std::set<MountPointInfo>& files);
121
122 // For a single-path external file system.
123 Instance(FileSystemType type, const FilePath& path);
124 117
125 ~Instance(); 118 ~Instance();
126 119
127 MountType mount_type() const { return mount_type_; }
128 FileSystemType type() const { return type_; } 120 FileSystemType type() const { return type_; }
129 const FileInfo& file_info() const { return file_info_; } 121 const MountPointInfo& file_info() const { return file_info_; }
130 const std::set<FileInfo>& files() const { return files_; } 122 const std::set<MountPointInfo>& files() const { return files_; }
131 int ref_counts() const { return ref_counts_; } 123 int ref_counts() const { return ref_counts_; }
132 124
133 void AddRef() { ++ref_counts_; } 125 void AddRef() { ++ref_counts_; }
134 void RemoveRef() { --ref_counts_; } 126 void RemoveRef() { --ref_counts_; }
135 127
136 bool ResolvePathForName(const std::string& name, FilePath* path) const; 128 bool ResolvePathForName(const std::string& name, FilePath* path) const;
137 129
138 // Returns true if the instance is a single-path instance. 130 // Returns true if the instance is a single-path instance.
139 bool IsSinglePathInstance() const; 131 bool IsSinglePathInstance() const;
140 132
141 private: 133 private:
142 const MountType mount_type_;
143 const FileSystemType type_; 134 const FileSystemType type_;
144 135
145 // For single-path instance. 136 // For single-path instance.
146 const FileInfo file_info_; 137 const MountPointInfo file_info_;
147 138
148 // For multiple-path instance (e.g. dragged file system). 139 // For multiple-path instance (e.g. dragged file system).
149 const std::set<FileInfo> files_; 140 const std::set<MountPointInfo> files_;
150 141
151 // Reference counts. Note that an isolated filesystem is created with ref==0 142 // Reference counts. Note that an isolated filesystem is created with ref==0
152 // and will get deleted when the ref count reaches <=0. 143 // and will get deleted when the ref count reaches <=0.
153 int ref_counts_; 144 int ref_counts_;
154 145
155 DISALLOW_COPY_AND_ASSIGN(Instance); 146 DISALLOW_COPY_AND_ASSIGN(Instance);
156 }; 147 };
157 148
158 IsolatedContext::Instance::Instance(FileSystemType type, 149 IsolatedContext::Instance::Instance(FileSystemType type,
159 const FileInfo& file_info) 150 const MountPointInfo& file_info)
160 : mount_type_(kFileSystemTypeIsolated), 151 : type_(type),
161 type_(type),
162 file_info_(file_info), 152 file_info_(file_info),
163 ref_counts_(0) { 153 ref_counts_(0) {
164 DCHECK(IsSinglePathIsolatedFileSystem(type_)); 154 DCHECK(IsSinglePathIsolatedFileSystem(type_));
165 } 155 }
166 156
167 IsolatedContext::Instance::Instance(FileSystemType type, 157 IsolatedContext::Instance::Instance(FileSystemType type,
168 const std::set<FileInfo>& files) 158 const std::set<MountPointInfo>& files)
169 : mount_type_(kFileSystemTypeIsolated), 159 : type_(type),
170 type_(type),
171 files_(files), 160 files_(files),
172 ref_counts_(0) { 161 ref_counts_(0) {
173 DCHECK(!IsSinglePathIsolatedFileSystem(type_)); 162 DCHECK(!IsSinglePathIsolatedFileSystem(type_));
174 } 163 }
175 164
176 IsolatedContext::Instance::Instance(FileSystemType type,
177 const FilePath& path)
178 : mount_type_(kFileSystemTypeExternal),
179 type_(type),
180 file_info_(FileInfo("", path)),
181 ref_counts_(0) {
182 DCHECK(IsSinglePathIsolatedFileSystem(type_));
183 }
184
185 IsolatedContext::Instance::~Instance() {} 165 IsolatedContext::Instance::~Instance() {}
186 166
187 bool IsolatedContext::Instance::ResolvePathForName(const std::string& name, 167 bool IsolatedContext::Instance::ResolvePathForName(const std::string& name,
188 FilePath* path) const { 168 FilePath* path) const {
189 if (IsSinglePathIsolatedFileSystem(type_)) { 169 if (IsSinglePathIsolatedFileSystem(type_)) {
190 *path = file_info_.path; 170 *path = file_info_.path;
191 return file_info_.name == name; 171 return file_info_.name == name;
192 } 172 }
193 std::set<FileInfo>::const_iterator found = files_.find( 173 std::set<MountPointInfo>::const_iterator found = files_.find(
194 FileInfo(name, FilePath())); 174 MountPointInfo(name, FilePath()));
195 if (found == files_.end()) 175 if (found == files_.end())
196 return false; 176 return false;
197 *path = found->path; 177 *path = found->path;
198 return true; 178 return true;
199 } 179 }
200 180
201 bool IsolatedContext::Instance::IsSinglePathInstance() const { 181 bool IsolatedContext::Instance::IsSinglePathInstance() const {
202 return IsSinglePathIsolatedFileSystem(type_); 182 return IsSinglePathIsolatedFileSystem(type_);
203 } 183 }
204 184
(...skipping 28 matching lines...) Expand all
233 if (register_name && !register_name->empty()) { 213 if (register_name && !register_name->empty()) {
234 name = *register_name; 214 name = *register_name;
235 } else { 215 } else {
236 name = FilePath(GetRegisterNameForPath(path)).AsUTF8Unsafe(); 216 name = FilePath(GetRegisterNameForPath(path)).AsUTF8Unsafe();
237 if (register_name) 217 if (register_name)
238 register_name->assign(name); 218 register_name->assign(name);
239 } 219 }
240 220
241 base::AutoLock locker(lock_); 221 base::AutoLock locker(lock_);
242 std::string filesystem_id = GetNewFileSystemId(); 222 std::string filesystem_id = GetNewFileSystemId();
243 instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path)); 223 instance_map_[filesystem_id] = new Instance(type, MountPointInfo(name, path));
244 path_to_id_map_[path].insert(filesystem_id); 224 path_to_id_map_[path].insert(filesystem_id);
245 return filesystem_id; 225 return filesystem_id;
246 } 226 }
247 227
248 bool IsolatedContext::RegisterExternalFileSystem(const std::string& mount_name,
249 FileSystemType type,
250 const FilePath& path) {
251 base::AutoLock locker(lock_);
252 IDToInstance::iterator found = instance_map_.find(mount_name);
253 if (found != instance_map_.end())
254 return false;
255 instance_map_[mount_name] = new Instance(type, path);
256 path_to_id_map_[path].insert(mount_name);
257 return true;
258 }
259
260 std::vector<IsolatedContext::FileInfo>
261 IsolatedContext::GetExternalMountPoints() const {
262 base::AutoLock locker(lock_);
263 std::vector<FileInfo> files;
264 for (IDToInstance::const_iterator iter = instance_map_.begin();
265 iter != instance_map_.end();
266 ++iter) {
267 if (iter->second->mount_type() == kFileSystemTypeExternal)
268 files.push_back(FileInfo(iter->first, iter->second->file_info().path));
269 }
270 return files;
271 }
272
273 bool IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) {
274 base::AutoLock locker(lock_);
275 return UnregisterFileSystem(filesystem_id);
276 }
277
278 void IsolatedContext::RevokeFileSystemByPath(const FilePath& path_in) { 228 void IsolatedContext::RevokeFileSystemByPath(const FilePath& path_in) {
279 base::AutoLock locker(lock_); 229 base::AutoLock locker(lock_);
280 FilePath path(path_in.NormalizePathSeparators()); 230 FilePath path(path_in.NormalizePathSeparators());
281 PathToID::iterator ids_iter = path_to_id_map_.find(path); 231 PathToID::iterator ids_iter = path_to_id_map_.find(path);
282 if (ids_iter == path_to_id_map_.end()) 232 if (ids_iter == path_to_id_map_.end())
283 return; 233 return;
284 std::set<std::string>& ids = ids_iter->second; 234 std::set<std::string>& ids = ids_iter->second;
285 for (std::set<std::string>::iterator iter = ids.begin(); 235 for (std::set<std::string>::iterator iter = ids.begin();
286 iter != ids.end(); ++iter) { 236 iter != ids.end(); ++iter) {
287 IDToInstance::iterator found = instance_map_.find(*iter); 237 IDToInstance::iterator found = instance_map_.find(*iter);
(...skipping 14 matching lines...) Expand all
302 void IsolatedContext::RemoveReference(const std::string& filesystem_id) { 252 void IsolatedContext::RemoveReference(const std::string& filesystem_id) {
303 base::AutoLock locker(lock_); 253 base::AutoLock locker(lock_);
304 // This could get called for non-existent filesystem if it has been 254 // This could get called for non-existent filesystem if it has been
305 // already deleted by RevokeFileSystemByPath. 255 // already deleted by RevokeFileSystemByPath.
306 IDToInstance::iterator found = instance_map_.find(filesystem_id); 256 IDToInstance::iterator found = instance_map_.find(filesystem_id);
307 if (found == instance_map_.end()) 257 if (found == instance_map_.end())
308 return; 258 return;
309 Instance* instance = found->second; 259 Instance* instance = found->second;
310 DCHECK_GT(instance->ref_counts(), 0); 260 DCHECK_GT(instance->ref_counts(), 0);
311 instance->RemoveRef(); 261 instance->RemoveRef();
312 if (instance->ref_counts() == 0 && 262 if (instance->ref_counts() == 0) {
313 instance->mount_type() != kFileSystemTypeExternal) {
314 bool deleted = UnregisterFileSystem(filesystem_id); 263 bool deleted = UnregisterFileSystem(filesystem_id);
315 DCHECK(deleted); 264 DCHECK(deleted);
316 } 265 }
317 } 266 }
318 267
319 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, 268 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path,
320 std::string* id_or_name, 269 std::string* id_or_name,
321 FileSystemType* type, 270 FileSystemType* type,
322 FilePath* path) const { 271 FilePath* path) const {
323 DCHECK(id_or_name); 272 DCHECK(id_or_name);
(...skipping 17 matching lines...) Expand all
341 FilePath cracked_path; 290 FilePath cracked_path;
342 { 291 {
343 base::AutoLock locker(lock_); 292 base::AutoLock locker(lock_);
344 IDToInstance::const_iterator found_instance = instance_map_.find(fsid); 293 IDToInstance::const_iterator found_instance = instance_map_.find(fsid);
345 if (found_instance == instance_map_.end()) 294 if (found_instance == instance_map_.end())
346 return false; 295 return false;
347 *id_or_name = fsid; 296 *id_or_name = fsid;
348 const Instance* instance = found_instance->second; 297 const Instance* instance = found_instance->second;
349 if (type) 298 if (type)
350 *type = instance->type(); 299 *type = instance->type();
351 switch (instance->mount_type()) { 300
352 case kFileSystemTypeIsolated: { 301 if (component_iter == components.end()) {
353 if (component_iter == components.end()) { 302 // The virtual root case.
354 // The virtual root case. 303 path->clear();
355 path->clear(); 304 return true;
356 return true;
357 }
358 // *component_iter should be a name of the registered path.
359 std::string name = FilePath(*component_iter++).AsUTF8Unsafe();
360 if (!instance->ResolvePathForName(name, &cracked_path))
361 return false;
362 break;
363 }
364 case kFileSystemTypeExternal:
365 cracked_path = instance->file_info().path;
366 break;
367 default:
368 NOTREACHED();
369 break;
370 } 305 }
306
307 // *component_iter should be a name of the registered path.
308 std::string name = FilePath(*component_iter++).AsUTF8Unsafe();
309 if (!instance->ResolvePathForName(name, &cracked_path))
310 return false;
371 } 311 }
372 312
373 for (; component_iter != components.end(); ++component_iter) 313 for (; component_iter != components.end(); ++component_iter)
374 cracked_path = cracked_path.Append(*component_iter); 314 cracked_path = cracked_path.Append(*component_iter);
375 *path = cracked_path; 315 *path = cracked_path;
376 return true; 316 return true;
377 } 317 }
378 318
379 bool IsolatedContext::GetDraggedFileInfo( 319 bool IsolatedContext::GetDraggedFileInfo(
380 const std::string& filesystem_id, std::vector<FileInfo>* files) const { 320 const std::string& filesystem_id,
321 std::vector<MountPointInfo>* files) const {
381 DCHECK(files); 322 DCHECK(files);
382 base::AutoLock locker(lock_); 323 base::AutoLock locker(lock_);
383 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); 324 IDToInstance::const_iterator found = instance_map_.find(filesystem_id);
384 if (found == instance_map_.end() || 325 if (found == instance_map_.end() ||
385 found->second->type() != kFileSystemTypeDragged) 326 found->second->type() != kFileSystemTypeDragged)
386 return false; 327 return false;
387 files->assign(found->second->files().begin(), 328 files->assign(found->second->files().begin(),
388 found->second->files().end()); 329 found->second->files().end());
389 return true; 330 return true;
390 } 331 }
391 332
333 bool IsolatedContext::CanCrackMountType(FileSystemType type) const {
334 return type == kFileSystemTypeIsolated;
335 }
336
392 bool IsolatedContext::GetRegisteredPath( 337 bool IsolatedContext::GetRegisteredPath(
393 const std::string& filesystem_id, FilePath* path) const { 338 const std::string& filesystem_id, FilePath* path) const {
394 DCHECK(path); 339 DCHECK(path);
395 base::AutoLock locker(lock_); 340 base::AutoLock locker(lock_);
396 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); 341 IDToInstance::const_iterator found = instance_map_.find(filesystem_id);
397 if (found == instance_map_.end() || !found->second->IsSinglePathInstance()) 342 if (found == instance_map_.end() || !found->second->IsSinglePathInstance())
398 return false; 343 return false;
399 *path = found->second->file_info().path; 344 *path = found->second->file_info().path;
400 return true; 345 return true;
401 } 346 }
402 347
348 bool IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) {
349 base::AutoLock locker(lock_);
kinuko 2013/01/08 12:22:43 nit:indent
tbarzic 2013/01/09 01:26:34 I think indent is fine..
350 return UnregisterFileSystem(filesystem_id);
351 }
352
353
kinuko 2013/01/08 12:22:43 nit: extra empty line
tbarzic 2013/01/09 01:26:34 Done.
403 FilePath IsolatedContext::CreateVirtualRootPath( 354 FilePath IsolatedContext::CreateVirtualRootPath(
404 const std::string& filesystem_id) const { 355 const std::string& filesystem_id) const {
405 return FilePath().AppendASCII(filesystem_id); 356 return FilePath().AppendASCII(filesystem_id);
406 } 357 }
407 358
408 IsolatedContext::IsolatedContext() { 359 IsolatedContext::IsolatedContext() {
409 } 360 }
410 361
411 IsolatedContext::~IsolatedContext() { 362 IsolatedContext::~IsolatedContext() {
412 STLDeleteContainerPairSecondPointers(instance_map_.begin(), 363 STLDeleteContainerPairSecondPointers(instance_map_.begin(),
(...skipping 24 matching lines...) Expand all
437 lock_.AssertAcquired(); 388 lock_.AssertAcquired();
438 uint32 random_data[4]; 389 uint32 random_data[4];
439 std::string id; 390 std::string id;
440 do { 391 do {
441 base::RandBytes(random_data, sizeof(random_data)); 392 base::RandBytes(random_data, sizeof(random_data));
442 id = base::HexEncode(random_data, sizeof(random_data)); 393 id = base::HexEncode(random_data, sizeof(random_data));
443 } while (instance_map_.find(id) != instance_map_.end()); 394 } while (instance_map_.find(id) != instance_map_.end());
444 return id; 395 return id;
445 } 396 }
446 397
447 ScopedExternalFileSystem::ScopedExternalFileSystem(
448 const std::string& mount_name,
449 FileSystemType type,
450 const FilePath& path)
451 : mount_name_(mount_name) {
452 IsolatedContext::GetInstance()->RegisterExternalFileSystem(
453 mount_name, type, path);
454 }
455
456 FilePath ScopedExternalFileSystem::GetVirtualRootPath() const {
457 return IsolatedContext::GetInstance()->CreateVirtualRootPath(mount_name_);
458 }
459
460 ScopedExternalFileSystem::~ScopedExternalFileSystem() {
461 IsolatedContext::GetInstance()->RevokeFileSystem(mount_name_);
462 }
463
464 } // namespace fileapi 398 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698