Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / drive / file_system / search_operation.cc
blobd1663f844fbf9eef06335dae59073f2a0476b533
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 "chrome/browser/chromeos/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 "chrome/browser/chromeos/drive/file_system_util.h"
15 #include "chrome/browser/chromeos/drive/job_scheduler.h"
16 #include "chrome/browser/chromeos/drive/resource_entry_conversion.h"
17 #include "chrome/browser/chromeos/drive/resource_metadata.h"
18 #include "content/public/browser/browser_thread.h"
19 #include "google_apis/drive/gdata_wapi_parser.h"
20 #include "url/gurl.h"
22 using content::BrowserThread;
24 namespace drive {
25 namespace file_system {
26 namespace {
28 // Computes the path of each item in |resource_list| returned from the server
29 // and stores to |result|, by using |resource_metadata|. If the metadata is not
30 // up-to-date and did not contain an item, adds the item to "drive/other" for
31 // temporally assigning a path.
32 FileError ResolveSearchResultOnBlockingPool(
33 internal::ResourceMetadata* resource_metadata,
34 scoped_ptr<google_apis::ResourceList> resource_list,
35 std::vector<SearchResultInfo>* result) {
36 DCHECK(resource_metadata);
37 DCHECK(result);
39 const ScopedVector<google_apis::ResourceEntry>& entries =
40 resource_list->entries();
41 result->reserve(entries.size());
42 for (size_t i = 0; i < entries.size(); ++i) {
43 std::string local_id;
44 FileError error = resource_metadata->GetIdByResourceId(
45 entries[i]->resource_id(), &local_id);
47 ResourceEntry entry;
48 if (error == FILE_ERROR_OK)
49 error = resource_metadata->GetResourceEntryById(local_id, &entry);
51 if (error == FILE_ERROR_NOT_FOUND) {
52 std::string original_parent_id;
53 if (!ConvertToResourceEntry(*entries[i], &entry, &original_parent_id))
54 continue; // Skip non-file entries.
56 // The result is absent in local resource metadata. This can happen if
57 // the metadata is not synced to the latest server state yet. In that
58 // case, we temporarily add the file to the special "drive/other"
59 // directory in order to assign a path, which is needed to access the
60 // file through FileSystem API.
62 // It will be moved to the right place when the metadata gets synced
63 // in normal loading process in ChangeListProcessor.
64 entry.set_parent_local_id(util::kDriveOtherDirLocalId);
65 error = resource_metadata->AddEntry(entry, &local_id);
67 if (error != FILE_ERROR_OK)
68 return error;
69 result->push_back(
70 SearchResultInfo(resource_metadata->GetFilePath(local_id),
71 entry.file_info().is_directory()));
74 return FILE_ERROR_OK;
77 } // namespace
79 SearchOperation::SearchOperation(
80 base::SequencedTaskRunner* blocking_task_runner,
81 JobScheduler* scheduler,
82 internal::ResourceMetadata* metadata)
83 : blocking_task_runner_(blocking_task_runner),
84 scheduler_(scheduler),
85 metadata_(metadata),
86 weak_ptr_factory_(this) {
89 SearchOperation::~SearchOperation() {
92 void SearchOperation::Search(const std::string& search_query,
93 const GURL& next_link,
94 const SearchCallback& callback) {
95 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
96 DCHECK(!callback.is_null());
98 if (next_link.is_empty()) {
99 // This is first request for the |search_query|.
100 scheduler_->Search(
101 search_query,
102 base::Bind(&SearchOperation::SearchAfterGetResourceList,
103 weak_ptr_factory_.GetWeakPtr(), callback));
104 } else {
105 // There is the remaining result so fetch it.
106 scheduler_->GetRemainingFileList(
107 next_link,
108 base::Bind(&SearchOperation::SearchAfterGetResourceList,
109 weak_ptr_factory_.GetWeakPtr(), callback));
113 void SearchOperation::SearchAfterGetResourceList(
114 const SearchCallback& callback,
115 google_apis::GDataErrorCode gdata_error,
116 scoped_ptr<google_apis::ResourceList> resource_list) {
117 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
118 DCHECK(!callback.is_null());
120 FileError error = GDataToFileError(gdata_error);
121 if (error != FILE_ERROR_OK) {
122 callback.Run(error, GURL(), scoped_ptr<std::vector<SearchResultInfo> >());
123 return;
126 DCHECK(resource_list);
128 GURL next_url;
129 resource_list->GetNextFeedURL(&next_url);
131 scoped_ptr<std::vector<SearchResultInfo> > result(
132 new std::vector<SearchResultInfo>);
133 if (resource_list->entries().empty()) {
134 // Short cut. If the resource entry is empty, we don't need to refresh
135 // the resource metadata.
136 callback.Run(FILE_ERROR_OK, next_url, result.Pass());
137 return;
140 std::vector<SearchResultInfo>* result_ptr = result.get();
141 base::PostTaskAndReplyWithResult(
142 blocking_task_runner_.get(),
143 FROM_HERE,
144 base::Bind(&ResolveSearchResultOnBlockingPool,
145 metadata_,
146 base::Passed(&resource_list),
147 result_ptr),
148 base::Bind(&SearchOperation::SearchAfterResolveSearchResult,
149 weak_ptr_factory_.GetWeakPtr(),
150 callback,
151 next_url,
152 base::Passed(&result)));
155 void SearchOperation::SearchAfterResolveSearchResult(
156 const SearchCallback& callback,
157 const GURL& next_link,
158 scoped_ptr<std::vector<SearchResultInfo> > result,
159 FileError error) {
160 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
161 DCHECK(!callback.is_null());
162 DCHECK(result);
164 if (error != FILE_ERROR_OK) {
165 callback.Run(error, GURL(), scoped_ptr<std::vector<SearchResultInfo> >());
166 return;
169 callback.Run(error, next_link, result.Pass());
172 } // namespace file_system
173 } // namespace drive