summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/browser_init.cc38
-rw-r--r--chrome/browser/extensions/crx_installer.cc1
-rw-r--r--chrome/browser/shell_integration.cc54
-rw-r--r--chrome/browser/shell_integration.h14
-rw-r--r--chrome/browser/shell_integration_linux.cc11
-rw-r--r--chrome/browser/shell_integration_unittest.cc1
-rw-r--r--chrome/browser/web_applications/web_app.cc10
-rw-r--r--chrome/common/chrome_switches.cc4
-rw-r--r--chrome/common/chrome_switches.h1
-rw-r--r--chrome/common/extensions/extension.cc12
-rw-r--r--chrome/common/extensions/extension.h14
-rw-r--r--chrome/common/extensions/extension_constants.cc5
-rw-r--r--chrome/common/extensions/extension_constants.h4
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;