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/browser/fileapi/sandbox_file_system_backend.h" | 5 #include "webkit/browser/fileapi/sandbox_file_system_backend.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/file_util.h" | 8 #include "base/file_util.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
55 kCreateDirectoryError, | 55 kCreateDirectoryError, |
56 kNotFound, | 56 kNotFound, |
57 kUnknownError, | 57 kUnknownError, |
58 kFileSystemErrorMax, | 58 kFileSystemErrorMax, |
59 }; | 59 }; |
60 | 60 |
61 const char kTemporaryOriginsCountLabel[] = "FileSystem.TemporaryOriginsCount"; | 61 const char kTemporaryOriginsCountLabel[] = "FileSystem.TemporaryOriginsCount"; |
62 const char kPersistentOriginsCountLabel[] = "FileSystem.PersistentOriginsCount"; | 62 const char kPersistentOriginsCountLabel[] = "FileSystem.PersistentOriginsCount"; |
63 const char kSyncableOriginsCountLabel[] = "FileSystem.SyncableOriginsCount"; | 63 const char kSyncableOriginsCountLabel[] = "FileSystem.SyncableOriginsCount"; |
64 | 64 |
65 // Restricted names. | |
66 // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions | |
67 const base::FilePath::CharType* const kRestrictedNames[] = { | |
68 FILE_PATH_LITERAL("."), FILE_PATH_LITERAL(".."), | |
69 }; | |
70 | |
71 // Restricted chars. | |
72 const base::FilePath::CharType kRestrictedChars[] = { | |
73 FILE_PATH_LITERAL('/'), FILE_PATH_LITERAL('\\'), | |
74 }; | |
75 | |
76 class ObfuscatedOriginEnumerator | |
77 : public SandboxFileSystemBackend::OriginEnumerator { | |
78 public: | |
79 explicit ObfuscatedOriginEnumerator(ObfuscatedFileUtil* file_util) { | |
80 enum_.reset(file_util->CreateOriginEnumerator()); | |
81 } | |
82 virtual ~ObfuscatedOriginEnumerator() {} | |
83 | |
84 virtual GURL Next() OVERRIDE { | |
85 return enum_->Next(); | |
86 } | |
87 | |
88 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE { | |
89 return enum_->HasFileSystemType(type); | |
90 } | |
91 | |
92 private: | |
93 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enum_; | |
94 }; | |
95 | |
96 void DidOpenFileSystem( | 65 void DidOpenFileSystem( |
97 base::WeakPtr<SandboxFileSystemBackend> sandbox_backend, | 66 base::WeakPtr<SandboxFileSystemBackend> sandbox_backend, |
98 const base::Callback<void(base::PlatformFileError error)>& callback, | 67 const base::Callback<void(base::PlatformFileError error)>& callback, |
99 base::PlatformFileError* error) { | 68 base::PlatformFileError* error) { |
100 if (sandbox_backend.get()) | 69 if (sandbox_backend.get()) |
101 sandbox_backend.get()->CollectOpenFileSystemMetrics(*error); | 70 sandbox_backend.get()->CollectOpenFileSystemMetrics(*error); |
102 callback.Run(*error); | 71 callback.Run(*error); |
103 } | 72 } |
104 | 73 |
105 void OpenFileSystemOnFileThread( | 74 void OpenFileSystemOnFileThread( |
(...skipping 16 matching lines...) Expand all Loading... |
122 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, kOK, kFileSystemErrorMax); | 91 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, kOK, kFileSystemErrorMax); |
123 } | 92 } |
124 // The reference of file_util will be derefed on the FILE thread | 93 // The reference of file_util will be derefed on the FILE thread |
125 // when the storage of this callback gets deleted regardless of whether | 94 // when the storage of this callback gets deleted regardless of whether |
126 // this method is called or not. | 95 // this method is called or not. |
127 } | 96 } |
128 | 97 |
129 } // anonymous namespace | 98 } // anonymous namespace |
130 | 99 |
131 SandboxFileSystemBackend::SandboxFileSystemBackend( | 100 SandboxFileSystemBackend::SandboxFileSystemBackend( |
132 SandboxContext* sandbox_context, | 101 SandboxContext* sandbox_context) |
133 const FileSystemOptions& file_system_options) | 102 : sandbox_context_(sandbox_context), |
134 : file_system_options_(file_system_options), | |
135 sandbox_context_(sandbox_context), | |
136 enable_temporary_file_system_in_incognito_(false), | 103 enable_temporary_file_system_in_incognito_(false), |
137 weak_factory_(this) { | 104 weak_factory_(this) { |
138 } | 105 } |
139 | 106 |
140 SandboxFileSystemBackend::~SandboxFileSystemBackend() { | 107 SandboxFileSystemBackend::~SandboxFileSystemBackend() { |
141 } | 108 } |
142 | 109 |
143 bool SandboxFileSystemBackend::CanHandleType(FileSystemType type) const { | 110 bool SandboxFileSystemBackend::CanHandleType(FileSystemType type) const { |
144 return type == kFileSystemTypeTemporary || | 111 return type == kFileSystemTypeTemporary || |
145 type == kFileSystemTypePersistent || | 112 type == kFileSystemTypePersistent || |
(...skipping 21 matching lines...) Expand all Loading... |
167 base::Bind(&ObfuscatedFileUtil::MaybePrepopulateDatabase, | 134 base::Bind(&ObfuscatedFileUtil::MaybePrepopulateDatabase, |
168 base::Unretained(sandbox_sync_file_util()))); | 135 base::Unretained(sandbox_sync_file_util()))); |
169 } | 136 } |
170 } | 137 } |
171 | 138 |
172 void SandboxFileSystemBackend::OpenFileSystem( | 139 void SandboxFileSystemBackend::OpenFileSystem( |
173 const GURL& origin_url, | 140 const GURL& origin_url, |
174 fileapi::FileSystemType type, | 141 fileapi::FileSystemType type, |
175 OpenFileSystemMode mode, | 142 OpenFileSystemMode mode, |
176 const OpenFileSystemCallback& callback) { | 143 const OpenFileSystemCallback& callback) { |
177 if (file_system_options_.is_incognito() && | 144 DCHECK(sandbox_context_); |
| 145 if (sandbox_context_->file_system_options().is_incognito() && |
178 !(type == kFileSystemTypeTemporary && | 146 !(type == kFileSystemTypeTemporary && |
179 enable_temporary_file_system_in_incognito_)) { | 147 enable_temporary_file_system_in_incognito_)) { |
180 // TODO(kinuko): return an isolated temporary directory. | 148 // TODO(kinuko): return an isolated temporary directory. |
181 callback.Run(GURL(), std::string(), base::PLATFORM_FILE_ERROR_SECURITY); | 149 callback.Run(GURL(), std::string(), base::PLATFORM_FILE_ERROR_SECURITY); |
182 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, | 150 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, |
183 kIncognito, | 151 kIncognito, |
184 kFileSystemErrorMax); | 152 kFileSystemErrorMax); |
185 return; | 153 return; |
186 } | 154 } |
187 | 155 |
188 if (!IsAllowedScheme(origin_url)) { | 156 if (!sandbox_context_->IsAllowedScheme(origin_url)) { |
189 callback.Run(GURL(), std::string(), base::PLATFORM_FILE_ERROR_SECURITY); | 157 callback.Run(GURL(), std::string(), base::PLATFORM_FILE_ERROR_SECURITY); |
190 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, | 158 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, |
191 kInvalidSchemeError, | 159 kInvalidSchemeError, |
192 kFileSystemErrorMax); | 160 kFileSystemErrorMax); |
193 return; | 161 return; |
194 } | 162 } |
195 | 163 |
196 // TODO(nhiroki): Factor out SyncFS related code to SyncFileSystemBackend we | 164 // TODO(nhiroki): Factor out SyncFS related code to SyncFileSystemBackend we |
197 // plan to introduce. (http://crbug.com/242422/) | 165 // plan to introduce. (http://crbug.com/242422/) |
198 GURL root_url = (type == kFileSystemTypeSyncable) | 166 GURL root_url = (type == kFileSystemTypeSyncable) |
199 ? sync_file_system::GetSyncableFileSystemRootURI(origin_url) | 167 ? sync_file_system::GetSyncableFileSystemRootURI(origin_url) |
200 : GetFileSystemRootURI(origin_url, type); | 168 : GetFileSystemRootURI(origin_url, type); |
201 std::string name = GetFileSystemName(origin_url, type); | 169 std::string name = GetFileSystemName(origin_url, type); |
202 | 170 |
203 base::PlatformFileError* error_ptr = new base::PlatformFileError; | 171 base::PlatformFileError* error_ptr = new base::PlatformFileError; |
204 sandbox_context_->file_task_runner()->PostTaskAndReply( | 172 sandbox_context_->file_task_runner()->PostTaskAndReply( |
205 FROM_HERE, | 173 FROM_HERE, |
206 base::Bind(&OpenFileSystemOnFileThread, | 174 base::Bind(&OpenFileSystemOnFileThread, |
207 sandbox_sync_file_util(), | 175 sandbox_sync_file_util(), |
208 origin_url, type, mode, | 176 origin_url, type, mode, |
209 base::Unretained(error_ptr)), | 177 base::Unretained(error_ptr)), |
210 base::Bind(&DidOpenFileSystem, | 178 base::Bind(&DidOpenFileSystem, |
211 weak_factory_.GetWeakPtr(), | 179 weak_factory_.GetWeakPtr(), |
212 base::Bind(callback, root_url, name), | 180 base::Bind(callback, root_url, name), |
213 base::Owned(error_ptr))); | 181 base::Owned(error_ptr))); |
214 | |
215 if (sandbox_context_->is_usage_tracking_enabled()) | |
216 return; | |
217 | |
218 // Schedule full usage recalculation on the next launch without | |
219 // --disable-file-system-usage-tracking. | |
220 sandbox_context_->file_task_runner()->PostTask( | |
221 FROM_HERE, | |
222 base::Bind(&SandboxFileSystemBackend::InvalidateUsageCacheOnFileThread, | |
223 sandbox_sync_file_util(), origin_url, type, usage_cache())); | |
224 }; | 182 }; |
225 | 183 |
226 FileSystemFileUtil* SandboxFileSystemBackend::GetFileUtil( | 184 FileSystemFileUtil* SandboxFileSystemBackend::GetFileUtil( |
227 FileSystemType type) { | 185 FileSystemType type) { |
228 DCHECK(sandbox_context_); | 186 DCHECK(sandbox_context_); |
229 return sandbox_context_->sync_file_util(); | 187 return sandbox_context_->sync_file_util(); |
230 } | 188 } |
231 | 189 |
232 AsyncFileUtil* SandboxFileSystemBackend::GetAsyncFileUtil( | 190 AsyncFileUtil* SandboxFileSystemBackend::GetAsyncFileUtil( |
233 FileSystemType type) { | 191 FileSystemType type) { |
234 DCHECK(sandbox_context_); | 192 DCHECK(sandbox_context_); |
235 return sandbox_context_->file_util(); | 193 return sandbox_context_->file_util(); |
236 } | 194 } |
237 | 195 |
238 CopyOrMoveFileValidatorFactory* | 196 CopyOrMoveFileValidatorFactory* |
239 SandboxFileSystemBackend::GetCopyOrMoveFileValidatorFactory( | 197 SandboxFileSystemBackend::GetCopyOrMoveFileValidatorFactory( |
240 FileSystemType type, | 198 FileSystemType type, |
241 base::PlatformFileError* error_code) { | 199 base::PlatformFileError* error_code) { |
242 DCHECK(error_code); | 200 DCHECK(error_code); |
243 *error_code = base::PLATFORM_FILE_OK; | 201 *error_code = base::PLATFORM_FILE_OK; |
244 return NULL; | 202 return NULL; |
245 } | 203 } |
246 | 204 |
247 FileSystemOperation* SandboxFileSystemBackend::CreateFileSystemOperation( | 205 FileSystemOperation* SandboxFileSystemBackend::CreateFileSystemOperation( |
248 const FileSystemURL& url, | 206 const FileSystemURL& url, |
249 FileSystemContext* context, | 207 FileSystemContext* context, |
250 base::PlatformFileError* error_code) const { | 208 base::PlatformFileError* error_code) const { |
251 if (!IsAccessValid(url)) { | 209 DCHECK(sandbox_context_); |
| 210 if (!sandbox_context_->IsAccessValid(url)) { |
252 *error_code = base::PLATFORM_FILE_ERROR_SECURITY; | 211 *error_code = base::PLATFORM_FILE_ERROR_SECURITY; |
253 return NULL; | 212 return NULL; |
254 } | 213 } |
255 | 214 |
256 scoped_ptr<FileSystemOperationContext> operation_context( | 215 scoped_ptr<FileSystemOperationContext> operation_context( |
257 new FileSystemOperationContext(context)); | 216 new FileSystemOperationContext(context)); |
258 | 217 |
259 // Copy the observer lists (assuming we only have small number of observers). | 218 // Copy the observer lists (assuming we only have small number of observers). |
260 if (url.type() == kFileSystemTypeSyncable) { | 219 if (url.type() == kFileSystemTypeSyncable) { |
261 operation_context->set_update_observers(syncable_update_observers_); | 220 operation_context->set_update_observers(syncable_update_observers_); |
(...skipping 14 matching lines...) Expand all Loading... |
276 | 235 |
277 return new LocalFileSystemOperation(url, context, operation_context.Pass()); | 236 return new LocalFileSystemOperation(url, context, operation_context.Pass()); |
278 } | 237 } |
279 | 238 |
280 scoped_ptr<webkit_blob::FileStreamReader> | 239 scoped_ptr<webkit_blob::FileStreamReader> |
281 SandboxFileSystemBackend::CreateFileStreamReader( | 240 SandboxFileSystemBackend::CreateFileStreamReader( |
282 const FileSystemURL& url, | 241 const FileSystemURL& url, |
283 int64 offset, | 242 int64 offset, |
284 const base::Time& expected_modification_time, | 243 const base::Time& expected_modification_time, |
285 FileSystemContext* context) const { | 244 FileSystemContext* context) const { |
286 if (!IsAccessValid(url)) | 245 DCHECK(sandbox_context_); |
| 246 if (!sandbox_context_->IsAccessValid(url)) |
287 return scoped_ptr<webkit_blob::FileStreamReader>(); | 247 return scoped_ptr<webkit_blob::FileStreamReader>(); |
288 return scoped_ptr<webkit_blob::FileStreamReader>( | 248 return scoped_ptr<webkit_blob::FileStreamReader>( |
289 new FileSystemFileStreamReader( | 249 new FileSystemFileStreamReader( |
290 context, url, offset, expected_modification_time)); | 250 context, url, offset, expected_modification_time)); |
291 } | 251 } |
292 | 252 |
293 scoped_ptr<fileapi::FileStreamWriter> | 253 scoped_ptr<fileapi::FileStreamWriter> |
294 SandboxFileSystemBackend::CreateFileStreamWriter( | 254 SandboxFileSystemBackend::CreateFileStreamWriter( |
295 const FileSystemURL& url, | 255 const FileSystemURL& url, |
296 int64 offset, | 256 int64 offset, |
297 FileSystemContext* context) const { | 257 FileSystemContext* context) const { |
298 if (!IsAccessValid(url)) | 258 DCHECK(sandbox_context_); |
| 259 if (!sandbox_context_->IsAccessValid(url)) |
299 return scoped_ptr<fileapi::FileStreamWriter>(); | 260 return scoped_ptr<fileapi::FileStreamWriter>(); |
300 return scoped_ptr<fileapi::FileStreamWriter>( | 261 return scoped_ptr<fileapi::FileStreamWriter>( |
301 new SandboxFileStreamWriter(context, url, offset, update_observers_)); | 262 new SandboxFileStreamWriter(context, url, offset, update_observers_)); |
302 } | 263 } |
303 | 264 |
304 FileSystemQuotaUtil* SandboxFileSystemBackend::GetQuotaUtil() { | 265 FileSystemQuotaUtil* SandboxFileSystemBackend::GetQuotaUtil() { |
305 return this; | 266 return this; |
306 } | 267 } |
307 | 268 |
308 SandboxFileSystemBackend::OriginEnumerator* | 269 SandboxContext::OriginEnumerator* |
309 SandboxFileSystemBackend::CreateOriginEnumerator() { | 270 SandboxFileSystemBackend::CreateOriginEnumerator() { |
310 return new ObfuscatedOriginEnumerator(sandbox_sync_file_util()); | 271 DCHECK(sandbox_context_); |
311 } | 272 return sandbox_context_->CreateOriginEnumerator(); |
312 | |
313 base::FilePath SandboxFileSystemBackend::GetBaseDirectoryForOriginAndType( | |
314 const GURL& origin_url, fileapi::FileSystemType type, bool create) { | |
315 base::PlatformFileError error = base::PLATFORM_FILE_OK; | |
316 base::FilePath path = sandbox_sync_file_util()->GetDirectoryForOriginAndType( | |
317 origin_url, type, create, &error); | |
318 if (error != base::PLATFORM_FILE_OK) | |
319 return base::FilePath(); | |
320 return path; | |
321 } | 273 } |
322 | 274 |
323 base::PlatformFileError | 275 base::PlatformFileError |
324 SandboxFileSystemBackend::DeleteOriginDataOnFileThread( | 276 SandboxFileSystemBackend::DeleteOriginDataOnFileThread( |
325 FileSystemContext* file_system_context, | 277 FileSystemContext* file_system_context, |
326 QuotaManagerProxy* proxy, | 278 QuotaManagerProxy* proxy, |
327 const GURL& origin_url, | 279 const GURL& origin_url, |
328 fileapi::FileSystemType type) { | 280 fileapi::FileSystemType type) { |
329 int64 usage = GetOriginUsageOnFileThread(file_system_context, | 281 DCHECK(sandbox_context_); |
330 origin_url, type); | 282 return sandbox_context_->DeleteOriginDataOnFileThreadImpl( |
331 | 283 file_system_context, proxy, origin_url, type); |
332 usage_cache()->CloseCacheFiles(); | |
333 bool result = sandbox_sync_file_util()->DeleteDirectoryForOriginAndType( | |
334 origin_url, type); | |
335 if (result && proxy) { | |
336 proxy->NotifyStorageModified( | |
337 quota::QuotaClient::kFileSystem, | |
338 origin_url, | |
339 FileSystemTypeToQuotaStorageType(type), | |
340 -usage); | |
341 } | |
342 | |
343 if (result) | |
344 return base::PLATFORM_FILE_OK; | |
345 return base::PLATFORM_FILE_ERROR_FAILED; | |
346 } | 284 } |
347 | 285 |
348 void SandboxFileSystemBackend::GetOriginsForTypeOnFileThread( | 286 void SandboxFileSystemBackend::GetOriginsForTypeOnFileThread( |
349 fileapi::FileSystemType type, std::set<GURL>* origins) { | 287 fileapi::FileSystemType type, std::set<GURL>* origins) { |
350 DCHECK(CanHandleType(type)); | 288 DCHECK(sandbox_context_); |
351 DCHECK(origins); | 289 sandbox_context_->GetOriginsForTypeOnFileThreadImpl(type, origins); |
352 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); | |
353 GURL origin; | |
354 while (!(origin = enumerator->Next()).is_empty()) { | |
355 if (enumerator->HasFileSystemType(type)) | |
356 origins->insert(origin); | |
357 } | |
358 switch (type) { | 290 switch (type) { |
359 case kFileSystemTypeTemporary: | 291 case kFileSystemTypeTemporary: |
360 UMA_HISTOGRAM_COUNTS(kTemporaryOriginsCountLabel, origins->size()); | 292 UMA_HISTOGRAM_COUNTS(kTemporaryOriginsCountLabel, origins->size()); |
361 break; | 293 break; |
362 case kFileSystemTypePersistent: | 294 case kFileSystemTypePersistent: |
363 UMA_HISTOGRAM_COUNTS(kPersistentOriginsCountLabel, origins->size()); | 295 UMA_HISTOGRAM_COUNTS(kPersistentOriginsCountLabel, origins->size()); |
364 break; | 296 break; |
365 case kFileSystemTypeSyncable: | 297 case kFileSystemTypeSyncable: |
366 UMA_HISTOGRAM_COUNTS(kSyncableOriginsCountLabel, origins->size()); | 298 UMA_HISTOGRAM_COUNTS(kSyncableOriginsCountLabel, origins->size()); |
367 break; | 299 break; |
368 default: | 300 default: |
369 break; | 301 break; |
370 } | 302 } |
371 } | 303 } |
372 | 304 |
373 void SandboxFileSystemBackend::GetOriginsForHostOnFileThread( | 305 void SandboxFileSystemBackend::GetOriginsForHostOnFileThread( |
374 fileapi::FileSystemType type, const std::string& host, | 306 fileapi::FileSystemType type, const std::string& host, |
375 std::set<GURL>* origins) { | 307 std::set<GURL>* origins) { |
376 DCHECK(CanHandleType(type)); | 308 DCHECK(sandbox_context_); |
377 DCHECK(origins); | 309 sandbox_context_->GetOriginsForHostOnFileThreadImpl(type, host, origins); |
378 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); | |
379 GURL origin; | |
380 while (!(origin = enumerator->Next()).is_empty()) { | |
381 if (host == net::GetHostOrSpecFromURL(origin) && | |
382 enumerator->HasFileSystemType(type)) | |
383 origins->insert(origin); | |
384 } | |
385 } | 310 } |
386 | 311 |
387 int64 SandboxFileSystemBackend::GetOriginUsageOnFileThread( | 312 int64 SandboxFileSystemBackend::GetOriginUsageOnFileThread( |
388 FileSystemContext* file_system_context, | 313 FileSystemContext* file_system_context, |
389 const GURL& origin_url, | 314 const GURL& origin_url, |
390 fileapi::FileSystemType type) { | 315 fileapi::FileSystemType type) { |
391 DCHECK(CanHandleType(type)); | 316 DCHECK(sandbox_context_); |
392 if (!sandbox_context_->is_usage_tracking_enabled()) | 317 return sandbox_context_->GetOriginUsageOnFileThreadImpl( |
393 return 0; | 318 file_system_context, origin_url, type); |
394 | |
395 // Don't use usage cache and return recalculated usage for sticky invalidated | |
396 // origins. | |
397 if (ContainsKey(sticky_dirty_origins_, std::make_pair(origin_url, type))) | |
398 return RecalculateUsage(file_system_context, origin_url, type); | |
399 | |
400 base::FilePath base_path = | |
401 GetBaseDirectoryForOriginAndType(origin_url, type, false); | |
402 if (base_path.empty() || !base::DirectoryExists(base_path)) | |
403 return 0; | |
404 base::FilePath usage_file_path = | |
405 base_path.Append(FileSystemUsageCache::kUsageFileName); | |
406 | |
407 bool is_valid = usage_cache()->IsValid(usage_file_path); | |
408 uint32 dirty_status = 0; | |
409 bool dirty_status_available = | |
410 usage_cache()->GetDirty(usage_file_path, &dirty_status); | |
411 bool visited = !visited_origins_.insert(origin_url).second; | |
412 if (is_valid && (dirty_status == 0 || (dirty_status_available && visited))) { | |
413 // The usage cache is clean (dirty == 0) or the origin is already | |
414 // initialized and running. Read the cache file to get the usage. | |
415 int64 usage = 0; | |
416 return usage_cache()->GetUsage(usage_file_path, &usage) ? usage : -1; | |
417 } | |
418 // The usage cache has not been initialized or the cache is dirty. | |
419 // Get the directory size now and update the cache. | |
420 usage_cache()->Delete(usage_file_path); | |
421 | |
422 int64 usage = RecalculateUsage(file_system_context, origin_url, type); | |
423 | |
424 // This clears the dirty flag too. | |
425 usage_cache()->UpdateUsage(usage_file_path, usage); | |
426 return usage; | |
427 } | 319 } |
428 | 320 |
429 void SandboxFileSystemBackend::InvalidateUsageCache( | 321 void SandboxFileSystemBackend::InvalidateUsageCache( |
430 const GURL& origin, | 322 const GURL& origin, |
431 fileapi::FileSystemType type) { | 323 fileapi::FileSystemType type) { |
432 DCHECK(CanHandleType(type)); | 324 DCHECK(sandbox_context_); |
433 base::PlatformFileError error = base::PLATFORM_FILE_OK; | 325 sandbox_context_->InvalidateUsageCacheImpl(origin, type); |
434 base::FilePath usage_file_path = GetUsageCachePathForOriginAndType( | |
435 sandbox_sync_file_util(), origin, type, &error); | |
436 if (error != base::PLATFORM_FILE_OK) | |
437 return; | |
438 usage_cache()->IncrementDirty(usage_file_path); | |
439 } | 326 } |
440 | 327 |
441 void SandboxFileSystemBackend::StickyInvalidateUsageCache( | 328 void SandboxFileSystemBackend::StickyInvalidateUsageCache( |
442 const GURL& origin, | 329 const GURL& origin, |
443 fileapi::FileSystemType type) { | 330 fileapi::FileSystemType type) { |
444 DCHECK(CanHandleType(type)); | 331 DCHECK(sandbox_context_); |
445 sticky_dirty_origins_.insert(std::make_pair(origin, type)); | 332 sandbox_context_->StickyInvalidateUsageCacheImpl(origin, type); |
446 sandbox_context_->quota_observer()->SetUsageCacheEnabled(origin, type, false); | |
447 InvalidateUsageCache(origin, type); | |
448 } | 333 } |
449 | 334 |
450 void SandboxFileSystemBackend::AddFileUpdateObserver( | 335 void SandboxFileSystemBackend::AddFileUpdateObserver( |
451 FileSystemType type, | 336 FileSystemType type, |
452 FileUpdateObserver* observer, | 337 FileUpdateObserver* observer, |
453 base::SequencedTaskRunner* task_runner) { | 338 base::SequencedTaskRunner* task_runner) { |
454 DCHECK(CanHandleType(type)); | 339 DCHECK(CanHandleType(type)); |
455 UpdateObserverList* list = &update_observers_; | 340 UpdateObserverList* list = &update_observers_; |
456 if (type == kFileSystemTypeSyncable) | 341 if (type == kFileSystemTypeSyncable) |
457 list = &syncable_update_observers_; | 342 list = &syncable_update_observers_; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
492 return &syncable_change_observers_; | 377 return &syncable_change_observers_; |
493 return &change_observers_; | 378 return &change_observers_; |
494 } | 379 } |
495 | 380 |
496 const AccessObserverList* SandboxFileSystemBackend::GetAccessObservers( | 381 const AccessObserverList* SandboxFileSystemBackend::GetAccessObservers( |
497 FileSystemType type) const { | 382 FileSystemType type) const { |
498 DCHECK(CanHandleType(type)); | 383 DCHECK(CanHandleType(type)); |
499 return &access_observers_; | 384 return &access_observers_; |
500 } | 385 } |
501 | 386 |
| 387 ObfuscatedFileUtil* SandboxFileSystemBackend::sandbox_sync_file_util() { |
| 388 DCHECK(sandbox_context_); |
| 389 return sandbox_context_->sync_file_util(); |
| 390 } |
| 391 |
502 void SandboxFileSystemBackend::CollectOpenFileSystemMetrics( | 392 void SandboxFileSystemBackend::CollectOpenFileSystemMetrics( |
503 base::PlatformFileError error_code) { | 393 base::PlatformFileError error_code) { |
504 base::Time now = base::Time::Now(); | 394 base::Time now = base::Time::Now(); |
505 bool throttled = now < next_release_time_for_open_filesystem_stat_; | 395 bool throttled = now < next_release_time_for_open_filesystem_stat_; |
506 if (!throttled) { | 396 if (!throttled) { |
507 next_release_time_for_open_filesystem_stat_ = | 397 next_release_time_for_open_filesystem_stat_ = |
508 now + base::TimeDelta::FromHours(kMinimumStatsCollectionIntervalHours); | 398 now + base::TimeDelta::FromHours(kMinimumStatsCollectionIntervalHours); |
509 } | 399 } |
510 | 400 |
511 #define REPORT(report_value) \ | 401 #define REPORT(report_value) \ |
(...skipping 17 matching lines...) Expand all Loading... |
529 REPORT(kNotFound); | 419 REPORT(kNotFound); |
530 break; | 420 break; |
531 case base::PLATFORM_FILE_ERROR_FAILED: | 421 case base::PLATFORM_FILE_ERROR_FAILED: |
532 default: | 422 default: |
533 REPORT(kUnknownError); | 423 REPORT(kUnknownError); |
534 break; | 424 break; |
535 } | 425 } |
536 #undef REPORT | 426 #undef REPORT |
537 } | 427 } |
538 | 428 |
539 bool SandboxFileSystemBackend::IsAccessValid( | |
540 const FileSystemURL& url) const { | |
541 if (!IsAllowedScheme(url.origin())) | |
542 return false; | |
543 | |
544 if (!CanHandleType(url.type())) | |
545 return false; | |
546 | |
547 if (url.path().ReferencesParent()) | |
548 return false; | |
549 | |
550 // Return earlier if the path is '/', because VirtualPath::BaseName() | |
551 // returns '/' for '/' and we fail the "basename != '/'" check below. | |
552 // (We exclude '.' because it's disallowed by spec.) | |
553 if (VirtualPath::IsRootPath(url.path()) && | |
554 url.path() != base::FilePath(base::FilePath::kCurrentDirectory)) | |
555 return true; | |
556 | |
557 // Restricted names specified in | |
558 // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restriction
s | |
559 base::FilePath filename = VirtualPath::BaseName(url.path()); | |
560 // See if the name is allowed to create. | |
561 for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) { | |
562 if (filename.value() == kRestrictedNames[i]) | |
563 return false; | |
564 } | |
565 for (size_t i = 0; i < arraysize(kRestrictedChars); ++i) { | |
566 if (filename.value().find(kRestrictedChars[i]) != | |
567 base::FilePath::StringType::npos) | |
568 return false; | |
569 } | |
570 | |
571 return true; | |
572 } | |
573 | |
574 base::FilePath SandboxFileSystemBackend::GetUsageCachePathForOriginAndType( | |
575 const GURL& origin_url, | |
576 FileSystemType type) { | |
577 base::PlatformFileError error; | |
578 base::FilePath path = GetUsageCachePathForOriginAndType( | |
579 sandbox_sync_file_util(), origin_url, type, &error); | |
580 if (error != base::PLATFORM_FILE_OK) | |
581 return base::FilePath(); | |
582 return path; | |
583 } | |
584 | |
585 // static | |
586 base::FilePath SandboxFileSystemBackend::GetUsageCachePathForOriginAndType( | |
587 ObfuscatedFileUtil* sandbox_file_util, | |
588 const GURL& origin_url, | |
589 fileapi::FileSystemType type, | |
590 base::PlatformFileError* error_out) { | |
591 DCHECK(error_out); | |
592 *error_out = base::PLATFORM_FILE_OK; | |
593 base::FilePath base_path = sandbox_file_util->GetDirectoryForOriginAndType( | |
594 origin_url, type, false /* create */, error_out); | |
595 if (*error_out != base::PLATFORM_FILE_OK) | |
596 return base::FilePath(); | |
597 return base_path.Append(FileSystemUsageCache::kUsageFileName); | |
598 } | |
599 | |
600 bool SandboxFileSystemBackend::IsAllowedScheme(const GURL& url) const { | |
601 // Basically we only accept http or https. We allow file:// URLs | |
602 // only if --allow-file-access-from-files flag is given. | |
603 if (url.SchemeIs("http") || url.SchemeIs("https")) | |
604 return true; | |
605 if (url.SchemeIsFileSystem()) | |
606 return url.inner_url() && IsAllowedScheme(*url.inner_url()); | |
607 | |
608 for (size_t i = 0; | |
609 i < file_system_options_.additional_allowed_schemes().size(); | |
610 ++i) { | |
611 if (url.SchemeIs( | |
612 file_system_options_.additional_allowed_schemes()[i].c_str())) | |
613 return true; | |
614 } | |
615 return false; | |
616 } | |
617 | |
618 ObfuscatedFileUtil* SandboxFileSystemBackend::sandbox_sync_file_util() { | |
619 DCHECK(sandbox_context_); | |
620 return sandbox_context_->sync_file_util(); | |
621 } | |
622 | |
623 FileSystemUsageCache* SandboxFileSystemBackend::usage_cache() { | |
624 DCHECK(sandbox_context_); | |
625 return sandbox_context_->usage_cache(); | |
626 } | |
627 | |
628 // static | |
629 void SandboxFileSystemBackend::InvalidateUsageCacheOnFileThread( | |
630 ObfuscatedFileUtil* file_util, | |
631 const GURL& origin, | |
632 FileSystemType type, | |
633 FileSystemUsageCache* usage_cache) { | |
634 base::PlatformFileError error = base::PLATFORM_FILE_OK; | |
635 base::FilePath usage_cache_path = GetUsageCachePathForOriginAndType( | |
636 file_util, origin, type, &error); | |
637 if (error == base::PLATFORM_FILE_OK) | |
638 usage_cache->IncrementDirty(usage_cache_path); | |
639 } | |
640 | |
641 int64 SandboxFileSystemBackend::RecalculateUsage(FileSystemContext* context, | |
642 const GURL& origin, | |
643 FileSystemType type) { | |
644 FileSystemOperationContext operation_context(context); | |
645 FileSystemURL url = context->CreateCrackedFileSystemURL( | |
646 origin, type, base::FilePath()); | |
647 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator( | |
648 sandbox_sync_file_util()->CreateFileEnumerator( | |
649 &operation_context, url, true)); | |
650 | |
651 base::FilePath file_path_each; | |
652 int64 usage = 0; | |
653 | |
654 while (!(file_path_each = enumerator->Next()).empty()) { | |
655 usage += enumerator->Size(); | |
656 usage += ObfuscatedFileUtil::ComputeFilePathCost(file_path_each); | |
657 } | |
658 | |
659 return usage; | |
660 } | |
661 | |
662 } // namespace fileapi | 429 } // namespace fileapi |
OLD | NEW |