Chromium Code Reviews| 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 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 494 void ProvidedFileSystem::AddObserver(ProvidedFileSystemObserver* observer) { | 494 void ProvidedFileSystem::AddObserver(ProvidedFileSystemObserver* observer) { |
| 495 DCHECK(observer); | 495 DCHECK(observer); |
| 496 observers_.AddObserver(observer); | 496 observers_.AddObserver(observer); |
| 497 } | 497 } |
| 498 | 498 |
| 499 void ProvidedFileSystem::RemoveObserver(ProvidedFileSystemObserver* observer) { | 499 void ProvidedFileSystem::RemoveObserver(ProvidedFileSystemObserver* observer) { |
| 500 DCHECK(observer); | 500 DCHECK(observer); |
| 501 observers_.RemoveObserver(observer); | 501 observers_.RemoveObserver(observer); |
| 502 } | 502 } |
| 503 | 503 |
| 504 bool ProvidedFileSystem::Notify( | 504 void ProvidedFileSystem::Notify( |
| 505 const base::FilePath& entry_path, | 505 const base::FilePath& entry_path, |
| 506 bool recursive, | 506 bool recursive, |
| 507 storage::WatcherManager::ChangeType change_type, | 507 storage::WatcherManager::ChangeType change_type, |
| 508 scoped_ptr<ProvidedFileSystemObserver::Changes> changes, | 508 scoped_ptr<ProvidedFileSystemObserver::Changes> changes, |
| 509 const std::string& tag) { | 509 const std::string& tag, |
| 510 const storage::AsyncFileUtil::StatusCallback& callback) { | |
| 510 const WatcherKey key(entry_path, recursive); | 511 const WatcherKey key(entry_path, recursive); |
| 511 const auto& watcher_it = watchers_.find(key); | 512 const auto& watcher_it = watchers_.find(key); |
| 512 if (watcher_it == watchers_.end()) | 513 if (watcher_it == watchers_.end()) { |
| 513 return false; | 514 callback.Run(base::File::FILE_ERROR_NOT_FOUND); |
| 515 return; | |
| 516 } | |
| 514 | 517 |
| 515 // The tag must be provided if and only if it's explicitly supported. | 518 // The tag must be provided if and only if it's explicitly supported. |
| 516 if (file_system_info_.supports_notify_tag() == tag.empty()) | 519 if (file_system_info_.supports_notify_tag() == tag.empty()) { |
| 517 return false; | 520 callback.Run(base::File::FILE_ERROR_INVALID_OPERATION); |
| 521 return; | |
| 522 } | |
| 523 | |
| 524 // It's illegal to provide a tag which is not unique. | |
| 525 if (!tag.empty() && tag == watcher_it->second.last_tag) { | |
| 526 callback.Run(base::File::FILE_ERROR_INVALID_OPERATION); | |
| 527 return; | |
| 528 } | |
| 518 | 529 |
| 519 // The object is owned by AutoUpdated, so the reference is valid as long as | 530 // The object is owned by AutoUpdated, so the reference is valid as long as |
| 520 // callbacks created with AutoUpdater::CreateCallback(). | 531 // callbacks created with AutoUpdater::CreateCallback(). |
| 521 const ProvidedFileSystemObserver::Changes& changes_ref = *changes.get(); | 532 const ProvidedFileSystemObserver::Changes& changes_ref = *changes.get(); |
| 522 | 533 |
| 523 scoped_refptr<AutoUpdater> auto_updater( | 534 scoped_refptr<AutoUpdater> auto_updater(new AutoUpdater( |
| 524 new AutoUpdater(base::Bind(&ProvidedFileSystem::OnNotifyCompleted, | 535 base::Bind(&ProvidedFileSystem::OnNotifyCompleted, |
| 525 weak_ptr_factory_.GetWeakPtr(), | 536 weak_ptr_factory_.GetWeakPtr(), entry_path, recursive, |
| 526 entry_path, | 537 change_type, base::Passed(&changes), tag, callback))); |
| 527 recursive, | |
| 528 change_type, | |
| 529 base::Passed(&changes), | |
| 530 watcher_it->second.last_tag, | |
| 531 tag))); | |
| 532 | 538 |
| 533 // Call all notification callbacks (if any). | 539 // Call all notification callbacks (if any). |
| 534 for (const auto& subscriber_it : watcher_it->second.subscribers) { | 540 for (const auto& subscriber_it : watcher_it->second.subscribers) { |
| 535 const storage::WatcherManager::NotificationCallback& notification_callback = | 541 const storage::WatcherManager::NotificationCallback& notification_callback = |
| 536 subscriber_it.second.notification_callback; | 542 subscriber_it.second.notification_callback; |
| 537 if (!notification_callback.is_null()) | 543 if (!notification_callback.is_null()) |
| 538 notification_callback.Run(change_type); | 544 notification_callback.Run(change_type); |
| 539 } | 545 } |
| 540 | 546 |
| 541 // Notify all observers. | 547 // Notify all observers. |
| 542 FOR_EACH_OBSERVER(ProvidedFileSystemObserver, | 548 FOR_EACH_OBSERVER(ProvidedFileSystemObserver, |
| 543 observers_, | 549 observers_, |
| 544 OnWatcherChanged(file_system_info_, | 550 OnWatcherChanged(file_system_info_, |
| 545 watcher_it->second, | 551 watcher_it->second, |
| 546 change_type, | 552 change_type, |
| 547 changes_ref, | 553 changes_ref, |
| 548 auto_updater->CreateCallback())); | 554 auto_updater->CreateCallback())); |
| 549 | |
| 550 return true; | |
| 551 } | 555 } |
| 552 | 556 |
| 553 base::WeakPtr<ProvidedFileSystemInterface> ProvidedFileSystem::GetWeakPtr() { | 557 base::WeakPtr<ProvidedFileSystemInterface> ProvidedFileSystem::GetWeakPtr() { |
| 554 return weak_ptr_factory_.GetWeakPtr(); | 558 return weak_ptr_factory_.GetWeakPtr(); |
| 555 } | 559 } |
| 556 | 560 |
| 557 void ProvidedFileSystem::Abort( | 561 void ProvidedFileSystem::Abort( |
| 558 int operation_request_id, | 562 int operation_request_id, |
| 559 const storage::AsyncFileUtil::StatusCallback& callback) { | 563 const storage::AsyncFileUtil::StatusCallback& callback) { |
| 560 request_manager_->RejectRequest(operation_request_id, | 564 request_manager_->RejectRequest(operation_request_id, |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 600 OnWatcherListChanged(file_system_info_, watchers_)); | 604 OnWatcherListChanged(file_system_info_, watchers_)); |
| 601 | 605 |
| 602 callback.Run(base::File::FILE_OK); | 606 callback.Run(base::File::FILE_OK); |
| 603 } | 607 } |
| 604 | 608 |
| 605 void ProvidedFileSystem::OnNotifyCompleted( | 609 void ProvidedFileSystem::OnNotifyCompleted( |
| 606 const base::FilePath& entry_path, | 610 const base::FilePath& entry_path, |
| 607 bool recursive, | 611 bool recursive, |
| 608 storage::WatcherManager::ChangeType change_type, | 612 storage::WatcherManager::ChangeType change_type, |
| 609 scoped_ptr<ProvidedFileSystemObserver::Changes> /* changes */, | 613 scoped_ptr<ProvidedFileSystemObserver::Changes> /* changes */, |
| 610 const std::string& last_tag, | 614 const std::string& tag, |
| 611 const std::string& tag) { | 615 const storage::AsyncFileUtil::StatusCallback& callback) { |
| 612 const WatcherKey key(entry_path, recursive); | 616 const WatcherKey key(entry_path, recursive); |
| 613 const Watchers::iterator it = watchers_.find(key); | 617 const Watchers::iterator it = watchers_.find(key); |
| 614 // Check if the entry is still watched. | 618 // Check if the entry is still watched. |
| 615 if (it == watchers_.end()) | 619 if (it == watchers_.end()) { |
| 620 callback.Run(base::File::FILE_ERROR_NOT_FOUND); | |
| 616 return; | 621 return; |
| 622 } | |
| 617 | 623 |
| 618 // Another following notification finished earlier. | 624 // TODO(mtomasz): Add an async queue around notify and other watcher related |
| 619 if (it->second.last_tag != last_tag) | 625 // methods so there is no rate. |
|
fukino
2014/11/07 10:26:53
nit: rate -> race?
mtomasz
2014/11/07 11:20:22
Done.
| |
| 620 return; | |
| 621 | |
| 622 // It's illegal to provide a tag which is not unique. As for now only an error | |
| 623 // message is printed, but we may want to pass the error to the providing | |
| 624 // extension. TODO(mtomasz): Consider it. | |
| 625 if (!tag.empty() && tag == it->second.last_tag) | |
| 626 LOG(ERROR) << "Tag specified, but same as the previous one."; | |
| 627 | 626 |
| 628 it->second.last_tag = tag; | 627 it->second.last_tag = tag; |
| 629 | 628 |
| 630 FOR_EACH_OBSERVER(ProvidedFileSystemObserver, | 629 FOR_EACH_OBSERVER(ProvidedFileSystemObserver, |
| 631 observers_, | 630 observers_, |
| 632 OnWatcherTagUpdated(file_system_info_, it->second)); | 631 OnWatcherTagUpdated(file_system_info_, it->second)); |
| 633 | 632 |
| 634 // If the watched entry is deleted, then remove the watcher. | 633 // If the watched entry is deleted, then remove the watcher. |
| 635 if (change_type == storage::WatcherManager::DELETED) { | 634 if (change_type == storage::WatcherManager::DELETED) { |
| 636 // Make a copy, since the |it| iterator will get invalidated on the last | 635 // Make a copy, since the |it| iterator will get invalidated on the last |
| 637 // subscriber. | 636 // subscriber. |
| 638 Subscribers subscribers = it->second.subscribers; | 637 Subscribers subscribers = it->second.subscribers; |
| 639 for (const auto& subscriber_it : subscribers) { | 638 for (const auto& subscriber_it : subscribers) { |
| 640 RemoveWatcher(subscriber_it.second.origin, | 639 RemoveWatcher(subscriber_it.second.origin, |
| 641 entry_path, | 640 entry_path, |
| 642 recursive, | 641 recursive, |
| 643 base::Bind(&EmptyStatusCallback)); | 642 base::Bind(&EmptyStatusCallback)); |
| 644 } | 643 } |
| 645 } | 644 } |
| 645 | |
| 646 callback.Run(base::File::FILE_OK); | |
| 646 } | 647 } |
| 647 | 648 |
| 648 } // namespace file_system_provider | 649 } // namespace file_system_provider |
| 649 } // namespace chromeos | 650 } // namespace chromeos |
| OLD | NEW |