diff options
author | sammc@chromium.org <sammc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-03 11:26:38 +0000 |
---|---|---|
committer | sammc@chromium.org <sammc@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-03 11:26:38 +0000 |
commit | 99b920483d64d9e121da019117c51be5e0614ce4 (patch) | |
tree | 1f4501b57556c1121744871f1901c1952f361610 /chrome/browser | |
parent | 79c8c5c4448f7b81c752a5428d794e2d06e18002 (diff) | |
download | chromium_src-99b920483d64d9e121da019117c51be5e0614ce4.zip chromium_src-99b920483d64d9e121da019117c51be5e0614ce4.tar.gz chromium_src-99b920483d64d9e121da019117c51be5e0614ce4.tar.bz2 |
Support extension-based file-handlers for packaged apps.
This rolls forward r197909 but without the windows breakage.
Previously, file_handlers could only specify the file types they
accepted by MIME type. This limited apps to only accepting types known
to the local operating system or accepting any unknown type. This change
allows file_handlers to restrict types by file extension.
BUG=167950
TEST=browser_tests PlatformAppBrowserTest.Launch*
Review URL: https://chromiumcodereview.appspot.com/14887004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@198091 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
4 files changed, 164 insertions, 19 deletions
diff --git a/chrome/browser/extensions/api/file_handlers/app_file_handler_util.cc b/chrome/browser/extensions/api/file_handlers/app_file_handler_util.cc index 27579a2..a66298d 100644 --- a/chrome/browser/extensions/api/file_handlers/app_file_handler_util.cc +++ b/chrome/browser/extensions/api/file_handlers/app_file_handler_util.cc @@ -16,6 +16,35 @@ namespace extensions { namespace app_file_handler_util { +namespace { + +bool FileHandlerCanHandleFileWithExtension( + const FileHandlerInfo& handler, + const base::FilePath& path) { + for (std::set<std::string>::const_iterator extension = + handler.extensions.begin(); + extension != handler.extensions.end(); ++extension) { + if (*extension == "*") + return true; + + if (path.MatchesExtension( + base::FilePath::kExtensionSeparator + + base::FilePath::FromUTF8Unsafe(*extension).value())) { + return true; + } + + // Also accept files with no extension for handlers that support an + // empty extension, i.e. both "foo" and "foo." match. + if (extension->empty() && + path.MatchesExtension(base::FilePath::StringType())) { + return true; + } + } + return false; +} + +} // namespace + typedef std::vector<FileHandlerInfo> FileHandlerList; const FileHandlerInfo* FileHandlerForId(const Extension& app, @@ -32,19 +61,18 @@ const FileHandlerInfo* FileHandlerForId(const Extension& app, return NULL; } -const FileHandlerInfo* FirstFileHandlerForMimeType(const Extension& app, - const std::string& mime_type) { +const FileHandlerInfo* FirstFileHandlerForFile( + const Extension& app, + const std::string& mime_type, + const base::FilePath& path) { const FileHandlerList* file_handlers = FileHandlers::GetFileHandlers(&app); if (!file_handlers) return NULL; for (FileHandlerList::const_iterator i = file_handlers->begin(); i != file_handlers->end(); i++) { - for (std::set<std::string>::const_iterator t = i->types.begin(); - t != i->types.end(); t++) { - if (net::MatchesMimeType(*t, mime_type)) - return &*i; - } + if (FileHandlerCanHandleFile(*i, mime_type, path)) + return &*i; } return NULL; } @@ -76,10 +104,17 @@ std::vector<const FileHandlerInfo*> FindFileHandlersForMimeTypes( return handlers; } +bool FileHandlerCanHandleFile( + const FileHandlerInfo& handler, + const std::string& mime_type, + const base::FilePath& path) { + return FileHandlerCanHandleFileWithMimeType(handler, mime_type) || + FileHandlerCanHandleFileWithExtension(handler, path); +} + bool FileHandlerCanHandleFileWithMimeType( const FileHandlerInfo& handler, const std::string& mime_type) { - // TODO(benwells): this should check the file's extension as well. for (std::set<std::string>::const_iterator type = handler.types.begin(); type != handler.types.end(); ++type) { if (net::MatchesMimeType(*type, mime_type)) diff --git a/chrome/browser/extensions/api/file_handlers/app_file_handler_util.h b/chrome/browser/extensions/api/file_handlers/app_file_handler_util.h index a73a0c7..ad7d4b7 100644 --- a/chrome/browser/extensions/api/file_handlers/app_file_handler_util.h +++ b/chrome/browser/extensions/api/file_handlers/app_file_handler_util.h @@ -24,17 +24,24 @@ namespace app_file_handler_util { const FileHandlerInfo* FileHandlerForId(const Extension& app, const std::string& handler_id); -// Returns the first file handler that can handle the given MIME type, or NULL -// if is no such handler. -const FileHandlerInfo* FirstFileHandlerForMimeType(const Extension& app, - const std::string& mime_type); +// Returns the first file handler that can handle the given MIME type or +// filename, or NULL if is no such handler. +const FileHandlerInfo* FirstFileHandlerForFile( + const Extension& app, + const std::string& mime_type, + const base::FilePath& path); std::vector<const FileHandlerInfo*> FindFileHandlersForMimeTypes(const Extension& extension, const std::set<std::string>& mime_types); -bool FileHandlerCanHandleFileWithMimeType(const FileHandlerInfo& handler, - const std::string& mime_type); +bool FileHandlerCanHandleFile( + const FileHandlerInfo& handler, + const std::string& mime_type, + const base::FilePath& path); +bool FileHandlerCanHandleFileWithMimeType( + const FileHandlerInfo& handler, + const std::string& mime_type); // Represents a file entry that a user has given an extension permission to // access. Intended to be persisted to disk (in the Preferences file), so should diff --git a/chrome/browser/extensions/platform_app_browsertest.cc b/chrome/browser/extensions/platform_app_browsertest.cc index 5f1b6bf..38ca40b 100644 --- a/chrome/browser/extensions/platform_app_browsertest.cc +++ b/chrome/browser/extensions/platform_app_browsertest.cc @@ -4,6 +4,7 @@ #include "base/bind.h" #include "base/file_util.h" +#include "base/files/scoped_temp_dir.h" #include "base/prefs/pref_service.h" #include "base/test/test_timeouts.h" #include "base/threading/platform_thread.h" @@ -96,6 +97,20 @@ class TabsAddedNotificationObserver DISALLOW_COPY_AND_ASSIGN(TabsAddedNotificationObserver); }; +bool CopyTestDataAndSetCommandLineArg( + const base::FilePath& test_data_file, + const base::FilePath& temp_dir, + const char* filename) { + base::FilePath path = temp_dir.AppendASCII( + filename).NormalizePathSeparators(); + if (!(file_util::CopyFile(test_data_file, path))) + return false; + + CommandLine* command_line = CommandLine::ForCurrentProcess(); + command_line->AppendArgPath(path); + return true; +} + const char kTestFilePath[] = "platform_apps/launch_files/test.txt"; } // namespace @@ -439,6 +454,95 @@ IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithRelativeFile) { } } +// Tests that launch data is sent through if the file extension matches. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithFileExtension) { + SetCommandLineArg(kTestFilePath); + ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_file_by_extension")) + << message_; +} + +// Tests that launch data is sent through if the file extension and MIME type +// both match. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, + LaunchWithFileExtensionAndMimeType) { + SetCommandLineArg(kTestFilePath); + ASSERT_TRUE(RunPlatformAppTest( + "platform_apps/launch_file_by_extension_and_type")) << message_; +} + +// Tests that launch data is sent through for a file with no extension if a +// handler accepts "". +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithFileWithoutExtension) { + SetCommandLineArg("platform_apps/launch_files/test"); + ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_file_with_no_extension")) + << message_; +} + +#if !defined(OS_WIN) +// Tests that launch data is sent through for a file with an empty extension if +// a handler accepts "". +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithFileEmptyExtension) { + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + ClearCommandLineArgs(); + ASSERT_TRUE(CopyTestDataAndSetCommandLineArg( + test_data_dir_.AppendASCII(kTestFilePath), + temp_dir.path(), + "test.")); + ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_file_with_no_extension")) + << message_; +} + +// Tests that launch data is sent through for a file with an empty extension if +// a handler accepts *. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, + LaunchWithFileEmptyExtensionAcceptAny) { + base::ScopedTempDir temp_dir; + ASSERT_TRUE(temp_dir.CreateUniqueTempDir()); + ClearCommandLineArgs(); + ASSERT_TRUE(CopyTestDataAndSetCommandLineArg( + test_data_dir_.AppendASCII(kTestFilePath), + temp_dir.path(), + "test.")); + ASSERT_TRUE(RunPlatformAppTest( + "platform_apps/launch_file_with_any_extension")) << message_; +} +#endif + +// Tests that launch data is sent through for a file with no extension if a +// handler accepts *. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, + LaunchWithFileWithoutExtensionAcceptAny) { + SetCommandLineArg("platform_apps/launch_files/test"); + ASSERT_TRUE(RunPlatformAppTest( + "platform_apps/launch_file_with_any_extension")) << message_; +} + +// Tests that launch data is sent through for a file with an extension if a +// handler accepts *. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, + LaunchWithFileAcceptAnyExtension) { + SetCommandLineArg(kTestFilePath); + ASSERT_TRUE(RunPlatformAppTest( + "platform_apps/launch_file_with_any_extension")) << message_; +} + +// Tests that no launch data is sent through if the file has the wrong +// extension. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithWrongExtension) { + SetCommandLineArg(kTestFilePath); + ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_wrong_extension")) + << message_; +} + +// Tests that no launch data is sent through if the file has no extension but +// the handler requires a specific extension. +IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithWrongEmptyExtension) { + SetCommandLineArg("platform_apps/launch_files/test"); + ASSERT_TRUE(RunPlatformAppTest("platform_apps/launch_wrong_extension")) + << message_; +} + // Tests that no launch data is sent through if the file is of the wrong MIME // type. IN_PROC_BROWSER_TEST_F(PlatformAppBrowserTest, LaunchWithWrongType) { diff --git a/chrome/browser/extensions/platform_app_launcher.cc b/chrome/browser/extensions/platform_app_launcher.cc index e13dddc..f0cf0c6 100644 --- a/chrome/browser/extensions/platform_app_launcher.cc +++ b/chrome/browser/extensions/platform_app_launcher.cc @@ -46,8 +46,8 @@ using content::BrowserThread; using extensions::app_file_handler_util::FileHandlerForId; -using extensions::app_file_handler_util::FileHandlerCanHandleFileWithMimeType; -using extensions::app_file_handler_util::FirstFileHandlerForMimeType; +using extensions::app_file_handler_util::FileHandlerCanHandleFile; +using extensions::app_file_handler_util::FirstFileHandlerForFile; using extensions::app_file_handler_util::CreateFileEntry; using extensions::app_file_handler_util::GrantedFileEntry; using extensions::app_file_handler_util::SavedFileEntry; @@ -205,9 +205,8 @@ class PlatformAppPathLauncher if (!handler_id_.empty()) handler = FileHandlerForId(*extension_, handler_id_); else - handler = FirstFileHandlerForMimeType(*extension_, mime_type); - if (handler && - !FileHandlerCanHandleFileWithMimeType(*handler, mime_type)) { + handler = FirstFileHandlerForFile(*extension_, mime_type, file_path_); + if (handler && !FileHandlerCanHandleFile(*handler, mime_type, file_path_)) { LOG(WARNING) << "Extension does not provide a valid file handler for " << file_path_.value(); LaunchWithNoLaunchData(); |