OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/extensions/file_manager/open_util.h" | 5 #include "chrome/browser/chromeos/extensions/file_manager/open_util.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/strings/utf_string_conversions.h" | 10 #include "base/strings/utf_string_conversions.h" |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
127 if (!ConvertAbsoluteFilePathToFileSystemUrl( | 127 if (!ConvertAbsoluteFilePathToFileSystemUrl( |
128 profile, file_path, kFileManagerAppId, &url)) | 128 profile, file_path, kFileManagerAppId, &url)) |
129 return; | 129 return; |
130 | 130 |
131 file_tasks::TaskDescriptor task(kFileManagerAppId, | 131 file_tasks::TaskDescriptor task(kFileManagerAppId, |
132 file_tasks::TASK_TYPE_FILE_BROWSER_HANDLER, | 132 file_tasks::TASK_TYPE_FILE_BROWSER_HANDLER, |
133 action_id); | 133 action_id); |
134 ExecuteFileTaskForUrl(profile, task, url); | 134 ExecuteFileTaskForUrl(profile, task, url); |
135 } | 135 } |
136 | 136 |
137 // Opens the file specified by |file_path| and |url| with a file handler, | 137 // Opens the file specified by |file_path| by finding and executing a file |
138 // preferably the default handler for the type of the file. Returns false if | 138 // task for the file. Returns false if failed to open the file (i.e. no file |
139 // no file handler is found. | 139 // task is found). |
140 bool OpenFileWithFileHandler(Profile* profile, | 140 bool OpenFile(Profile* profile, const base::FilePath& file_path) { |
141 const base::FilePath& file_path, | |
142 const GURL& url, | |
143 const std::string& mime_type, | |
144 const std::string& default_task_id) { | |
145 ExtensionService* service = profile->GetExtensionService(); | |
146 if (!service) | |
147 return false; | |
148 | |
149 PathAndMimeTypeSet files; | |
150 files.insert(std::make_pair(file_path, mime_type)); | |
151 const extensions::FileHandlerInfo* first_handler = NULL; | |
152 const extensions::Extension* extension_for_first_handler = NULL; | |
153 | |
154 // If we find the default handler, we execute it immediately, but otherwise, | |
155 // we remember the first handler, and if there was no default handler, simply | |
156 // execute the first one. | |
157 for (ExtensionSet::const_iterator iter = service->extensions()->begin(); | |
158 iter != service->extensions()->end(); | |
159 ++iter) { | |
160 const Extension* extension = iter->get(); | |
161 | |
162 // We don't support using hosted apps to open files. | |
163 if (!extension->is_platform_app()) | |
164 continue; | |
165 | |
166 // We only support apps that specify "incognito: split" if in incognito | |
167 // mode. | |
168 if (profile->IsOffTheRecord() && | |
169 !service->IsIncognitoEnabled(extension->id())) | |
170 continue; | |
171 | |
172 typedef std::vector<const extensions::FileHandlerInfo*> FileHandlerList; | |
173 FileHandlerList file_handlers = FindFileHandlersForFiles(*extension, files); | |
174 for (FileHandlerList::iterator i = file_handlers.begin(); | |
175 i != file_handlers.end(); ++i) { | |
176 const extensions::FileHandlerInfo* handler = *i; | |
177 std::string task_id = file_tasks::MakeTaskID( | |
178 extension->id(), | |
179 file_tasks::TASK_TYPE_FILE_HANDLER, | |
180 handler->id); | |
181 if (task_id == default_task_id) { | |
182 file_tasks::TaskDescriptor task(extension->id(), | |
183 file_tasks::TASK_TYPE_FILE_HANDLER, | |
184 handler->id); | |
185 ExecuteFileTaskForUrl(profile, task, url); | |
186 return true; | |
187 | |
188 } else if (!first_handler) { | |
189 first_handler = handler; | |
190 extension_for_first_handler = extension; | |
191 } | |
192 } | |
193 } | |
194 if (first_handler) { | |
195 file_tasks::TaskDescriptor task(extension_for_first_handler->id(), | |
196 file_tasks::TASK_TYPE_FILE_HANDLER, | |
197 first_handler->id); | |
198 ExecuteFileTaskForUrl(profile, task, url); | |
199 return true; | |
200 } | |
201 return false; | |
202 } | |
203 | |
204 // Opens the file specified by |file_path| and |url| with the file browser | |
205 // handler specified by |handler|. Returns false if failed to open the file. | |
206 bool OpenFileWithFileBrowserHandler(Profile* profile, | |
207 const base::FilePath& file_path, | |
208 const FileBrowserHandler& handler, | |
209 const GURL& url) { | |
210 file_tasks::TaskDescriptor task(handler.extension_id(), | |
211 file_tasks::TASK_TYPE_FILE_BROWSER_HANDLER, | |
212 handler.id()); | |
213 ExecuteFileTaskForUrl(profile, task, url); | |
214 return true; | |
215 } | |
216 | |
217 // Opens the file specified by |file_path| with a handler (either of file | |
218 // browser handler or file handler, preferably the default handler for the | |
219 // type of the file), or opens the file with the browser. Returns false if | |
220 // failed to open the file. | |
221 bool OpenFileWithHandler(Profile* profile, const base::FilePath& file_path) { | |
222 GURL url; | 141 GURL url; |
223 if (!ConvertAbsoluteFilePathToFileSystemUrl( | 142 if (!ConvertAbsoluteFilePathToFileSystemUrl( |
224 profile, file_path, kFileManagerAppId, &url)) | 143 profile, file_path, kFileManagerAppId, &url)) |
225 return false; | 144 return false; |
226 | 145 |
| 146 // The file is opened per the file extension, hence extension-less files |
| 147 // cannot be opened properly. |
227 std::string mime_type = GetMimeTypeForPath(file_path); | 148 std::string mime_type = GetMimeTypeForPath(file_path); |
228 std::string default_task_id = file_tasks::GetDefaultTaskIdFromPrefs( | 149 extensions::app_file_handler_util::PathAndMimeTypeSet path_mime_set; |
229 *profile->GetPrefs(), mime_type, file_path.Extension()); | 150 path_mime_set.insert(std::make_pair(file_path, mime_type)); |
230 | 151 |
231 // We choose the file handler from the following in decreasing priority or | 152 std::vector<GURL> file_urls; |
232 // fail if none support the file type: | 153 file_urls.push_back(url); |
233 // 1. default file browser handler | 154 |
234 // 2. default file handler | 155 std::vector<file_tasks::FullTaskDescriptor> tasks; |
235 // 3. a fallback handler (e.g. opening in the browser) | 156 file_tasks::FindAllTypesOfTasks(profile, |
236 // 4. non-default file handler | 157 path_mime_set, |
237 // 5. non-default file browser handler | 158 file_urls, |
238 // Note that there can be at most one of default extension and default app. | 159 &tasks); |
239 const FileBrowserHandler* handler = | 160 if (tasks.empty()) |
240 file_browser_handlers::FindFileBrowserHandlerForURLAndPath( | 161 return false; |
241 profile, url, file_path); | 162 |
242 if (!handler) { | 163 const file_tasks::FullTaskDescriptor* chosen_task = &tasks[0]; |
243 return OpenFileWithFileHandler( | 164 for (size_t i = 0; i < tasks.size(); ++i) { |
244 profile, file_path, url, mime_type, default_task_id); | 165 if (tasks[i].is_default()) { |
| 166 chosen_task = &tasks[i]; |
| 167 break; |
| 168 } |
245 } | 169 } |
246 | 170 |
247 const file_tasks::TaskDescriptor task_descriptor( | 171 ExecuteFileTaskForUrl(profile, chosen_task->task_descriptor(), url); |
248 handler->extension_id(), | 172 return true; |
249 file_tasks::TASK_TYPE_FILE_BROWSER_HANDLER, | |
250 handler->id()); | |
251 const std::string handler_task_id = | |
252 file_tasks::TaskDescriptorToId(task_descriptor); | |
253 if (handler_task_id != default_task_id && | |
254 !file_browser_handlers::IsFallbackFileBrowserHandler(task_descriptor) && | |
255 OpenFileWithFileHandler( | |
256 profile, file_path, url, mime_type, default_task_id)) { | |
257 return true; | |
258 } | |
259 return OpenFileWithFileBrowserHandler(profile, file_path, *handler, url); | |
260 } | 173 } |
261 | 174 |
262 // Used to implement OpenItem(). | 175 // Used to implement OpenItem(). |
263 void ContinueOpenItem(Profile* profile, | 176 void ContinueOpenItem(Profile* profile, |
264 const base::FilePath& file_path, | 177 const base::FilePath& file_path, |
265 base::PlatformFileError error) { | 178 base::PlatformFileError error) { |
266 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 179 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
267 | 180 |
268 if (error == base::PLATFORM_FILE_OK) { | 181 if (error == base::PLATFORM_FILE_OK) { |
269 // A directory exists at |file_path|. Open it with the file manager. | 182 // A directory exists at |file_path|. Open it with the file manager. |
270 OpenFileManagerWithInternalActionId(file_path, "open"); | 183 OpenFileManagerWithInternalActionId(file_path, "open"); |
271 } else { | 184 } else { |
272 // |file_path| should be a file. Open it with a handler. | 185 // |file_path| should be a file. Open it. |
273 if (!OpenFileWithHandler(profile, file_path)) | 186 if (!OpenFile(profile, file_path)) |
274 ShowWarningMessageBox(profile, file_path); | 187 ShowWarningMessageBox(profile, file_path); |
275 } | 188 } |
276 } | 189 } |
277 | 190 |
278 // Used to implement CheckIfDirectoryExists(). | 191 // Used to implement CheckIfDirectoryExists(). |
279 void CheckIfDirectoryExistsOnIOThread( | 192 void CheckIfDirectoryExistsOnIOThread( |
280 scoped_refptr<fileapi::FileSystemContext> file_system_context, | 193 scoped_refptr<fileapi::FileSystemContext> file_system_context, |
281 const GURL& url, | 194 const GURL& url, |
282 const fileapi::FileSystemOperationRunner::StatusCallback& callback) { | 195 const fileapi::FileSystemOperationRunner::StatusCallback& callback) { |
283 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 196 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
328 base::Bind(&ContinueOpenItem, profile, file_path)); | 241 base::Bind(&ContinueOpenItem, profile, file_path)); |
329 } | 242 } |
330 | 243 |
331 void ShowItemInFolder(const base::FilePath& file_path) { | 244 void ShowItemInFolder(const base::FilePath& file_path) { |
332 // This action changes the selection so we do not reuse existing tabs. | 245 // This action changes the selection so we do not reuse existing tabs. |
333 OpenFileManagerWithInternalActionId(file_path, "select"); | 246 OpenFileManagerWithInternalActionId(file_path, "select"); |
334 } | 247 } |
335 | 248 |
336 } // namespace util | 249 } // namespace util |
337 } // namespace file_manager | 250 } // namespace file_manager |
OLD | NEW |