diff options
Diffstat (limited to 'chrome/browser/chromeos/drive')
8 files changed, 338 insertions, 171 deletions
diff --git a/chrome/browser/chromeos/drive/change_list_loader.cc b/chrome/browser/chromeos/drive/change_list_loader.cc index 40036ba4b..6f7e2d3 100644 --- a/chrome/browser/chromeos/drive/change_list_loader.cc +++ b/chrome/browser/chromeos/drive/change_list_loader.cc @@ -101,27 +101,6 @@ void ChangeListLoader::LoadDirectoryFromServer( callback)); } -void ChangeListLoader::SearchFromServer( - const std::string& search_query, - const GURL& next_feed, - const LoadFeedListCallback& callback) { - DCHECK(!callback.is_null()); - - if (next_feed.is_empty()) { - // This is first request for the |search_query|. - scheduler_->Search( - search_query, - base::Bind(&ChangeListLoader::SearchFromServerAfterGetResourceList, - weak_ptr_factory_.GetWeakPtr(), callback)); - } else { - // There is the remaining result so fetch it. - scheduler_->ContinueGetResourceList( - next_feed, - base::Bind(&ChangeListLoader::SearchFromServerAfterGetResourceList, - weak_ptr_factory_.GetWeakPtr(), callback)); - } -} - void ChangeListLoader::UpdateFromFeed( scoped_ptr<google_apis::AboutResource> about_resource, ScopedVector<ChangeList> change_lists, @@ -707,26 +686,6 @@ void ChangeListLoader::OnGetAppList(google_apis::GDataErrorCode status, webapps_registry_->UpdateFromAppList(*app_list); } -void ChangeListLoader::SearchFromServerAfterGetResourceList( - const LoadFeedListCallback& callback, - google_apis::GDataErrorCode status, - scoped_ptr<google_apis::ResourceList> resource_list) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(!callback.is_null()); - - FileError error = util::GDataToFileError(status); - if (error != FILE_ERROR_OK) { - callback.Run(ScopedVector<ChangeList>(), error); - return; - } - - DCHECK(resource_list); - - ScopedVector<ChangeList> change_lists; - change_lists.push_back(new ChangeList(*resource_list)); - callback.Run(change_lists.Pass(), FILE_ERROR_OK); -} - void ChangeListLoader::NotifyDirectoryChangedAfterApplyFeed( bool should_notify_changed_directories, base::Time start_time, diff --git a/chrome/browser/chromeos/drive/change_list_loader.h b/chrome/browser/chromeos/drive/change_list_loader.h index 516f601..f69340e 100644 --- a/chrome/browser/chromeos/drive/change_list_loader.h +++ b/chrome/browser/chromeos/drive/change_list_loader.h @@ -91,15 +91,6 @@ class ChangeListLoader { void LoadDirectoryFromServer(const std::string& directory_resource_id, const FileOperationCallback& callback); - // Starts retrieving search results for |search_query| from the server. - // If |next_feed| is set, this is the feed url that will be fetched. - // If |next_feed| is an empty string, the default URL is used. - // Upon completion, |callback| is invoked. - // |callback| must not be null. - void SearchFromServer(const std::string& search_query, - const GURL& next_feed, - const LoadFeedListCallback& callback); - // TODO(satorux): Make this private. crbug.com/232208 // Updates whole directory structure feeds collected in |feed_list|. // Record file statistics as UMA histograms. @@ -262,13 +253,6 @@ class ChangeListLoader { void OnGetAppList(google_apis::GDataErrorCode status, scoped_ptr<google_apis::AppList> app_list); - // Part of SearchFromServer(). - // Processes the ResourceList received from server and passes to |callback|. - void SearchFromServerAfterGetResourceList( - const LoadFeedListCallback& callback, - google_apis::GDataErrorCode status, - scoped_ptr<google_apis::ResourceList> resource_list); - // Part of UpdateFromFeed(). // Callback for ChangeListProcessor::ApplyFeeds. void NotifyDirectoryChangedAfterApplyFeed(bool should_notify, diff --git a/chrome/browser/chromeos/drive/file_system.cc b/chrome/browser/chromeos/drive/file_system.cc index bfffa60..d7c2d70 100644 --- a/chrome/browser/chromeos/drive/file_system.cc +++ b/chrome/browser/chromeos/drive/file_system.cc @@ -1213,84 +1213,18 @@ void FileSystem::OnGetAboutResource( about_resource->quota_bytes_used()); } -void FileSystem::OnSearch(const SearchCallback& search_callback, - ScopedVector<ChangeList> change_lists, - FileError error) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - DCHECK(!search_callback.is_null()); - - if (error != FILE_ERROR_OK) { - search_callback.Run(error, - GURL(), - scoped_ptr<std::vector<SearchResultInfo> >()); - return; - } - - // The search results will be returned using virtual directory. - // The directory is not really part of the file system, so it has no parent or - // root. - std::vector<SearchResultInfo>* results(new std::vector<SearchResultInfo>()); - scoped_ptr<std::vector<SearchResultInfo> > result_vec(results); - - DCHECK_EQ(1u, change_lists.size()); - const ChangeList* change_list = change_lists[0]; - - // TODO(tbarzic): Limit total number of returned results for the query. - const GURL& next_feed = change_list->next_url(); - - const base::Closure callback = base::Bind( - search_callback, FILE_ERROR_OK, next_feed, base::Passed(&result_vec)); - - const std::vector<ResourceEntry>& entries = change_list->entries(); - if (entries.empty()) { - callback.Run(); - return; - } - - DVLOG(1) << "OnSearch number of entries=" << entries.size(); - // Go through all entries generated by the feed and add them to the search - // result directory. - for (size_t i = 0; i < entries.size(); ++i) { - // Run the callback if this is the last iteration of the loop. - const bool should_run_callback = (i + 1 == entries.size()); - const ResourceEntry& entry = entries[i]; - - const GetEntryInfoWithFilePathCallback entry_info_callback = - base::Bind(&FileSystem::AddToSearchResults, - weak_ptr_factory_.GetWeakPtr(), - results, - should_run_callback, - callback); - - resource_metadata_->RefreshEntryOnUIThread(entry, entry_info_callback); - } -} - -void FileSystem::AddToSearchResults( - std::vector<SearchResultInfo>* results, - bool should_run_callback, - const base::Closure& callback, - FileError error, - const base::FilePath& drive_file_path, - scoped_ptr<ResourceEntry> entry) { +void FileSystem::OnSearch(const SearchCallback& callback, + FileError error, + bool is_update_needed, + const GURL& next_feed, + scoped_ptr<std::vector<SearchResultInfo> > result) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(!callback.is_null()); - // If a result is not present in our local file system snapshot, call - // CheckForUpdates to refresh the snapshot with a delta feed. This may happen - // if the entry has recently been added to the drive (and we still haven't - // received its delta feed). - if (error == FILE_ERROR_OK) { - DCHECK(entry.get()); - results->push_back(SearchResultInfo(drive_file_path, *entry.get())); - DVLOG(1) << "AddToSearchResults " << drive_file_path.value(); - } else if (error == FILE_ERROR_NOT_FOUND) { + if (is_update_needed) CheckForUpdates(); - } else { - NOTREACHED(); - } - if (should_run_callback) - callback.Run(); + callback.Run(error, next_feed, result.Pass()); } void FileSystem::Search(const std::string& search_query, @@ -1299,12 +1233,11 @@ void FileSystem::Search(const std::string& search_query, DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(!callback.is_null()); - change_list_loader_->SearchFromServer( - search_query, - next_feed, - base::Bind(&FileSystem::OnSearch, - weak_ptr_factory_.GetWeakPtr(), - callback)); + drive_operations_.Search(search_query, + next_feed, + base::Bind(&FileSystem::OnSearch, + weak_ptr_factory_.GetWeakPtr(), + callback)); } void FileSystem::SearchMetadata(const std::string& query, diff --git a/chrome/browser/chromeos/drive/file_system.h b/chrome/browser/chromeos/drive/file_system.h index 0907cc4..ff4dd29 100644 --- a/chrome/browser/chromeos/drive/file_system.h +++ b/chrome/browser/chromeos/drive/file_system.h @@ -188,25 +188,12 @@ class FileSystem : public FileSystemInterface, // Called on preference change. void OnDisableDriveHostedFilesChanged(); - // Callback passed to ChangeListLoader from |Search| method. - // |callback| is that should be run with data received. It must not be null. - // |change_lists| is the document feed for content search. - // |error| is the error code returned by ChangeListLoader. + // Part of Search(). Called after DriveOperations::Search is completed. void OnSearch(const SearchCallback& callback, - ScopedVector<ChangeList> change_lists, - FileError error); - - // Callback for ResourceMetadata::RefreshEntry, from OnSearch. - // Adds |drive_file_path| to |results|. When |entry| is not present in - // the local file system snapshot, it is not added to |results|. Instead, - // CheckForUpdates is called. Runs |callback| with |results| if - // |should_run_callback| is true. - void AddToSearchResults(std::vector<SearchResultInfo>* results, - bool should_run_callback, - const base::Closure& callback, - FileError error, - const base::FilePath& drive_file_path, - scoped_ptr<ResourceEntry> entry); + FileError error, + bool is_update_needed, + const GURL& next_feed, + scoped_ptr<std::vector<SearchResultInfo> > result); // Part of CreateDirectory(). Called after ChangeListLoader::LoadIfNeeded() // is called and made sure that the resource metadata is loaded. diff --git a/chrome/browser/chromeos/drive/file_system/drive_operations.cc b/chrome/browser/chromeos/drive/file_system/drive_operations.cc index 5dab6c9..e69ee0f 100644 --- a/chrome/browser/chromeos/drive/file_system/drive_operations.cc +++ b/chrome/browser/chromeos/drive/file_system/drive_operations.cc @@ -10,6 +10,7 @@ #include "chrome/browser/chromeos/drive/file_system/create_file_operation.h" #include "chrome/browser/chromeos/drive/file_system/move_operation.h" #include "chrome/browser/chromeos/drive/file_system/remove_operation.h" +#include "chrome/browser/chromeos/drive/file_system/search_operation.h" #include "chrome/browser/chromeos/drive/file_system/update_operation.h" #include "content/public/browser/browser_thread.h" @@ -46,22 +47,25 @@ void DriveOperations::Init( metadata, observer)); create_file_operation_.reset( - new file_system::CreateFileOperation(job_scheduler, - file_system, - metadata, - blocking_task_runner)); - move_operation_.reset(new file_system::MoveOperation(job_scheduler, - metadata, - observer)); - remove_operation_.reset(new file_system::RemoveOperation(job_scheduler, - cache, - metadata, - observer)); - update_operation_.reset(new file_system::UpdateOperation(cache, - metadata, - job_scheduler, - blocking_task_runner, - observer)); + new CreateFileOperation(job_scheduler, + file_system, + metadata, + blocking_task_runner)); + move_operation_.reset(new MoveOperation(job_scheduler, + metadata, + observer)); + remove_operation_.reset(new RemoveOperation(job_scheduler, + cache, + metadata, + observer)); + update_operation_.reset(new UpdateOperation(cache, + metadata, + job_scheduler, + blocking_task_runner, + observer)); + search_operation_.reset(new SearchOperation(blocking_task_runner, + job_scheduler, + metadata)); } void DriveOperations::InitForTesting(CopyOperation* copy_operation, @@ -158,5 +162,14 @@ void DriveOperations::UpdateFileByResourceId( update_operation_->UpdateFileByResourceId(resource_id, context, callback); } +void DriveOperations::Search(const std::string& search_query, + const GURL& next_feed, + const SearchOperationCallback& callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(!callback.is_null()); + + search_operation_->Search(search_query, next_feed, callback); +} + } // namespace file_system } // namespace drive diff --git a/chrome/browser/chromeos/drive/file_system/drive_operations.h b/chrome/browser/chromeos/drive/file_system/drive_operations.h index 4c8c3a9..453377a 100644 --- a/chrome/browser/chromeos/drive/file_system/drive_operations.h +++ b/chrome/browser/chromeos/drive/file_system/drive_operations.h @@ -32,6 +32,22 @@ class MoveOperation; class OperationObserver; class RemoveOperation; class UpdateOperation; +class SearchOperation; + +// Callback for DriveOperations::Search. +// On success, |error| is FILE_ERROR_OK, and remaining arguments are valid to +// use. if |is_update_needed| is true, some mismatch is found between +// the result from the server and local metadata, so the caller should update +// the resource metadata. +// |next_feed| is the URL to fetch the remaining result from the server. Maybe +// empty if there is no more results. +// On error, |error| is set to other than FILE_ERROR_OK, and the caller +// shouldn't use remaining arguments. +typedef base::Callback<void(FileError error, + bool is_update_needed, + const GURL& next_feed, + scoped_ptr<std::vector<SearchResultInfo> > result)> + SearchOperationCallback; // Passes notifications from Drive operations back to the file system. class DriveOperations { @@ -103,6 +119,12 @@ class DriveOperations { DriveClientContext context, const FileOperationCallback& callback); + // Wrapper function for search_operation_. + // |callback| must not be null. + void Search(const std::string& search_query, + const GURL& next_feed, + const SearchOperationCallback& callback); + private: scoped_ptr<CopyOperation> copy_operation_; scoped_ptr<CreateDirectoryOperation> create_directory_operation_; @@ -110,6 +132,7 @@ class DriveOperations { scoped_ptr<MoveOperation> move_operation_; scoped_ptr<RemoveOperation> remove_operation_; scoped_ptr<UpdateOperation> update_operation_; + scoped_ptr<SearchOperation> search_operation_; }; } // namespace file_system diff --git a/chrome/browser/chromeos/drive/file_system/search_operation.cc b/chrome/browser/chromeos/drive/file_system/search_operation.cc new file mode 100644 index 0000000..76ce0f1 --- /dev/null +++ b/chrome/browser/chromeos/drive/file_system/search_operation.cc @@ -0,0 +1,181 @@ +// Copyright 2013 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/file_system/search_operation.h" + +#include <string> +#include <vector> + +#include "base/bind.h" +#include "base/bind_helpers.h" +#include "base/callback.h" +#include "base/sequenced_task_runner.h" +#include "base/sequenced_task_runner.h" +#include "base/task_runner_util.h" +#include "chrome/browser/chromeos/drive/file_system_util.h" +#include "chrome/browser/chromeos/drive/job_scheduler.h" +#include "chrome/browser/chromeos/drive/resource_entry_conversion.h" +#include "chrome/browser/chromeos/drive/resource_metadata.h" +#include "chrome/browser/google_apis/gdata_wapi_parser.h" +#include "content/public/browser/browser_thread.h" +#include "googleurl/src/gurl.h" + +using content::BrowserThread; + +namespace drive { +namespace file_system { +namespace { + +// Refreshes entries of |resource_metadata| based on |resource_list|, and +// returns the result. |is_update_needed| will be set to true, if an +// inconsitency is found between |resource_list| and |resource_metadata|. +// Refreshed entries will be stored into |result|. +FileError RefreshEntriesOnBlockingPool( + internal::ResourceMetadata* resource_metadata, + scoped_ptr<google_apis::ResourceList> resource_list, + bool* is_update_needed, + std::vector<SearchResultInfo>* result) { + DCHECK(resource_metadata); + DCHECK(is_update_needed); + DCHECK(result); + + const ScopedVector<google_apis::ResourceEntry>& entries = + resource_list->entries(); + result->reserve(entries.size()); + for (size_t i = 0; i < entries.size(); ++i) { + ResourceEntry entry = ConvertToResourceEntry(*entries[i]); + base::FilePath drive_file_path; + FileError error = resource_metadata->RefreshEntry( + entry, &drive_file_path, &entry); + if (error == FILE_ERROR_OK) { + result->push_back(SearchResultInfo(drive_file_path, entry)); + } else if (error == FILE_ERROR_NOT_FOUND) { + // If a result is not present in our local resource metadata, + // it is necessary to update the resource metadata. + // This may happen if the entry has recently been added to the drive (and + // we haven't received the delta update feed yet). + // This is not a fatal error, so skip to add the result, but notify + // the caller that the update is needed. + *is_update_needed = true; + } else { + // Otherwise, it is a fatal error. Give up to return the search result. + return error; + } + } + + return FILE_ERROR_OK; +} + +} // namespace + +SearchOperation::SearchOperation( + base::SequencedTaskRunner* blocking_task_runner, + JobScheduler* scheduler, + internal::ResourceMetadata* resource_metadata) + : blocking_task_runner_(blocking_task_runner), + scheduler_(scheduler), + resource_metadata_(resource_metadata), + weak_ptr_factory_(this) { +} + +SearchOperation::~SearchOperation() { +} + +void SearchOperation::Search(const std::string& search_query, + const GURL& next_feed, + const SearchOperationCallback& callback) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(!callback.is_null()); + + if (next_feed.is_empty()) { + // This is first request for the |search_query|. + scheduler_->Search( + search_query, + base::Bind(&SearchOperation::SearchAfterGetResourceList, + weak_ptr_factory_.GetWeakPtr(), callback)); + } else { + // There is the remaining result so fetch it. + scheduler_->ContinueGetResourceList( + next_feed, + base::Bind(&SearchOperation::SearchAfterGetResourceList, + weak_ptr_factory_.GetWeakPtr(), callback)); + } +} + +void SearchOperation::SearchAfterGetResourceList( + const SearchOperationCallback& callback, + google_apis::GDataErrorCode gdata_error, + scoped_ptr<google_apis::ResourceList> resource_list) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(!callback.is_null()); + + FileError error = util::GDataToFileError(gdata_error); + if (error != FILE_ERROR_OK) { + callback.Run( + error, false, GURL(), scoped_ptr<std::vector<SearchResultInfo> >()); + return; + } + + DCHECK(resource_list); + + GURL next_feed; + resource_list->GetNextFeedURL(&next_feed); + + LOG(ERROR) << "Search Result: " << resource_list->entries().size(); + + // The search results will be returned using virtual directory. + // The directory is not really part of the file system, so it has no parent or + // root. + scoped_ptr<std::vector<SearchResultInfo> > result( + new std::vector<SearchResultInfo>); + if (resource_list->entries().empty()) { + // Short cut. If the resource entry is empty, we don't need to refresh + // the resource metadata. + callback.Run(FILE_ERROR_OK, false, next_feed, result.Pass()); + return; + } + + bool* is_update_needed = new bool(false); + std::vector<SearchResultInfo>* result_ptr = result.get(); + base::PostTaskAndReplyWithResult( + blocking_task_runner_, + FROM_HERE, + base::Bind(&RefreshEntriesOnBlockingPool, + resource_metadata_, + base::Passed(&resource_list), + is_update_needed, + result_ptr), + base::Bind(&SearchOperation::SearchAfterRefreshEntry, + weak_ptr_factory_.GetWeakPtr(), + callback, + next_feed, + base::Owned(is_update_needed), + base::Passed(&result))); +} + +void SearchOperation::SearchAfterRefreshEntry( + const SearchOperationCallback& callback, + const GURL& next_feed, + bool* is_update_needed, + scoped_ptr<std::vector<SearchResultInfo> > result, + FileError error) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(!callback.is_null()); + DCHECK(is_update_needed); + DCHECK(result); + + if (error != FILE_ERROR_OK) { + callback.Run( + error, false, GURL(), scoped_ptr<std::vector<SearchResultInfo> >()); + return; + } + + LOG(ERROR) << "Search Result2: " << result->size(); + LOG(ERROR) << "Is update needed: " << (*is_update_needed ? "true" : "false"); + + callback.Run(error, *is_update_needed, next_feed, result.Pass()); +} + +} // namespace file_system +} // namespace drive diff --git a/chrome/browser/chromeos/drive/file_system/search_operation.h b/chrome/browser/chromeos/drive/file_system/search_operation.h new file mode 100644 index 0000000..36a7594 --- /dev/null +++ b/chrome/browser/chromeos/drive/file_system/search_operation.h @@ -0,0 +1,87 @@ +// Copyright 2013 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. + +#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_SEARCH_OPERATION_H_ +#define CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_SEARCH_OPERATION_H_ + +#include "base/basictypes.h" +#include "base/callback_forward.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "chrome/browser/chromeos/drive/file_errors.h" +#include "chrome/browser/chromeos/drive/file_system/drive_operations.h" +#include "chrome/browser/chromeos/drive/file_system_interface.h" +#include "chrome/browser/google_apis/gdata_errorcode.h" + +class GURL; + +namespace base { +class SequencedTaskRunner; +} // namespace base + +namespace google_apis { +class ResourceEntry; +} // namespace google_apis + +namespace drive { + +class JobScheduler; + +namespace internal { +class ResourceMetadata; +} // namespace internal + +namespace file_system { + +// This class encapsulates the drive Search function. It is responsible for +// sending the request to the drive API. +class SearchOperation { + public: + SearchOperation(base::SequencedTaskRunner* blocking_task_runner_, + JobScheduler* job_scheduler, + internal::ResourceMetadata* resource_metadata); + ~SearchOperation(); + + // Performs server side content search operation for |search_query|. + // If |next_feed| is set, this is the feed url that will be fetched. + // Upon completion, |callback| will be called with the result. + // This is implementation of FileSystemInterface::Search() method. + // + // |callback| must not be null. + void Search(const std::string& search_query, + const GURL& next_feed, + const SearchOperationCallback& callback); + + private: + // Part of Search(). This is called after the ResourceList is fetched from + // the server. + void SearchAfterGetResourceList( + const SearchOperationCallback& callback, + google_apis::GDataErrorCode gdata_error, + scoped_ptr<google_apis::ResourceList> resource_list); + + // Part of Search(). This is called after the RefreshEntryOnBlockingPool + // is completed. + void SearchAfterRefreshEntry( + const SearchOperationCallback& callback, + const GURL& next_feed, + bool* is_update_needed, + scoped_ptr<std::vector<SearchResultInfo> > result, + FileError error); + + scoped_refptr<base::SequencedTaskRunner> blocking_task_runner_; + JobScheduler* scheduler_; // Not owned. + internal::ResourceMetadata* resource_metadata_; // Not owned. + + // Note: This should remain the last member so it'll be destroyed and + // invalidate the weak pointers before any other members are destroyed. + base::WeakPtrFactory<SearchOperation> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(SearchOperation); +}; + +} // namespace file_system +} // namespace drive + +#endif // CHROME_BROWSER_CHROMEOS_DRIVE_FILE_SYSTEM_SEARCH_OPERATION_H_ |