| Index: chrome/browser/chromeos/file_system_provider/provided_file_system.cc
|
| diff --git a/chrome/browser/chromeos/file_system_provider/provided_file_system.cc b/chrome/browser/chromeos/file_system_provider/provided_file_system.cc
|
| index a593ce22cd6937ea1d9685852e4ab5bb83216a57..cdf2a466f01ab01c14b0121692573a987ebf1b57 100644
|
| --- a/chrome/browser/chromeos/file_system_provider/provided_file_system.cc
|
| +++ b/chrome/browser/chromeos/file_system_provider/provided_file_system.cc
|
| @@ -369,29 +369,37 @@ ProvidedFileSystem::AbortCallback ProvidedFileSystem::AddWatcher(
|
| const base::FilePath& entry_path,
|
| bool recursive,
|
| bool persistent,
|
| - const storage::AsyncFileUtil::StatusCallback& callback) {
|
| + const storage::AsyncFileUtil::StatusCallback& callback,
|
| + const storage::WatcherManager::NotificationCallback&
|
| + notification_callback) {
|
| // TODO(mtomasz): Wrap the entire method body with an asynchronous queue to
|
| // avoid races.
|
| - if (persistent && !file_system_info_.supports_notify_tag()) {
|
| - OnAddWatcherCompleted(origin,
|
| - entry_path,
|
| + if (persistent && (!file_system_info_.supports_notify_tag() ||
|
| + !notification_callback.is_null())) {
|
| + OnAddWatcherCompleted(entry_path,
|
| recursive,
|
| - persistent,
|
| + Subscriber(),
|
| callback,
|
| base::File::FILE_ERROR_INVALID_OPERATION);
|
| return AbortCallback();
|
| }
|
|
|
| + // Create a candidate subscriber. This could be done in OnAddWatcherCompleted,
|
| + // but base::Bind supports only up to 7 arguments.
|
| + Subscriber subscriber;
|
| + subscriber.origin = origin;
|
| + subscriber.persistent = persistent;
|
| + subscriber.notification_callback = notification_callback;
|
| +
|
| const WatcherKey key(entry_path, recursive);
|
| const Watchers::const_iterator it = watchers_.find(key);
|
| if (it != watchers_.end()) {
|
| const bool exists =
|
| it->second.subscribers.find(origin) != it->second.subscribers.end();
|
| OnAddWatcherCompleted(
|
| - origin,
|
| entry_path,
|
| recursive,
|
| - persistent,
|
| + subscriber,
|
| callback,
|
| exists ? base::File::FILE_ERROR_EXISTS : base::File::FILE_OK);
|
| return AbortCallback();
|
| @@ -406,17 +414,15 @@ ProvidedFileSystem::AbortCallback ProvidedFileSystem::AddWatcher(
|
| recursive,
|
| base::Bind(&ProvidedFileSystem::OnAddWatcherCompleted,
|
| weak_ptr_factory_.GetWeakPtr(),
|
| - origin,
|
| entry_path,
|
| recursive,
|
| - persistent,
|
| + subscriber,
|
| callback))));
|
|
|
| if (!request_id) {
|
| - OnAddWatcherCompleted(origin,
|
| - entry_path,
|
| + OnAddWatcherCompleted(entry_path,
|
| recursive,
|
| - persistent,
|
| + subscriber,
|
| callback,
|
| base::File::FILE_ERROR_SECURITY);
|
| return AbortCallback();
|
| @@ -498,12 +504,12 @@ void ProvidedFileSystem::RemoveObserver(ProvidedFileSystemObserver* observer) {
|
| bool ProvidedFileSystem::Notify(
|
| const base::FilePath& entry_path,
|
| bool recursive,
|
| - ProvidedFileSystemObserver::ChangeType change_type,
|
| + storage::WatcherManager::ChangeType change_type,
|
| scoped_ptr<ProvidedFileSystemObserver::Changes> changes,
|
| const std::string& tag) {
|
| const WatcherKey key(entry_path, recursive);
|
| - const Watchers::iterator it = watchers_.find(key);
|
| - if (it == watchers_.end())
|
| + const auto& watcher_it = watchers_.find(key);
|
| + if (watcher_it == watchers_.end())
|
| return false;
|
|
|
| // The tag must be provided if and only if it's explicitly supported.
|
| @@ -521,13 +527,22 @@ bool ProvidedFileSystem::Notify(
|
| recursive,
|
| change_type,
|
| base::Passed(&changes),
|
| - it->second.last_tag,
|
| + watcher_it->second.last_tag,
|
| tag)));
|
|
|
| + // Call all notification callbacks (if any).
|
| + for (const auto& subscriber_it : watcher_it->second.subscribers) {
|
| + const storage::WatcherManager::NotificationCallback& notification_callback =
|
| + subscriber_it.second.notification_callback;
|
| + if (!notification_callback.is_null())
|
| + notification_callback.Run(change_type);
|
| + }
|
| +
|
| + // Notify all observers.
|
| FOR_EACH_OBSERVER(ProvidedFileSystemObserver,
|
| observers_,
|
| OnWatcherChanged(file_system_info_,
|
| - it->second,
|
| + watcher_it->second,
|
| change_type,
|
| changes_ref,
|
| auto_updater->CreateCallback()));
|
| @@ -557,10 +572,9 @@ void ProvidedFileSystem::Abort(
|
| }
|
|
|
| void ProvidedFileSystem::OnAddWatcherCompleted(
|
| - const GURL& origin,
|
| const base::FilePath& entry_path,
|
| bool recursive,
|
| - bool persistent,
|
| + const Subscriber& subscriber,
|
| const storage::AsyncFileUtil::StatusCallback& callback,
|
| base::File::Error result) {
|
| if (result != base::File::FILE_OK) {
|
| @@ -575,11 +589,11 @@ void ProvidedFileSystem::OnAddWatcherCompleted(
|
| return;
|
| }
|
|
|
| + // TODO(mtomasz): Add a queue to prevent races.
|
| Watcher* const watcher = &watchers_[key];
|
| watcher->entry_path = entry_path;
|
| watcher->recursive = recursive;
|
| - watcher->subscribers[origin].origin = origin;
|
| - watcher->subscribers[origin].persistent |= persistent;
|
| + watcher->subscribers[subscriber.origin] = subscriber;
|
|
|
| FOR_EACH_OBSERVER(ProvidedFileSystemObserver,
|
| observers_,
|
| @@ -591,7 +605,7 @@ void ProvidedFileSystem::OnAddWatcherCompleted(
|
| void ProvidedFileSystem::OnNotifyCompleted(
|
| const base::FilePath& entry_path,
|
| bool recursive,
|
| - ProvidedFileSystemObserver::ChangeType change_type,
|
| + storage::WatcherManager::ChangeType change_type,
|
| scoped_ptr<ProvidedFileSystemObserver::Changes> /* changes */,
|
| const std::string& last_tag,
|
| const std::string& tag) {
|
| @@ -618,7 +632,7 @@ void ProvidedFileSystem::OnNotifyCompleted(
|
| OnWatcherTagUpdated(file_system_info_, it->second));
|
|
|
| // If the watched entry is deleted, then remove the watcher.
|
| - if (change_type == ProvidedFileSystemObserver::DELETED) {
|
| + if (change_type == storage::WatcherManager::DELETED) {
|
| // Make a copy, since the |it| iterator will get invalidated on the last
|
| // subscriber.
|
| Subscribers subscribers = it->second.subscribers;
|
|
|