Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3694)

Unified Diff: chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc

Issue 14670023: ChromeOS: Support opening files with apps from the downloads page. (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: prioritize fallback handlers over non-default app handlers Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « chrome/browser/chromeos/extensions/file_manager/file_manager_util.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 24e708bf2272ac976103ebb670b056c449df410c..72c172d26d4a75d78ee336b464d613b36fa837d2 100644
--- a/chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc
+++ b/chrome/browser/chromeos/extensions/file_manager/file_manager_util.cc
@@ -20,6 +20,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"
@@ -49,6 +50,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"
@@ -65,6 +67,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;
@@ -314,7 +318,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))
@@ -332,7 +337,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);
}
@@ -351,7 +356,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;
}
@@ -409,17 +415,70 @@ Browser* GetBrowserForUrl(GURL target_url) {
return NULL;
}
-bool ExecuteDefaultHandler(Profile* profile, const base::FilePath& path) {
- GURL url;
- if (!ConvertFileToFileSystemUrl(profile, path, kFileBrowserDomain, &url))
+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;
- const FileBrowserHandler* handler;
- if (!file_handler_util::GetTaskForURLAndPath(profile, url, path, &handler))
- 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;
+
+ // If we find the default handler, we execute it immediately, but otherwise,
+ // we remember the first handler, and if there was no default handler, simply
+ // execute the first one.
+ for (ExtensionSet::const_iterator iter = service->extensions()->begin();
+ iter != service->extensions()->end();
+ ++iter) {
+ const Extension* extension = *iter;
+
+ // We don't support using hosted apps to open files.
mtomasz 2013/06/07 02:36:00 This comment is misleading. is_platform_app disall
Sam McNally 2013/06/07 05:29:13 This is copied from the check in file_manager_priv
+ if (!extension->is_platform_app())
+ continue;
+
+ // We only support apps that specify "incognito: split" if in incognito
mtomasz 2013/06/07 02:36:00 I'm wondering if this behavior is documented somew
Sam McNally 2013/06/07 05:29:13 Same as above. This check may be unnecessary thoug
+ // mode.
+ if (profile->IsOffTheRecord() &&
+ !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;
+}
- std::string extension_id = handler->extension_id();
- std::string action_id = handler->id();
+bool ExecuteExtensionHandler(Profile* profile,
+ const base::FilePath& path,
+ const FileBrowserHandler& handler,
+ const GURL& url) {
+ std::string extension_id = handler.extension_id();
+ std::string action_id = handler.id();
Browser* browser = chrome::FindLastActiveWithProfile(profile,
chrome::HOST_DESKTOP_TYPE_ASH);
@@ -434,7 +493,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);
@@ -454,10 +514,45 @@ 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;
}
+bool ExecuteDefaultHandler(Profile* profile, const base::FilePath& path) {
+ GURL url;
+ if (!ConvertFileToFileSystemUrl(profile, path, kFileBrowserDomain, &url))
+ return false;
+
+ std::string mime_type = GetMimeTypeForPath(path);
+ std::string default_task_id = file_handler_util::GetDefaultTaskIdFromPrefs(
+ profile, mime_type, path.Extension());
+ const FileBrowserHandler* handler;
+
+ // We choose the file handler from the following in decreasing priority or
+ // fail if none support the file type:
+ // 1. default extension
mtomasz 2013/06/07 02:36:00 default extensions before apps, but non-default ap
Sam McNally 2013/06/07 05:29:13 Yes, but there can be at most one default handler.
+ // 2. default app
+ // 3. a fallback handler (e.g. opening in the browser)
+ // 4. non-default app
+ // 5. non-default extension
+ // Note that there can be at most one of default extension and default app.
+ if (!file_handler_util::GetTaskForURLAndPath(profile, url, path, &handler)) {
+ 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 &&
+ !file_handler_util::IsFallbackTask(handler) &&
+ ExecuteDefaultAppHandler(
+ profile, path, url, mime_type, default_task_id)) {
+ return true;
+ }
+ return ExecuteExtensionHandler(profile, path, *handler, url);
+}
+
// Reads the alternate URL from a GDoc file. When it fails, returns a file URL
// for |file_path| as fallback.
// Note that an alternate url is a URL to open a hosted document.
@@ -889,4 +984,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
« no previous file with comments | « chrome/browser/chromeos/extensions/file_manager/file_manager_util.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698