private_api_tasks.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
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/fileapi_util.h" 13#include "chrome/browser/chromeos/fileapi/file_system_backend.h" 14#include "chrome/browser/extensions/api/file_handlers/mime_util.h" 15#include "chrome/browser/profiles/profile.h" 16#include "content/public/browser/browser_thread.h" 17#include "net/base/filename_util.h" 18#include "storage/browser/fileapi/file_system_context.h" 19#include "storage/browser/fileapi/file_system_url.h" 20 21using content::BrowserThread; 22using storage::FileSystemURL; 23 24namespace extensions { 25namespace { 26 27// Error messages. 28const char kInvalidTask[] = "Invalid task: "; 29const char kInvalidFileUrl[] = "Invalid file URL"; 30 31// Make a set of unique filename suffixes out of the list of file URLs. 32std::set<std::string> GetUniqueSuffixes( 33 const std::vector<std::string>& file_url_list, 34 const storage::FileSystemContext* context) { 35 std::set<std::string> suffixes; 36 for (size_t i = 0; i < file_url_list.size(); ++i) { 37 const FileSystemURL url = context->CrackURL(GURL(file_url_list[i])); 38 if (!url.is_valid() || url.path().empty()) 39 return std::set<std::string>(); 40 // We'll skip empty suffixes. 41 if (!url.path().Extension().empty()) 42 suffixes.insert(url.path().Extension()); 43 } 44 return suffixes; 45} 46 47// Make a set of unique MIME types out of the list of MIME types. 48std::set<std::string> GetUniqueMimeTypes( 49 const std::vector<std::string>& mime_type_list) { 50 std::set<std::string> mime_types; 51 for (size_t i = 0; i < mime_type_list.size(); ++i) { 52 const std::string mime_type = mime_type_list[i]; 53 // We'll skip empty MIME types and existing MIME types. 54 if (!mime_type.empty()) 55 mime_types.insert(mime_type); 56 } 57 return mime_types; 58} 59 60} // namespace 61 62bool FileManagerPrivateExecuteTaskFunction::RunAsync() { 63 using extensions::api::file_manager_private::ExecuteTask::Params; 64 using extensions::api::file_manager_private::ExecuteTask::Results::Create; 65 const scoped_ptr<Params> params(Params::Create(*args_)); 66 EXTENSION_FUNCTION_VALIDATE(params); 67 68 file_manager::file_tasks::TaskDescriptor task; 69 if (!file_manager::file_tasks::ParseTaskID(params->task_id, &task)) { 70 SetError(kInvalidTask + params->task_id); 71 results_ = 72 Create(extensions::api::file_manager_private::TASK_RESULT_FAILED); 73 return false; 74 } 75 76 if (params->file_urls.empty()) { 77 results_ = Create(extensions::api::file_manager_private::TASK_RESULT_EMPTY); 78 SendResponse(true); 79 return true; 80 } 81 82 const scoped_refptr<storage::FileSystemContext> file_system_context = 83 file_manager::util::GetFileSystemContextForRenderViewHost( 84 GetProfile(), render_view_host()); 85 86 std::vector<FileSystemURL> file_urls; 87 for (size_t i = 0; i < params->file_urls.size(); i++) { 88 const FileSystemURL url = 89 file_system_context->CrackURL(GURL(params->file_urls[i])); 90 if (!chromeos::FileSystemBackend::CanHandleURL(url)) { 91 SetError(kInvalidFileUrl); 92 results_ = 93 Create(extensions::api::file_manager_private::TASK_RESULT_FAILED); 94 return false; 95 } 96 file_urls.push_back(url); 97 } 98 99 const bool result = file_manager::file_tasks::ExecuteFileTask( 100 GetProfile(), 101 source_url(), 102 task, 103 file_urls, 104 base::Bind(&FileManagerPrivateExecuteTaskFunction::OnTaskExecuted, this)); 105 if (!result) { 106 results_ = 107 Create(extensions::api::file_manager_private::TASK_RESULT_FAILED); 108 } 109 return result; 110} 111 112void FileManagerPrivateExecuteTaskFunction::OnTaskExecuted( 113 extensions::api::file_manager_private::TaskResult result) { 114 results_ = 115 extensions::api::file_manager_private::ExecuteTask::Results::Create( 116 result); 117 SendResponse(result != 118 extensions::api::file_manager_private::TASK_RESULT_FAILED); 119} 120 121FileManagerPrivateGetFileTasksFunction:: 122 FileManagerPrivateGetFileTasksFunction() { 123} 124 125FileManagerPrivateGetFileTasksFunction:: 126 ~FileManagerPrivateGetFileTasksFunction() { 127} 128 129bool FileManagerPrivateGetFileTasksFunction::RunAsync() { 130 using extensions::api::file_manager_private::GetFileTasks::Params; 131 const scoped_ptr<Params> params(Params::Create(*args_)); 132 EXTENSION_FUNCTION_VALIDATE(params); 133 134 if (params->file_urls.empty()) 135 return false; 136 137 const scoped_refptr<storage::FileSystemContext> file_system_context = 138 file_manager::util::GetFileSystemContextForRenderViewHost( 139 GetProfile(), render_view_host()); 140 141 // Collect all the URLs, convert them to GURLs, and crack all the urls into 142 // file paths. 143 for (size_t i = 0; i < params->file_urls.size(); ++i) { 144 const GURL file_url(params->file_urls[i]); 145 storage::FileSystemURL file_system_url( 146 file_system_context->CrackURL(file_url)); 147 if (!chromeos::FileSystemBackend::CanHandleURL(file_system_url)) 148 continue; 149 file_urls_.push_back(file_url); 150 local_paths_.push_back(file_system_url.path()); 151 } 152 153 collector_.reset(new app_file_handler_util::MimeTypeCollector(GetProfile())); 154 collector_->CollectForLocalPaths( 155 local_paths_, 156 base::Bind(&FileManagerPrivateGetFileTasksFunction::OnMimeTypesCollected, 157 this)); 158 159 return true; 160} 161 162void FileManagerPrivateGetFileTasksFunction::OnMimeTypesCollected( 163 scoped_ptr<std::vector<std::string> > mime_types) { 164 app_file_handler_util::PathAndMimeTypeSet path_mime_set; 165 for (size_t i = 0; i < local_paths_.size(); ++i) { 166 path_mime_set.insert(std::make_pair(local_paths_[i], (*mime_types)[i])); 167 } 168 169 std::vector<file_manager::file_tasks::FullTaskDescriptor> tasks; 170 file_manager::file_tasks::FindAllTypesOfTasks( 171 GetProfile(), 172 drive::util::GetDriveAppRegistryByProfile(GetProfile()), 173 path_mime_set, 174 file_urls_, 175 &tasks); 176 177 // Convert the tasks into JSON compatible objects. 178 using api::file_manager_private::FileTask; 179 std::vector<linked_ptr<FileTask> > results; 180 for (size_t i = 0; i < tasks.size(); ++i) { 181 const file_manager::file_tasks::FullTaskDescriptor& task = tasks[i]; 182 const linked_ptr<FileTask> converted(new FileTask); 183 converted->task_id = file_manager::file_tasks::TaskDescriptorToId( 184 task.task_descriptor()); 185 if (!task.icon_url().is_empty()) 186 converted->icon_url = task.icon_url().spec(); 187 converted->title = task.task_title(); 188 converted->is_default = task.is_default(); 189 results.push_back(converted); 190 } 191 192 results_ = extensions::api::file_manager_private::GetFileTasks::Results:: 193 Create(results); 194 SendResponse(true); 195} 196 197bool FileManagerPrivateSetDefaultTaskFunction::RunSync() { 198 using extensions::api::file_manager_private::SetDefaultTask::Params; 199 const scoped_ptr<Params> params(Params::Create(*args_)); 200 EXTENSION_FUNCTION_VALIDATE(params); 201 202 const scoped_refptr<storage::FileSystemContext> file_system_context = 203 file_manager::util::GetFileSystemContextForRenderViewHost( 204 GetProfile(), render_view_host()); 205 206 const std::set<std::string> suffixes = 207 GetUniqueSuffixes(params->file_urls, file_system_context.get()); 208 209 // MIME types are an optional parameter. 210 std::set<std::string> mime_types; 211 if (params->mime_types && !params->mime_types->empty()) { 212 if (params->mime_types->size() != params->file_urls.size()) 213 return false; 214 mime_types = GetUniqueMimeTypes(*params->mime_types); 215 } 216 217 // If there weren't any mime_types, and all the suffixes were blank, 218 // then we "succeed", but don't actually associate with anything. 219 // Otherwise, any time we set the default on a file with no extension 220 // on the local drive, we'd fail. 221 // TODO(gspencer): Fix file manager so that it never tries to set default in 222 // cases where extensionless local files are part of the selection. 223 if (suffixes.empty() && mime_types.empty()) { 224 SetResult(new base::FundamentalValue(true)); 225 return true; 226 } 227 228 file_manager::file_tasks::UpdateDefaultTask( 229 GetProfile()->GetPrefs(), params->task_id, suffixes, mime_types); 230 return true; 231} 232 233} // namespace extensions 234