Index: chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc |
diff --git a/chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc b/chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc |
index 4682561fb1ebea6546b9133131dfb419a6111226..efbd2524c65277af8d485a2cc3624ef12965934c 100644 |
--- a/chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc |
+++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc |
@@ -22,6 +22,7 @@ |
#include "chrome/browser/chromeos/extensions/file_manager/file_browser_handler.h" |
#include "chrome/browser/chromeos/extensions/file_manager/file_handler_util.h" |
#include "chrome/browser/chromeos/media/media_player.h" |
+#include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" |
#include "chrome/browser/extensions/crx_installer.h" |
#include "chrome/browser/extensions/extension_install_prompt.h" |
#include "chrome/browser/extensions/extension_service.h" |
@@ -50,6 +51,7 @@ |
#include "content/public/common/pepper_plugin_info.h" |
#include "grit/generated_resources.h" |
#include "net/base/escape.h" |
+#include "net/base/mime_util.h" |
#include "net/base/net_util.h" |
#include "ui/base/l10n/l10n_util.h" |
#include "ui/gfx/screen.h" |
@@ -66,6 +68,8 @@ using content::BrowserContext; |
using content::BrowserThread; |
using content::PluginService; |
using content::UserMetricsAction; |
+using extensions::app_file_handler_util::FindFileHandlersForFiles; |
+using extensions::app_file_handler_util::PathAndMimeTypeSet; |
using extensions::Extension; |
using file_handler_util::FileTaskExecutor; |
using fileapi::FileSystemURL; |
@@ -336,7 +340,8 @@ bool GrantFileSystemAccessToFileBrowser(Profile* profile) { |
void ExecuteHandler(Profile* profile, |
std::string extension_id, |
std::string action_id, |
- const GURL& url) { |
+ const GURL& url, |
+ const std::string& task_type) { |
// If File Browser has not been open yet then it did not request access |
// to the file system. Do it now. |
if (!GrantFileSystemAccessToFileBrowser(profile)) |
@@ -354,7 +359,7 @@ void ExecuteHandler(Profile* profile, |
urls.push_back(file_system_context->CrackURL(url)); |
scoped_refptr<FileTaskExecutor> executor = FileTaskExecutor::Create(profile, |
source_url, kFileBrowserDomain, 0 /* no tab id */, extension_id, |
- file_handler_util::kTaskFile, action_id); |
+ task_type, action_id); |
executor->Execute(urls); |
} |
@@ -375,7 +380,8 @@ void OpenFileBrowserImpl(const base::FilePath& path, |
// Some values of |action_id| are not listed in the manifest and are used |
// to parametrize the behavior when opening the Files app window. |
- ExecuteHandler(profile, kFileBrowserDomain, action_id, url); |
+ ExecuteHandler(profile, kFileBrowserDomain, action_id, url, |
+ file_handler_util::kTaskFile); |
return; |
} |
@@ -430,14 +436,79 @@ Browser* GetBrowserForUrl(GURL target_url) { |
return NULL; |
} |
+bool ExecuteDefaultAppHandler(Profile* profile, |
+ const base::FilePath& path, |
+ const GURL& url, |
+ const std::string& mime_type, |
+ const std::string& default_task_id) { |
+ ExtensionService* service = profile->GetExtensionService(); |
+ if (!service) |
+ return false; |
+ |
+ PathAndMimeTypeSet files; |
+ files.insert(std::make_pair(path, mime_type)); |
+ const extensions::FileHandlerInfo* first_handler = NULL; |
+ const extensions::Extension* extension_for_first_handler = NULL; |
+ |
+ for (ExtensionSet::const_iterator iter = service->extensions()->begin(); |
Matt Giuca
2013/05/09 04:58:22
Explain the algorithm overall.
// If we find the
Sam McNally
2013/05/09 07:31:35
Done.
|
+ iter != service->extensions()->end(); |
+ ++iter) { |
+ const Extension* extension = *iter; |
+ |
+ // We don't support using hosted apps to open files. |
+ if (!extension->is_platform_app()) |
+ continue; |
+ |
+ if (profile->IsOffTheRecord() && |
Matt Giuca
2013/05/09 04:58:22
What does this mean? Can you add a comment?
Sam McNally
2013/05/09 07:31:35
Done.
Matt Giuca
2013/05/09 08:56:58
Can you put quotes around "incognito: split". It's
Sam McNally
2013/05/09 23:27:44
Done.
|
+ !service->IsIncognitoEnabled(extension->id())) |
+ continue; |
+ |
+ typedef std::vector<const extensions::FileHandlerInfo*> FileHandlerList; |
+ FileHandlerList file_handlers = FindFileHandlersForFiles(*extension, files); |
+ for (FileHandlerList::iterator i = file_handlers.begin(); |
+ i != file_handlers.end(); ++i) { |
+ const extensions::FileHandlerInfo* handler = *i; |
+ std::string task_id = file_handler_util::MakeTaskID(extension->id(), |
+ file_handler_util::kTaskApp, handler->id); |
+ if (task_id == default_task_id) { |
+ ExecuteHandler(profile, extension->id(), handler->id, url, |
+ file_handler_util::kTaskApp); |
+ return true; |
+ |
+ } else if (!first_handler) { |
+ first_handler = handler; |
+ extension_for_first_handler = extension; |
+ } |
+ } |
+ } |
+ if (first_handler) { |
+ ExecuteHandler(profile, extension_for_first_handler->id(), |
+ first_handler->id, url, file_handler_util::kTaskApp); |
+ return true; |
+ } |
+ return false; |
+} |
+ |
bool ExecuteDefaultHandler(Profile* profile, const base::FilePath& path) { |
GURL url; |
if (!ConvertFileToFileSystemUrl(profile, path, kFileBrowserDomain, &url)) |
return false; |
+ std::string mime_type = GetMimeTypeForPath(path); |
Matt Giuca
2013/05/09 04:58:22
Explain the approach you are taking in comments he
Sam McNally
2013/05/09 07:31:35
Done.
|
+ std::string default_task_id = file_handler_util::GetDefaultTaskIdFromPrefs( |
+ profile, mime_type, path.Extension()); |
const FileBrowserHandler* handler; |
- if (!file_handler_util::GetTaskForURLAndPath(profile, url, path, &handler)) |
- return false; |
+ if (!file_handler_util::GetTaskForURLAndPath(profile, url, path, &handler)) { |
Matt Giuca
2013/05/09 04:58:22
I think this could be clearer. It seems as though
Sam McNally
2013/05/09 07:31:35
Done.
|
+ return ExecuteDefaultAppHandler( |
+ profile, path, url, mime_type, default_task_id); |
+ } |
+ |
+ std::string handler_task_id = file_handler_util::MakeTaskID( |
+ handler->extension_id(), file_handler_util::kTaskFile, handler->id()); |
+ if (handler_task_id != default_task_id && ExecuteDefaultAppHandler( |
+ profile, path, url, mime_type, default_task_id)) { |
+ return true; |
+ } |
std::string extension_id = handler->extension_id(); |
std::string action_id = handler->id(); |
@@ -455,7 +526,8 @@ bool ExecuteDefaultHandler(Profile* profile, const base::FilePath& path) { |
action_id == kFileBrowserMountArchiveTaskId || |
action_id == kFileBrowserPlayTaskId || |
action_id == kFileBrowserWatchTaskId) { |
- ExecuteHandler(profile, extension_id, action_id, url); |
+ ExecuteHandler(profile, extension_id, action_id, url, |
+ file_handler_util::kTaskFile); |
return true; |
} |
return ExecuteBuiltinHandler(browser, path, action_id); |
@@ -475,7 +547,8 @@ bool ExecuteDefaultHandler(Profile* profile, const base::FilePath& path) { |
return ExecuteBuiltinHandler(browser, path, action_id); |
} |
- ExecuteHandler(profile, extension_id, action_id, url); |
+ ExecuteHandler(profile, extension_id, action_id, url, |
+ file_handler_util::kTaskFile); |
return true; |
} |
@@ -925,4 +998,24 @@ bool ShouldBeOpenedWithPlugin(Profile* profile, const char* file_extension) { |
return false; |
} |
+std::string GetMimeTypeForPath(const base::FilePath& file_path) { |
+ const base::FilePath::StringType file_extension = |
+ StringToLowerASCII(file_path.Extension()); |
+ |
+ // TODO(thorogood): Rearchitect this call so it can run on the File thread; |
+ // GetMimeTypeFromFile requires this on Linux. Right now, we use |
+ // Chrome-level knowledge only. |
+ std::string mime_type; |
+ if (file_extension.empty() || |
+ !net::GetWellKnownMimeTypeFromExtension(file_extension.substr(1), |
+ &mime_type)) { |
+ // If the file doesn't have an extension or its mime-type cannot be |
+ // determined, then indicate that it has the empty mime-type. This will |
+ // only be matched if the Web Intents accepts "*" or "*/*". |
+ return ""; |
+ } else { |
+ return mime_type; |
+ } |
+} |
+ |
} // namespace file_manager_util |