diff options
author | hashimoto@chromium.org <hashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-26 03:39:03 +0000 |
---|---|---|
committer | hashimoto@chromium.org <hashimoto@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-02-26 03:39:03 +0000 |
commit | 53f57109e2f790d5824b129515568f8746c05948 (patch) | |
tree | d17f2551c14a9cecfea12bee27e03fd533b2f2f9 | |
parent | 403ce3f3f97cc57a4227c75ba9b780667c566d3f (diff) | |
download | chromium_src-53f57109e2f790d5824b129515568f8746c05948.zip chromium_src-53f57109e2f790d5824b129515568f8746c05948.tar.gz chromium_src-53f57109e2f790d5824b129515568f8746c05948.tar.bz2 |
drive: No dependency between ChangeListLoader and DirectoryLoader
Move LoadDirectoryIfNeeded from ChangeListLoader to FileSystem
Remove ChangeListLoader::LoadForTesting().
Add DirectoryLoaderTest.
BUG=335469
TEST=unit_tests
R=kinaba@chromium.org
Review URL: https://codereview.chromium.org/179323002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@253343 0039d316-1c4b-4281-b951-d872f2087c98
10 files changed, 287 insertions, 216 deletions
diff --git a/chrome/browser/chromeos/drive/change_list_loader.cc b/chrome/browser/chromeos/drive/change_list_loader.cc index 0fd0a60..c8a1b63 100644 --- a/chrome/browser/chromeos/drive/change_list_loader.cc +++ b/chrome/browser/chromeos/drive/change_list_loader.cc @@ -13,11 +13,9 @@ #include "base/time/time.h" #include "chrome/browser/chromeos/drive/change_list_loader_observer.h" #include "chrome/browser/chromeos/drive/change_list_processor.h" -#include "chrome/browser/chromeos/drive/directory_loader.h" #include "chrome/browser/chromeos/drive/file_system_util.h" #include "chrome/browser/chromeos/drive/job_scheduler.h" #include "chrome/browser/chromeos/drive/resource_metadata.h" -#include "chrome/browser/drive/drive_service_interface.h" #include "chrome/browser/drive/event_logger.h" #include "content/public/browser/browser_thread.h" #include "google_apis/drive/drive_api_parser.h" @@ -278,23 +276,14 @@ ChangeListLoader::ChangeListLoader( base::SequencedTaskRunner* blocking_task_runner, ResourceMetadata* resource_metadata, JobScheduler* scheduler, - DriveServiceInterface* drive_service, AboutResourceLoader* about_resource_loader, LoaderController* loader_controller) : logger_(logger), blocking_task_runner_(blocking_task_runner), resource_metadata_(resource_metadata), scheduler_(scheduler), - drive_service_(drive_service), about_resource_loader_(about_resource_loader), loader_controller_(loader_controller), - directory_loader_(new DirectoryLoader(logger, - blocking_task_runner, - resource_metadata, - scheduler, - drive_service, - about_resource_loader, - loader_controller)), loaded_(false), weak_ptr_factory_(this) { } @@ -311,13 +300,11 @@ bool ChangeListLoader::IsRefreshing() const { void ChangeListLoader::AddObserver(ChangeListLoaderObserver* observer) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); observers_.AddObserver(observer); - directory_loader_->AddObserver(observer); } void ChangeListLoader::RemoveObserver(ChangeListLoaderObserver* observer) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); observers_.RemoveObserver(observer); - directory_loader_->RemoveObserver(observer); } void ChangeListLoader::CheckForUpdates(const FileOperationCallback& callback) { @@ -340,24 +327,13 @@ void ChangeListLoader::CheckForUpdates(const FileOperationCallback& callback) { } } -void ChangeListLoader::LoadDirectoryIfNeeded( - const base::FilePath& directory_path, - const FileOperationCallback& callback) { +void ChangeListLoader::LoadIfNeeded(const FileOperationCallback& callback) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(!callback.is_null()); - directory_loader_->LoadDirectoryIfNeeded(directory_path, callback); - // If the metadata is not yet loaded, start loading. if (!loaded_) - Load(base::Bind(&util::EmptyFileOperationCallback)); -} - -void ChangeListLoader::LoadForTesting(const FileOperationCallback& callback) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(!callback.is_null()); - - Load(callback); + Load(callback); } void ChangeListLoader::Load(const FileOperationCallback& callback) { diff --git a/chrome/browser/chromeos/drive/change_list_loader.h b/chrome/browser/chromeos/drive/change_list_loader.h index 8b2c5cc..14ab89a 100644 --- a/chrome/browser/chromeos/drive/change_list_loader.h +++ b/chrome/browser/chromeos/drive/change_list_loader.h @@ -32,7 +32,6 @@ class ResourceList; namespace drive { -class DriveServiceInterface; class EventLogger; class JobScheduler; class ResourceEntry; @@ -132,7 +131,6 @@ class ChangeListLoader { base::SequencedTaskRunner* blocking_task_runner, ResourceMetadata* resource_metadata, JobScheduler* scheduler, - DriveServiceInterface* drive_service, AboutResourceLoader* about_resource_loader, LoaderController* apply_task_controller); ~ChangeListLoader(); @@ -158,16 +156,8 @@ class ChangeListLoader { // starts loading from the server, and runs |callback| to tell the result to // the caller when it is finished. // - // The specified directory will be fetched first from the server, so the UI - // can show the directory contents instantly before the entire change list - // loading is complete. - // // |callback| must not be null. - void LoadDirectoryIfNeeded(const base::FilePath& directory_path, - const FileOperationCallback& callback); - - // Calls Load(). Only for testing purposes. - void LoadForTesting(const FileOperationCallback& callback); + void LoadIfNeeded(const FileOperationCallback& callback); private: // Starts the resource metadata loading and calls |callback| when it's done. @@ -211,10 +201,8 @@ class ChangeListLoader { scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; ResourceMetadata* resource_metadata_; // Not owned. JobScheduler* scheduler_; // Not owned. - DriveServiceInterface* drive_service_; // Not owned. AboutResourceLoader* about_resource_loader_; // Not owned. LoaderController* loader_controller_; // Not owned. - scoped_ptr<DirectoryLoader> directory_loader_; ObserverList<ChangeListLoaderObserver> observers_; std::vector<FileOperationCallback> pending_load_callback_; FileOperationCallback pending_update_check_callback_; diff --git a/chrome/browser/chromeos/drive/change_list_loader_unittest.cc b/chrome/browser/chromeos/drive/change_list_loader_unittest.cc index 153a8ea..30ad9f5 100644 --- a/chrome/browser/chromeos/drive/change_list_loader_unittest.cc +++ b/chrome/browser/chromeos/drive/change_list_loader_unittest.cc @@ -111,7 +111,6 @@ class ChangeListLoaderTest : public testing::Test { base::MessageLoopProxy::current().get(), metadata_.get(), scheduler_.get(), - drive_service_.get(), about_resource_loader_.get(), loader_controller_.get())); } @@ -156,7 +155,7 @@ TEST_F(ChangeListLoaderTest, Load) { EXPECT_EQ(0, drive_service_->about_resource_load_count()); FileError error = FILE_ERROR_FAILED; - change_list_loader_->LoadForTesting( + change_list_loader_->LoadIfNeeded( google_apis::test_util::CreateCopyResultCallback(&error)); EXPECT_TRUE(change_list_loader_->IsRefreshing()); base::RunLoop().RunUntilIdle(); @@ -175,27 +174,12 @@ TEST_F(ChangeListLoaderTest, Load) { ResourceEntry entry; EXPECT_EQ(FILE_ERROR_OK, metadata_->GetResourceEntryByPath(file_path, &entry)); - - // Reload. This should result in no-op. - int64 previous_changestamp = metadata_->GetLargestChangestamp(); - int previous_resource_list_load_count = - drive_service_->resource_list_load_count(); - change_list_loader_->LoadForTesting( - google_apis::test_util::CreateCopyResultCallback(&error)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - - EXPECT_FALSE(change_list_loader_->IsRefreshing()); - // Cached value is used. - EXPECT_EQ(previous_changestamp, metadata_->GetLargestChangestamp()); - EXPECT_EQ(previous_resource_list_load_count, - drive_service_->resource_list_load_count()); } TEST_F(ChangeListLoaderTest, Load_LocalMetadataAvailable) { // Prepare metadata. FileError error = FILE_ERROR_FAILED; - change_list_loader_->LoadForTesting( + change_list_loader_->LoadIfNeeded( google_apis::test_util::CreateCopyResultCallback(&error)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); @@ -206,7 +190,6 @@ TEST_F(ChangeListLoaderTest, Load_LocalMetadataAvailable) { base::MessageLoopProxy::current().get(), metadata_.get(), scheduler_.get(), - drive_service_.get(), about_resource_loader_.get(), loader_controller_.get())); @@ -220,7 +203,7 @@ TEST_F(ChangeListLoaderTest, Load_LocalMetadataAvailable) { drive_service_->resource_list_load_count(); TestChangeListLoaderObserver observer(change_list_loader_.get()); - change_list_loader_->LoadForTesting( + change_list_loader_->LoadIfNeeded( google_apis::test_util::CreateCopyResultCallback(&error)); EXPECT_TRUE(change_list_loader_->IsRefreshing()); base::RunLoop().RunUntilIdle(); @@ -244,138 +227,6 @@ TEST_F(ChangeListLoaderTest, Load_LocalMetadataAvailable) { metadata_->GetResourceEntryByPath(file_path, &entry)); } -TEST_F(ChangeListLoaderTest, LoadDirectoryIfNeeded_GrandRoot) { - TestChangeListLoaderObserver observer(change_list_loader_.get()); - - // Emulate the slowness of GetAllResourceList(). - drive_service_->set_never_return_all_resource_list(true); - - // Load grand root. - FileError error = FILE_ERROR_FAILED; - change_list_loader_->LoadDirectoryIfNeeded( - util::GetDriveGrandRootPath(), - google_apis::test_util::CreateCopyResultCallback(&error)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - EXPECT_EQ(0U, observer.changed_directories().size()); - observer.clear_changed_directories(); - - // GetAllResourceList() was called. - EXPECT_EQ(1, drive_service_->blocked_resource_list_load_count()); - - // My Drive has resource ID. - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_OK, - metadata_->GetResourceEntryByPath(util::GetDriveMyDriveRootPath(), - &entry)); - EXPECT_EQ(drive_service_->GetRootResourceId(), entry.resource_id()); -} - -TEST_F(ChangeListLoaderTest, LoadDirectoryIfNeeded_MyDrive) { - TestChangeListLoaderObserver observer(change_list_loader_.get()); - - // My Drive does not have resource ID yet. - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_OK, - metadata_->GetResourceEntryByPath(util::GetDriveMyDriveRootPath(), - &entry)); - EXPECT_TRUE(entry.resource_id().empty()); - - // Emulate the slowness of GetAllResourceList(). - drive_service_->set_never_return_all_resource_list(true); - - // Load My Drive. - FileError error = FILE_ERROR_FAILED; - change_list_loader_->LoadDirectoryIfNeeded( - util::GetDriveMyDriveRootPath(), - google_apis::test_util::CreateCopyResultCallback(&error)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - EXPECT_EQ(1U, observer.changed_directories().count( - util::GetDriveMyDriveRootPath())); - - // GetAllResourceList() was called. - EXPECT_EQ(1, drive_service_->blocked_resource_list_load_count()); - - // My Drive has resource ID. - EXPECT_EQ(FILE_ERROR_OK, - metadata_->GetResourceEntryByPath(util::GetDriveMyDriveRootPath(), - &entry)); - EXPECT_EQ(drive_service_->GetRootResourceId(), entry.resource_id()); - - // My Drive's child is present. - base::FilePath file_path = - util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt"); - EXPECT_EQ(FILE_ERROR_OK, - metadata_->GetResourceEntryByPath(file_path, &entry)); -} - -TEST_F(ChangeListLoaderTest, LoadDirectoryIfNeeded_NewDirectories) { - // Make local metadata up to date. - FileError error = FILE_ERROR_FAILED; - change_list_loader_->LoadForTesting( - google_apis::test_util::CreateCopyResultCallback(&error)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - - // Add a new file. - scoped_ptr<google_apis::ResourceEntry> file = AddNewFile("New File"); - ASSERT_TRUE(file); - - // Emulate the slowness of GetAllResourceList(). - drive_service_->set_never_return_all_resource_list(true); - - // Enter refreshing state. - FileError check_for_updates_error = FILE_ERROR_FAILED; - change_list_loader_->CheckForUpdates( - google_apis::test_util::CreateCopyResultCallback( - &check_for_updates_error)); - EXPECT_TRUE(change_list_loader_->IsRefreshing()); - - // Load My Drive. - TestChangeListLoaderObserver observer(change_list_loader_.get()); - change_list_loader_->LoadDirectoryIfNeeded( - util::GetDriveMyDriveRootPath(), - google_apis::test_util::CreateCopyResultCallback(&error)); - base::RunLoop().RunUntilIdle(); - EXPECT_EQ(FILE_ERROR_OK, error); - EXPECT_EQ(1U, observer.changed_directories().count( - util::GetDriveMyDriveRootPath())); - - // The new file is present in the local metadata. - base::FilePath file_path = - util::GetDriveMyDriveRootPath().AppendASCII(file->title()); - ResourceEntry entry; - EXPECT_EQ(FILE_ERROR_OK, - metadata_->GetResourceEntryByPath(file_path, &entry)); -} - -TEST_F(ChangeListLoaderTest, LoadDirectoryIfNeeded_MultipleCalls) { - TestChangeListLoaderObserver observer(change_list_loader_.get()); - - // Load grand root. - FileError error = FILE_ERROR_FAILED; - change_list_loader_->LoadDirectoryIfNeeded( - util::GetDriveGrandRootPath(), - google_apis::test_util::CreateCopyResultCallback(&error)); - - // Load grand root again without waiting for the result. - FileError error2 = FILE_ERROR_FAILED; - change_list_loader_->LoadDirectoryIfNeeded( - util::GetDriveGrandRootPath(), - google_apis::test_util::CreateCopyResultCallback(&error2)); - base::RunLoop().RunUntilIdle(); - - // Callback is called for each method call. - EXPECT_EQ(FILE_ERROR_OK, error); - EXPECT_EQ(FILE_ERROR_OK, error2); - - // No duplicated resource list load and observer events. - EXPECT_EQ(1, drive_service_->resource_list_load_count()); - EXPECT_EQ(1, observer.initial_load_complete_count()); - EXPECT_EQ(1, observer.load_from_server_complete_count()); -} - TEST_F(ChangeListLoaderTest, CheckForUpdates) { // CheckForUpdates() results in no-op before load. FileError check_for_updates_error = FILE_ERROR_FAILED; @@ -392,7 +243,7 @@ TEST_F(ChangeListLoaderTest, CheckForUpdates) { // Start initial load. FileError load_error = FILE_ERROR_FAILED; - change_list_loader_->LoadForTesting( + change_list_loader_->LoadIfNeeded( google_apis::test_util::CreateCopyResultCallback(&load_error)); EXPECT_TRUE(change_list_loader_->IsRefreshing()); @@ -445,7 +296,7 @@ TEST_F(ChangeListLoaderTest, CheckForUpdates) { TEST_F(ChangeListLoaderTest, Lock) { FileError error = FILE_ERROR_FAILED; - change_list_loader_->LoadForTesting( + change_list_loader_->LoadIfNeeded( google_apis::test_util::CreateCopyResultCallback(&error)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); diff --git a/chrome/browser/chromeos/drive/directory_loader_unittest.cc b/chrome/browser/chromeos/drive/directory_loader_unittest.cc new file mode 100644 index 0000000..50040e9 --- /dev/null +++ b/chrome/browser/chromeos/drive/directory_loader_unittest.cc @@ -0,0 +1,232 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/chromeos/drive/directory_loader.h" + +#include "base/callback_helpers.h" +#include "base/files/scoped_temp_dir.h" +#include "base/memory/scoped_ptr.h" +#include "base/prefs/testing_pref_service.h" +#include "base/run_loop.h" +#include "chrome/browser/chromeos/drive/change_list_loader.h" +#include "chrome/browser/chromeos/drive/change_list_loader_observer.h" +#include "chrome/browser/chromeos/drive/file_cache.h" +#include "chrome/browser/chromeos/drive/file_system_util.h" +#include "chrome/browser/chromeos/drive/job_scheduler.h" +#include "chrome/browser/chromeos/drive/resource_metadata.h" +#include "chrome/browser/chromeos/drive/test_util.h" +#include "chrome/browser/drive/event_logger.h" +#include "chrome/browser/drive/fake_drive_service.h" +#include "content/public/test/test_browser_thread_bundle.h" +#include "google_apis/drive/drive_api_parser.h" +#include "google_apis/drive/test_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace drive { +namespace internal { + +class TestDirectoryLoaderObserver : public ChangeListLoaderObserver { + public: + explicit TestDirectoryLoaderObserver(DirectoryLoader* loader) + : loader_(loader) { + loader_->AddObserver(this); + } + + virtual ~TestDirectoryLoaderObserver() { + loader_->RemoveObserver(this); + } + + const std::set<base::FilePath>& changed_directories() const { + return changed_directories_; + } + void clear_changed_directories() { changed_directories_.clear(); } + + // ChageListObserver overrides: + virtual void OnDirectoryChanged( + const base::FilePath& directory_path) OVERRIDE { + changed_directories_.insert(directory_path); + } + + private: + DirectoryLoader* loader_; + std::set<base::FilePath> changed_directories_; + + DISALLOW_COPY_AND_ASSIGN(TestDirectoryLoaderObserver); +}; + +class DirectoryLoaderTest : public testing::Test { + protected: + virtual void SetUp() OVERRIDE { + ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); + pref_service_.reset(new TestingPrefServiceSimple); + test_util::RegisterDrivePrefs(pref_service_->registry()); + + logger_.reset(new EventLogger); + + drive_service_.reset(new FakeDriveService); + ASSERT_TRUE(drive_service_->LoadResourceListForWapi( + "gdata/root_feed.json")); + ASSERT_TRUE(drive_service_->LoadAccountMetadataForWapi( + "gdata/account_metadata.json")); + + scheduler_.reset(new JobScheduler(pref_service_.get(), + logger_.get(), + drive_service_.get(), + base::MessageLoopProxy::current().get())); + metadata_storage_.reset(new ResourceMetadataStorage( + temp_dir_.path(), base::MessageLoopProxy::current().get())); + ASSERT_TRUE(metadata_storage_->Initialize()); + + metadata_.reset(new ResourceMetadata( + metadata_storage_.get(), base::MessageLoopProxy::current().get())); + ASSERT_EQ(FILE_ERROR_OK, metadata_->Initialize()); + + cache_.reset(new FileCache(metadata_storage_.get(), + temp_dir_.path(), + base::MessageLoopProxy::current().get(), + NULL /* free_disk_space_getter */)); + ASSERT_TRUE(cache_->Initialize()); + + about_resource_loader_.reset(new AboutResourceLoader(scheduler_.get())); + loader_controller_.reset(new LoaderController); + directory_loader_.reset( + new DirectoryLoader(logger_.get(), + base::MessageLoopProxy::current().get(), + metadata_.get(), + scheduler_.get(), + drive_service_.get(), + about_resource_loader_.get(), + loader_controller_.get())); + } + + // Adds a new file to the root directory of the service. + scoped_ptr<google_apis::ResourceEntry> AddNewFile(const std::string& title) { + google_apis::GDataErrorCode error = google_apis::GDATA_FILE_ERROR; + scoped_ptr<google_apis::ResourceEntry> entry; + drive_service_->AddNewFile( + "text/plain", + "content text", + drive_service_->GetRootResourceId(), + title, + false, // shared_with_me + google_apis::test_util::CreateCopyResultCallback(&error, &entry)); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(google_apis::HTTP_CREATED, error); + return entry.Pass(); + } + + content::TestBrowserThreadBundle thread_bundle_; + base::ScopedTempDir temp_dir_; + scoped_ptr<TestingPrefServiceSimple> pref_service_; + scoped_ptr<EventLogger> logger_; + scoped_ptr<FakeDriveService> drive_service_; + scoped_ptr<JobScheduler> scheduler_; + scoped_ptr<ResourceMetadataStorage, + test_util::DestroyHelperForTests> metadata_storage_; + scoped_ptr<ResourceMetadata, test_util::DestroyHelperForTests> metadata_; + scoped_ptr<FileCache, test_util::DestroyHelperForTests> cache_; + scoped_ptr<AboutResourceLoader> about_resource_loader_; + scoped_ptr<LoaderController> loader_controller_; + scoped_ptr<DirectoryLoader> directory_loader_; +}; + +TEST_F(DirectoryLoaderTest, LoadDirectoryIfNeeded_GrandRoot) { + TestDirectoryLoaderObserver observer(directory_loader_.get()); + + // Load grand root. + FileError error = FILE_ERROR_FAILED; + directory_loader_->LoadDirectoryIfNeeded( + util::GetDriveGrandRootPath(), + google_apis::test_util::CreateCopyResultCallback(&error)); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(FILE_ERROR_OK, error); + EXPECT_EQ(0U, observer.changed_directories().size()); + observer.clear_changed_directories(); + + // My Drive has resource ID. + ResourceEntry entry; + EXPECT_EQ(FILE_ERROR_OK, + metadata_->GetResourceEntryByPath(util::GetDriveMyDriveRootPath(), + &entry)); + EXPECT_EQ(drive_service_->GetRootResourceId(), entry.resource_id()); +} + +TEST_F(DirectoryLoaderTest, LoadDirectoryIfNeeded_MyDrive) { + TestDirectoryLoaderObserver observer(directory_loader_.get()); + + // My Drive does not have resource ID yet. + ResourceEntry entry; + EXPECT_EQ(FILE_ERROR_OK, + metadata_->GetResourceEntryByPath(util::GetDriveMyDriveRootPath(), + &entry)); + EXPECT_TRUE(entry.resource_id().empty()); + + // Load My Drive. + FileError error = FILE_ERROR_FAILED; + directory_loader_->LoadDirectoryIfNeeded( + util::GetDriveMyDriveRootPath(), + google_apis::test_util::CreateCopyResultCallback(&error)); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(FILE_ERROR_OK, error); + EXPECT_EQ(1U, observer.changed_directories().count( + util::GetDriveMyDriveRootPath())); + + // My Drive has resource ID. + EXPECT_EQ(FILE_ERROR_OK, + metadata_->GetResourceEntryByPath(util::GetDriveMyDriveRootPath(), + &entry)); + EXPECT_EQ(drive_service_->GetRootResourceId(), entry.resource_id()); + + // My Drive's child is present. + base::FilePath file_path = + util::GetDriveMyDriveRootPath().AppendASCII("File 1.txt"); + EXPECT_EQ(FILE_ERROR_OK, + metadata_->GetResourceEntryByPath(file_path, &entry)); +} + +TEST_F(DirectoryLoaderTest, LoadDirectoryIfNeeded_MultipleCalls) { + TestDirectoryLoaderObserver observer(directory_loader_.get()); + + // Load grand root. + FileError error = FILE_ERROR_FAILED; + directory_loader_->LoadDirectoryIfNeeded( + util::GetDriveGrandRootPath(), + google_apis::test_util::CreateCopyResultCallback(&error)); + + // Load grand root again without waiting for the result. + FileError error2 = FILE_ERROR_FAILED; + directory_loader_->LoadDirectoryIfNeeded( + util::GetDriveGrandRootPath(), + google_apis::test_util::CreateCopyResultCallback(&error2)); + base::RunLoop().RunUntilIdle(); + + // Callback is called for each method call. + EXPECT_EQ(FILE_ERROR_OK, error); + EXPECT_EQ(FILE_ERROR_OK, error2); +} + +TEST_F(DirectoryLoaderTest, Lock) { + // Lock the loader. + scoped_ptr<base::ScopedClosureRunner> lock = loader_controller_->GetLock(); + + // Start loading. + TestDirectoryLoaderObserver observer(directory_loader_.get()); + FileError error = FILE_ERROR_FAILED; + directory_loader_->LoadDirectoryIfNeeded( + util::GetDriveMyDriveRootPath(), + google_apis::test_util::CreateCopyResultCallback(&error)); + base::RunLoop().RunUntilIdle(); + + // Update is pending due to the lock. + EXPECT_TRUE(observer.changed_directories().empty()); + + // Unlock the loader, this should resume the pending udpate. + lock.reset(); + base::RunLoop().RunUntilIdle(); + EXPECT_EQ(1U, observer.changed_directories().count( + util::GetDriveMyDriveRootPath())); +} + +} // namespace internal +} // namespace drive diff --git a/chrome/browser/chromeos/drive/file_system.cc b/chrome/browser/chromeos/drive/file_system.cc index d821fe4..6a5e9d6 100644 --- a/chrome/browser/chromeos/drive/file_system.cc +++ b/chrome/browser/chromeos/drive/file_system.cc @@ -9,6 +9,7 @@ #include "base/platform_file.h" #include "base/prefs/pref_service.h" #include "chrome/browser/chromeos/drive/change_list_loader.h" +#include "chrome/browser/chromeos/drive/directory_loader.h" #include "chrome/browser/chromeos/drive/drive.pb.h" #include "chrome/browser/chromeos/drive/file_cache.h" #include "chrome/browser/chromeos/drive/file_system/copy_operation.h" @@ -230,6 +231,7 @@ FileSystem::FileSystem( FileSystem::~FileSystem() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + directory_loader_->RemoveObserver(this); change_list_loader_->RemoveObserver(this); } @@ -258,10 +260,18 @@ void FileSystem::ResetComponents() { blocking_task_runner_.get(), resource_metadata_, scheduler_, - drive_service_, about_resource_loader_.get(), loader_controller_.get())); change_list_loader_->AddObserver(this); + directory_loader_.reset(new internal::DirectoryLoader( + logger_, + blocking_task_runner_.get(), + resource_metadata_, + scheduler_, + drive_service_, + about_resource_loader_.get(), + loader_controller_.get())); + directory_loader_->AddObserver(this); sync_client_.reset(new internal::SyncClient(blocking_task_runner_.get(), observer, @@ -403,7 +413,7 @@ void FileSystem::CreateDirectory( DCHECK(!callback.is_null()); // Ensure its parent directory is loaded to the local metadata. - change_list_loader_->LoadDirectoryIfNeeded( + LoadDirectoryIfNeeded( directory_path.DirName(), base::Bind(&FileSystem::CreateDirectoryAfterLoad, weak_ptr_factory_.GetWeakPtr(), @@ -560,12 +570,11 @@ void FileSystem::GetResourceEntry( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(!callback.is_null()); - change_list_loader_->LoadDirectoryIfNeeded( - file_path.DirName(), - base::Bind(&FileSystem::GetResourceEntryAfterLoad, - weak_ptr_factory_.GetWeakPtr(), - file_path, - callback)); + LoadDirectoryIfNeeded(file_path.DirName(), + base::Bind(&FileSystem::GetResourceEntryAfterLoad, + weak_ptr_factory_.GetWeakPtr(), + file_path, + callback)); } void FileSystem::GetResourceEntryAfterLoad( @@ -597,12 +606,11 @@ void FileSystem::ReadDirectory( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(!callback.is_null()); - change_list_loader_->LoadDirectoryIfNeeded( - directory_path, - base::Bind(&FileSystem::ReadDirectoryAfterLoad, - weak_ptr_factory_.GetWeakPtr(), - directory_path, - callback)); + LoadDirectoryIfNeeded(directory_path, + base::Bind(&FileSystem::ReadDirectoryAfterLoad, + weak_ptr_factory_.GetWeakPtr(), + directory_path, + callback)); } void FileSystem::ReadDirectoryAfterLoad( @@ -930,4 +938,16 @@ void FileSystem::OpenFile(const base::FilePath& file_path, open_file_operation_->OpenFile(file_path, open_mode, mime_type, callback); } +void FileSystem::LoadDirectoryIfNeeded(const base::FilePath& directory_path, + const FileOperationCallback& callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(!callback.is_null()); + + directory_loader_->LoadDirectoryIfNeeded(directory_path, callback); + + // Also start loading all of the user's contents. + change_list_loader_->LoadIfNeeded( + base::Bind(&util::EmptyFileOperationCallback)); +} + } // namespace drive diff --git a/chrome/browser/chromeos/drive/file_system.h b/chrome/browser/chromeos/drive/file_system.h index 5842bea..08f85a1 100644 --- a/chrome/browser/chromeos/drive/file_system.h +++ b/chrome/browser/chromeos/drive/file_system.h @@ -38,6 +38,7 @@ class JobScheduler; namespace internal { class AboutResourceLoader; class ChangeListLoader; +class DirectoryLoader; class FileCache; class LoaderController; class ResourceMetadata; @@ -182,6 +183,10 @@ class FileSystem : public FileSystemInterface, // need to be recreated during the reset of resource metadata and the cache. void ResetComponents(); + // Loads the contents of the directory from the server if needed. + void LoadDirectoryIfNeeded(const base::FilePath& directory_path, + const FileOperationCallback& callback); + // Part of CreateDirectory(). Called after ChangeListLoader::LoadIfNeeded() // is called and made sure that the resource metadata is loaded. void CreateDirectoryAfterLoad(const base::FilePath& directory_path, @@ -267,6 +272,8 @@ class FileSystem : public FileSystemInterface, // The loader is used to load the change lists. scoped_ptr<internal::ChangeListLoader> change_list_loader_; + scoped_ptr<internal::DirectoryLoader> directory_loader_; + scoped_ptr<internal::SyncClient> sync_client_; ObserverList<FileSystemObserver> observers_; diff --git a/chrome/browser/chromeos/drive/file_system/operation_test_base.cc b/chrome/browser/chromeos/drive/file_system/operation_test_base.cc index 9da6e80..38089b5 100644 --- a/chrome/browser/chromeos/drive/file_system/operation_test_base.cc +++ b/chrome/browser/chromeos/drive/file_system/operation_test_base.cc @@ -126,10 +126,9 @@ void OperationTestBase::SetUp() { blocking_task_runner_.get(), metadata_.get(), scheduler_.get(), - fake_drive_service_.get(), about_resource_loader_.get(), loader_controller_.get())); - change_list_loader_->LoadForTesting( + change_list_loader_->LoadIfNeeded( google_apis::test_util::CreateCopyResultCallback(&error)); test_util::RunBlockingPoolTask(); ASSERT_EQ(FILE_ERROR_OK, error); diff --git a/chrome/browser/chromeos/drive/file_system_unittest.cc b/chrome/browser/chromeos/drive/file_system_unittest.cc index eefd9d8..158d72c 100644 --- a/chrome/browser/chromeos/drive/file_system_unittest.cc +++ b/chrome/browser/chromeos/drive/file_system_unittest.cc @@ -142,7 +142,7 @@ class FileSystemTest : public testing::Test { // Loads the full resource list via FakeDriveService. bool LoadFullResourceList() { FileError error = FILE_ERROR_FAILED; - file_system_->change_list_loader_for_testing()->LoadForTesting( + file_system_->change_list_loader_for_testing()->LoadIfNeeded( google_apis::test_util::CreateCopyResultCallback(&error)); test_util::RunBlockingPoolTask(); return error == FILE_ERROR_OK; @@ -735,9 +735,8 @@ TEST_F(FileSystemTest, LoadFileSystemFromCacheWhileOffline) { } TEST_F(FileSystemTest, ReadDirectoryWhileRefreshing) { - // Enter the "refreshing" state so the fast fetch will be performed. + // Use old timestamp so the fast fetch will be performed. ASSERT_NO_FATAL_FAILURE(SetUpTestFileSystem(USE_OLD_TIMESTAMP)); - file_system_->CheckForUpdates(); // The list of resources in "drive/root/Dir1" should be fetched. EXPECT_TRUE(ReadDirectorySync(base::FilePath( @@ -748,9 +747,8 @@ TEST_F(FileSystemTest, ReadDirectoryWhileRefreshing) { } TEST_F(FileSystemTest, GetResourceEntryNonExistentWhileRefreshing) { - // Enter the "refreshing" state so the fast fetch will be performed. + // Use old timestamp so the fast fetch will be performed. ASSERT_NO_FATAL_FAILURE(SetUpTestFileSystem(USE_OLD_TIMESTAMP)); - file_system_->CheckForUpdates(); // If an entry is not found, parent directory's resource list is fetched. EXPECT_FALSE(GetResourceEntrySync(base::FilePath( diff --git a/chrome/browser/chromeos/drive/sync_client_unittest.cc b/chrome/browser/chromeos/drive/sync_client_unittest.cc index 6144e21..151e871 100644 --- a/chrome/browser/chromeos/drive/sync_client_unittest.cc +++ b/chrome/browser/chromeos/drive/sync_client_unittest.cc @@ -146,7 +146,6 @@ class SyncClientTest : public testing::Test { base::MessageLoopProxy::current().get(), metadata_.get(), scheduler_.get(), - drive_service_.get(), about_resource_loader_.get(), loader_controller_.get())); ASSERT_NO_FATAL_FAILURE(SetUpTestData()); @@ -199,7 +198,7 @@ class SyncClientTest : public testing::Test { // Load data from the service to the metadata. FileError error = FILE_ERROR_FAILED; - change_list_loader_->LoadForTesting( + change_list_loader_->LoadIfNeeded( google_apis::test_util::CreateCopyResultCallback(&error)); base::RunLoop().RunUntilIdle(); EXPECT_EQ(FILE_ERROR_OK, error); diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 0fc76ea..4972e97 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -647,6 +647,7 @@ 'browser/chromeos/display/display_preferences_unittest.cc', 'browser/chromeos/drive/change_list_loader_unittest.cc', 'browser/chromeos/drive/change_list_processor_unittest.cc', + 'browser/chromeos/drive/directory_loader_unittest.cc', 'browser/chromeos/drive/download_handler_unittest.cc', 'browser/chromeos/drive/drive_file_stream_reader_unittest.cc', 'browser/chromeos/drive/drive_integration_service_unittest.cc', |