| 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" |
| 11 #include "chrome/browser/chromeos/file_system_provider/notification_manager.h" | 11 #include "chrome/browser/chromeos/file_system_provider/notification_manager.h" |
| 12 #include "chrome/browser/chromeos/file_system_provider/operations/abort.h" | 12 #include "chrome/browser/chromeos/file_system_provider/operations/abort.h" |
| 13 #include "chrome/browser/chromeos/file_system_provider/operations/add_watcher.h" |
| 13 #include "chrome/browser/chromeos/file_system_provider/operations/close_file.h" | 14 #include "chrome/browser/chromeos/file_system_provider/operations/close_file.h" |
| 14 #include "chrome/browser/chromeos/file_system_provider/operations/copy_entry.h" | 15 #include "chrome/browser/chromeos/file_system_provider/operations/copy_entry.h" |
| 15 #include "chrome/browser/chromeos/file_system_provider/operations/create_directo
ry.h" | 16 #include "chrome/browser/chromeos/file_system_provider/operations/create_directo
ry.h" |
| 16 #include "chrome/browser/chromeos/file_system_provider/operations/create_file.h" | 17 #include "chrome/browser/chromeos/file_system_provider/operations/create_file.h" |
| 17 #include "chrome/browser/chromeos/file_system_provider/operations/delete_entry.h
" | 18 #include "chrome/browser/chromeos/file_system_provider/operations/delete_entry.h
" |
| 18 #include "chrome/browser/chromeos/file_system_provider/operations/get_metadata.h
" | 19 #include "chrome/browser/chromeos/file_system_provider/operations/get_metadata.h
" |
| 19 #include "chrome/browser/chromeos/file_system_provider/operations/move_entry.h" | 20 #include "chrome/browser/chromeos/file_system_provider/operations/move_entry.h" |
| 20 #include "chrome/browser/chromeos/file_system_provider/operations/observe_direct
ory.h" | |
| 21 #include "chrome/browser/chromeos/file_system_provider/operations/open_file.h" | 21 #include "chrome/browser/chromeos/file_system_provider/operations/open_file.h" |
| 22 #include "chrome/browser/chromeos/file_system_provider/operations/read_directory
.h" | 22 #include "chrome/browser/chromeos/file_system_provider/operations/read_directory
.h" |
| 23 #include "chrome/browser/chromeos/file_system_provider/operations/read_file.h" | 23 #include "chrome/browser/chromeos/file_system_provider/operations/read_file.h" |
| 24 #include "chrome/browser/chromeos/file_system_provider/operations/remove_watcher
.h" |
| 24 #include "chrome/browser/chromeos/file_system_provider/operations/truncate.h" | 25 #include "chrome/browser/chromeos/file_system_provider/operations/truncate.h" |
| 25 #include "chrome/browser/chromeos/file_system_provider/operations/unmount.h" | 26 #include "chrome/browser/chromeos/file_system_provider/operations/unmount.h" |
| 26 #include "chrome/browser/chromeos/file_system_provider/operations/unobserve_entr
y.h" | |
| 27 #include "chrome/browser/chromeos/file_system_provider/operations/write_file.h" | 27 #include "chrome/browser/chromeos/file_system_provider/operations/write_file.h" |
| 28 #include "chrome/browser/chromeos/file_system_provider/request_manager.h" | 28 #include "chrome/browser/chromeos/file_system_provider/request_manager.h" |
| 29 #include "chrome/browser/profiles/profile.h" | 29 #include "chrome/browser/profiles/profile.h" |
| 30 #include "chrome/common/extensions/api/file_system_provider.h" | 30 #include "chrome/common/extensions/api/file_system_provider.h" |
| 31 #include "extensions/browser/event_router.h" | 31 #include "extensions/browser/event_router.h" |
| 32 | 32 |
| 33 namespace net { | 33 namespace net { |
| 34 class IOBuffer; | 34 class IOBuffer; |
| 35 } // namespace net | 35 } // namespace net |
| 36 | 36 |
| (...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 357 event_router_, file_system_info_, file_path, length, callback))); | 357 event_router_, file_system_info_, file_path, length, callback))); |
| 358 if (!request_id) { | 358 if (!request_id) { |
| 359 callback.Run(base::File::FILE_ERROR_SECURITY); | 359 callback.Run(base::File::FILE_ERROR_SECURITY); |
| 360 return AbortCallback(); | 360 return AbortCallback(); |
| 361 } | 361 } |
| 362 | 362 |
| 363 return base::Bind( | 363 return base::Bind( |
| 364 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); | 364 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); |
| 365 } | 365 } |
| 366 | 366 |
| 367 ProvidedFileSystem::AbortCallback ProvidedFileSystem::ObserveDirectory( | 367 ProvidedFileSystem::AbortCallback ProvidedFileSystem::AddWatcher( |
| 368 const GURL& origin, | 368 const GURL& origin, |
| 369 const base::FilePath& directory_path, | 369 const base::FilePath& entry_path, |
| 370 bool recursive, | 370 bool recursive, |
| 371 bool persistent, | 371 bool persistent, |
| 372 const storage::AsyncFileUtil::StatusCallback& callback) { | 372 const storage::AsyncFileUtil::StatusCallback& callback) { |
| 373 // 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 |
| 374 // avoid races. | 374 // avoid races. |
| 375 if (persistent && !file_system_info_.supports_notify_tag()) { | 375 if (persistent && !file_system_info_.supports_notify_tag()) { |
| 376 OnObserveDirectoryCompleted(origin, | 376 OnAddWatcherCompleted(origin, |
| 377 directory_path, | 377 entry_path, |
| 378 recursive, | 378 recursive, |
| 379 persistent, | 379 persistent, |
| 380 callback, | 380 callback, |
| 381 base::File::FILE_ERROR_INVALID_OPERATION); | 381 base::File::FILE_ERROR_INVALID_OPERATION); |
| 382 return AbortCallback(); | 382 return AbortCallback(); |
| 383 } | 383 } |
| 384 | 384 |
| 385 const ObservedEntryKey key(directory_path, recursive); | 385 const WatcherKey key(entry_path, recursive); |
| 386 const ObservedEntries::const_iterator it = observed_entries_.find(key); | 386 const Watchers::const_iterator it = watchers_.find(key); |
| 387 if (it != observed_entries_.end()) { | 387 if (it != watchers_.end()) { |
| 388 const bool exists = | 388 const bool exists = |
| 389 it->second.subscribers.find(origin) != it->second.subscribers.end(); | 389 it->second.subscribers.find(origin) != it->second.subscribers.end(); |
| 390 OnObserveDirectoryCompleted( | 390 OnAddWatcherCompleted( |
| 391 origin, | 391 origin, |
| 392 directory_path, | 392 entry_path, |
| 393 recursive, | 393 recursive, |
| 394 persistent, | 394 persistent, |
| 395 callback, | 395 callback, |
| 396 exists ? base::File::FILE_ERROR_EXISTS : base::File::FILE_OK); | 396 exists ? base::File::FILE_ERROR_EXISTS : base::File::FILE_OK); |
| 397 return AbortCallback(); | 397 return AbortCallback(); |
| 398 } | 398 } |
| 399 | 399 |
| 400 const int request_id = request_manager_->CreateRequest( | 400 const int request_id = request_manager_->CreateRequest( |
| 401 OBSERVE_DIRECTORY, | 401 ADD_WATCHER, |
| 402 scoped_ptr<RequestManager::HandlerInterface>( | 402 scoped_ptr<RequestManager::HandlerInterface>(new operations::AddWatcher( |
| 403 new operations::ObserveDirectory( | 403 event_router_, |
| 404 event_router_, | 404 file_system_info_, |
| 405 file_system_info_, | 405 entry_path, |
| 406 directory_path, | 406 recursive, |
| 407 recursive, | 407 base::Bind(&ProvidedFileSystem::OnAddWatcherCompleted, |
| 408 base::Bind(&ProvidedFileSystem::OnObserveDirectoryCompleted, | 408 weak_ptr_factory_.GetWeakPtr(), |
| 409 weak_ptr_factory_.GetWeakPtr(), | 409 origin, |
| 410 origin, | 410 entry_path, |
| 411 directory_path, | 411 recursive, |
| 412 recursive, | 412 persistent, |
| 413 persistent, | 413 callback)))); |
| 414 callback)))); | |
| 415 | 414 |
| 416 if (!request_id) { | 415 if (!request_id) { |
| 417 OnObserveDirectoryCompleted(origin, | 416 OnAddWatcherCompleted(origin, |
| 418 directory_path, | 417 entry_path, |
| 419 recursive, | 418 recursive, |
| 420 persistent, | 419 persistent, |
| 421 callback, | 420 callback, |
| 422 base::File::FILE_ERROR_SECURITY); | 421 base::File::FILE_ERROR_SECURITY); |
| 423 return AbortCallback(); | 422 return AbortCallback(); |
| 424 } | 423 } |
| 425 | 424 |
| 426 return base::Bind( | 425 return base::Bind( |
| 427 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); | 426 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); |
| 428 } | 427 } |
| 429 | 428 |
| 430 void ProvidedFileSystem::UnobserveEntry( | 429 void ProvidedFileSystem::RemoveWatcher( |
| 431 const GURL& origin, | 430 const GURL& origin, |
| 432 const base::FilePath& entry_path, | 431 const base::FilePath& entry_path, |
| 433 bool recursive, | 432 bool recursive, |
| 434 const storage::AsyncFileUtil::StatusCallback& callback) { | 433 const storage::AsyncFileUtil::StatusCallback& callback) { |
| 435 const ObservedEntryKey key(entry_path, recursive); | 434 const WatcherKey key(entry_path, recursive); |
| 436 const ObservedEntries::iterator it = observed_entries_.find(key); | 435 const Watchers::iterator it = watchers_.find(key); |
| 437 if (it == observed_entries_.end() || | 436 if (it == watchers_.end() || |
| 438 it->second.subscribers.find(origin) == it->second.subscribers.end()) { | 437 it->second.subscribers.find(origin) == it->second.subscribers.end()) { |
| 439 callback.Run(base::File::FILE_ERROR_NOT_FOUND); | 438 callback.Run(base::File::FILE_ERROR_NOT_FOUND); |
| 440 return; | 439 return; |
| 441 } | 440 } |
| 442 | 441 |
| 443 // Delete the subscriber in advance, since the list of observed entries is | 442 // Delete the subscriber in advance, since the list of watchers is owned by |
| 444 // owned by the C++ layer, not by the extension. | 443 // the C++ layer, not by the extension. |
| 445 it->second.subscribers.erase(origin); | 444 it->second.subscribers.erase(origin); |
| 446 | 445 |
| 447 FOR_EACH_OBSERVER( | 446 FOR_EACH_OBSERVER(ProvidedFileSystemObserver, |
| 448 ProvidedFileSystemObserver, | 447 observers_, |
| 449 observers_, | 448 OnWatcherListChanged(file_system_info_, watchers_)); |
| 450 OnObservedEntryListChanged(file_system_info_, observed_entries_)); | |
| 451 | 449 |
| 452 // If there are other subscribers, then do not remove the obsererver, but | 450 // If there are other subscribers, then do not remove the obsererver, but |
| 453 // simply return a success. | 451 // simply return a success. |
| 454 if (it->second.subscribers.size()) { | 452 if (it->second.subscribers.size()) { |
| 455 callback.Run(base::File::FILE_OK); | 453 callback.Run(base::File::FILE_OK); |
| 456 return; | 454 return; |
| 457 } | 455 } |
| 458 | 456 |
| 459 // Delete the watcher in advance. | 457 // Delete the watcher in advance. |
| 460 observed_entries_.erase(it); | 458 watchers_.erase(it); |
| 461 | 459 |
| 462 // Even if the extension returns an error, the callback is called with base:: | 460 // Even if the extension returns an error, the callback is called with base:: |
| 463 // File::FILE_OK. The reason for that is that the observed is not watched | 461 // File::FILE_OK. The reason for that is that the entry is not watche anymore |
| 464 // anymore anyway, as it's removed in advance. | 462 // anyway, as it's removed in advance. |
| 465 const int request_id = request_manager_->CreateRequest( | 463 const int request_id = request_manager_->CreateRequest( |
| 466 UNOBSERVE_ENTRY, | 464 REMOVE_WATCHER, |
| 467 scoped_ptr<RequestManager::HandlerInterface>( | 465 scoped_ptr<RequestManager::HandlerInterface>( |
| 468 new operations::UnobserveEntry( | 466 new operations::RemoveWatcher( |
| 469 event_router_, | 467 event_router_, |
| 470 file_system_info_, | 468 file_system_info_, |
| 471 entry_path, | 469 entry_path, |
| 472 recursive, | 470 recursive, |
| 473 base::Bind(&AlwaysSuccessCallback, callback)))); | 471 base::Bind(&AlwaysSuccessCallback, callback)))); |
| 474 if (!request_id) | 472 if (!request_id) |
| 475 callback.Run(base::File::FILE_OK); | 473 callback.Run(base::File::FILE_OK); |
| 476 } | 474 } |
| 477 | 475 |
| 478 const ProvidedFileSystemInfo& ProvidedFileSystem::GetFileSystemInfo() const { | 476 const ProvidedFileSystemInfo& ProvidedFileSystem::GetFileSystemInfo() const { |
| 479 return file_system_info_; | 477 return file_system_info_; |
| 480 } | 478 } |
| 481 | 479 |
| 482 RequestManager* ProvidedFileSystem::GetRequestManager() { | 480 RequestManager* ProvidedFileSystem::GetRequestManager() { |
| 483 return request_manager_.get(); | 481 return request_manager_.get(); |
| 484 } | 482 } |
| 485 | 483 |
| 486 ObservedEntries* ProvidedFileSystem::GetObservedEntries() { | 484 Watchers* ProvidedFileSystem::GetWatchers() { |
| 487 return &observed_entries_; | 485 return &watchers_; |
| 488 } | 486 } |
| 489 | 487 |
| 490 void ProvidedFileSystem::AddObserver(ProvidedFileSystemObserver* observer) { | 488 void ProvidedFileSystem::AddObserver(ProvidedFileSystemObserver* observer) { |
| 491 DCHECK(observer); | 489 DCHECK(observer); |
| 492 observers_.AddObserver(observer); | 490 observers_.AddObserver(observer); |
| 493 } | 491 } |
| 494 | 492 |
| 495 void ProvidedFileSystem::RemoveObserver(ProvidedFileSystemObserver* observer) { | 493 void ProvidedFileSystem::RemoveObserver(ProvidedFileSystemObserver* observer) { |
| 496 DCHECK(observer); | 494 DCHECK(observer); |
| 497 observers_.RemoveObserver(observer); | 495 observers_.RemoveObserver(observer); |
| 498 } | 496 } |
| 499 | 497 |
| 500 bool ProvidedFileSystem::Notify( | 498 bool ProvidedFileSystem::Notify( |
| 501 const base::FilePath& observed_path, | 499 const base::FilePath& entry_path, |
| 502 bool recursive, | 500 bool recursive, |
| 503 ProvidedFileSystemObserver::ChangeType change_type, | 501 ProvidedFileSystemObserver::ChangeType change_type, |
| 504 scoped_ptr<ProvidedFileSystemObserver::Changes> changes, | 502 scoped_ptr<ProvidedFileSystemObserver::Changes> changes, |
| 505 const std::string& tag) { | 503 const std::string& tag) { |
| 506 const ObservedEntryKey key(observed_path, recursive); | 504 const WatcherKey key(entry_path, recursive); |
| 507 const ObservedEntries::iterator it = observed_entries_.find(key); | 505 const Watchers::iterator it = watchers_.find(key); |
| 508 if (it == observed_entries_.end()) | 506 if (it == watchers_.end()) |
| 509 return false; | 507 return false; |
| 510 | 508 |
| 511 // The tag must be provided if and only if it's explicitly supported. | 509 // The tag must be provided if and only if it's explicitly supported. |
| 512 if (file_system_info_.supports_notify_tag() == tag.empty()) | 510 if (file_system_info_.supports_notify_tag() == tag.empty()) |
| 513 return false; | 511 return false; |
| 514 | 512 |
| 515 // The object is owned by AutoUpdated, so the reference is valid as long as | 513 // The object is owned by AutoUpdated, so the reference is valid as long as |
| 516 // callbacks created with AutoUpdater::CreateCallback(). | 514 // callbacks created with AutoUpdater::CreateCallback(). |
| 517 const ProvidedFileSystemObserver::Changes& changes_ref = *changes.get(); | 515 const ProvidedFileSystemObserver::Changes& changes_ref = *changes.get(); |
| 518 | 516 |
| 519 scoped_refptr<AutoUpdater> auto_updater( | 517 scoped_refptr<AutoUpdater> auto_updater( |
| 520 new AutoUpdater(base::Bind(&ProvidedFileSystem::OnNotifyCompleted, | 518 new AutoUpdater(base::Bind(&ProvidedFileSystem::OnNotifyCompleted, |
| 521 weak_ptr_factory_.GetWeakPtr(), | 519 weak_ptr_factory_.GetWeakPtr(), |
| 522 observed_path, | 520 entry_path, |
| 523 recursive, | 521 recursive, |
| 524 change_type, | 522 change_type, |
| 525 base::Passed(&changes), | 523 base::Passed(&changes), |
| 526 it->second.last_tag, | 524 it->second.last_tag, |
| 527 tag))); | 525 tag))); |
| 528 | 526 |
| 529 FOR_EACH_OBSERVER(ProvidedFileSystemObserver, | 527 FOR_EACH_OBSERVER(ProvidedFileSystemObserver, |
| 530 observers_, | 528 observers_, |
| 531 OnObservedEntryChanged(file_system_info_, | 529 OnWatcherChanged(file_system_info_, |
| 532 it->second, | 530 it->second, |
| 533 change_type, | 531 change_type, |
| 534 changes_ref, | 532 changes_ref, |
| 535 auto_updater->CreateCallback())); | 533 auto_updater->CreateCallback())); |
| 536 | 534 |
| 537 return true; | 535 return true; |
| 538 } | 536 } |
| 539 | 537 |
| 540 base::WeakPtr<ProvidedFileSystemInterface> ProvidedFileSystem::GetWeakPtr() { | 538 base::WeakPtr<ProvidedFileSystemInterface> ProvidedFileSystem::GetWeakPtr() { |
| 541 return weak_ptr_factory_.GetWeakPtr(); | 539 return weak_ptr_factory_.GetWeakPtr(); |
| 542 } | 540 } |
| 543 | 541 |
| 544 void ProvidedFileSystem::Abort( | 542 void ProvidedFileSystem::Abort( |
| 545 int operation_request_id, | 543 int operation_request_id, |
| 546 const storage::AsyncFileUtil::StatusCallback& callback) { | 544 const storage::AsyncFileUtil::StatusCallback& callback) { |
| 547 request_manager_->RejectRequest(operation_request_id, | 545 request_manager_->RejectRequest(operation_request_id, |
| 548 make_scoped_ptr(new RequestValue()), | 546 make_scoped_ptr(new RequestValue()), |
| 549 base::File::FILE_ERROR_ABORT); | 547 base::File::FILE_ERROR_ABORT); |
| 550 if (!request_manager_->CreateRequest( | 548 if (!request_manager_->CreateRequest( |
| 551 ABORT, | 549 ABORT, |
| 552 scoped_ptr<RequestManager::HandlerInterface>( | 550 scoped_ptr<RequestManager::HandlerInterface>( |
| 553 new operations::Abort(event_router_, | 551 new operations::Abort(event_router_, |
| 554 file_system_info_, | 552 file_system_info_, |
| 555 operation_request_id, | 553 operation_request_id, |
| 556 callback)))) { | 554 callback)))) { |
| 557 callback.Run(base::File::FILE_ERROR_SECURITY); | 555 callback.Run(base::File::FILE_ERROR_SECURITY); |
| 558 } | 556 } |
| 559 } | 557 } |
| 560 | 558 |
| 561 void ProvidedFileSystem::OnObserveDirectoryCompleted( | 559 void ProvidedFileSystem::OnAddWatcherCompleted( |
| 562 const GURL& origin, | 560 const GURL& origin, |
| 563 const base::FilePath& directory_path, | 561 const base::FilePath& entry_path, |
| 564 bool recursive, | 562 bool recursive, |
| 565 bool persistent, | 563 bool persistent, |
| 566 const storage::AsyncFileUtil::StatusCallback& callback, | 564 const storage::AsyncFileUtil::StatusCallback& callback, |
| 567 base::File::Error result) { | 565 base::File::Error result) { |
| 568 if (result != base::File::FILE_OK) { | 566 if (result != base::File::FILE_OK) { |
| 569 callback.Run(result); | 567 callback.Run(result); |
| 570 return; | 568 return; |
| 571 } | 569 } |
| 572 | 570 |
| 573 const ObservedEntryKey key(directory_path, recursive); | 571 const WatcherKey key(entry_path, recursive); |
| 574 const ObservedEntries::iterator it = observed_entries_.find(key); | 572 const Watchers::iterator it = watchers_.find(key); |
| 575 if (it != observed_entries_.end()) { | 573 if (it != watchers_.end()) { |
| 576 callback.Run(base::File::FILE_OK); | 574 callback.Run(base::File::FILE_OK); |
| 577 return; | 575 return; |
| 578 } | 576 } |
| 579 | 577 |
| 580 ObservedEntry* const observed_entry = &observed_entries_[key]; | 578 Watcher* const watcher = &watchers_[key]; |
| 581 observed_entry->entry_path = directory_path; | 579 watcher->entry_path = entry_path; |
| 582 observed_entry->recursive = recursive; | 580 watcher->recursive = recursive; |
| 583 observed_entry->subscribers[origin].origin = origin; | 581 watcher->subscribers[origin].origin = origin; |
| 584 observed_entry->subscribers[origin].persistent |= persistent; | 582 watcher->subscribers[origin].persistent |= persistent; |
| 585 | 583 |
| 586 FOR_EACH_OBSERVER( | 584 FOR_EACH_OBSERVER(ProvidedFileSystemObserver, |
| 587 ProvidedFileSystemObserver, | 585 observers_, |
| 588 observers_, | 586 OnWatcherListChanged(file_system_info_, watchers_)); |
| 589 OnObservedEntryListChanged(file_system_info_, observed_entries_)); | |
| 590 | 587 |
| 591 callback.Run(base::File::FILE_OK); | 588 callback.Run(base::File::FILE_OK); |
| 592 } | 589 } |
| 593 | 590 |
| 594 void ProvidedFileSystem::OnNotifyCompleted( | 591 void ProvidedFileSystem::OnNotifyCompleted( |
| 595 const base::FilePath& observed_path, | 592 const base::FilePath& entry_path, |
| 596 bool recursive, | 593 bool recursive, |
| 597 ProvidedFileSystemObserver::ChangeType change_type, | 594 ProvidedFileSystemObserver::ChangeType change_type, |
| 598 scoped_ptr<ProvidedFileSystemObserver::Changes> /* changes */, | 595 scoped_ptr<ProvidedFileSystemObserver::Changes> /* changes */, |
| 599 const std::string& last_tag, | 596 const std::string& last_tag, |
| 600 const std::string& tag) { | 597 const std::string& tag) { |
| 601 const ObservedEntryKey key(observed_path, recursive); | 598 const WatcherKey key(entry_path, recursive); |
| 602 const ObservedEntries::iterator it = observed_entries_.find(key); | 599 const Watchers::iterator it = watchers_.find(key); |
| 603 // Check if the entry is still observed. | 600 // Check if the entry is still watched. |
| 604 if (it == observed_entries_.end()) | 601 if (it == watchers_.end()) |
| 605 return; | 602 return; |
| 606 | 603 |
| 607 // Another following notification finished earlier. | 604 // Another following notification finished earlier. |
| 608 if (it->second.last_tag != last_tag) | 605 if (it->second.last_tag != last_tag) |
| 609 return; | 606 return; |
| 610 | 607 |
| 611 // It's illegal to provide a tag which is not unique. As for now only an error | 608 // It's illegal to provide a tag which is not unique. As for now only an error |
| 612 // message is printed, but we may want to pass the error to the providing | 609 // message is printed, but we may want to pass the error to the providing |
| 613 // extension. TODO(mtomasz): Consider it. | 610 // extension. TODO(mtomasz): Consider it. |
| 614 if (!tag.empty() && tag == it->second.last_tag) | 611 if (!tag.empty() && tag == it->second.last_tag) |
| 615 LOG(ERROR) << "Tag specified, but same as the previous one."; | 612 LOG(ERROR) << "Tag specified, but same as the previous one."; |
| 616 | 613 |
| 617 it->second.last_tag = tag; | 614 it->second.last_tag = tag; |
| 618 | 615 |
| 619 FOR_EACH_OBSERVER(ProvidedFileSystemObserver, | 616 FOR_EACH_OBSERVER(ProvidedFileSystemObserver, |
| 620 observers_, | 617 observers_, |
| 621 OnObservedEntryTagUpdated(file_system_info_, it->second)); | 618 OnWatcherTagUpdated(file_system_info_, it->second)); |
| 622 | 619 |
| 623 // If the observed entry is deleted, then unobserve it. | 620 // If the watched entry is deleted, then remove the watcher. |
| 624 if (change_type == ProvidedFileSystemObserver::DELETED) { | 621 if (change_type == ProvidedFileSystemObserver::DELETED) { |
| 625 // Make a copy, since the |it| iterator will get invalidated on the last | 622 // Make a copy, since the |it| iterator will get invalidated on the last |
| 626 // subscriber. | 623 // subscriber. |
| 627 Subscribers subscribers = it->second.subscribers; | 624 Subscribers subscribers = it->second.subscribers; |
| 628 for (const auto& subscriber_it : subscribers) { | 625 for (const auto& subscriber_it : subscribers) { |
| 629 UnobserveEntry(subscriber_it.second.origin, | 626 RemoveWatcher(subscriber_it.second.origin, |
| 630 observed_path, | 627 entry_path, |
| 631 recursive, | 628 recursive, |
| 632 base::Bind(&EmptyStatusCallback)); | 629 base::Bind(&EmptyStatusCallback)); |
| 633 } | 630 } |
| 634 } | 631 } |
| 635 } | 632 } |
| 636 | 633 |
| 637 } // namespace file_system_provider | 634 } // namespace file_system_provider |
| 638 } // namespace chromeos | 635 } // namespace chromeos |
| OLD | NEW |