OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "chrome/browser/chromeos/file_system_provider/provided_file_system.h" | 5 #include "chrome/browser/chromeos/file_system_provider/provided_file_system.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/files/file.h" | 10 #include "base/files/file.h" |
(...skipping 24 matching lines...) Expand all Loading... | |
35 } // namespace net | 35 } // namespace net |
36 | 36 |
37 namespace chromeos { | 37 namespace chromeos { |
38 namespace file_system_provider { | 38 namespace file_system_provider { |
39 namespace { | 39 namespace { |
40 | 40 |
41 // Discards the result of Abort() when called from the destructor. | 41 // Discards the result of Abort() when called from the destructor. |
42 void EmptyStatusCallback(base::File::Error /* result */) { | 42 void EmptyStatusCallback(base::File::Error /* result */) { |
43 } | 43 } |
44 | 44 |
45 // Discards the error code and always calls the callback with a success. | |
46 void AlwaysSuccessCallback( | |
47 const storage::AsyncFileUtil::StatusCallback& callback, | |
48 base::File::Error /* result */) { | |
49 callback.Run(base::File::FILE_OK); | |
50 } | |
51 | |
45 } // namespace | 52 } // namespace |
46 | 53 |
47 AutoUpdater::AutoUpdater(const base::Closure& update_callback) | 54 AutoUpdater::AutoUpdater(const base::Closure& update_callback) |
48 : update_callback_(update_callback), | 55 : update_callback_(update_callback), |
49 created_callbacks_(0), | 56 created_callbacks_(0), |
50 pending_callbacks_(0) { | 57 pending_callbacks_(0) { |
51 } | 58 } |
52 | 59 |
53 base::Closure AutoUpdater::CreateCallback() { | 60 base::Closure AutoUpdater::CreateCallback() { |
54 ++created_callbacks_; | 61 ++created_callbacks_; |
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
351 if (!request_id) { | 358 if (!request_id) { |
352 callback.Run(base::File::FILE_ERROR_SECURITY); | 359 callback.Run(base::File::FILE_ERROR_SECURITY); |
353 return AbortCallback(); | 360 return AbortCallback(); |
354 } | 361 } |
355 | 362 |
356 return base::Bind( | 363 return base::Bind( |
357 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); | 364 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); |
358 } | 365 } |
359 | 366 |
360 ProvidedFileSystem::AbortCallback ProvidedFileSystem::ObserveDirectory( | 367 ProvidedFileSystem::AbortCallback ProvidedFileSystem::ObserveDirectory( |
368 const GURL& origin, | |
361 const base::FilePath& directory_path, | 369 const base::FilePath& directory_path, |
362 bool recursive, | 370 bool recursive, |
371 bool persistent, | |
363 const storage::AsyncFileUtil::StatusCallback& callback) { | 372 const storage::AsyncFileUtil::StatusCallback& callback) { |
364 // TODO(mtomasz): Wrap the entire method body with an asynchronous queue to | 373 // TODO(mtomasz): Wrap the entire method body with an asynchronous queue to |
365 // avoid races. | 374 // avoid races. |
375 if (persistent && !file_system_info_.supports_notify_tag()) { | |
376 OnObserveDirectoryCompleted(origin, | |
377 directory_path, | |
378 recursive, | |
379 persistent, | |
380 callback, | |
381 base::File::FILE_ERROR_INVALID_OPERATION); | |
382 return AbortCallback(); | |
383 } | |
384 | |
366 const ObservedEntryKey key(directory_path, recursive); | 385 const ObservedEntryKey key(directory_path, recursive); |
367 const ObservedEntries::const_iterator it = observed_entries_.find(key); | 386 const ObservedEntries::const_iterator it = observed_entries_.find(key); |
368 if (it != observed_entries_.end()) { | 387 if (it != observed_entries_.end()) { |
369 OnObserveDirectoryCompleted( | 388 OnObserveDirectoryCompleted(origin, |
370 directory_path, recursive, callback, base::File::FILE_ERROR_EXISTS); | 389 directory_path, |
390 recursive, | |
391 persistent, | |
392 callback, | |
393 base::File::FILE_ERROR_EXISTS); | |
371 return AbortCallback(); | 394 return AbortCallback(); |
372 } | 395 } |
373 | 396 |
397 if (it != observed_entries_.end()) { | |
hirono
2014/10/27 04:50:31
it != observed_entries_.end() is always false beca
mtomasz
2014/10/27 05:01:18
Right. Done.
| |
398 if (it->second.subscribers.find(origin) != it->second.subscribers.end()) { | |
399 OnObserveDirectoryCompleted(origin, | |
400 directory_path, | |
401 recursive, | |
402 persistent, | |
403 callback, | |
404 base::File::FILE_ERROR_EXISTS); | |
405 return AbortCallback(); | |
406 } | |
407 } | |
408 | |
374 const int request_id = request_manager_->CreateRequest( | 409 const int request_id = request_manager_->CreateRequest( |
375 OBSERVE_DIRECTORY, | 410 OBSERVE_DIRECTORY, |
376 scoped_ptr<RequestManager::HandlerInterface>( | 411 scoped_ptr<RequestManager::HandlerInterface>( |
377 new operations::ObserveDirectory( | 412 new operations::ObserveDirectory( |
378 event_router_, | 413 event_router_, |
379 file_system_info_, | 414 file_system_info_, |
380 directory_path, | 415 directory_path, |
381 recursive, | 416 recursive, |
382 base::Bind(&ProvidedFileSystem::OnObserveDirectoryCompleted, | 417 base::Bind(&ProvidedFileSystem::OnObserveDirectoryCompleted, |
383 weak_ptr_factory_.GetWeakPtr(), | 418 weak_ptr_factory_.GetWeakPtr(), |
419 origin, | |
384 directory_path, | 420 directory_path, |
385 recursive, | 421 recursive, |
422 persistent, | |
386 callback)))); | 423 callback)))); |
424 | |
387 if (!request_id) { | 425 if (!request_id) { |
388 callback.Run(base::File::FILE_ERROR_SECURITY); | 426 OnObserveDirectoryCompleted(origin, |
427 directory_path, | |
428 recursive, | |
429 persistent, | |
430 callback, | |
431 base::File::FILE_ERROR_SECURITY); | |
389 return AbortCallback(); | 432 return AbortCallback(); |
390 } | 433 } |
391 | 434 |
392 return base::Bind( | 435 return base::Bind( |
393 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); | 436 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); |
394 } | 437 } |
395 | 438 |
396 void ProvidedFileSystem::UnobserveEntry( | 439 void ProvidedFileSystem::UnobserveEntry( |
440 const GURL& origin, | |
397 const base::FilePath& entry_path, | 441 const base::FilePath& entry_path, |
398 bool recursive, | 442 bool recursive, |
399 const storage::AsyncFileUtil::StatusCallback& callback) { | 443 const storage::AsyncFileUtil::StatusCallback& callback) { |
400 const ObservedEntryKey key(entry_path, recursive); | 444 const ObservedEntryKey key(entry_path, recursive); |
401 const ObservedEntries::const_iterator it = observed_entries_.find(key); | 445 const ObservedEntries::iterator it = observed_entries_.find(key); |
402 if (it == observed_entries_.end()) { | 446 if (it == observed_entries_.end() || |
447 it->second.subscribers.find(origin) == it->second.subscribers.end()) { | |
403 callback.Run(base::File::FILE_ERROR_NOT_FOUND); | 448 callback.Run(base::File::FILE_ERROR_NOT_FOUND); |
404 return; | 449 return; |
405 } | 450 } |
406 | 451 |
407 // Delete the watcher in advance since the list of observed entries is owned | 452 // Delete the subscriber in advance, since the list of observed entries is |
408 // by the C++ layer, not by the extension. | 453 // owned by the C++ layer, not by the extension. |
409 observed_entries_.erase(it); | 454 it->second.subscribers.erase(origin); |
410 | 455 |
411 FOR_EACH_OBSERVER( | 456 FOR_EACH_OBSERVER( |
412 ProvidedFileSystemObserver, | 457 ProvidedFileSystemObserver, |
413 observers_, | 458 observers_, |
414 OnObservedEntryListChanged(file_system_info_, observed_entries_)); | 459 OnObservedEntryListChanged(file_system_info_, observed_entries_)); |
415 | 460 |
416 // TODO(mtomasz): Consider returning always an OK error code, since for the | 461 // If there are other subscribers, then do not remove the obsererver, but |
417 // callers it's important that the entry is not watched anymore. The watcher | 462 // simply return a success. |
418 // is removed even if the extension returns an error. | 463 if (it->second.subscribers.size()) { |
464 callback.Run(base::File::FILE_OK); | |
465 return; | |
466 } | |
467 | |
468 // Delete the watcher in advance. | |
469 observed_entries_.erase(it); | |
470 | |
471 // Even if the extension returns an error, the callback is called with base:: | |
472 // File::FILE_OK. The reason for that is that the observed is not watched | |
473 // anymore anyway, as it's removed in advance. | |
419 const int request_id = request_manager_->CreateRequest( | 474 const int request_id = request_manager_->CreateRequest( |
420 UNOBSERVE_ENTRY, | 475 UNOBSERVE_ENTRY, |
421 scoped_ptr<RequestManager::HandlerInterface>( | 476 scoped_ptr<RequestManager::HandlerInterface>( |
422 new operations::UnobserveEntry(event_router_, | 477 new operations::UnobserveEntry( |
423 file_system_info_, | 478 event_router_, |
424 entry_path, | 479 file_system_info_, |
425 recursive, | 480 entry_path, |
426 callback))); | 481 recursive, |
482 base::Bind(&AlwaysSuccessCallback, callback)))); | |
427 if (!request_id) | 483 if (!request_id) |
428 callback.Run(base::File::FILE_ERROR_SECURITY); | 484 callback.Run(base::File::FILE_OK); |
429 } | 485 } |
430 | 486 |
431 const ProvidedFileSystemInfo& ProvidedFileSystem::GetFileSystemInfo() const { | 487 const ProvidedFileSystemInfo& ProvidedFileSystem::GetFileSystemInfo() const { |
432 return file_system_info_; | 488 return file_system_info_; |
433 } | 489 } |
434 | 490 |
435 RequestManager* ProvidedFileSystem::GetRequestManager() { | 491 RequestManager* ProvidedFileSystem::GetRequestManager() { |
436 return request_manager_.get(); | 492 return request_manager_.get(); |
437 } | 493 } |
438 | 494 |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
505 scoped_ptr<RequestManager::HandlerInterface>( | 561 scoped_ptr<RequestManager::HandlerInterface>( |
506 new operations::Abort(event_router_, | 562 new operations::Abort(event_router_, |
507 file_system_info_, | 563 file_system_info_, |
508 operation_request_id, | 564 operation_request_id, |
509 callback)))) { | 565 callback)))) { |
510 callback.Run(base::File::FILE_ERROR_SECURITY); | 566 callback.Run(base::File::FILE_ERROR_SECURITY); |
511 } | 567 } |
512 } | 568 } |
513 | 569 |
514 void ProvidedFileSystem::OnObserveDirectoryCompleted( | 570 void ProvidedFileSystem::OnObserveDirectoryCompleted( |
571 const GURL& origin, | |
515 const base::FilePath& directory_path, | 572 const base::FilePath& directory_path, |
516 bool recursive, | 573 bool recursive, |
574 bool persistent, | |
517 const storage::AsyncFileUtil::StatusCallback& callback, | 575 const storage::AsyncFileUtil::StatusCallback& callback, |
518 base::File::Error result) { | 576 base::File::Error result) { |
519 if (result != base::File::FILE_OK) { | 577 if (result != base::File::FILE_OK) { |
520 callback.Run(result); | 578 callback.Run(result); |
521 return; | 579 return; |
522 } | 580 } |
523 | 581 |
524 const ObservedEntryKey key(directory_path, recursive); | 582 const ObservedEntryKey key(directory_path, recursive); |
525 const ObservedEntries::iterator it = observed_entries_.find(key); | 583 const ObservedEntries::iterator it = observed_entries_.find(key); |
526 if (it != observed_entries_.end()) { | 584 if (it != observed_entries_.end()) { |
527 callback.Run(base::File::FILE_OK); | 585 callback.Run(base::File::FILE_OK); |
528 return; | 586 return; |
529 } | 587 } |
530 | 588 |
531 observed_entries_[key].entry_path = directory_path; | 589 ObservedEntry* const observed_entry = &observed_entries_[key]; |
532 observed_entries_[key].recursive = recursive; | 590 observed_entry->entry_path = directory_path; |
591 observed_entry->recursive = recursive; | |
592 observed_entry->subscribers[origin].origin = origin; | |
593 observed_entry->subscribers[origin].persistent |= persistent; | |
533 | 594 |
534 FOR_EACH_OBSERVER( | 595 FOR_EACH_OBSERVER( |
535 ProvidedFileSystemObserver, | 596 ProvidedFileSystemObserver, |
536 observers_, | 597 observers_, |
537 OnObservedEntryListChanged(file_system_info_, observed_entries_)); | 598 OnObservedEntryListChanged(file_system_info_, observed_entries_)); |
538 | 599 |
539 callback.Run(base::File::FILE_OK); | 600 callback.Run(base::File::FILE_OK); |
540 } | 601 } |
541 | 602 |
542 void ProvidedFileSystem::OnNotifyCompleted( | 603 void ProvidedFileSystem::OnNotifyCompleted( |
(...skipping 19 matching lines...) Expand all Loading... | |
562 if (!tag.empty() && tag == it->second.last_tag) | 623 if (!tag.empty() && tag == it->second.last_tag) |
563 LOG(ERROR) << "Tag specified, but same as the previous one."; | 624 LOG(ERROR) << "Tag specified, but same as the previous one."; |
564 | 625 |
565 it->second.last_tag = tag; | 626 it->second.last_tag = tag; |
566 | 627 |
567 FOR_EACH_OBSERVER(ProvidedFileSystemObserver, | 628 FOR_EACH_OBSERVER(ProvidedFileSystemObserver, |
568 observers_, | 629 observers_, |
569 OnObservedEntryTagUpdated(file_system_info_, it->second)); | 630 OnObservedEntryTagUpdated(file_system_info_, it->second)); |
570 | 631 |
571 // If the observed entry is deleted, then unobserve it. | 632 // If the observed entry is deleted, then unobserve it. |
572 if (change_type == ProvidedFileSystemObserver::DELETED) | 633 if (change_type == ProvidedFileSystemObserver::DELETED) { |
573 UnobserveEntry(observed_path, recursive, base::Bind(&EmptyStatusCallback)); | 634 // Make a copy, since the |it| iterator will get invalidated on the last |
635 // subscriber. | |
636 Subscribers subscribers = it->second.subscribers; | |
637 for (const auto& subscriber_it : subscribers) { | |
638 UnobserveEntry(subscriber_it.second.origin, | |
639 observed_path, | |
640 recursive, | |
641 base::Bind(&EmptyStatusCallback)); | |
642 } | |
643 } | |
574 } | 644 } |
575 | 645 |
576 } // namespace file_system_provider | 646 } // namespace file_system_provider |
577 } // namespace chromeos | 647 } // namespace chromeos |
OLD | NEW |