Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / chromeos / extensions / file_manager / private_api_tasks.cc
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.
4
5 #include "chrome/browser/chromeos/extensions/file_manager/private_api_tasks.h"
6
7 #include <set>
8 #include <string>
9 #include <vector>
10
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"
19
20 using fileapi::FileSystemURL;
21
22 namespace extensions {
23 namespace {
24
25 // Error messages.
26 const char kInvalidFileUrl[] = "Invalid file URL";
27
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());
40   }
41   return suffixes;
42 }
43
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);
53   }
54   return mime_types;
55 }
56
57 }  // namespace
58
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);
64
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;
68     results_ =
69         Create(extensions::api::file_browser_private::TASK_RESULT_FAILED);
70     return false;
71   }
72
73   if (params->file_urls.empty()) {
74     results_ = Create(extensions::api::file_browser_private::TASK_RESULT_EMPTY);
75     SendResponse(true);
76     return true;
77   }
78
79   const scoped_refptr<fileapi::FileSystemContext> file_system_context =
80       file_manager::util::GetFileSystemContextForRenderViewHost(
81           GetProfile(), render_view_host());
82
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);
89       results_ =
90           Create(extensions::api::file_browser_private::TASK_RESULT_FAILED);
91       return false;
92     }
93     file_urls.push_back(url);
94   }
95
96   const bool result = file_manager::file_tasks::ExecuteFileTask(
97       GetProfile(),
98       source_url(),
99       task,
100       file_urls,
101       base::Bind(&FileBrowserPrivateExecuteTaskFunction::OnTaskExecuted, this));
102   if (!result) {
103     results_ =
104         Create(extensions::api::file_browser_private::TASK_RESULT_FAILED);
105   }
106   return result;
107 }
108
109 void FileBrowserPrivateExecuteTaskFunction::OnTaskExecuted(
110     extensions::api::file_browser_private::TaskResult result) {
111   results_ =
112       extensions::api::file_browser_private::ExecuteTask::Results::Create(
113           result);
114   SendResponse(result !=
115                extensions::api::file_browser_private::TASK_RESULT_FAILED);
116 }
117
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);
122
123   if (params->file_urls.empty())
124     return false;
125
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)
129     return false;
130
131   const scoped_refptr<fileapi::FileSystemContext> file_system_context =
132       file_manager::util::GetFileSystemContextForRenderViewHost(
133           GetProfile(), render_view_host());
134
135   // Collect all the URLs, convert them to GURLs, and crack all the urls into
136   // file paths.
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];
143
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))
148       continue;
149     const base::FilePath file_path = file_system_url.path();
150
151     file_urls.push_back(file_url);
152
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);
156
157     path_mime_set.insert(std::make_pair(file_path, mime_type));
158   }
159
160   std::vector<file_manager::file_tasks::FullTaskDescriptor> tasks;
161   file_manager::file_tasks::FindAllTypesOfTasks(
162       GetProfile(),
163       drive::util::GetDriveAppRegistryByProfile(GetProfile()),
164       path_mime_set,
165       file_urls,
166       &tasks);
167
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);
181   }
182   results_ = extensions::api::file_browser_private::GetFileTasks::Results::
183       Create(results);
184   SendResponse(true);
185   return true;
186 }
187
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);
192
193   const scoped_refptr<fileapi::FileSystemContext> file_system_context =
194       file_manager::util::GetFileSystemContextForRenderViewHost(
195           GetProfile(), render_view_host());
196
197   const std::set<std::string> suffixes =
198       GetUniqueSuffixes(params->file_urls, file_system_context.get());
199
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())
204       return false;
205     mime_types = GetUniqueMimeTypes(*params->mime_types);
206   }
207
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));
216     return true;
217   }
218
219   file_manager::file_tasks::UpdateDefaultTask(
220       GetProfile()->GetPrefs(), params->task_id, suffixes, mime_types);
221   return true;
222 }
223
224 }  // namespace extensions