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/local_file_system_operation.h" | 5 #include "webkit/fileapi/local_file_system_operation.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/single_thread_task_runner.h" | 8 #include "base/single_thread_task_runner.h" |
9 #include "base/time.h" | 9 #include "base/time.h" |
10 #include "base/utf_string_conversions.h" | 10 #include "base/utf_string_conversions.h" |
11 #include "net/base/escape.h" | 11 #include "net/base/escape.h" |
12 #include "net/url_request/url_request_context.h" | 12 #include "net/url_request/url_request_context.h" |
13 #include "webkit/blob/shareable_file_reference.h" | 13 #include "webkit/blob/shareable_file_reference.h" |
14 #include "webkit/fileapi/file_observers.h" | 14 #include "webkit/fileapi/file_observers.h" |
15 #include "webkit/fileapi/file_system_context.h" | 15 #include "webkit/fileapi/file_system_context.h" |
16 #include "webkit/fileapi/file_system_file_util_proxy.h" | 16 #include "webkit/fileapi/file_system_file_util_proxy.h" |
17 #include "webkit/fileapi/file_system_mount_point_provider.h" | 17 #include "webkit/fileapi/file_system_mount_point_provider.h" |
18 #include "webkit/fileapi/file_system_task_runners.h" | 18 #include "webkit/fileapi/file_system_task_runners.h" |
19 #include "webkit/fileapi/file_system_types.h" | 19 #include "webkit/fileapi/file_system_types.h" |
20 #include "webkit/fileapi/file_system_url.h" | 20 #include "webkit/fileapi/file_system_url.h" |
21 #include "webkit/fileapi/file_system_util.h" | 21 #include "webkit/fileapi/file_system_util.h" |
22 #include "webkit/fileapi/file_writer_delegate.h" | 22 #include "webkit/fileapi/file_writer_delegate.h" |
| 23 #include "webkit/fileapi/remove_operation_delegate.h" |
23 #include "webkit/fileapi/sandbox_file_stream_writer.h" | 24 #include "webkit/fileapi/sandbox_file_stream_writer.h" |
24 #include "webkit/quota/quota_manager.h" | 25 #include "webkit/quota/quota_manager.h" |
25 #include "webkit/quota/quota_types.h" | 26 #include "webkit/quota/quota_types.h" |
26 | 27 |
27 using webkit_blob::ShareableFileReference; | 28 using webkit_blob::ShareableFileReference; |
28 | 29 |
29 namespace fileapi { | 30 namespace fileapi { |
30 | 31 |
31 namespace { | 32 namespace { |
32 | 33 |
33 bool IsMediaFileSystemType(FileSystemType type) { | 34 bool IsMediaFileSystemType(FileSystemType type) { |
34 return type == kFileSystemTypeNativeMedia || | 35 return type == kFileSystemTypeNativeMedia || |
35 type == kFileSystemTypeDeviceMedia; | 36 type == kFileSystemTypeDeviceMedia; |
36 } | 37 } |
37 | 38 |
38 bool IsCrossOperationAllowed(FileSystemType src_type, | 39 bool IsCrossOperationAllowed(FileSystemType src_type, |
39 FileSystemType dest_type) { | 40 FileSystemType dest_type) { |
40 // If two types are supposed to run on different task runners we should not | 41 // If two types are supposed to run on different task runners we should not |
41 // allow cross FileUtil operations at this layer. | 42 // allow cross FileUtil operations at this layer. |
42 return IsMediaFileSystemType(src_type) == IsMediaFileSystemType(dest_type); | 43 return IsMediaFileSystemType(src_type) == IsMediaFileSystemType(dest_type); |
43 } | 44 } |
44 | 45 |
45 } // namespace | 46 } // namespace |
46 | 47 |
| 48 // LocalFileSystemOperation::ScopedUpdateNotifier ----------------------------- |
| 49 |
47 class LocalFileSystemOperation::ScopedUpdateNotifier { | 50 class LocalFileSystemOperation::ScopedUpdateNotifier { |
48 public: | 51 public: |
49 ScopedUpdateNotifier(FileSystemOperationContext* operation_context, | 52 ScopedUpdateNotifier(FileSystemOperationContext* operation_context, |
50 const FileSystemURL& url); | 53 const FileSystemURL& url); |
51 ~ScopedUpdateNotifier(); | 54 ~ScopedUpdateNotifier(); |
52 | 55 |
53 private: | 56 private: |
54 // Not owned; owned by the owner of this instance | 57 // Not owned; owned by the owner of this instance |
55 // (i.e. LocalFileSystemOperation). | 58 // (i.e. LocalFileSystemOperation). |
56 FileSystemOperationContext* operation_context_; | 59 FileSystemOperationContext* operation_context_; |
57 FileSystemURL url_; | 60 FileSystemURL url_; |
58 DISALLOW_COPY_AND_ASSIGN(ScopedUpdateNotifier); | 61 DISALLOW_COPY_AND_ASSIGN(ScopedUpdateNotifier); |
59 }; | 62 }; |
60 | 63 |
61 LocalFileSystemOperation::ScopedUpdateNotifier::ScopedUpdateNotifier( | 64 LocalFileSystemOperation::ScopedUpdateNotifier::ScopedUpdateNotifier( |
62 FileSystemOperationContext* operation_context, | 65 FileSystemOperationContext* operation_context, |
63 const FileSystemURL& url) | 66 const FileSystemURL& url) |
64 : operation_context_(operation_context), url_(url) { | 67 : operation_context_(operation_context), url_(url) { |
65 operation_context_->update_observers()->Notify( | 68 operation_context_->update_observers()->Notify( |
66 &FileUpdateObserver::OnStartUpdate, MakeTuple(url_)); | 69 &FileUpdateObserver::OnStartUpdate, MakeTuple(url_)); |
67 } | 70 } |
68 | 71 |
69 LocalFileSystemOperation::ScopedUpdateNotifier::~ScopedUpdateNotifier() { | 72 LocalFileSystemOperation::ScopedUpdateNotifier::~ScopedUpdateNotifier() { |
70 operation_context_->update_observers()->Notify( | 73 operation_context_->update_observers()->Notify( |
71 &FileUpdateObserver::OnEndUpdate, MakeTuple(url_)); | 74 &FileUpdateObserver::OnEndUpdate, MakeTuple(url_)); |
72 } | 75 } |
73 | 76 |
| 77 // LocalFileSystemOperation --------------------------------------------------- |
| 78 |
74 LocalFileSystemOperation::~LocalFileSystemOperation() { | 79 LocalFileSystemOperation::~LocalFileSystemOperation() { |
| 80 if (!termination_callback_.is_null()) |
| 81 termination_callback_.Run(); |
75 } | 82 } |
76 | 83 |
77 void LocalFileSystemOperation::CreateFile(const FileSystemURL& url, | 84 void LocalFileSystemOperation::CreateFile(const FileSystemURL& url, |
78 bool exclusive, | 85 bool exclusive, |
79 const StatusCallback& callback) { | 86 const StatusCallback& callback) { |
80 DCHECK(SetPendingOperationType(kOperationCreateFile)); | 87 DCHECK(SetPendingOperationType(kOperationCreateFile)); |
81 | 88 |
82 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_CREATE); | 89 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_CREATE); |
83 if (result != base::PLATFORM_FILE_OK) { | 90 if (result != base::PLATFORM_FILE_OK) { |
84 callback.Run(result); | 91 callback.Run(result); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 DCHECK(SetPendingOperationType(kOperationDirectoryExists)); | 187 DCHECK(SetPendingOperationType(kOperationDirectoryExists)); |
181 | 188 |
182 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_READ); | 189 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_READ); |
183 if (result != base::PLATFORM_FILE_OK) { | 190 if (result != base::PLATFORM_FILE_OK) { |
184 callback.Run(result); | 191 callback.Run(result); |
185 delete this; | 192 delete this; |
186 return; | 193 return; |
187 } | 194 } |
188 | 195 |
189 FileSystemFileUtilProxy::GetFileInfo( | 196 FileSystemFileUtilProxy::GetFileInfo( |
190 operation_context_.get(), src_util_, url, | 197 operation_context(), src_util_, url, |
191 base::Bind(&LocalFileSystemOperation::DidDirectoryExists, | 198 base::Bind(&LocalFileSystemOperation::DidDirectoryExists, |
192 base::Owned(this), callback)); | 199 base::Owned(this), callback)); |
193 } | 200 } |
194 | 201 |
195 void LocalFileSystemOperation::FileExists(const FileSystemURL& url, | 202 void LocalFileSystemOperation::FileExists(const FileSystemURL& url, |
196 const StatusCallback& callback) { | 203 const StatusCallback& callback) { |
197 DCHECK(SetPendingOperationType(kOperationFileExists)); | 204 DCHECK(SetPendingOperationType(kOperationFileExists)); |
198 | 205 |
199 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_READ); | 206 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_READ); |
200 if (result != base::PLATFORM_FILE_OK) { | 207 if (result != base::PLATFORM_FILE_OK) { |
201 callback.Run(result); | 208 callback.Run(result); |
202 delete this; | 209 delete this; |
203 return; | 210 return; |
204 } | 211 } |
205 | 212 |
206 FileSystemFileUtilProxy::GetFileInfo( | 213 FileSystemFileUtilProxy::GetFileInfo( |
207 operation_context_.get(), src_util_, url, | 214 operation_context(), src_util_, url, |
208 base::Bind(&LocalFileSystemOperation::DidFileExists, | 215 base::Bind(&LocalFileSystemOperation::DidFileExists, |
209 base::Owned(this), callback)); | 216 base::Owned(this), callback)); |
210 } | 217 } |
211 | 218 |
212 void LocalFileSystemOperation::GetMetadata( | 219 void LocalFileSystemOperation::GetMetadata( |
213 const FileSystemURL& url, const GetMetadataCallback& callback) { | 220 const FileSystemURL& url, const GetMetadataCallback& callback) { |
214 DCHECK(SetPendingOperationType(kOperationGetMetadata)); | 221 DCHECK(SetPendingOperationType(kOperationGetMetadata)); |
215 | 222 |
216 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_READ); | 223 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_READ); |
217 if (result != base::PLATFORM_FILE_OK) { | 224 if (result != base::PLATFORM_FILE_OK) { |
218 callback.Run(result, base::PlatformFileInfo(), FilePath()); | 225 callback.Run(result, base::PlatformFileInfo(), FilePath()); |
219 delete this; | 226 delete this; |
220 return; | 227 return; |
221 } | 228 } |
222 | 229 |
223 FileSystemFileUtilProxy::GetFileInfo( | 230 FileSystemFileUtilProxy::GetFileInfo( |
224 operation_context_.get(), src_util_, url, | 231 operation_context(), src_util_, url, |
225 base::Bind(&LocalFileSystemOperation::DidGetMetadata, | 232 base::Bind(&LocalFileSystemOperation::DidGetMetadata, |
226 base::Owned(this), callback)); | 233 base::Owned(this), callback)); |
227 } | 234 } |
228 | 235 |
229 void LocalFileSystemOperation::ReadDirectory( | 236 void LocalFileSystemOperation::ReadDirectory( |
230 const FileSystemURL& url, const ReadDirectoryCallback& callback) { | 237 const FileSystemURL& url, const ReadDirectoryCallback& callback) { |
231 DCHECK(SetPendingOperationType(kOperationReadDirectory)); | 238 DCHECK(SetPendingOperationType(kOperationReadDirectory)); |
232 | 239 |
233 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_READ); | 240 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_READ); |
234 if (result != base::PLATFORM_FILE_OK) { | 241 if (result != base::PLATFORM_FILE_OK) { |
235 callback.Run(result, std::vector<base::FileUtilProxy::Entry>(), false); | 242 callback.Run(result, std::vector<base::FileUtilProxy::Entry>(), false); |
236 delete this; | 243 delete this; |
237 return; | 244 return; |
238 } | 245 } |
239 | 246 |
240 FileSystemFileUtilProxy::ReadDirectory( | 247 FileSystemFileUtilProxy::ReadDirectory( |
241 operation_context_.get(), src_util_, url, | 248 operation_context(), src_util_, url, |
242 base::Bind(&LocalFileSystemOperation::DidReadDirectory, | 249 base::Bind(&LocalFileSystemOperation::DidReadDirectory, |
243 base::Owned(this), callback)); | 250 base::Owned(this), callback)); |
244 } | 251 } |
245 | 252 |
246 void LocalFileSystemOperation::Remove(const FileSystemURL& url, | 253 void LocalFileSystemOperation::Remove(const FileSystemURL& url, |
247 bool recursive, | 254 bool recursive, |
248 const StatusCallback& callback) { | 255 const StatusCallback& callback) { |
249 DCHECK(SetPendingOperationType(kOperationRemove)); | 256 DCHECK(SetPendingOperationType(kOperationRemove)); |
250 | 257 DCHECK(!remove_operation_delegate_); |
251 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_WRITE); | 258 remove_operation_delegate_.reset(new RemoveOperationDelegate( |
252 if (result != base::PLATFORM_FILE_OK) { | 259 this, base::Bind(&LocalFileSystemOperation::DidFinishDelegatedOperation, |
253 callback.Run(result); | 260 base::Unretained(this), callback))); |
254 delete this; | 261 if (recursive) |
255 return; | 262 remove_operation_delegate_->RunRecursively(url); |
256 } | 263 else |
257 | 264 remove_operation_delegate_->Run(url); |
258 FileSystemFileUtilProxy::Delete( | |
259 operation_context_.get(), src_util_, url, recursive, | |
260 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, | |
261 base::Owned(this), callback)); | |
262 } | 265 } |
263 | 266 |
264 void LocalFileSystemOperation::Write( | 267 void LocalFileSystemOperation::Write( |
265 const net::URLRequestContext* url_request_context, | 268 const net::URLRequestContext* url_request_context, |
266 const FileSystemURL& url, | 269 const FileSystemURL& url, |
267 const GURL& blob_url, | 270 const GURL& blob_url, |
268 int64 offset, | 271 int64 offset, |
269 const WriteCallback& callback) { | 272 const WriteCallback& callback) { |
270 GetWriteClosure(url_request_context, url, blob_url, offset, callback).Run(); | 273 GetWriteClosure(url_request_context, url, blob_url, offset, callback).Run(); |
271 } | 274 } |
(...skipping 22 matching lines...) Expand all Loading... |
294 DCHECK(SetPendingOperationType(kOperationTouchFile)); | 297 DCHECK(SetPendingOperationType(kOperationTouchFile)); |
295 | 298 |
296 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_WRITE); | 299 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_WRITE); |
297 if (result != base::PLATFORM_FILE_OK) { | 300 if (result != base::PLATFORM_FILE_OK) { |
298 callback.Run(result); | 301 callback.Run(result); |
299 delete this; | 302 delete this; |
300 return; | 303 return; |
301 } | 304 } |
302 | 305 |
303 FileSystemFileUtilProxy::Touch( | 306 FileSystemFileUtilProxy::Touch( |
304 operation_context_.get(), src_util_, url, | 307 operation_context(), src_util_, url, |
305 last_access_time, last_modified_time, | 308 last_access_time, last_modified_time, |
306 base::Bind(&LocalFileSystemOperation::DidTouchFile, | 309 base::Bind(&LocalFileSystemOperation::DidTouchFile, |
307 base::Owned(this), callback)); | 310 base::Owned(this), callback)); |
308 } | 311 } |
309 | 312 |
310 void LocalFileSystemOperation::OpenFile(const FileSystemURL& url, | 313 void LocalFileSystemOperation::OpenFile(const FileSystemURL& url, |
311 int file_flags, | 314 int file_flags, |
312 base::ProcessHandle peer_handle, | 315 base::ProcessHandle peer_handle, |
313 const OpenFileCallback& callback) { | 316 const OpenFileCallback& callback) { |
314 DCHECK(SetPendingOperationType(kOperationOpenFile)); | 317 DCHECK(SetPendingOperationType(kOperationOpenFile)); |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
398 void LocalFileSystemOperation::SyncGetPlatformPath(const FileSystemURL& url, | 401 void LocalFileSystemOperation::SyncGetPlatformPath(const FileSystemURL& url, |
399 FilePath* platform_path) { | 402 FilePath* platform_path) { |
400 DCHECK(SetPendingOperationType(kOperationGetLocalPath)); | 403 DCHECK(SetPendingOperationType(kOperationGetLocalPath)); |
401 | 404 |
402 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_READ); | 405 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_READ); |
403 if (result != base::PLATFORM_FILE_OK) { | 406 if (result != base::PLATFORM_FILE_OK) { |
404 delete this; | 407 delete this; |
405 return; | 408 return; |
406 } | 409 } |
407 | 410 |
408 src_util_->GetLocalFilePath(operation_context_.get(), url, platform_path); | 411 src_util_->GetLocalFilePath(operation_context(), url, platform_path); |
409 | 412 |
410 delete this; | 413 delete this; |
411 } | 414 } |
412 | 415 |
413 void LocalFileSystemOperation::CreateSnapshotFile( | 416 void LocalFileSystemOperation::CreateSnapshotFile( |
414 const FileSystemURL& url, | 417 const FileSystemURL& url, |
415 const SnapshotFileCallback& callback) { | 418 const SnapshotFileCallback& callback) { |
416 DCHECK(SetPendingOperationType(kOperationCreateSnapshotFile)); | 419 DCHECK(SetPendingOperationType(kOperationCreateSnapshotFile)); |
417 | 420 |
418 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_READ); | 421 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_READ); |
419 if (result != base::PLATFORM_FILE_OK) { | 422 if (result != base::PLATFORM_FILE_OK) { |
420 callback.Run(result, base::PlatformFileInfo(), FilePath(), NULL); | 423 callback.Run(result, base::PlatformFileInfo(), FilePath(), NULL); |
421 delete this; | 424 delete this; |
422 return; | 425 return; |
423 } | 426 } |
424 | 427 |
425 FileSystemFileUtilProxy::CreateSnapshotFile( | 428 FileSystemFileUtilProxy::CreateSnapshotFile( |
426 operation_context_.get(), src_util_, url, | 429 operation_context(), src_util_, url, |
427 base::Bind(&LocalFileSystemOperation::DidCreateSnapshotFile, | 430 base::Bind(&LocalFileSystemOperation::DidCreateSnapshotFile, |
428 base::Owned(this), callback)); | 431 base::Owned(this), callback)); |
429 } | 432 } |
430 | 433 |
431 void LocalFileSystemOperation::CopyInForeignFile( | 434 void LocalFileSystemOperation::CopyInForeignFile( |
432 const FilePath& src_local_disk_file_path, | 435 const FilePath& src_local_disk_file_path, |
433 const FileSystemURL& dest_url, | 436 const FileSystemURL& dest_url, |
434 const StatusCallback& callback) { | 437 const StatusCallback& callback) { |
435 DCHECK(SetPendingOperationType(kOperationCopyInForeignFile)); | 438 DCHECK(SetPendingOperationType(kOperationCopyInForeignFile)); |
436 | 439 |
437 base::PlatformFileError result = SetUp( | 440 base::PlatformFileError result = SetUp( |
438 dest_url, &dest_util_, SETUP_FOR_CREATE); | 441 dest_url, &dest_util_, SETUP_FOR_CREATE); |
439 if (result != base::PLATFORM_FILE_OK) { | 442 if (result != base::PLATFORM_FILE_OK) { |
440 callback.Run(result); | 443 callback.Run(result); |
441 delete this; | 444 delete this; |
442 return; | 445 return; |
443 } | 446 } |
444 | 447 |
445 GetUsageAndQuotaThenRunTask( | 448 GetUsageAndQuotaThenRunTask( |
446 dest_url, | 449 dest_url, |
447 base::Bind(&LocalFileSystemOperation::DoCopyInForeignFile, | 450 base::Bind(&LocalFileSystemOperation::DoCopyInForeignFile, |
448 base::Unretained(this), src_local_disk_file_path, dest_url, | 451 base::Unretained(this), src_local_disk_file_path, dest_url, |
449 callback), | 452 callback), |
450 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED)); | 453 base::Bind(callback, base::PLATFORM_FILE_ERROR_FAILED)); |
451 } | 454 } |
452 | 455 |
| 456 void LocalFileSystemOperation::RemoveFile( |
| 457 const FileSystemURL& url, |
| 458 const StatusCallback& callback) { |
| 459 DCHECK(SetPendingOperationType(kOperationRemove)); |
| 460 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_WRITE); |
| 461 if (result != base::PLATFORM_FILE_OK) { |
| 462 callback.Run(result); |
| 463 delete this; |
| 464 return; |
| 465 } |
| 466 |
| 467 FileSystemFileUtilProxy::DeleteFile( |
| 468 operation_context(), src_util_, url, |
| 469 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, |
| 470 base::Owned(this), callback)); |
| 471 } |
| 472 |
| 473 void LocalFileSystemOperation::RemoveDirectory( |
| 474 const FileSystemURL& url, |
| 475 const StatusCallback& callback) { |
| 476 DCHECK(SetPendingOperationType(kOperationRemove)); |
| 477 base::PlatformFileError result = SetUp(url, &src_util_, SETUP_FOR_WRITE); |
| 478 if (result != base::PLATFORM_FILE_OK) { |
| 479 callback.Run(result); |
| 480 delete this; |
| 481 return; |
| 482 } |
| 483 |
| 484 FileSystemFileUtilProxy::DeleteDirectory( |
| 485 operation_context(), src_util_, url, |
| 486 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, |
| 487 base::Owned(this), callback)); |
| 488 } |
| 489 |
453 LocalFileSystemOperation::LocalFileSystemOperation( | 490 LocalFileSystemOperation::LocalFileSystemOperation( |
454 FileSystemContext* file_system_context, | 491 FileSystemContext* file_system_context, |
455 scoped_ptr<FileSystemOperationContext> operation_context) | 492 scoped_ptr<FileSystemOperationContext> operation_context) |
456 : file_system_context_(file_system_context), | 493 : file_system_context_(file_system_context), |
457 operation_context_(operation_context.Pass()), | 494 operation_context_(operation_context.Pass()), |
458 src_util_(NULL), | 495 src_util_(NULL), |
459 dest_util_(NULL), | 496 dest_util_(NULL), |
| 497 overriding_operation_context_(NULL), |
460 is_cross_operation_(false), | 498 is_cross_operation_(false), |
461 peer_handle_(base::kNullProcessHandle), | 499 peer_handle_(base::kNullProcessHandle), |
462 pending_operation_(kOperationNone), | 500 pending_operation_(kOperationNone), |
463 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { | 501 weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) { |
464 DCHECK(operation_context_.get()); | 502 DCHECK(operation_context_.get()); |
465 } | 503 } |
466 | 504 |
467 void LocalFileSystemOperation::GetUsageAndQuotaThenRunTask( | 505 void LocalFileSystemOperation::GetUsageAndQuotaThenRunTask( |
468 const FileSystemURL& url, | 506 const FileSystemURL& url, |
469 const base::Closure& task, | 507 const base::Closure& task, |
470 const base::Closure& error_callback) { | 508 const base::Closure& error_callback) { |
471 quota::QuotaManagerProxy* quota_manager_proxy = | 509 quota::QuotaManagerProxy* quota_manager_proxy = |
472 file_system_context()->quota_manager_proxy(); | 510 file_system_context()->quota_manager_proxy(); |
473 if (!quota_manager_proxy || | 511 if (!quota_manager_proxy || |
474 !file_system_context()->GetQuotaUtil(url.type())) { | 512 !file_system_context()->GetQuotaUtil(url.type())) { |
475 // If we don't have the quota manager or the requested filesystem type | 513 // If we don't have the quota manager or the requested filesystem type |
476 // does not support quota, we should be able to let it go. | 514 // does not support quota, we should be able to let it go. |
477 operation_context_->set_allowed_bytes_growth(kint64max); | 515 operation_context()->set_allowed_bytes_growth(kint64max); |
478 task.Run(); | 516 task.Run(); |
479 return; | 517 return; |
480 } | 518 } |
481 | 519 |
482 DCHECK(quota_manager_proxy); | 520 DCHECK(quota_manager_proxy); |
483 DCHECK(quota_manager_proxy->quota_manager()); | 521 DCHECK(quota_manager_proxy->quota_manager()); |
484 quota_manager_proxy->quota_manager()->GetUsageAndQuota( | 522 quota_manager_proxy->quota_manager()->GetUsageAndQuota( |
485 url.origin(), | 523 url.origin(), |
486 FileSystemTypeToQuotaStorageType(url.type()), | 524 FileSystemTypeToQuotaStorageType(url.type()), |
487 base::Bind(&LocalFileSystemOperation::DidGetUsageAndQuotaAndRunTask, | 525 base::Bind(&LocalFileSystemOperation::DidGetUsageAndQuotaAndRunTask, |
488 weak_factory_.GetWeakPtr(), task, error_callback)); | 526 weak_factory_.GetWeakPtr(), task, error_callback)); |
489 } | 527 } |
490 | 528 |
491 void LocalFileSystemOperation::DidGetUsageAndQuotaAndRunTask( | 529 void LocalFileSystemOperation::DidGetUsageAndQuotaAndRunTask( |
492 const base::Closure& task, | 530 const base::Closure& task, |
493 const base::Closure& error_callback, | 531 const base::Closure& error_callback, |
494 quota::QuotaStatusCode status, | 532 quota::QuotaStatusCode status, |
495 int64 usage, int64 quota) { | 533 int64 usage, int64 quota) { |
496 if (status != quota::kQuotaStatusOk) { | 534 if (status != quota::kQuotaStatusOk) { |
497 LOG(WARNING) << "Got unexpected quota error : " << status; | 535 LOG(WARNING) << "Got unexpected quota error : " << status; |
498 error_callback.Run(); | 536 error_callback.Run(); |
499 return; | 537 return; |
500 } | 538 } |
501 | 539 |
502 operation_context_->set_allowed_bytes_growth(quota - usage); | 540 operation_context()->set_allowed_bytes_growth(quota - usage); |
503 task.Run(); | 541 task.Run(); |
504 } | 542 } |
505 | 543 |
506 base::Closure LocalFileSystemOperation::GetWriteClosure( | 544 base::Closure LocalFileSystemOperation::GetWriteClosure( |
507 const net::URLRequestContext* url_request_context, | 545 const net::URLRequestContext* url_request_context, |
508 const FileSystemURL& url, | 546 const FileSystemURL& url, |
509 const GURL& blob_url, | 547 const GURL& blob_url, |
510 int64 offset, | 548 int64 offset, |
511 const WriteCallback& callback) { | 549 const WriteCallback& callback) { |
512 DCHECK(SetPendingOperationType(kOperationWrite)); | 550 DCHECK(SetPendingOperationType(kOperationWrite)); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
549 const WriteCallback& callback, | 587 const WriteCallback& callback, |
550 base::PlatformFileError result) { | 588 base::PlatformFileError result) { |
551 callback.Run(result, 0, false); | 589 callback.Run(result, 0, false); |
552 } | 590 } |
553 | 591 |
554 void LocalFileSystemOperation::DoCreateFile( | 592 void LocalFileSystemOperation::DoCreateFile( |
555 const FileSystemURL& url, | 593 const FileSystemURL& url, |
556 const StatusCallback& callback, | 594 const StatusCallback& callback, |
557 bool exclusive) { | 595 bool exclusive) { |
558 FileSystemFileUtilProxy::EnsureFileExists( | 596 FileSystemFileUtilProxy::EnsureFileExists( |
559 operation_context_.get(), | 597 operation_context(), |
560 src_util_, url, | 598 src_util_, url, |
561 base::Bind( | 599 base::Bind( |
562 exclusive ? | 600 exclusive ? |
563 &LocalFileSystemOperation::DidEnsureFileExistsExclusive : | 601 &LocalFileSystemOperation::DidEnsureFileExistsExclusive : |
564 &LocalFileSystemOperation::DidEnsureFileExistsNonExclusive, | 602 &LocalFileSystemOperation::DidEnsureFileExistsNonExclusive, |
565 base::Owned(this), callback)); | 603 base::Owned(this), callback)); |
566 } | 604 } |
567 | 605 |
568 void LocalFileSystemOperation::DoCreateDirectory( | 606 void LocalFileSystemOperation::DoCreateDirectory( |
569 const FileSystemURL& url, | 607 const FileSystemURL& url, |
570 const StatusCallback& callback, | 608 const StatusCallback& callback, |
571 bool exclusive, bool recursive) { | 609 bool exclusive, bool recursive) { |
572 FileSystemFileUtilProxy::CreateDirectory( | 610 FileSystemFileUtilProxy::CreateDirectory( |
573 operation_context_.get(), | 611 operation_context(), |
574 src_util_, url, exclusive, recursive, | 612 src_util_, url, exclusive, recursive, |
575 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, | 613 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, |
576 base::Owned(this), callback)); | 614 base::Owned(this), callback)); |
577 } | 615 } |
578 | 616 |
579 void LocalFileSystemOperation::DoCopy(const FileSystemURL& src_url, | 617 void LocalFileSystemOperation::DoCopy(const FileSystemURL& src_url, |
580 const FileSystemURL& dest_url, | 618 const FileSystemURL& dest_url, |
581 const StatusCallback& callback) { | 619 const StatusCallback& callback) { |
582 FileSystemFileUtilProxy::Copy( | 620 FileSystemFileUtilProxy::Copy( |
583 operation_context_.get(), | 621 operation_context(), |
584 src_util_, dest_util_, | 622 src_util_, dest_util_, |
585 src_url, dest_url, | 623 src_url, dest_url, |
586 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, | 624 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, |
587 base::Owned(this), callback)); | 625 base::Owned(this), callback)); |
588 } | 626 } |
589 | 627 |
590 void LocalFileSystemOperation::DoCopyInForeignFile( | 628 void LocalFileSystemOperation::DoCopyInForeignFile( |
591 const FilePath& src_local_disk_file_path, | 629 const FilePath& src_local_disk_file_path, |
592 const FileSystemURL& dest_url, | 630 const FileSystemURL& dest_url, |
593 const StatusCallback& callback) { | 631 const StatusCallback& callback) { |
594 FileSystemFileUtilProxy::CopyInForeignFile( | 632 FileSystemFileUtilProxy::CopyInForeignFile( |
595 operation_context_.get(), | 633 operation_context(), |
596 dest_util_, | 634 dest_util_, |
597 src_local_disk_file_path, dest_url, | 635 src_local_disk_file_path, dest_url, |
598 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, | 636 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, |
599 base::Owned(this), callback)); | 637 base::Owned(this), callback)); |
600 } | 638 } |
601 | 639 |
602 void LocalFileSystemOperation::DoMove(const FileSystemURL& src_url, | 640 void LocalFileSystemOperation::DoMove(const FileSystemURL& src_url, |
603 const FileSystemURL& dest_url, | 641 const FileSystemURL& dest_url, |
604 const StatusCallback& callback) { | 642 const StatusCallback& callback) { |
605 FileSystemFileUtilProxy::Move( | 643 FileSystemFileUtilProxy::Move( |
606 operation_context_.get(), | 644 operation_context(), |
607 src_util_, dest_util_, | 645 src_util_, dest_util_, |
608 src_url, dest_url, | 646 src_url, dest_url, |
609 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, | 647 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, |
610 base::Owned(this), callback)); | 648 base::Owned(this), callback)); |
611 } | 649 } |
612 | 650 |
613 void LocalFileSystemOperation::DoTruncate(const FileSystemURL& url, | 651 void LocalFileSystemOperation::DoTruncate(const FileSystemURL& url, |
614 const StatusCallback& callback, | 652 const StatusCallback& callback, |
615 int64 length) { | 653 int64 length) { |
616 FileSystemFileUtilProxy::Truncate( | 654 FileSystemFileUtilProxy::Truncate( |
617 operation_context_.get(), src_util_, url, length, | 655 operation_context(), src_util_, url, length, |
618 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, | 656 base::Bind(&LocalFileSystemOperation::DidFinishFileOperation, |
619 base::Owned(this), callback)); | 657 base::Owned(this), callback)); |
620 } | 658 } |
621 | 659 |
622 void LocalFileSystemOperation::DoOpenFile(const FileSystemURL& url, | 660 void LocalFileSystemOperation::DoOpenFile(const FileSystemURL& url, |
623 const OpenFileCallback& callback, | 661 const OpenFileCallback& callback, |
624 int file_flags) { | 662 int file_flags) { |
625 FileSystemFileUtilProxy::CreateOrOpen( | 663 FileSystemFileUtilProxy::CreateOrOpen( |
626 operation_context_.get(), src_util_, url, file_flags, | 664 operation_context(), src_util_, url, file_flags, |
627 base::Bind(&LocalFileSystemOperation::DidOpenFile, | 665 base::Bind(&LocalFileSystemOperation::DidOpenFile, |
628 base::Owned(this), callback)); | 666 base::Owned(this), callback)); |
629 } | 667 } |
630 | 668 |
631 void LocalFileSystemOperation::DidEnsureFileExistsExclusive( | 669 void LocalFileSystemOperation::DidEnsureFileExistsExclusive( |
632 const StatusCallback& callback, | 670 const StatusCallback& callback, |
633 base::PlatformFileError rv, bool created) { | 671 base::PlatformFileError rv, bool created) { |
634 if (rv == base::PLATFORM_FILE_OK && !created) { | 672 if (rv == base::PLATFORM_FILE_OK && !created) { |
635 callback.Run(base::PLATFORM_FILE_ERROR_EXISTS); | 673 callback.Run(base::PLATFORM_FILE_ERROR_EXISTS); |
636 } else { | 674 } else { |
(...skipping 14 matching lines...) Expand all Loading... |
651 DCHECK_EQ(kOperationTruncate, pending_operation_); | 689 DCHECK_EQ(kOperationTruncate, pending_operation_); |
652 | 690 |
653 callback.Run(base::PLATFORM_FILE_ERROR_ABORT); | 691 callback.Run(base::PLATFORM_FILE_ERROR_ABORT); |
654 cancel_callback_.Run(base::PLATFORM_FILE_OK); | 692 cancel_callback_.Run(base::PLATFORM_FILE_OK); |
655 cancel_callback_.Reset(); | 693 cancel_callback_.Reset(); |
656 } else { | 694 } else { |
657 callback.Run(rv); | 695 callback.Run(rv); |
658 } | 696 } |
659 } | 697 } |
660 | 698 |
| 699 void LocalFileSystemOperation::DidFinishDelegatedOperation( |
| 700 const StatusCallback& callback, |
| 701 base::PlatformFileError rv) { |
| 702 // The callback might be held by the delegate and Owned() may not work, |
| 703 // so just explicitly delete this now. |
| 704 callback.Run(rv); |
| 705 delete this; |
| 706 } |
| 707 |
661 void LocalFileSystemOperation::DidDirectoryExists( | 708 void LocalFileSystemOperation::DidDirectoryExists( |
662 const StatusCallback& callback, | 709 const StatusCallback& callback, |
663 base::PlatformFileError rv, | 710 base::PlatformFileError rv, |
664 const base::PlatformFileInfo& file_info, | 711 const base::PlatformFileInfo& file_info, |
665 const FilePath& unused) { | 712 const FilePath& unused) { |
666 if (rv == base::PLATFORM_FILE_OK && !file_info.is_directory) | 713 if (rv == base::PLATFORM_FILE_OK && !file_info.is_directory) |
667 rv = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; | 714 rv = base::PLATFORM_FILE_ERROR_NOT_A_DIRECTORY; |
668 callback.Run(rv); | 715 callback.Run(rv); |
669 } | 716 } |
670 | 717 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 if (write_callback_.is_null()) { | 749 if (write_callback_.is_null()) { |
703 // If cancelled, callback is already invoked and set to null in Cancel(). | 750 // If cancelled, callback is already invoked and set to null in Cancel(). |
704 // We must not call it twice. Just shut down this operation object. | 751 // We must not call it twice. Just shut down this operation object. |
705 delete this; | 752 delete this; |
706 return; | 753 return; |
707 } | 754 } |
708 | 755 |
709 const bool complete = ( | 756 const bool complete = ( |
710 write_status != FileWriterDelegate::SUCCESS_IO_PENDING); | 757 write_status != FileWriterDelegate::SUCCESS_IO_PENDING); |
711 if (complete && write_status != FileWriterDelegate::ERROR_WRITE_NOT_STARTED) { | 758 if (complete && write_status != FileWriterDelegate::ERROR_WRITE_NOT_STARTED) { |
712 operation_context_->change_observers()->Notify( | 759 operation_context()->change_observers()->Notify( |
713 &FileChangeObserver::OnModifyFile, MakeTuple(url)); | 760 &FileChangeObserver::OnModifyFile, MakeTuple(url)); |
714 } | 761 } |
715 | 762 |
716 write_callback_.Run(rv, bytes, complete); | 763 write_callback_.Run(rv, bytes, complete); |
717 if (complete || rv != base::PLATFORM_FILE_OK) | 764 if (complete || rv != base::PLATFORM_FILE_OK) |
718 delete this; | 765 delete this; |
719 } | 766 } |
720 | 767 |
721 void LocalFileSystemOperation::DidTouchFile(const StatusCallback& callback, | 768 void LocalFileSystemOperation::DidTouchFile(const StatusCallback& callback, |
722 base::PlatformFileError rv) { | 769 base::PlatformFileError rv) { |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
754 FileSystemFileUtil** file_util, | 801 FileSystemFileUtil** file_util, |
755 SetUpMode mode) { | 802 SetUpMode mode) { |
756 if (!url.is_valid()) | 803 if (!url.is_valid()) |
757 return base::PLATFORM_FILE_ERROR_INVALID_URL; | 804 return base::PLATFORM_FILE_ERROR_INVALID_URL; |
758 | 805 |
759 // Restricted file system is read-only. | 806 // Restricted file system is read-only. |
760 if (url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal && | 807 if (url.type() == fileapi::kFileSystemTypeRestrictedNativeLocal && |
761 mode != SETUP_FOR_READ) | 808 mode != SETUP_FOR_READ) |
762 return base::PLATFORM_FILE_ERROR_SECURITY; | 809 return base::PLATFORM_FILE_ERROR_SECURITY; |
763 | 810 |
764 if (!file_system_context()->GetMountPointProvider( | |
765 url.type())->IsAccessAllowed(url)) | |
766 return base::PLATFORM_FILE_ERROR_SECURITY; | |
767 | |
768 DCHECK(file_util); | 811 DCHECK(file_util); |
769 if (!*file_util) | 812 if (!*file_util) |
770 *file_util = file_system_context()->GetFileUtil(url.type()); | 813 *file_util = file_system_context()->GetFileUtil(url.type()); |
771 if (!*file_util) | 814 if (!*file_util) |
772 return base::PLATFORM_FILE_ERROR_SECURITY; | 815 return base::PLATFORM_FILE_ERROR_SECURITY; |
773 | 816 |
| 817 // If this operation is created for recursive sub-operations (i.e. |
| 818 // operation context is overridden from another operation) we skip |
| 819 // some duplicated security checks. |
| 820 if (overriding_operation_context_) |
| 821 return base::PLATFORM_FILE_OK; |
| 822 |
| 823 if (!file_system_context()->GetMountPointProvider( |
| 824 url.type())->IsAccessAllowed(url)) |
| 825 return base::PLATFORM_FILE_ERROR_SECURITY; |
| 826 |
774 if (mode == SETUP_FOR_READ) { | 827 if (mode == SETUP_FOR_READ) { |
775 // TODO(kinuko): This doesn't work well for cross-filesystem operation | 828 // TODO(kinuko): This doesn't work well for cross-filesystem operation |
776 // in the current architecture since the operation context (thus the | 829 // in the current architecture since the operation context (thus the |
777 // observers) is configured for the destination URL while this method | 830 // observers) is configured for the destination URL while this method |
778 // could be called for both src and dest URL. | 831 // could be called for both src and dest URL. |
779 if (!is_cross_operation_) { | 832 if (!is_cross_operation_) { |
780 operation_context_->access_observers()->Notify( | 833 operation_context()->access_observers()->Notify( |
781 &FileAccessObserver::OnAccess, MakeTuple(url)); | 834 &FileAccessObserver::OnAccess, MakeTuple(url)); |
782 } | 835 } |
783 return base::PLATFORM_FILE_OK; | 836 return base::PLATFORM_FILE_OK; |
784 } | 837 } |
785 | 838 |
786 DCHECK(mode == SETUP_FOR_WRITE || mode == SETUP_FOR_CREATE); | 839 DCHECK(mode == SETUP_FOR_WRITE || mode == SETUP_FOR_CREATE); |
787 | 840 |
788 scoped_update_notifiers_.push_back(new ScopedUpdateNotifier( | 841 scoped_update_notifiers_.push_back(new ScopedUpdateNotifier( |
789 operation_context_.get(), url)); | 842 operation_context(), url)); |
790 | 843 |
791 // Any write access is disallowed on the root path. | 844 // Any write access is disallowed on the root path. |
792 if (url.path().value().length() == 0 || | 845 if (url.path().value().length() == 0 || |
793 url.path().DirName().value() == url.path().value()) | 846 url.path().DirName().value() == url.path().value()) |
794 return base::PLATFORM_FILE_ERROR_SECURITY; | 847 return base::PLATFORM_FILE_ERROR_SECURITY; |
795 | 848 |
796 if (mode == SETUP_FOR_CREATE) { | 849 if (mode == SETUP_FOR_CREATE) { |
797 FileSystemMountPointProvider* provider = file_system_context()-> | 850 FileSystemMountPointProvider* provider = file_system_context()-> |
798 GetMountPointProvider(url.type()); | 851 GetMountPointProvider(url.type()); |
799 | 852 |
800 // Check if the cracked file name looks good to create. | 853 // Check if the cracked file name looks good to create. |
801 if (provider->IsRestrictedFileName(VirtualPath::BaseName(url.path()))) | 854 if (provider->IsRestrictedFileName(VirtualPath::BaseName(url.path()))) |
802 return base::PLATFORM_FILE_ERROR_SECURITY; | 855 return base::PLATFORM_FILE_ERROR_SECURITY; |
803 } | 856 } |
804 | 857 |
805 return base::PLATFORM_FILE_OK; | 858 return base::PLATFORM_FILE_OK; |
806 } | 859 } |
807 | 860 |
808 bool LocalFileSystemOperation::SetPendingOperationType(OperationType type) { | 861 bool LocalFileSystemOperation::SetPendingOperationType(OperationType type) { |
809 if (pending_operation_ != kOperationNone) | 862 if (pending_operation_ != kOperationNone) |
810 return false; | 863 return false; |
811 pending_operation_ = type; | 864 pending_operation_ = type; |
812 return true; | 865 return true; |
813 } | 866 } |
814 | 867 |
815 } // namespace fileapi | 868 } // namespace fileapi |
OLD | NEW |