BookmarkManager: Fix 'new folder text field size changes on clicking it' issue.
[chromium-blink-merge.git] / components / drive / file_system / search_operation.cc
bloba0be870bf982f7d26ed10b5869973fdf2c8931ab
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "components/drive/file_system/search_operation.h"
7 #include <string>
8 #include <vector>
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/callback.h"
13 #include "base/task_runner_util.h"
14 #include "components/drive/change_list_loader.h"
15 #include "components/drive/drive_api_util.h"
16 #include "components/drive/file_system_core_util.h"
17 #include "components/drive/job_scheduler.h"
18 #include "components/drive/resource_entry_conversion.h"
19 #include "components/drive/resource_metadata.h"
20 #include "google_apis/drive/drive_api_parser.h"
21 #include "url/gurl.h"
23 namespace drive {
24 namespace file_system {
25 namespace {
27 // Computes the path of each item in |file_list| returned from the server
28 // and stores to |result|, by using |resource_metadata|. If the metadata is not
29 // up-to-date and did not contain an item, adds the item to "drive/other" for
30 // temporally assigning a path.
31 FileError ResolveSearchResultOnBlockingPool(
32 internal::ResourceMetadata* resource_metadata,
33 scoped_ptr<google_apis::FileList> file_list,
34 std::vector<SearchResultInfo>* result) {
35 DCHECK(resource_metadata);
36 DCHECK(result);
38 const ScopedVector<google_apis::FileResource>& entries = file_list->items();
39 result->reserve(entries.size());
40 for (size_t i = 0; i < entries.size(); ++i) {
41 std::string local_id;
42 FileError error = resource_metadata->GetIdByResourceId(
43 entries[i]->file_id(), &local_id);
45 ResourceEntry entry;
46 if (error == FILE_ERROR_OK)
47 error = resource_metadata->GetResourceEntryById(local_id, &entry);
49 if (error == FILE_ERROR_NOT_FOUND) {
50 std::string original_parent_id;
51 if (!ConvertFileResourceToResourceEntry(*entries[i], &entry,
52 &original_parent_id))
53 continue; // Skip non-file entries.
55 // The result is absent in local resource metadata. This can happen if
56 // the metadata is not synced to the latest server state yet. In that
57 // case, we temporarily add the file to the special "drive/other"
58 // directory in order to assign a path, which is needed to access the
59 // file through FileSystem API.
61 // It will be moved to the right place when the metadata gets synced
62 // in normal loading process in ChangeListProcessor.
63 entry.set_parent_local_id(util::kDriveOtherDirLocalId);
64 error = resource_metadata->AddEntry(entry, &local_id);
66 if (error != FILE_ERROR_OK)
67 return error;
68 base::FilePath path;
69 error = resource_metadata->GetFilePath(local_id, &path);
70 if (error != FILE_ERROR_OK)
71 return error;
72 result->push_back(SearchResultInfo(path, entry.file_info().is_directory()));
75 return FILE_ERROR_OK;
78 } // namespace
80 SearchOperation::SearchOperation(
81 base::SequencedTaskRunner* blocking_task_runner,
82 JobScheduler* scheduler,
83 internal::ResourceMetadata* metadata,
84 internal::LoaderController* loader_controller)
85 : blocking_task_runner_(blocking_task_runner),
86 scheduler_(scheduler),
87 metadata_(metadata),
88 loader_controller_(loader_controller),
89 weak_ptr_factory_(this) {
92 SearchOperation::~SearchOperation() {
95 void SearchOperation::Search(const std::string& search_query,
96 const GURL& next_link,
97 const SearchCallback& callback) {
98 DCHECK(thread_checker_.CalledOnValidThread());
99 DCHECK(!callback.is_null());
101 if (next_link.is_empty()) {
102 // This is first request for the |search_query|.
103 scheduler_->Search(
104 search_query,
105 base::Bind(&SearchOperation::SearchAfterGetFileList,
106 weak_ptr_factory_.GetWeakPtr(), callback));
107 } else {
108 // There is the remaining result so fetch it.
109 scheduler_->GetRemainingFileList(
110 next_link,
111 base::Bind(&SearchOperation::SearchAfterGetFileList,
112 weak_ptr_factory_.GetWeakPtr(), callback));
116 void SearchOperation::SearchAfterGetFileList(
117 const SearchCallback& callback,
118 google_apis::DriveApiErrorCode gdata_error,
119 scoped_ptr<google_apis::FileList> file_list) {
120 DCHECK(thread_checker_.CalledOnValidThread());
121 DCHECK(!callback.is_null());
123 FileError error = GDataToFileError(gdata_error);
124 if (error != FILE_ERROR_OK) {
125 callback.Run(error, GURL(), scoped_ptr<std::vector<SearchResultInfo> >());
126 return;
129 DCHECK(file_list);
131 GURL next_url = file_list->next_link();
133 scoped_ptr<std::vector<SearchResultInfo> > result(
134 new std::vector<SearchResultInfo>);
135 if (file_list->items().empty()) {
136 // Short cut. If the resource entry is empty, we don't need to refresh
137 // the resource metadata.
138 callback.Run(FILE_ERROR_OK, next_url, result.Pass());
139 return;
142 // ResolveSearchResultOnBlockingPool() may add entries newly created on the
143 // server to the local metadata.
144 // This may race with sync tasks so we should ask LoaderController here.
145 std::vector<SearchResultInfo>* result_ptr = result.get();
146 loader_controller_->ScheduleRun(base::Bind(
147 base::IgnoreResult(
148 &base::PostTaskAndReplyWithResult<FileError, FileError>),
149 blocking_task_runner_,
150 FROM_HERE,
151 base::Bind(&ResolveSearchResultOnBlockingPool,
152 metadata_,
153 base::Passed(&file_list),
154 result_ptr),
155 base::Bind(&SearchOperation::SearchAfterResolveSearchResult,
156 weak_ptr_factory_.GetWeakPtr(),
157 callback,
158 next_url,
159 base::Passed(&result))));
162 void SearchOperation::SearchAfterResolveSearchResult(
163 const SearchCallback& callback,
164 const GURL& next_link,
165 scoped_ptr<std::vector<SearchResultInfo> > result,
166 FileError error) {
167 DCHECK(thread_checker_.CalledOnValidThread());
168 DCHECK(!callback.is_null());
169 DCHECK(result);
171 if (error != FILE_ERROR_OK) {
172 callback.Run(error, GURL(), scoped_ptr<std::vector<SearchResultInfo> >());
173 return;
176 callback.Run(error, next_link, result.Pass());
179 } // namespace file_system
180 } // namespace drive