Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / chrome / browser / chromeos / drive / file_system / search_operation.cc
blob8b323174f5dc4e34872aef4673b63defc65cb92f
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/change_list_loader.h"
15 #include "chrome/browser/chromeos/drive/file_system_util.h"
16 #include "chrome/browser/chromeos/drive/job_scheduler.h"
17 #include "chrome/browser/chromeos/drive/resource_entry_conversion.h"
18 #include "chrome/browser/chromeos/drive/resource_metadata.h"
19 #include "chrome/browser/drive/drive_api_util.h"
20 #include "content/public/browser/browser_thread.h"
21 #include "google_apis/drive/drive_api_parser.h"
22 #include "url/gurl.h"
24 using content::BrowserThread;
26 namespace drive {
27 namespace file_system {
28 namespace {
30 // Computes the path of each item in |file_list| returned from the server
31 // and stores to |result|, by using |resource_metadata|. If the metadata is not
32 // up-to-date and did not contain an item, adds the item to "drive/other" for
33 // temporally assigning a path.
34 FileError ResolveSearchResultOnBlockingPool(
35 internal::ResourceMetadata* resource_metadata,
36 scoped_ptr<google_apis::FileList> file_list,
37 std::vector<SearchResultInfo>* result) {
38 DCHECK(resource_metadata);
39 DCHECK(result);
41 const ScopedVector<google_apis::FileResource>& entries = file_list->items();
42 result->reserve(entries.size());
43 for (size_t i = 0; i < entries.size(); ++i) {
44 std::string local_id;
45 FileError error = resource_metadata->GetIdByResourceId(
46 entries[i]->file_id(), &local_id);
48 ResourceEntry entry;
49 if (error == FILE_ERROR_OK)
50 error = resource_metadata->GetResourceEntryById(local_id, &entry);
52 if (error == FILE_ERROR_NOT_FOUND) {
53 std::string original_parent_id;
54 if (!ConvertFileResourceToResourceEntry(*entries[i], &entry,
55 &original_parent_id))
56 continue; // Skip non-file entries.
58 // The result is absent in local resource metadata. This can happen if
59 // the metadata is not synced to the latest server state yet. In that
60 // case, we temporarily add the file to the special "drive/other"
61 // directory in order to assign a path, which is needed to access the
62 // file through FileSystem API.
64 // It will be moved to the right place when the metadata gets synced
65 // in normal loading process in ChangeListProcessor.
66 entry.set_parent_local_id(util::kDriveOtherDirLocalId);
67 error = resource_metadata->AddEntry(entry, &local_id);
69 if (error != FILE_ERROR_OK)
70 return error;
71 base::FilePath path;
72 error = resource_metadata->GetFilePath(local_id, &path);
73 if (error != FILE_ERROR_OK)
74 return error;
75 result->push_back(SearchResultInfo(path, entry.file_info().is_directory()));
78 return FILE_ERROR_OK;
81 } // namespace
83 SearchOperation::SearchOperation(
84 base::SequencedTaskRunner* blocking_task_runner,
85 JobScheduler* scheduler,
86 internal::ResourceMetadata* metadata,
87 internal::LoaderController* loader_controller)
88 : blocking_task_runner_(blocking_task_runner),
89 scheduler_(scheduler),
90 metadata_(metadata),
91 loader_controller_(loader_controller),
92 weak_ptr_factory_(this) {
95 SearchOperation::~SearchOperation() {
98 void SearchOperation::Search(const std::string& search_query,
99 const GURL& next_link,
100 const SearchCallback& callback) {
101 DCHECK_CURRENTLY_ON(BrowserThread::UI);
102 DCHECK(!callback.is_null());
104 if (next_link.is_empty()) {
105 // This is first request for the |search_query|.
106 scheduler_->Search(
107 search_query,
108 base::Bind(&SearchOperation::SearchAfterGetFileList,
109 weak_ptr_factory_.GetWeakPtr(), callback));
110 } else {
111 // There is the remaining result so fetch it.
112 scheduler_->GetRemainingFileList(
113 next_link,
114 base::Bind(&SearchOperation::SearchAfterGetFileList,
115 weak_ptr_factory_.GetWeakPtr(), callback));
119 void SearchOperation::SearchAfterGetFileList(
120 const SearchCallback& callback,
121 google_apis::DriveApiErrorCode gdata_error,
122 scoped_ptr<google_apis::FileList> file_list) {
123 DCHECK_CURRENTLY_ON(BrowserThread::UI);
124 DCHECK(!callback.is_null());
126 FileError error = GDataToFileError(gdata_error);
127 if (error != FILE_ERROR_OK) {
128 callback.Run(error, GURL(), scoped_ptr<std::vector<SearchResultInfo> >());
129 return;
132 DCHECK(file_list);
134 GURL next_url = file_list->next_link();
136 scoped_ptr<std::vector<SearchResultInfo> > result(
137 new std::vector<SearchResultInfo>);
138 if (file_list->items().empty()) {
139 // Short cut. If the resource entry is empty, we don't need to refresh
140 // the resource metadata.
141 callback.Run(FILE_ERROR_OK, next_url, result.Pass());
142 return;
145 // ResolveSearchResultOnBlockingPool() may add entries newly created on the
146 // server to the local metadata.
147 // This may race with sync tasks so we should ask LoaderController here.
148 std::vector<SearchResultInfo>* result_ptr = result.get();
149 loader_controller_->ScheduleRun(base::Bind(
150 base::IgnoreResult(
151 &base::PostTaskAndReplyWithResult<FileError, FileError>),
152 blocking_task_runner_,
153 FROM_HERE,
154 base::Bind(&ResolveSearchResultOnBlockingPool,
155 metadata_,
156 base::Passed(&file_list),
157 result_ptr),
158 base::Bind(&SearchOperation::SearchAfterResolveSearchResult,
159 weak_ptr_factory_.GetWeakPtr(),
160 callback,
161 next_url,
162 base::Passed(&result))));
165 void SearchOperation::SearchAfterResolveSearchResult(
166 const SearchCallback& callback,
167 const GURL& next_link,
168 scoped_ptr<std::vector<SearchResultInfo> > result,
169 FileError error) {
170 DCHECK_CURRENTLY_ON(BrowserThread::UI);
171 DCHECK(!callback.is_null());
172 DCHECK(result);
174 if (error != FILE_ERROR_OK) {
175 callback.Run(error, GURL(), scoped_ptr<std::vector<SearchResultInfo> >());
176 return;
179 callback.Run(error, next_link, result.Pass());
182 } // namespace file_system
183 } // namespace drive