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 21 matching lines...) Expand all Loading... |
32 break; | 32 break; |
33 } | 33 } |
34 name.append(1, path.value()[i]); | 34 name.append(1, path.value()[i]); |
35 } | 35 } |
36 return name; | 36 return name; |
37 #else | 37 #else |
38 return FILE_PATH_LITERAL("<root>"); | 38 return FILE_PATH_LITERAL("<root>"); |
39 #endif | 39 #endif |
40 } | 40 } |
41 | 41 |
| 42 bool IsSinglePathIsolatedFileSystem(FileSystemType type) { |
| 43 switch (type) { |
| 44 // As of writing dragged file system is the only filesystem |
| 45 // which could have multiple toplevel paths. |
| 46 case kFileSystemTypeDragged: |
| 47 return false; |
| 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: |
| 60 NOTREACHED(); |
| 61 return true; |
| 62 } |
| 63 NOTREACHED(); |
| 64 return true; |
| 65 } |
| 66 |
42 } | 67 } |
43 | 68 |
44 static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context = | 69 static base::LazyInstance<IsolatedContext>::Leaky g_isolated_context = |
45 LAZY_INSTANCE_INITIALIZER; | 70 LAZY_INSTANCE_INITIALIZER; |
46 | 71 |
47 IsolatedContext::FileInfo::FileInfo() {} | 72 IsolatedContext::FileInfo::FileInfo() {} |
48 IsolatedContext::FileInfo::FileInfo( | 73 IsolatedContext::FileInfo::FileInfo( |
49 const std::string& name, const FilePath& path) | 74 const std::string& name, const FilePath& path) |
50 : name(name), path(path) {} | 75 : name(name), path(path) {} |
51 | 76 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 return false; | 109 return false; |
85 return fileset_.insert(FileInfo(name, path.NormalizePathSeparators())).second; | 110 return fileset_.insert(FileInfo(name, path.NormalizePathSeparators())).second; |
86 } | 111 } |
87 | 112 |
88 //-------------------------------------------------------------------------- | 113 //-------------------------------------------------------------------------- |
89 | 114 |
90 IsolatedContext::Instance::Instance(FileSystemType type, | 115 IsolatedContext::Instance::Instance(FileSystemType type, |
91 const FileInfo& file_info) | 116 const FileInfo& file_info) |
92 : type_(type), | 117 : type_(type), |
93 file_info_(file_info), | 118 file_info_(file_info), |
94 ref_counts_(0) {} | 119 ref_counts_(0) { |
| 120 DCHECK(IsSinglePathIsolatedFileSystem(type_)); |
| 121 } |
95 | 122 |
96 IsolatedContext::Instance::Instance(const std::set<FileInfo>& dragged_files) | 123 IsolatedContext::Instance::Instance(FileSystemType type, |
97 : type_(kFileSystemTypeDragged), | 124 const std::set<FileInfo>& files) |
98 dragged_files_(dragged_files), | 125 : type_(type), |
99 ref_counts_(0) {} | 126 files_(files), |
| 127 ref_counts_(0) { |
| 128 DCHECK(!IsSinglePathIsolatedFileSystem(type_)); |
| 129 } |
100 | 130 |
101 IsolatedContext::Instance::~Instance() {} | 131 IsolatedContext::Instance::~Instance() {} |
102 | 132 |
103 bool IsolatedContext::Instance::ResolvePathForName(const std::string& name, | 133 bool IsolatedContext::Instance::ResolvePathForName(const std::string& name, |
104 FilePath* path) { | 134 FilePath* path) const { |
105 if (type_ != kFileSystemTypeDragged) { | 135 if (IsSinglePathIsolatedFileSystem(type_)) { |
106 *path = file_info_.path; | 136 *path = file_info_.path; |
107 return file_info_.name == name; | 137 return file_info_.name == name; |
108 } | 138 } |
109 std::set<FileInfo>::const_iterator found = dragged_files_.find( | 139 std::set<FileInfo>::const_iterator found = files_.find( |
110 FileInfo(name, FilePath())); | 140 FileInfo(name, FilePath())); |
111 if (found == dragged_files_.end()) | 141 if (found == files_.end()) |
112 return false; | 142 return false; |
113 *path = found->path; | 143 *path = found->path; |
114 return true; | 144 return true; |
115 } | 145 } |
116 | 146 |
| 147 bool IsolatedContext::Instance::IsSinglePathInstance() const { |
| 148 return IsSinglePathIsolatedFileSystem(type_); |
| 149 } |
| 150 |
117 //-------------------------------------------------------------------------- | 151 //-------------------------------------------------------------------------- |
118 | 152 |
119 // static | 153 // static |
120 IsolatedContext* IsolatedContext::GetInstance() { | 154 IsolatedContext* IsolatedContext::GetInstance() { |
121 return g_isolated_context.Pointer(); | 155 return g_isolated_context.Pointer(); |
122 } | 156 } |
123 | 157 |
124 std::string IsolatedContext::RegisterDraggedFileSystem( | 158 std::string IsolatedContext::RegisterDraggedFileSystem( |
125 const FileInfoSet& files) { | 159 const FileInfoSet& files) { |
126 base::AutoLock locker(lock_); | 160 base::AutoLock locker(lock_); |
127 std::string filesystem_id = GetNewFileSystemId(); | 161 std::string filesystem_id = GetNewFileSystemId(); |
128 instance_map_[filesystem_id] = new Instance(files.fileset()); | 162 instance_map_[filesystem_id] = new Instance( |
| 163 kFileSystemTypeDragged, files.fileset()); |
129 return filesystem_id; | 164 return filesystem_id; |
130 } | 165 } |
131 | 166 |
132 std::string IsolatedContext::RegisterFileSystemForPath( | 167 std::string IsolatedContext::RegisterFileSystemForPath( |
133 FileSystemType type, | 168 FileSystemType type, |
134 const FilePath& path, | 169 const FilePath& path, |
135 std::string* register_name) { | 170 std::string* register_name) { |
136 DCHECK(!path.ReferencesParent() && path.IsAbsolute()); | 171 DCHECK(!path.ReferencesParent() && path.IsAbsolute()); |
137 std::string name; | 172 std::string name; |
138 if (register_name && !register_name->empty()) { | 173 if (register_name && !register_name->empty()) { |
139 name = *register_name; | 174 name = *register_name; |
140 } else { | 175 } else { |
141 name = FilePath(GetRegisterNameForPath(path)).AsUTF8Unsafe(); | 176 name = FilePath(GetRegisterNameForPath(path)).AsUTF8Unsafe(); |
142 if (register_name) | 177 if (register_name) |
143 register_name->assign(name); | 178 register_name->assign(name); |
144 } | 179 } |
145 | 180 |
146 base::AutoLock locker(lock_); | 181 base::AutoLock locker(lock_); |
147 std::string filesystem_id = GetNewFileSystemId(); | 182 std::string filesystem_id = GetNewFileSystemId(); |
148 instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path)); | 183 instance_map_[filesystem_id] = new Instance(type, FileInfo(name, path)); |
| 184 path_to_id_map_[path].insert(filesystem_id); |
149 return filesystem_id; | 185 return filesystem_id; |
150 } | 186 } |
151 | 187 |
152 void IsolatedContext::RevokeFileSystem(const std::string& filesystem_id) { | 188 void IsolatedContext::RevokeFileSystemByPath(const FilePath& path) { |
153 base::AutoLock locker(lock_); | 189 base::AutoLock locker(lock_); |
154 IDToInstance::iterator found = instance_map_.find(filesystem_id); | 190 PathToID::iterator ids_iter = path_to_id_map_.find(path); |
155 if (found == instance_map_.end()) | 191 if (ids_iter == path_to_id_map_.end()) |
156 return; | 192 return; |
157 delete found->second; | 193 std::set<std::string>& ids = ids_iter->second; |
158 instance_map_.erase(found); | 194 for (std::set<std::string>::iterator iter = ids.begin(); |
| 195 iter != ids.end(); ++iter) { |
| 196 IDToInstance::iterator found = instance_map_.find(*iter); |
| 197 if (found != instance_map_.end()) { |
| 198 delete found->second; |
| 199 instance_map_.erase(found); |
| 200 } |
| 201 } |
| 202 path_to_id_map_.erase(ids_iter); |
159 } | 203 } |
160 | 204 |
161 void IsolatedContext::AddReference(const std::string& filesystem_id) { | 205 void IsolatedContext::AddReference(const std::string& filesystem_id) { |
162 base::AutoLock locker(lock_); | 206 base::AutoLock locker(lock_); |
163 DCHECK(instance_map_.find(filesystem_id) != instance_map_.end()); | 207 DCHECK(instance_map_.find(filesystem_id) != instance_map_.end()); |
164 instance_map_[filesystem_id]->AddRef(); | 208 instance_map_[filesystem_id]->AddRef(); |
165 } | 209 } |
166 | 210 |
167 void IsolatedContext::RemoveReference(const std::string& filesystem_id) { | 211 void IsolatedContext::RemoveReference(const std::string& filesystem_id) { |
168 base::AutoLock locker(lock_); | 212 base::AutoLock locker(lock_); |
169 // This could get called for non-existent filesystem if it has been | 213 // This could get called for non-existent filesystem if it has been |
170 // already deleted by RevokeFileSystem. | 214 // already deleted by RevokeFileSystemByPath. |
171 IDToInstance::iterator found = instance_map_.find(filesystem_id); | 215 IDToInstance::iterator found = instance_map_.find(filesystem_id); |
172 if (found == instance_map_.end()) | 216 if (found == instance_map_.end()) |
173 return; | 217 return; |
174 DCHECK(found->second->ref_counts() > 0); | 218 Instance* instance = found->second; |
175 found->second->RemoveRef(); | 219 DCHECK(instance->ref_counts() > 0); |
176 if (found->second->ref_counts() == 0) { | 220 instance->RemoveRef(); |
177 delete found->second; | 221 if (instance->ref_counts() == 0) { |
| 222 if (instance->IsSinglePathInstance()) { |
| 223 PathToID::iterator ids_iter = path_to_id_map_.find( |
| 224 instance->file_info().path); |
| 225 DCHECK(ids_iter != path_to_id_map_.end()); |
| 226 ids_iter->second.erase(filesystem_id); |
| 227 if (ids_iter->second.empty()) |
| 228 path_to_id_map_.erase(ids_iter); |
| 229 } |
| 230 delete instance; |
178 instance_map_.erase(found); | 231 instance_map_.erase(found); |
179 } | 232 } |
180 } | 233 } |
181 | 234 |
182 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, | 235 bool IsolatedContext::CrackIsolatedPath(const FilePath& virtual_path, |
183 std::string* filesystem_id, | 236 std::string* filesystem_id, |
184 FileSystemType* type, | 237 FileSystemType* type, |
185 FilePath* path) const { | 238 FilePath* path) const { |
186 DCHECK(filesystem_id); | 239 DCHECK(filesystem_id); |
187 DCHECK(path); | 240 DCHECK(path); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
222 } | 275 } |
223 | 276 |
224 bool IsolatedContext::GetDraggedFileInfo( | 277 bool IsolatedContext::GetDraggedFileInfo( |
225 const std::string& filesystem_id, std::vector<FileInfo>* files) const { | 278 const std::string& filesystem_id, std::vector<FileInfo>* files) const { |
226 DCHECK(files); | 279 DCHECK(files); |
227 base::AutoLock locker(lock_); | 280 base::AutoLock locker(lock_); |
228 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); | 281 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); |
229 if (found == instance_map_.end() || | 282 if (found == instance_map_.end() || |
230 found->second->type() != kFileSystemTypeDragged) | 283 found->second->type() != kFileSystemTypeDragged) |
231 return false; | 284 return false; |
232 files->assign(found->second->dragged_files().begin(), | 285 files->assign(found->second->files().begin(), |
233 found->second->dragged_files().end()); | 286 found->second->files().end()); |
234 return true; | 287 return true; |
235 } | 288 } |
236 | 289 |
237 bool IsolatedContext::GetRegisteredPath( | 290 bool IsolatedContext::GetRegisteredPath( |
238 const std::string& filesystem_id, FilePath* path) const { | 291 const std::string& filesystem_id, FilePath* path) const { |
239 DCHECK(path); | 292 DCHECK(path); |
240 base::AutoLock locker(lock_); | 293 base::AutoLock locker(lock_); |
241 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); | 294 IDToInstance::const_iterator found = instance_map_.find(filesystem_id); |
242 if (found == instance_map_.end() || | 295 if (found == instance_map_.end() || !found->second->IsSinglePathInstance()) |
243 found->second->type() == kFileSystemTypeDragged) | |
244 return false; | 296 return false; |
245 *path = found->second->file_info().path; | 297 *path = found->second->file_info().path; |
246 return true; | 298 return true; |
247 } | 299 } |
248 | 300 |
249 FilePath IsolatedContext::CreateVirtualRootPath( | 301 FilePath IsolatedContext::CreateVirtualRootPath( |
250 const std::string& filesystem_id) const { | 302 const std::string& filesystem_id) const { |
251 return FilePath().AppendASCII(filesystem_id); | 303 return FilePath().AppendASCII(filesystem_id); |
252 } | 304 } |
253 | 305 |
(...skipping 10 matching lines...) Expand all Loading... |
264 uint32 random_data[4]; | 316 uint32 random_data[4]; |
265 std::string id; | 317 std::string id; |
266 do { | 318 do { |
267 base::RandBytes(random_data, sizeof(random_data)); | 319 base::RandBytes(random_data, sizeof(random_data)); |
268 id = base::HexEncode(random_data, sizeof(random_data)); | 320 id = base::HexEncode(random_data, sizeof(random_data)); |
269 } while (instance_map_.find(id) != instance_map_.end()); | 321 } while (instance_map_.find(id) != instance_map_.end()); |
270 return id; | 322 return id; |
271 } | 323 } |
272 | 324 |
273 } // namespace fileapi | 325 } // namespace fileapi |
OLD | NEW |