private_api_tasks.cc revision 424c4d7b64af9d0d8fd9624f381f469654d5e3d2
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 "chrome/browser/chromeos/extensions/file_manager/file_tasks.h" 8#include "chrome/browser/chromeos/extensions/file_manager/fileapi_util.h" 9#include "chrome/browser/chromeos/extensions/file_manager/mime_util.h" 10#include "chrome/browser/chromeos/extensions/file_manager/private_api_util.h" 11#include "chrome/browser/chromeos/fileapi/file_system_backend.h" 12#include "chrome/browser/profiles/profile.h" 13#include "content/public/browser/render_view_host.h" 14#include "webkit/browser/fileapi/file_system_context.h" 15#include "webkit/browser/fileapi/file_system_url.h" 16 17using extensions::app_file_handler_util::PathAndMimeTypeSet; 18using extensions::Extension; 19using fileapi::FileSystemURL; 20 21namespace extensions { 22namespace { 23 24// Error messages. 25const char kInvalidFileUrl[] = "Invalid file URL"; 26 27// Make a set of unique filename suffixes out of the list of file URLs. 28std::set<std::string> GetUniqueSuffixes(base::ListValue* file_url_list, 29 fileapi::FileSystemContext* context) { 30 std::set<std::string> suffixes; 31 for (size_t i = 0; i < file_url_list->GetSize(); ++i) { 32 std::string url_str; 33 if (!file_url_list->GetString(i, &url_str)) 34 return std::set<std::string>(); 35 FileSystemURL url = context->CrackURL(GURL(url_str)); 36 if (!url.is_valid() || url.path().empty()) 37 return std::set<std::string>(); 38 // We'll skip empty suffixes. 39 if (!url.path().Extension().empty()) 40 suffixes.insert(url.path().Extension()); 41 } 42 return suffixes; 43} 44 45// Make a set of unique MIME types out of the list of MIME types. 46std::set<std::string> GetUniqueMimeTypes(base::ListValue* mime_type_list) { 47 std::set<std::string> mime_types; 48 for (size_t i = 0; i < mime_type_list->GetSize(); ++i) { 49 std::string mime_type; 50 if (!mime_type_list->GetString(i, &mime_type)) 51 return std::set<std::string>(); 52 // We'll skip empty MIME types. 53 if (!mime_type.empty()) 54 mime_types.insert(mime_type); 55 } 56 return mime_types; 57} 58 59} // namespace 60 61FileBrowserPrivateExecuteTaskFunction::FileBrowserPrivateExecuteTaskFunction() { 62} 63 64FileBrowserPrivateExecuteTaskFunction:: 65 ~FileBrowserPrivateExecuteTaskFunction() { 66} 67 68bool FileBrowserPrivateExecuteTaskFunction::RunImpl() { 69 // First param is task id that was to the extension with getFileTasks call. 70 std::string task_id; 71 if (!args_->GetString(0, &task_id) || !task_id.size()) 72 return false; 73 74 // TODO(kaznacheev): Crack the task_id here, store it in the Executor 75 // and avoid passing it around. 76 77 // The second param is the list of files that need to be executed with this 78 // task. 79 ListValue* files_list = NULL; 80 if (!args_->GetList(1, &files_list)) 81 return false; 82 83 file_manager::file_tasks::TaskDescriptor task; 84 if (!file_manager::file_tasks::ParseTaskID(task_id, &task)) { 85 LOG(WARNING) << "Invalid task " << task_id; 86 return false; 87 } 88 89 if (!files_list->GetSize()) 90 return true; 91 92 scoped_refptr<fileapi::FileSystemContext> file_system_context = 93 file_manager::util::GetFileSystemContextForRenderViewHost( 94 profile(), render_view_host()); 95 96 std::vector<FileSystemURL> file_urls; 97 for (size_t i = 0; i < files_list->GetSize(); i++) { 98 std::string file_url_str; 99 if (!files_list->GetString(i, &file_url_str)) { 100 error_ = kInvalidFileUrl; 101 return false; 102 } 103 FileSystemURL url = file_system_context->CrackURL(GURL(file_url_str)); 104 if (!chromeos::FileSystemBackend::CanHandleURL(url)) { 105 error_ = kInvalidFileUrl; 106 return false; 107 } 108 file_urls.push_back(url); 109 } 110 111 int32 tab_id = file_manager::util::GetTabId(dispatcher()); 112 return file_manager::file_tasks::ExecuteFileTask( 113 profile(), 114 source_url(), 115 extension_->id(), 116 tab_id, 117 task, 118 file_urls, 119 base::Bind(&FileBrowserPrivateExecuteTaskFunction::OnTaskExecuted, this)); 120} 121 122void FileBrowserPrivateExecuteTaskFunction::OnTaskExecuted(bool success) { 123 SetResult(new base::FundamentalValue(success)); 124 SendResponse(true); 125} 126 127FileBrowserPrivateGetFileTasksFunction:: 128 FileBrowserPrivateGetFileTasksFunction() { 129} 130 131FileBrowserPrivateGetFileTasksFunction:: 132 ~FileBrowserPrivateGetFileTasksFunction() { 133} 134 135bool FileBrowserPrivateGetFileTasksFunction::RunImpl() { 136 // First argument is the list of files to get tasks for. 137 ListValue* files_list = NULL; 138 if (!args_->GetList(0, &files_list)) 139 return false; 140 141 if (files_list->GetSize() == 0) 142 return false; 143 144 // Second argument is the list of mime types of each of the files in the list. 145 ListValue* mime_types_list = NULL; 146 if (!args_->GetList(1, &mime_types_list)) 147 return false; 148 149 // MIME types can either be empty, or there needs to be one for each file. 150 if (mime_types_list->GetSize() != files_list->GetSize() && 151 mime_types_list->GetSize() != 0) 152 return false; 153 154 scoped_refptr<fileapi::FileSystemContext> file_system_context = 155 file_manager::util::GetFileSystemContextForRenderViewHost( 156 profile(), render_view_host()); 157 158 // Collect all the URLs, convert them to GURLs, and crack all the urls into 159 // file paths. 160 PathAndMimeTypeSet path_mime_set; 161 std::vector<GURL> file_urls; 162 std::vector<base::FilePath> file_paths; 163 for (size_t i = 0; i < files_list->GetSize(); ++i) { 164 std::string file_url_str; 165 if (!files_list->GetString(i, &file_url_str)) 166 return false; 167 168 std::string mime_type; 169 if (mime_types_list->GetSize() != 0 && 170 !mime_types_list->GetString(i, &mime_type)) 171 return false; 172 173 GURL file_url(file_url_str); 174 fileapi::FileSystemURL file_system_url( 175 file_system_context->CrackURL(file_url)); 176 if (!chromeos::FileSystemBackend::CanHandleURL(file_system_url)) 177 continue; 178 const base::FilePath file_path = file_system_url.path(); 179 180 file_urls.push_back(file_url); 181 file_paths.push_back(file_path); 182 183 // If MIME type is not provided, guess it from the file path. 184 if (mime_type.empty()) 185 mime_type = file_manager::util::GetMimeTypeForPath(file_path); 186 187 path_mime_set.insert(std::make_pair(file_path, mime_type)); 188 } 189 190 std::vector<file_manager::file_tasks::FullTaskDescriptor> tasks; 191 file_manager::file_tasks::FindAllTypesOfTasks(profile_, 192 path_mime_set, 193 file_urls, 194 file_paths, 195 &tasks); 196 // Convert the tasks into JSON format. 197 ListValue* result_list = new ListValue(); 198 for (size_t i = 0; i < tasks.size(); ++i) 199 result_list->Append(tasks[i].AsDictionaryValue().release()); 200 201 SetResult(result_list); 202 SendResponse(true); 203 return true; 204} 205 206FileBrowserPrivateSetDefaultTaskFunction:: 207 FileBrowserPrivateSetDefaultTaskFunction() { 208} 209 210FileBrowserPrivateSetDefaultTaskFunction:: 211 ~FileBrowserPrivateSetDefaultTaskFunction() { 212} 213 214bool FileBrowserPrivateSetDefaultTaskFunction::RunImpl() { 215 // First param is task id that was to the extension with setDefaultTask call. 216 std::string task_id; 217 if (!args_->GetString(0, &task_id) || !task_id.size()) 218 return false; 219 220 base::ListValue* file_url_list; 221 if (!args_->GetList(1, &file_url_list)) 222 return false; 223 224 scoped_refptr<fileapi::FileSystemContext> file_system_context = 225 file_manager::util::GetFileSystemContextForRenderViewHost( 226 profile(), render_view_host()); 227 228 std::set<std::string> suffixes = 229 GetUniqueSuffixes(file_url_list, file_system_context.get()); 230 231 // MIME types are an optional parameter. 232 base::ListValue* mime_type_list; 233 std::set<std::string> mime_types; 234 if (args_->GetList(2, &mime_type_list) && !mime_type_list->empty()) { 235 if (mime_type_list->GetSize() != file_url_list->GetSize()) 236 return false; 237 mime_types = GetUniqueMimeTypes(mime_type_list); 238 } 239 240 // If there weren't any mime_types, and all the suffixes were blank, 241 // then we "succeed", but don't actually associate with anything. 242 // Otherwise, any time we set the default on a file with no extension 243 // on the local drive, we'd fail. 244 // TODO(gspencer): Fix file manager so that it never tries to set default in 245 // cases where extensionless local files are part of the selection. 246 if (suffixes.empty() && mime_types.empty()) { 247 SetResult(new base::FundamentalValue(true)); 248 return true; 249 } 250 251 file_manager::file_tasks::UpdateDefaultTask(profile_->GetPrefs(), 252 task_id, 253 suffixes, 254 mime_types); 255 return true; 256} 257 258} // namespace extensions 259