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/extensions/file_manager/private_api_tasks.h"
11 #include "chrome/browser/chromeos/drive/file_system_util.h"
12 #include "chrome/browser/chromeos/file_manager/file_tasks.h"
13 #include "chrome/browser/chromeos/file_manager/fileapi_util.h"
14 #include "chrome/browser/chromeos/file_manager/mime_util.h"
15 #include "chrome/browser/chromeos/fileapi/file_system_backend.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "webkit/browser/fileapi/file_system_context.h"
18 #include "webkit/browser/fileapi/file_system_url.h"
20 using fileapi::FileSystemURL;
22 namespace extensions {
26 const char kInvalidFileUrl[] = "Invalid file URL";
28 // Make a set of unique filename suffixes out of the list of file URLs.
29 std::set<std::string> GetUniqueSuffixes(
30 const std::vector<std::string>& file_url_list,
31 const fileapi::FileSystemContext* context) {
32 std::set<std::string> suffixes;
33 for (size_t i = 0; i < file_url_list.size(); ++i) {
34 const FileSystemURL url = context->CrackURL(GURL(file_url_list[i]));
35 if (!url.is_valid() || url.path().empty())
36 return std::set<std::string>();
37 // We'll skip empty suffixes.
38 if (!url.path().Extension().empty())
39 suffixes.insert(url.path().Extension());
44 // Make a set of unique MIME types out of the list of MIME types.
45 std::set<std::string> GetUniqueMimeTypes(
46 const std::vector<std::string>& mime_type_list) {
47 std::set<std::string> mime_types;
48 for (size_t i = 0; i < mime_type_list.size(); ++i) {
49 const std::string mime_type = mime_type_list[i];
50 // We'll skip empty MIME types and existing MIME types.
51 if (!mime_type.empty())
52 mime_types.insert(mime_type);
59 bool FileBrowserPrivateExecuteTaskFunction::RunImpl() {
60 using extensions::api::file_browser_private::ExecuteTask::Params;
61 using extensions::api::file_browser_private::ExecuteTask::Results::Create;
62 const scoped_ptr<Params> params(Params::Create(*args_));
63 EXTENSION_FUNCTION_VALIDATE(params);
65 file_manager::file_tasks::TaskDescriptor task;
66 if (!file_manager::file_tasks::ParseTaskID(params->task_id, &task)) {
67 LOG(WARNING) << "Invalid task " << params->task_id;
69 Create(extensions::api::file_browser_private::TASK_RESULT_FAILED);
73 if (params->file_urls.empty()) {
74 results_ = Create(extensions::api::file_browser_private::TASK_RESULT_EMPTY);
79 const scoped_refptr<fileapi::FileSystemContext> file_system_context =
80 file_manager::util::GetFileSystemContextForRenderViewHost(
81 GetProfile(), render_view_host());
83 std::vector<FileSystemURL> file_urls;
84 for (size_t i = 0; i < params->file_urls.size(); i++) {
85 const FileSystemURL url =
86 file_system_context->CrackURL(GURL(params->file_urls[i]));
87 if (!chromeos::FileSystemBackend::CanHandleURL(url)) {
88 SetError(kInvalidFileUrl);
90 Create(extensions::api::file_browser_private::TASK_RESULT_FAILED);
93 file_urls.push_back(url);
96 const bool result = file_manager::file_tasks::ExecuteFileTask(
101 base::Bind(&FileBrowserPrivateExecuteTaskFunction::OnTaskExecuted, this));
104 Create(extensions::api::file_browser_private::TASK_RESULT_FAILED);
109 void FileBrowserPrivateExecuteTaskFunction::OnTaskExecuted(
110 extensions::api::file_browser_private::TaskResult result) {
112 extensions::api::file_browser_private::ExecuteTask::Results::Create(
114 SendResponse(result !=
115 extensions::api::file_browser_private::TASK_RESULT_FAILED);
118 bool FileBrowserPrivateGetFileTasksFunction::RunImpl() {
119 using extensions::api::file_browser_private::GetFileTasks::Params;
120 const scoped_ptr<Params> params(Params::Create(*args_));
121 EXTENSION_FUNCTION_VALIDATE(params);
123 if (params->file_urls.empty())
126 // MIME types can either be empty, or there needs to be one for each file.
127 if (params->mime_types.size() != params->file_urls.size() &&
128 params->mime_types.size() != 0)
131 const scoped_refptr<fileapi::FileSystemContext> file_system_context =
132 file_manager::util::GetFileSystemContextForRenderViewHost(
133 GetProfile(), render_view_host());
135 // Collect all the URLs, convert them to GURLs, and crack all the urls into
137 extensions::app_file_handler_util::PathAndMimeTypeSet path_mime_set;
138 std::vector<GURL> file_urls;
139 for (size_t i = 0; i < params->file_urls.size(); ++i) {
140 std::string mime_type;
141 if (params->mime_types.size() != 0)
142 mime_type = params->mime_types[i];
144 const GURL file_url(params->file_urls[i]);
145 fileapi::FileSystemURL file_system_url(
146 file_system_context->CrackURL(file_url));
147 if (!chromeos::FileSystemBackend::CanHandleURL(file_system_url))
149 const base::FilePath file_path = file_system_url.path();
151 file_urls.push_back(file_url);
153 // If MIME type is not provided, guess it from the file path.
154 if (mime_type.empty())
155 mime_type = file_manager::util::GetMimeTypeForPath(file_path);
157 path_mime_set.insert(std::make_pair(file_path, mime_type));
160 std::vector<file_manager::file_tasks::FullTaskDescriptor> tasks;
161 file_manager::file_tasks::FindAllTypesOfTasks(
163 drive::util::GetDriveAppRegistryByProfile(GetProfile()),
168 // Convert the tasks into JSON compatible objects.
169 using api::file_browser_private::FileTask;
170 std::vector<linked_ptr<FileTask> > results;
171 for (size_t i = 0; i < tasks.size(); ++i) {
172 const file_manager::file_tasks::FullTaskDescriptor& task = tasks[i];
173 const linked_ptr<FileTask> converted(new FileTask);
174 converted->task_id = file_manager::file_tasks::TaskDescriptorToId(
175 task.task_descriptor());
176 if (!task.icon_url().is_empty())
177 converted->icon_url = task.icon_url().spec();
178 converted->title = task.task_title();
179 converted->is_default = task.is_default();
180 results.push_back(converted);
182 results_ = extensions::api::file_browser_private::GetFileTasks::Results::
188 bool FileBrowserPrivateSetDefaultTaskFunction::RunImpl() {
189 using extensions::api::file_browser_private::SetDefaultTask::Params;
190 const scoped_ptr<Params> params(Params::Create(*args_));
191 EXTENSION_FUNCTION_VALIDATE(params);
193 const scoped_refptr<fileapi::FileSystemContext> file_system_context =
194 file_manager::util::GetFileSystemContextForRenderViewHost(
195 GetProfile(), render_view_host());
197 const std::set<std::string> suffixes =
198 GetUniqueSuffixes(params->file_urls, file_system_context.get());
200 // MIME types are an optional parameter.
201 std::set<std::string> mime_types;
202 if (params->mime_types && !params->mime_types->empty()) {
203 if (params->mime_types->size() != params->file_urls.size())
205 mime_types = GetUniqueMimeTypes(*params->mime_types);
208 // If there weren't any mime_types, and all the suffixes were blank,
209 // then we "succeed", but don't actually associate with anything.
210 // Otherwise, any time we set the default on a file with no extension
211 // on the local drive, we'd fail.
212 // TODO(gspencer): Fix file manager so that it never tries to set default in
213 // cases where extensionless local files are part of the selection.
214 if (suffixes.empty() && mime_types.empty()) {
215 SetResult(new base::FundamentalValue(true));
219 file_manager::file_tasks::UpdateDefaultTask(
220 GetProfile()->GetPrefs(), params->task_id, suffixes, mime_types);
224 } // namespace extensions