Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Side by Side Diff: chrome/browser/chromeos/file_system_provider/provided_file_system.cc

Issue 689603002: [fsp] Implement storage::WatcherManager for FSP. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixed. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 351 matching lines...) Expand 10 before | Expand all | Expand 10 after
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::AddWatcher( 367 ProvidedFileSystem::AbortCallback ProvidedFileSystem::AddWatcher(
368 const GURL& origin, 368 const GURL& origin,
369 const base::FilePath& entry_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 const storage::WatcherManager::NotificationCallback&
374 notification_callback) {
373 // TODO(mtomasz): Wrap the entire method body with an asynchronous queue to 375 // TODO(mtomasz): Wrap the entire method body with an asynchronous queue to
374 // avoid races. 376 // avoid races.
375 if (persistent && !file_system_info_.supports_notify_tag()) { 377 if (persistent && (!file_system_info_.supports_notify_tag() ||
376 OnAddWatcherCompleted(origin, 378 !notification_callback.is_null())) {
377 entry_path, 379 OnAddWatcherCompleted(entry_path,
378 recursive, 380 recursive,
379 persistent, 381 Subscriber(),
380 callback, 382 callback,
381 base::File::FILE_ERROR_INVALID_OPERATION); 383 base::File::FILE_ERROR_INVALID_OPERATION);
382 return AbortCallback(); 384 return AbortCallback();
383 } 385 }
384 386
387 // Create a candidate subscriber. This could be done in OnAddWatcherCompleted,
388 // but base::Bind supports only up to 7 arguments.
389 Subscriber subscriber;
390 subscriber.origin = origin;
391 subscriber.persistent = persistent;
392 subscriber.notification_callback = notification_callback;
393
385 const WatcherKey key(entry_path, recursive); 394 const WatcherKey key(entry_path, recursive);
386 const Watchers::const_iterator it = watchers_.find(key); 395 const Watchers::const_iterator it = watchers_.find(key);
387 if (it != watchers_.end()) { 396 if (it != watchers_.end()) {
388 const bool exists = 397 const bool exists =
389 it->second.subscribers.find(origin) != it->second.subscribers.end(); 398 it->second.subscribers.find(origin) != it->second.subscribers.end();
390 OnAddWatcherCompleted( 399 OnAddWatcherCompleted(
391 origin,
392 entry_path, 400 entry_path,
393 recursive, 401 recursive,
394 persistent, 402 subscriber,
395 callback, 403 callback,
396 exists ? base::File::FILE_ERROR_EXISTS : base::File::FILE_OK); 404 exists ? base::File::FILE_ERROR_EXISTS : base::File::FILE_OK);
397 return AbortCallback(); 405 return AbortCallback();
398 } 406 }
399 407
400 const int request_id = request_manager_->CreateRequest( 408 const int request_id = request_manager_->CreateRequest(
401 ADD_WATCHER, 409 ADD_WATCHER,
402 scoped_ptr<RequestManager::HandlerInterface>(new operations::AddWatcher( 410 scoped_ptr<RequestManager::HandlerInterface>(new operations::AddWatcher(
403 event_router_, 411 event_router_,
404 file_system_info_, 412 file_system_info_,
405 entry_path, 413 entry_path,
406 recursive, 414 recursive,
407 base::Bind(&ProvidedFileSystem::OnAddWatcherCompleted, 415 base::Bind(&ProvidedFileSystem::OnAddWatcherCompleted,
408 weak_ptr_factory_.GetWeakPtr(), 416 weak_ptr_factory_.GetWeakPtr(),
409 origin,
410 entry_path, 417 entry_path,
411 recursive, 418 recursive,
412 persistent, 419 subscriber,
413 callback)))); 420 callback))));
414 421
415 if (!request_id) { 422 if (!request_id) {
416 OnAddWatcherCompleted(origin, 423 OnAddWatcherCompleted(entry_path,
417 entry_path,
418 recursive, 424 recursive,
419 persistent, 425 subscriber,
420 callback, 426 callback,
421 base::File::FILE_ERROR_SECURITY); 427 base::File::FILE_ERROR_SECURITY);
422 return AbortCallback(); 428 return AbortCallback();
423 } 429 }
424 430
425 return base::Bind( 431 return base::Bind(
426 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id); 432 &ProvidedFileSystem::Abort, weak_ptr_factory_.GetWeakPtr(), request_id);
427 } 433 }
428 434
429 void ProvidedFileSystem::RemoveWatcher( 435 void ProvidedFileSystem::RemoveWatcher(
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
491 } 497 }
492 498
493 void ProvidedFileSystem::RemoveObserver(ProvidedFileSystemObserver* observer) { 499 void ProvidedFileSystem::RemoveObserver(ProvidedFileSystemObserver* observer) {
494 DCHECK(observer); 500 DCHECK(observer);
495 observers_.RemoveObserver(observer); 501 observers_.RemoveObserver(observer);
496 } 502 }
497 503
498 bool ProvidedFileSystem::Notify( 504 bool ProvidedFileSystem::Notify(
499 const base::FilePath& entry_path, 505 const base::FilePath& entry_path,
500 bool recursive, 506 bool recursive,
501 ProvidedFileSystemObserver::ChangeType change_type, 507 storage::WatcherManager::ChangeType change_type,
502 scoped_ptr<ProvidedFileSystemObserver::Changes> changes, 508 scoped_ptr<ProvidedFileSystemObserver::Changes> changes,
503 const std::string& tag) { 509 const std::string& tag) {
504 const WatcherKey key(entry_path, recursive); 510 const WatcherKey key(entry_path, recursive);
505 const Watchers::iterator it = watchers_.find(key); 511 const auto& watcher_it = watchers_.find(key);
506 if (it == watchers_.end()) 512 if (watcher_it == watchers_.end())
507 return false; 513 return false;
508 514
509 // The tag must be provided if and only if it's explicitly supported. 515 // The tag must be provided if and only if it's explicitly supported.
510 if (file_system_info_.supports_notify_tag() == tag.empty()) 516 if (file_system_info_.supports_notify_tag() == tag.empty())
511 return false; 517 return false;
512 518
513 // The object is owned by AutoUpdated, so the reference is valid as long as 519 // The object is owned by AutoUpdated, so the reference is valid as long as
514 // callbacks created with AutoUpdater::CreateCallback(). 520 // callbacks created with AutoUpdater::CreateCallback().
515 const ProvidedFileSystemObserver::Changes& changes_ref = *changes.get(); 521 const ProvidedFileSystemObserver::Changes& changes_ref = *changes.get();
516 522
517 scoped_refptr<AutoUpdater> auto_updater( 523 scoped_refptr<AutoUpdater> auto_updater(
518 new AutoUpdater(base::Bind(&ProvidedFileSystem::OnNotifyCompleted, 524 new AutoUpdater(base::Bind(&ProvidedFileSystem::OnNotifyCompleted,
519 weak_ptr_factory_.GetWeakPtr(), 525 weak_ptr_factory_.GetWeakPtr(),
520 entry_path, 526 entry_path,
521 recursive, 527 recursive,
522 change_type, 528 change_type,
523 base::Passed(&changes), 529 base::Passed(&changes),
524 it->second.last_tag, 530 watcher_it->second.last_tag,
525 tag))); 531 tag)));
526 532
533 // Call all notification callbacks (if any).
534 for (const auto& subscriber_it : watcher_it->second.subscribers) {
535 const storage::WatcherManager::NotificationCallback& notification_callback =
536 subscriber_it.second.notification_callback;
537 if (!notification_callback.is_null())
538 notification_callback.Run(change_type);
539 }
540
541 // Notify all observers.
527 FOR_EACH_OBSERVER(ProvidedFileSystemObserver, 542 FOR_EACH_OBSERVER(ProvidedFileSystemObserver,
528 observers_, 543 observers_,
529 OnWatcherChanged(file_system_info_, 544 OnWatcherChanged(file_system_info_,
530 it->second, 545 watcher_it->second,
531 change_type, 546 change_type,
532 changes_ref, 547 changes_ref,
533 auto_updater->CreateCallback())); 548 auto_updater->CreateCallback()));
534 549
535 return true; 550 return true;
536 } 551 }
537 552
538 base::WeakPtr<ProvidedFileSystemInterface> ProvidedFileSystem::GetWeakPtr() { 553 base::WeakPtr<ProvidedFileSystemInterface> ProvidedFileSystem::GetWeakPtr() {
539 return weak_ptr_factory_.GetWeakPtr(); 554 return weak_ptr_factory_.GetWeakPtr();
540 } 555 }
541 556
542 void ProvidedFileSystem::Abort( 557 void ProvidedFileSystem::Abort(
543 int operation_request_id, 558 int operation_request_id,
544 const storage::AsyncFileUtil::StatusCallback& callback) { 559 const storage::AsyncFileUtil::StatusCallback& callback) {
545 request_manager_->RejectRequest(operation_request_id, 560 request_manager_->RejectRequest(operation_request_id,
546 make_scoped_ptr(new RequestValue()), 561 make_scoped_ptr(new RequestValue()),
547 base::File::FILE_ERROR_ABORT); 562 base::File::FILE_ERROR_ABORT);
548 if (!request_manager_->CreateRequest( 563 if (!request_manager_->CreateRequest(
549 ABORT, 564 ABORT,
550 scoped_ptr<RequestManager::HandlerInterface>( 565 scoped_ptr<RequestManager::HandlerInterface>(
551 new operations::Abort(event_router_, 566 new operations::Abort(event_router_,
552 file_system_info_, 567 file_system_info_,
553 operation_request_id, 568 operation_request_id,
554 callback)))) { 569 callback)))) {
555 callback.Run(base::File::FILE_ERROR_SECURITY); 570 callback.Run(base::File::FILE_ERROR_SECURITY);
556 } 571 }
557 } 572 }
558 573
559 void ProvidedFileSystem::OnAddWatcherCompleted( 574 void ProvidedFileSystem::OnAddWatcherCompleted(
560 const GURL& origin,
561 const base::FilePath& entry_path, 575 const base::FilePath& entry_path,
562 bool recursive, 576 bool recursive,
563 bool persistent, 577 const Subscriber& subscriber,
564 const storage::AsyncFileUtil::StatusCallback& callback, 578 const storage::AsyncFileUtil::StatusCallback& callback,
565 base::File::Error result) { 579 base::File::Error result) {
566 if (result != base::File::FILE_OK) { 580 if (result != base::File::FILE_OK) {
567 callback.Run(result); 581 callback.Run(result);
568 return; 582 return;
569 } 583 }
570 584
571 const WatcherKey key(entry_path, recursive); 585 const WatcherKey key(entry_path, recursive);
572 const Watchers::iterator it = watchers_.find(key); 586 const Watchers::iterator it = watchers_.find(key);
573 if (it != watchers_.end()) { 587 if (it != watchers_.end()) {
574 callback.Run(base::File::FILE_OK); 588 callback.Run(base::File::FILE_OK);
575 return; 589 return;
576 } 590 }
577 591
592 // TODO(mtomasz): Add a queue to prevent races.
578 Watcher* const watcher = &watchers_[key]; 593 Watcher* const watcher = &watchers_[key];
579 watcher->entry_path = entry_path; 594 watcher->entry_path = entry_path;
580 watcher->recursive = recursive; 595 watcher->recursive = recursive;
581 watcher->subscribers[origin].origin = origin; 596 watcher->subscribers[subscriber.origin] = subscriber;
582 watcher->subscribers[origin].persistent |= persistent;
583 597
584 FOR_EACH_OBSERVER(ProvidedFileSystemObserver, 598 FOR_EACH_OBSERVER(ProvidedFileSystemObserver,
585 observers_, 599 observers_,
586 OnWatcherListChanged(file_system_info_, watchers_)); 600 OnWatcherListChanged(file_system_info_, watchers_));
587 601
588 callback.Run(base::File::FILE_OK); 602 callback.Run(base::File::FILE_OK);
589 } 603 }
590 604
591 void ProvidedFileSystem::OnNotifyCompleted( 605 void ProvidedFileSystem::OnNotifyCompleted(
592 const base::FilePath& entry_path, 606 const base::FilePath& entry_path,
593 bool recursive, 607 bool recursive,
594 ProvidedFileSystemObserver::ChangeType change_type, 608 storage::WatcherManager::ChangeType change_type,
595 scoped_ptr<ProvidedFileSystemObserver::Changes> /* changes */, 609 scoped_ptr<ProvidedFileSystemObserver::Changes> /* changes */,
596 const std::string& last_tag, 610 const std::string& last_tag,
597 const std::string& tag) { 611 const std::string& tag) {
598 const WatcherKey key(entry_path, recursive); 612 const WatcherKey key(entry_path, recursive);
599 const Watchers::iterator it = watchers_.find(key); 613 const Watchers::iterator it = watchers_.find(key);
600 // Check if the entry is still watched. 614 // Check if the entry is still watched.
601 if (it == watchers_.end()) 615 if (it == watchers_.end())
602 return; 616 return;
603 617
604 // Another following notification finished earlier. 618 // Another following notification finished earlier.
605 if (it->second.last_tag != last_tag) 619 if (it->second.last_tag != last_tag)
606 return; 620 return;
607 621
608 // It's illegal to provide a tag which is not unique. As for now only an error 622 // It's illegal to provide a tag which is not unique. As for now only an error
609 // message is printed, but we may want to pass the error to the providing 623 // message is printed, but we may want to pass the error to the providing
610 // extension. TODO(mtomasz): Consider it. 624 // extension. TODO(mtomasz): Consider it.
611 if (!tag.empty() && tag == it->second.last_tag) 625 if (!tag.empty() && tag == it->second.last_tag)
612 LOG(ERROR) << "Tag specified, but same as the previous one."; 626 LOG(ERROR) << "Tag specified, but same as the previous one.";
613 627
614 it->second.last_tag = tag; 628 it->second.last_tag = tag;
615 629
616 FOR_EACH_OBSERVER(ProvidedFileSystemObserver, 630 FOR_EACH_OBSERVER(ProvidedFileSystemObserver,
617 observers_, 631 observers_,
618 OnWatcherTagUpdated(file_system_info_, it->second)); 632 OnWatcherTagUpdated(file_system_info_, it->second));
619 633
620 // If the watched entry is deleted, then remove the watcher. 634 // If the watched entry is deleted, then remove the watcher.
621 if (change_type == ProvidedFileSystemObserver::DELETED) { 635 if (change_type == storage::WatcherManager::DELETED) {
622 // Make a copy, since the |it| iterator will get invalidated on the last 636 // Make a copy, since the |it| iterator will get invalidated on the last
623 // subscriber. 637 // subscriber.
624 Subscribers subscribers = it->second.subscribers; 638 Subscribers subscribers = it->second.subscribers;
625 for (const auto& subscriber_it : subscribers) { 639 for (const auto& subscriber_it : subscribers) {
626 RemoveWatcher(subscriber_it.second.origin, 640 RemoveWatcher(subscriber_it.second.origin,
627 entry_path, 641 entry_path,
628 recursive, 642 recursive,
629 base::Bind(&EmptyStatusCallback)); 643 base::Bind(&EmptyStatusCallback));
630 } 644 }
631 } 645 }
632 } 646 }
633 647
634 } // namespace file_system_provider 648 } // namespace file_system_provider
635 } // namespace chromeos 649 } // namespace chromeos
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698