diff options
-rw-r--r-- | chrome/browser/browser_init.cc | 38 | ||||
-rw-r--r-- | chrome/browser/extensions/crx_installer.cc | 1 | ||||
-rw-r--r-- | chrome/browser/shell_integration.cc | 54 | ||||
-rw-r--r-- | chrome/browser/shell_integration.h | 14 | ||||
-rw-r--r-- | chrome/browser/shell_integration_linux.cc | 11 | ||||
-rw-r--r-- | chrome/browser/shell_integration_unittest.cc | 1 | ||||
-rw-r--r-- | chrome/browser/web_applications/web_app.cc | 10 | ||||
-rw-r--r-- | chrome/common/chrome_switches.cc | 4 | ||||
-rw-r--r-- | chrome/common/chrome_switches.h | 1 | ||||
-rw-r--r-- | chrome/common/extensions/extension.cc | 12 | ||||
-rw-r--r-- | chrome/common/extensions/extension.h | 14 | ||||
-rw-r--r-- | chrome/common/extensions/extension_constants.cc | 5 | ||||
-rw-r--r-- | chrome/common/extensions/extension_constants.h | 4 |
13 files changed, 150 insertions, 19 deletions
diff --git a/chrome/browser/browser_init.cc b/chrome/browser/browser_init.cc index 4c90a4b..4353846 100644 --- a/chrome/browser/browser_init.cc +++ b/chrome/browser/browser_init.cc @@ -18,6 +18,7 @@ #include "chrome/browser/chrome_thread.h" #include "chrome/browser/defaults.h" #include "chrome/browser/extensions/extension_creator.h" +#include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/first_run.h" #include "chrome/browser/net/dns_global.h" #include "chrome/browser/profile.h" @@ -504,13 +505,42 @@ bool BrowserInit::LaunchWithProfile::Launch(Profile* profile, } bool BrowserInit::LaunchWithProfile::OpenApplicationURL(Profile* profile) { - if (!command_line_.HasSwitch(switches::kApp)) + if (!command_line_.HasSwitch(switches::kApp) && + !command_line_.HasSwitch(switches::kAppId)) return false; - bool launch_as_panel = - command_line_.HasSwitch(switches::kEnableExtensionApps) && - command_line_.HasSwitch(switches::kAppLaunchAsPanel); std::string url_string(command_line_.GetSwitchValueASCII(switches::kApp)); + bool launch_as_panel = false; + + if (command_line_.HasSwitch(switches::kEnableExtensionApps)) { + if (command_line_.HasSwitch(switches::kAppId)) { + // TODO(rafaelw): There are two legitimate cases where the extensions + // service could not be ready at this point which need to be handled: + // 1) The locale has changed and the manifests stored in the preferences + // need to be relocalized. + // 2) An externally installed extension will be found and installed. + ExtensionsService* extensions_service = profile->GetExtensionsService(); + if (!extensions_service->is_ready()) + return false; + + std::string app_id(command_line_.GetSwitchValueASCII(switches::kAppId)); + Extension* extension_app = + extensions_service->GetExtensionById(app_id, false); + + // The extension with |app_id| could't be found, most likely because it + // was uninstalled. + // TODO(rafaelw): Do something reasonable here. Pop up a warning panel? + // Open a URL to the gallery page of the extension id? + if (!extension_app) + return false; + url_string = extension_app->app_launch_url().spec(); + launch_as_panel = + extension_app->app_launch_window_type() == Extension::PANEL; + } else { + launch_as_panel = command_line_.HasSwitch(switches::kAppLaunchAsPanel); + } + } + #if defined(OS_WIN) // Fix up Windows shortcuts. ReplaceSubstringsAfterOffset(&url_string, 0, "\\x", "%"); #endif diff --git a/chrome/browser/extensions/crx_installer.cc b/chrome/browser/extensions/crx_installer.cc index 675fc02..7549eb2 100644 --- a/chrome/browser/extensions/crx_installer.cc +++ b/chrome/browser/extensions/crx_installer.cc @@ -250,6 +250,7 @@ void CrxInstaller::CompleteInstall() { ShellIntegration::ShortcutInfo shortcut_info; shortcut_info.url = extension_->app_launch_url(); + shortcut_info.extension_id = UTF8ToUTF16(extension_->id()); shortcut_info.title = UTF8ToUTF16(extension_->name()); shortcut_info.description = UTF8ToUTF16(extension_->description()); shortcut_info.favicon = icon; diff --git a/chrome/browser/shell_integration.cc b/chrome/browser/shell_integration.cc index 4ec9096..debaca5 100644 --- a/chrome/browser/shell_integration.cc +++ b/chrome/browser/shell_integration.cc @@ -4,10 +4,64 @@ #include "chrome/browser/shell_integration.h" +#include "base/command_line.h" +#include "base/file_util.h" #include "base/path_service.h" #include "chrome/common/chrome_paths.h" +#include "chrome/common/chrome_switches.h" #include "chrome/browser/chrome_thread.h" +std::string ShellIntegration::GetCommandLineArgumentsCommon(const GURL& url, + const string16& extension_app_id) { + const CommandLine cmd = *CommandLine::ForCurrentProcess(); + std::wstring arguments_w; + + // Use the same UserDataDir for new launches that we currently have set. + std::wstring user_data_dir = cmd.GetSwitchValue(switches::kUserDataDir); + if (!user_data_dir.empty()) { + // Make sure user_data_dir is an absolute path. + if (file_util::AbsolutePath(&user_data_dir) && + file_util::PathExists(FilePath::FromWStringHack(user_data_dir))) { + arguments_w += std::wstring(L"--") + ASCIIToWide(switches::kUserDataDir) + + L"=\"" + user_data_dir + L"\" "; + } + } + +#if defined (OS_CHROMEOS) + std::wstring profile = cmd.GetSwitchValue(switches::kProfile); + if (!profile.empty()) { + arguments_w += std::wstring(L"--") + ASCIIToWide(switches::kProfile) + + L"=\"" + profile + L"\" "; + } +#endif + + // If |extension_app_id| is present, we use the kAppId switch rather than + // the kApp switch (the launch url will be read from the extension app + // during launch. + if (cmd.HasSwitch(switches::kEnableExtensionApps) && + !extension_app_id.empty()) { + arguments_w += std::wstring(L"--") + ASCIIToWide(switches::kAppId) + + L"=\"" + ASCIIToWide(UTF16ToASCII(extension_app_id)) + L"\" --" + + ASCIIToWide(switches::kEnableExtensionApps); + } else { + // Use '--app=url' instead of just 'url' to launch the browser with minimal + // chrome. + // Note: Do not change this flag! Old Gears shortcuts will break if you do! + std::string url_string = url.spec(); + ReplaceSubstringsAfterOffset(&url_string, 0, "\\", "%5C"); + ReplaceSubstringsAfterOffset(&url_string, 0, "\"", "%22"); + ReplaceSubstringsAfterOffset(&url_string, 0, ";", "%3B"); + ReplaceSubstringsAfterOffset(&url_string, 0, "$", "%24"); +#if defined(OS_WIN) // Windows shortcuts can't escape % so we use \x instead. + ReplaceSubstringsAfterOffset(&url_string, 0, "%", "\\x"); +#endif + std::wstring url_w = UTF8ToWide(url_string); + arguments_w += std::wstring(L"--") + ASCIIToWide(switches::kApp) + + L"=\"" + url_w + L"\""; + } + return WideToUTF8(arguments_w); +} + /////////////////////////////////////////////////////////////////////////////// // ShellIntegration::DefaultBrowserWorker // diff --git a/chrome/browser/shell_integration.h b/chrome/browser/shell_integration.h index 020e46d..5a24ea9 100644 --- a/chrome/browser/shell_integration.h +++ b/chrome/browser/shell_integration.h @@ -43,6 +43,10 @@ class ShellIntegration { struct ShortcutInfo { GURL url; + // If |extension_id| is non-empty, this is short cut is to an extension-app + // and the launch url will be detected at start-up. In this case, |url| + // is still used to generate the app id (windows app id, not chrome app id). + string16 extension_id; string16 title; string16 description; SkBitmap favicon; @@ -57,6 +61,13 @@ class ShellIntegration { bool create_in_quick_launch_bar; }; + // Re-implementation of chrome_plugin_utill::CPB_GetCommandLineArgumentsCommon + // which is deprecated. If |extension_app_id| is non-empty, an arguments + // string is created using the kAppId=<id> flag. Otherwise, the kApp=<url> is + // used. + static std::string GetCommandLineArgumentsCommon(const GURL& url, + const string16& extension_app_id); + #if defined(OS_LINUX) // Returns filename for .desktop file based on |url|, sanitized for security. static FilePath GetDesktopShortcutFilename(const GURL& url); @@ -66,7 +77,8 @@ class ShellIntegration { // used to launch Chrome. static std::string GetDesktopFileContents( const std::string& template_contents, const GURL& url, - const string16& title, const std::string& icon_name); + const string16& extension_id, const string16& title, + const std::string& icon_name); // Creates a desktop shortcut. It is not guaranteed to exist immediately after // returning from this function, because actual file operation is done on the diff --git a/chrome/browser/shell_integration_linux.cc b/chrome/browser/shell_integration_linux.cc index 3766249..78f765b 100644 --- a/chrome/browser/shell_integration_linux.cc +++ b/chrome/browser/shell_integration_linux.cc @@ -135,8 +135,8 @@ class CreateDesktopShortcutTask : public Task { std::string icon_name = CreateIcon(shortcut_filename); std::string contents = ShellIntegration::GetDesktopFileContents( - template_contents, shortcut_info_.url, shortcut_info_.title, - icon_name); + template_contents, shortcut_info_.url, shortcut_info_.extension_id, + shortcut_info_.title, icon_name); if (shortcut_info_.create_on_desktop) CreateOnDesktop(shortcut_filename, contents); @@ -327,7 +327,8 @@ FilePath ShellIntegration::GetDesktopShortcutFilename(const GURL& url) { std::string ShellIntegration::GetDesktopFileContents( const std::string& template_contents, const GURL& url, - const string16& title, const std::string& icon_name) { + const string16& extension_id, const string16& title, + const std::string& icon_name) { // See http://standards.freedesktop.org/desktop-entry-spec/latest/ // Although not required by the spec, Nautilus on Ubuntu Karmic creates its // launchers with an xdg-open shebang. Follow that convention. @@ -342,8 +343,8 @@ std::string ShellIntegration::GetDesktopFileContents( if (exec_tokenizer.token() != "%U") final_path += exec_tokenizer.token() + " "; } - std::string switches; - CPB_GetCommandLineArgumentsCommon(url.spec().c_str(), &switches); + std::string switches = + ShellIntegration::GetCommandLineArgumentsCommon(url, extension_id); output_buffer += std::string("Exec=") + final_path + switches + "\n"; } else if (tokenizer.token().substr(0, 5) == "Name=") { std::string final_title = UTF16ToUTF8(title); diff --git a/chrome/browser/shell_integration_unittest.cc b/chrome/browser/shell_integration_unittest.cc index e409013..cfbaed9 100644 --- a/chrome/browser/shell_integration_unittest.cc +++ b/chrome/browser/shell_integration_unittest.cc @@ -167,6 +167,7 @@ TEST(ShellIntegrationTest, GetDesktopFileContents) { ShellIntegration::GetDesktopFileContents( test_cases[i].template_contents, GURL(test_cases[i].url), + EmptyString16(), ASCIIToUTF16(test_cases[i].title), test_cases[i].icon_name)); } diff --git a/chrome/browser/web_applications/web_app.cc b/chrome/browser/web_applications/web_app.cc index 192c04d..b85035d 100644 --- a/chrome/browser/web_applications/web_app.cc +++ b/chrome/browser/web_applications/web_app.cc @@ -345,13 +345,9 @@ bool CreateShortcutTask::CreateShortcut() { // Working directory. std::wstring chrome_folder = file_util::GetDirectoryFromPath(chrome_exe); - // Gets the command line switches. - std::string switches; - if (CPB_GetCommandLineArgumentsCommon(shortcut_info_.url.spec().c_str(), - &switches) != CPERR_SUCCESS) { - NOTREACHED(); - return false; - } + std::string switches = + ShellIntegration::GetCommandLineArgumentsCommon(shortcut_info_.url, + shortcut_info_.extension_id); std::wstring wide_switchs(UTF8ToWide(switches)); // Generates app id from web app url and profile path. diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index cd00a4b..2a879fd 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -27,6 +27,10 @@ const char kAlwaysEnableDevTools[] = "always-enable-dev-tools"; // Specifies that the associated value should be launched in "application" mode. const char kApp[] = "app"; +// Specifies that the extension-app with the specified id should be launched +// according to its configuration. +const char kAppId[] = "app-id"; + // Lacks meaning with out kApp. Causes the specified app to be launched in an // panel window. const char kAppLaunchAsPanel[] = "app-launch-as-panel"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 07ba50b..e61a217 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -23,6 +23,7 @@ extern const char kActivateOnLaunch[]; extern const char kAllowSandboxDebugging[]; extern const char kAlwaysEnableDevTools[]; extern const char kApp[]; +extern const char kAppId[]; extern const char kAppLaunchAsPanel[]; extern const char kAutomationClientChannelID[]; extern const char kBookmarkMenu[]; diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc index 7bc46b6..8bd7b2f 100644 --- a/chrome/common/extensions/extension.cc +++ b/chrome/common/extensions/extension.cc @@ -537,6 +537,18 @@ bool Extension::LoadAppHelper(const DictionaryValue* app, std::string* error) { return false; } + // launch window type + app_launch_window_type_ = APP; + std::string window_type_string; + if (app->GetString(keys::kAppLaunchWindowType, &window_type_string)) { + if (window_type_string == std::string(values::kWindowTypePanel)) { + app_launch_window_type_ = PANEL; + } else if (window_type_string != std::string(values::kWindowTypeApp)) { + *error = errors::kInvalidAppLaunchWindowType; + return false; + } + } + // The launch URL is automatically added to the extent. URLPattern pattern; pattern.set_scheme(app_launch_url_.scheme()); diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h index c0c5a53..c858534 100644 --- a/chrome/common/extensions/extension.h +++ b/chrome/common/extensions/extension.h @@ -62,6 +62,11 @@ class Extension { EXTENSION_ICON_BITTY = 16, }; + enum AppLaunchWindowType { + APP, + PANEL + }; + // Icon sizes used by the extension system. static const int kIconSizes[]; @@ -283,6 +288,9 @@ class Extension { const URLPatternList& app_extent() const { return app_extent_; } const GURL& app_launch_url() const { return app_launch_url_; } bool IsApp() const { return !app_launch_url_.is_empty(); } + AppLaunchWindowType app_launch_window_type() { + return app_launch_window_type_; + } private: // Helper method that loads a UserScript object from a @@ -415,8 +423,10 @@ class Extension { // The URL an app should launch to. GURL app_launch_url_; - - + + // The type of window to start when the application is launched. + AppLaunchWindowType app_launch_window_type_; + // Runtime data: // True if the background page is ready. diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc index 1caa9e7..570e90d 100644 --- a/chrome/common/extensions/extension_constants.cc +++ b/chrome/common/extensions/extension_constants.cc @@ -10,6 +10,7 @@ const wchar_t* kAllFrames = L"all_frames"; const wchar_t* kApp = L"app"; const wchar_t* kAppExtent = L"extent"; const wchar_t* kAppLaunchUrl = L"launch.url"; +const wchar_t* kAppLaunchWindowType = L"launch.window_type"; const wchar_t* kBackground = L"background_page"; const wchar_t* kBrowserAction = L"browser_action"; const wchar_t* kChromeURLOverrides = L"chrome_url_overrides"; @@ -64,6 +65,8 @@ const char* kRunAtDocumentEnd = "document_end"; const char* kRunAtDocumentIdle = "document_idle"; const char* kPageActionTypeTab = "tab"; const char* kPageActionTypePermanent = "permanent"; +const char* kWindowTypeApp = "app"; +const char* kWindowTypePanel = "panel"; } // namespace extension_manifest_values // Extension-related error messages. Some of these are simple patterns, where a @@ -80,6 +83,8 @@ const char* kInvalidAppExtent = "Invalid value for app.extent."; const char* kInvalidAppExtentPattern = "Invalid value for app.extent[*]."; const char* kInvalidAppLaunchUrl = "Required value 'app.launch.url' is missing or invalid."; +const char* kInvalidAppLaunchWindowType = + "Invalid value for 'app.launch.window_type'."; const char* kInvalidBrowserAction = "Invalid value for 'browser_action'."; const char* kInvalidChromeURLOverrides = diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h index ac37214..f71d1eb 100644 --- a/chrome/common/extensions/extension_constants.h +++ b/chrome/common/extensions/extension_constants.h @@ -11,6 +11,7 @@ namespace extension_manifest_keys { extern const wchar_t* kApp; extern const wchar_t* kAppExtent; extern const wchar_t* kAppLaunchUrl; + extern const wchar_t* kAppLaunchWindowType; extern const wchar_t* kBackground; extern const wchar_t* kBrowserAction; extern const wchar_t* kMinimumChromeVersion; @@ -66,6 +67,8 @@ namespace extension_manifest_values { extern const char* kRunAtDocumentIdle; extern const char* kPageActionTypeTab; extern const char* kPageActionTypePermanent; + extern const char* kWindowTypeApp; + extern const char* kWindowTypePanel; } // namespace extension_manifest_values // Error messages returned from Extension::InitFromValue(). @@ -76,6 +79,7 @@ namespace extension_manifest_errors { extern const char* kInvalidAppExtent; extern const char* kInvalidAppExtentPattern; extern const char* kInvalidAppLaunchUrl; + extern const char* kInvalidAppLaunchWindowType; extern const char* kInvalidBackground; extern const char* kInvalidBrowserAction; extern const char* kInvalidChromeURLOverrides; |