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

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

Issue 10823273: Integrate external mount points to IsolatedContext (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: wording fix Created 8 years, 4 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 28 matching lines...) Expand all
39 #endif 39 #endif
40 } 40 }
41 41
42 bool IsSinglePathIsolatedFileSystem(FileSystemType type) { 42 bool IsSinglePathIsolatedFileSystem(FileSystemType type) {
43 switch (type) { 43 switch (type) {
44 // As of writing dragged file system is the only filesystem 44 // As of writing dragged file system is the only filesystem
45 // which could have multiple toplevel paths. 45 // which could have multiple toplevel paths.
46 case kFileSystemTypeDragged: 46 case kFileSystemTypeDragged:
47 return false; 47 return false;
48 48
49 // Regular file systems.
50 case kFileSystemTypeIsolated:
51 case kFileSystemTypeNativeMedia:
52 case kFileSystemTypeDeviceMedia:
53 case kFileSystemTypeTemporary:
54 case kFileSystemTypePersistent:
55 case kFileSystemTypeExternal:
56 case kFileSystemTypeTest:
57 return true;
58
59 case kFileSystemTypeUnknown: 49 case kFileSystemTypeUnknown:
60 NOTREACHED(); 50 NOTREACHED();
61 return true; 51 return true;
52
53 default:
54 return true;
62 } 55 }
63 NOTREACHED(); 56 NOTREACHED();
64 return true; 57 return true;
65 } 58 }
66 59
67 } 60 }
68 61
69 static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context = 62 static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context =
70 LAZY_INSTANCE_INITIALIZER; 63 LAZY_INSTANCE_INITIALIZER;
71 64
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 bool IsolatedContext::FileInfoSet::AddPathWithName( 98 bool IsolatedContext::FileInfoSet::AddPathWithName(
106 const FilePath& path, const std::string& name) { 99 const FilePath& path, const std::string& name) {
107 // The given path should not contain any '..' and should be absolute. 100 // The given path should not contain any '..' and should be absolute.
108 if (path.ReferencesParent() || !path.IsAbsolute()) 101 if (path.ReferencesParent() || !path.IsAbsolute())
109 return false; 102 return false;
110 return fileset_.insert(FileInfo(name, path.NormalizePathSeparators())).second; 103 return fileset_.insert(FileInfo(name, path.NormalizePathSeparators())).second;
111 } 104 }
112 105
113 //-------------------------------------------------------------------------- 106 //--------------------------------------------------------------------------
114 107
108 class IsolatedContext::Instance {
109 public:
110 enum InstanceType {
111 ISOLATED,
112 EXTERNAL,
113 };
114
115 // For a single-path isolated file system, which could be registered by
116 // IsolatedContext::RegisterFileSystemForPath().
117 // Most of isolated file system contexts should be of this type.
118 Instance(FileSystemType type, const FileInfo& file_info);
119
120 // For a multi-paths isolated file system. As of writing only file system
121 // type which could have multi-paths is Dragged file system, and
122 // could be registered by IsolatedContext::RegisterDraggedFileSystem().
123 Instance(FileSystemType type, const std::set<FileInfo>& files);
124
125 // For a single-path external file system.
126 Instance(FileSystemType type, const FilePath& path);
127
128 ~Instance();
129
130 InstanceType instance_type() const { return instance_type_; }
131 FileSystemType type() const { return type_; }
132 const FileInfo& file_info() const { return file_info_; }
133 const std::set<FileInfo>& files() const { return files_; }
134 int ref_counts() const { return ref_counts_; }
135
136 void AddRef() { ++ref_counts_; }
137 void RemoveRef() { --ref_counts_; }
138
139 bool ResolvePathForName(const std::string& name, FilePath* path) const;
140
141 // Returns true if the instance is a single-path instance.
142 bool IsSinglePathInstance() const;
143
144 private:
145 const InstanceType instance_type_;
146 const FileSystemType type_;
147
148 // For single-path instance.
149 const FileInfo file_info_;
150
151 // For multiple-path instance (e.g. dragged file system).
152 const std::set<FileInfo> files_;
153
154 // Reference counts. Note that an isolated filesystem is created with ref==0
155 // and will get deleted when the ref count reaches <=0.
156 int ref_counts_;
157
158 DISALLOW_COPY_AND_ASSIGN(Instance);
159 };
160
115 IsolatedContext::Instance::Instance(FileSystemType type, 161 IsolatedContext::Instance::Instance(FileSystemType type,
116 const FileInfo& file_info) 162 const FileInfo& file_info)
117 : type_(type), 163 : instance_type_(ISOLATED),
164 type_(type),
118 file_info_(file_info), 165 file_info_(file_info),
119 ref_counts_(0) { 166 ref_counts_(0) {
120 DCHECK(IsSinglePathIsolatedFileSystem(type_)); 167 DCHECK(IsSinglePathIsolatedFileSystem(type_));
121 } 168 }
122 169
123 IsolatedContext::Instance::Instance(FileSystemType type, 170 IsolatedContext::Instance::Instance(FileSystemType type,
124 const std::set<FileInfo>& files) 171 const std::set<FileInfo>& files)
125 : type_(type), 172 : instance_type_(ISOLATED),
173 type_(type),
126 files_(files), 174 files_(files),
127 ref_counts_(0) { 175 ref_counts_(0) {
128 DCHECK(!IsSinglePathIsolatedFileSystem(type_)); 176 DCHECK(!IsSinglePathIsolatedFileSystem(type_));
129 } 177 }
130 178
179 IsolatedContext::Instance::Instance(FileSystemType type,
180 const FilePath& path)
181 : instance_type_(EXTERNAL),
182 type_(type),
183 file_info_(FileInfo("", path)),
184 ref_counts_(0) {
185 DCHECK(IsSinglePathIsolatedFileSystem(type_));
186 }
187
131 IsolatedContext::Instance::~Instance() {} 188 IsolatedContext::Instance::~Instance() {}
132 189
133 bool IsolatedContext::Instance::ResolvePathForName(const std::string& name, 190 bool IsolatedContext::Instance::ResolvePathForName(const std::string& name,
134 FilePath* path) const { 191 FilePath* path) const {
135 if (IsSinglePathIsolatedFileSystem(type_)) { 192 if (IsSinglePathIsolatedFileSystem(type_)) {
136 *path = file_info_.path; 193 *path = file_info_.path;
137 return file_info_.name == name; 194 return file_info_.name == name;
138 } 195 }
139 std::set<FileInfo>::const_iterator found = files_.find( 196 std::set<FileInfo>::const_iterator found = files_.find(
140 FileInfo(name, FilePath())); 197 FileInfo(name, FilePath()));
141 if (found == files_.end()) 198 if (found == files_.end())
142 return false; 199 return false;
143 *path = found->path; 200 *path = found->path;
144 return true; 201 return true;
145 } 202 }
146 203
147 bool IsolatedContext::Instance::IsSinglePathInstance() const { 204 bool IsolatedContext::Instance::IsSinglePathInstance() const {
148 return IsSinglePathIsolatedFileSystem(type_); 205 return IsSinglePathIsolatedFileSystem(type_);
149 } 206 }
150 207
151 //-------------------------------------------------------------------------- 208 //--------------------------------------------------------------------------
152 209
153 // static 210 // static
154 IsolatedContext* IsolatedContext::GetInstance() { 211 IsolatedContext* IsolatedContext::GetInstance() {
155 return g_isolated_context.Pointer(); 212 return g_isolated_context.Pointer();
156 } 213 }
157 214
215 // static
216 bool IsolatedContext::IsIsolatedType(FileSystemType type) {
217 return type == kFileSystemTypeIsolated || type == kFileSystemTypeExternal;
218 }
219
158 std::string IsolatedContext::RegisterDraggedFileSystem( 220 std::string IsolatedContext::RegisterDraggedFileSystem(
159 const FileInfoSet& files) { 221 const FileInfoSet& files) {
160 base::AutoLock locker(lock_); 222 base::AutoLock locker(lock_);
161 std::string filesystem_id = GetNewFileSystemId(); 223 std::string filesystem_id = GetNewFileSystemId();
162 instance_map_[filesystem_id] = new Instance( 224 instance_map_[filesystem_id] = new Instance(
163 kFileSystemTypeDragged, files.fileset()); 225 kFileSystemTypeDragged, files.fileset());
164 return filesystem_id; 226 return filesystem_id;
165 } 227 }
166 228
167 std::string IsolatedContext::RegisterFileSystemForPath( 229 std::string IsolatedContext::RegisterFileSystemForPath(
(...skipping 11 matching lines...) Expand all
179 register_name->assign(name); 241 register_name->assign(name);
180 } 242 }
181 243
182 base::AutoLock locker(lock_); 244 base::AutoLock locker(lock_);
183 std::string filesystem_id = GetNewFileSystemId(); 245 std::string filesystem_id = GetNewFileSystemId();
184 instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path)); 246 instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path));
185 path_to_id_map_[path].insert(filesystem_id); 247 path_to_id_map_[path].insert(filesystem_id);
186 return filesystem_id; 248 return filesystem_id;
187 } 249 }
188 250
251 #if defined(OS_CHROMEOS)
252 bool IsolatedContext::RegisterExternalFileSystem(const std::string& mount_name,
253 FileSystemType type,
254 const FilePath& path) {
255 base::AutoLock locker(lock_);
256 IDToInstance::iterator found = instance_map_.find(mount_name);
257 if (found != instance_map_.end())
258 return false;
259 instance_map_[mount_name] = new Instance(type, path);
260 path_to_id_map_[path].insert(mount_name);
261 return true;
262 }
263
264 std::vector<IsolatedContext::FileInfo>
265 IsolatedContext::GetExternalMountPoints() const {
266 base::AutoLock locker(lock_);
267 std::vector<FileInfo> files;
268 for (IDToInstance::const_iterator iter = instance_map_.begin();
269 iter != instance_map_.end();
270 ++iter) {
271 if (iter->second->instance_type() == Instance::EXTERNAL)
272 files.push_back(FileInfo(iter->first, iter->second->file_info().path));
273 }
274 return files;
275 }
276 #endif
277
189 bool IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) { 278 bool IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) {
190 base::AutoLock locker(lock_); 279 base::AutoLock locker(lock_);
191 return UnregisterFileSystem(filesystem_id); 280 return UnregisterFileSystem(filesystem_id);
192 } 281 }
193 282
194 void IsolatedContext::RevokeFileSystemByPath(const FilePath& path_in) { 283 void IsolatedContext::RevokeFileSystemByPath(const FilePath& path_in) {
195 base::AutoLock locker(lock_); 284 base::AutoLock locker(lock_);
196 FilePath path(path_in.NormalizePathSeparators()); 285 FilePath path(path_in.NormalizePathSeparators());
197 PathToID::iterator ids_iter = path_to_id_map_.find(path); 286 PathToID::iterator ids_iter = path_to_id_map_.find(path);
198 if (ids_iter == path_to_id_map_.end()) 287 if (ids_iter == path_to_id_map_.end())
(...skipping 19 matching lines...) Expand all
218 void IsolatedContext::RemoveReference(const std::string& filesystem_id) { 307 void IsolatedContext::RemoveReference(const std::string& filesystem_id) {
219 base::AutoLock locker(lock_); 308 base::AutoLock locker(lock_);
220 // This could get called for non-existent filesystem if it has been 309 // This could get called for non-existent filesystem if it has been
221 // already deleted by RevokeFileSystemByPath. 310 // already deleted by RevokeFileSystemByPath.
222 IDToInstance::iterator found = instance_map_.find(filesystem_id); 311 IDToInstance::iterator found = instance_map_.find(filesystem_id);
223 if (found == instance_map_.end()) 312 if (found == instance_map_.end())
224 return; 313 return;
225 Instance* instance = found->second; 314 Instance* instance = found->second;
226 DCHECK(instance->ref_counts() > 0); 315 DCHECK(instance->ref_counts() > 0);
227 instance->RemoveRef(); 316 instance->RemoveRef();
228 if (instance->ref_counts() == 0) { 317 if (instance->ref_counts() == 0 &&
318 instance->instance_type() != Instance::EXTERNAL) {
229 bool deleted = UnregisterFileSystem(filesystem_id); 319 bool deleted = UnregisterFileSystem(filesystem_id);
230 DCHECK(deleted); 320 DCHECK(deleted);
231 } 321 }
232 } 322 }
233 323
234 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, 324 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path,
235 std::string* filesystem_id, 325 std::string* id_or_name,
236 FileSystemType* type, 326 FileSystemType* type,
237 FilePath* path) const { 327 FilePath* path) const {
238 DCHECK(filesystem_id); 328 DCHECK(id_or_name);
239 DCHECK(path); 329 DCHECK(path);
240 330
241 // This should not contain any '..' references. 331 // This should not contain any '..' references.
242 if (virtual_path.ReferencesParent()) 332 if (virtual_path.ReferencesParent())
243 return false; 333 return false;
244 334
245 // The virtual_path should comprise <filesystem_id> and <relative_path> parts. 335 // The virtual_path should comprise <id_or_name> and <relative_path> parts.
246 std::vector<FilePath::StringType> components; 336 std::vector<FilePath::StringType> components;
247 virtual_path.GetComponents(&components); 337 virtual_path.GetComponents(&components);
248 if (components.size() < 1) 338 if (components.size() < 1)
249 return false; 339 return false;
250 340 std::vector<FilePath::StringType>::iterator component_iter =
251 base::AutoLock locker(lock_); 341 components.begin();
252 std::string fsid = FilePath(components[0]).MaybeAsASCII(); 342 std::string fsid = FilePath(*component_iter++).MaybeAsASCII();
253 if (fsid.empty()) 343 if (fsid.empty())
254 return false; 344 return false;
255 IDToInstance::const_iterator found_instance = instance_map_.find(fsid); 345
256 if (found_instance == instance_map_.end()) 346 FilePath cracked_path;
257 return false; 347 {
258 *filesystem_id = fsid; 348 base::AutoLock locker(lock_);
259 if (type) 349 IDToInstance::const_iterator found_instance = instance_map_.find(fsid);
260 *type = found_instance->second->type(); 350 if (found_instance == instance_map_.end())
261 if (components.size() == 1) { 351 return false;
262 path->clear(); 352 *id_or_name = fsid;
263 return true; 353 const Instance* instance = found_instance->second;
354 if (type)
355 *type = instance->type();
356 switch (instance->instance_type()) {
357 case Instance::ISOLATED: {
358 if (component_iter == components.end()) {
359 // The virtual root case.
360 path->clear();
361 return true;
362 }
363 // *component_iter should be a name of the registered path.
364 std::string name = FilePath(*component_iter++).AsUTF8Unsafe();
365 if (!instance->ResolvePathForName(name, &cracked_path))
366 return false;
367 break;
368 }
369 case Instance::EXTERNAL:
370 cracked_path = instance->file_info().path;
371 break;
372 }
264 } 373 }
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 374
271 for (size_t i = 2; i < components.size(); ++i) 375 for (; component_iter != components.end(); ++component_iter)
272 cracked_path = cracked_path.Append(components[i]); 376 cracked_path = cracked_path.Append(*component_iter);
273 *path = cracked_path; 377 *path = cracked_path;
274 return true; 378 return true;
275 } 379 }
276 380
277 bool IsolatedContext::GetDraggedFileInfo( 381 bool IsolatedContext::GetDraggedFileInfo(
278 const std::string& filesystem_id, std::vector<FileInfo>* files) const { 382 const std::string& filesystem_id, std::vector<FileInfo>* files) const {
279 DCHECK(files); 383 DCHECK(files);
280 base::AutoLock locker(lock_); 384 base::AutoLock locker(lock_);
281 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); 385 IDToInstance::const_iterator found = instance_map_.find(filesystem_id);
282 if (found == instance_map_.end() || 386 if (found == instance_map_.end() ||
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 uint32 random_data[4]; 440 uint32 random_data[4];
337 std::string id; 441 std::string id;
338 do { 442 do {
339 base::RandBytes(random_data, sizeof(random_data)); 443 base::RandBytes(random_data, sizeof(random_data));
340 id = base::HexEncode(random_data, sizeof(random_data)); 444 id = base::HexEncode(random_data, sizeof(random_data));
341 } while (instance_map_.find(id) != instance_map_.end()); 445 } while (instance_map_.find(id) != instance_map_.end());
342 return id; 446 return id;
343 } 447 }
344 448
345 } // namespace fileapi 449 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698