summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorerikkay@chromium.org <erikkay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-12 17:28:56 +0000
committererikkay@chromium.org <erikkay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-12 17:28:56 +0000
commitc28071ad39fdf60db886e6d6844da7c3331825a6 (patch)
tree89edfcbf7bd70f18191496fbefafe843316e6139
parenta883f8fc702c2cb37130361b7ddc6fc86a8f2edf (diff)
downloadchromium_src-c28071ad39fdf60db886e6d6844da7c3331825a6.zip
chromium_src-c28071ad39fdf60db886e6d6844da7c3331825a6.tar.gz
chromium_src-c28071ad39fdf60db886e6d6844da7c3331825a6.tar.bz2
Support app tabs as a launch point for apps. Also, move the logic for launching into Browser for easier access by the launcher.
BUG=none TEST=none Review URL: http://codereview.chromium.org/668245 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41441 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/browser.cc61
-rw-r--r--chrome/browser/browser.h13
-rw-r--r--chrome/browser/browser_init.cc84
-rw-r--r--chrome/browser/browser_init.h12
-rw-r--r--chrome/common/extensions/extension.cc18
-rw-r--r--chrome/common/extensions/extension.h15
-rw-r--r--chrome/common/extensions/extension_constants.cc11
-rw-r--r--chrome/common/extensions/extension_constants.h9
8 files changed, 156 insertions, 67 deletions
diff --git a/chrome/browser/browser.cc b/chrome/browser/browser.cc
index 00cccfa..f4e1b3c7 100644
--- a/chrome/browser/browser.cc
+++ b/chrome/browser/browser.cc
@@ -365,6 +365,41 @@ void Browser::OpenURLOffTheRecord(Profile* profile, const GURL& url) {
}
// static
+// TODO(erikkay): There are multiple reasons why this could fail. Should
+// this function return an error reason as well so that callers can show
+// reasonable errors?
+bool Browser::OpenApplication(Profile* profile, const std::string& app_id) {
+ ExtensionsService* extensions_service = profile->GetExtensionsService();
+ if (!extensions_service->is_ready())
+ return false;
+
+ // If the extension with |app_id| could't be found, most likely because it
+ // was uninstalled.
+ Extension* extension_app =
+ extensions_service->GetExtensionById(app_id, false);
+ if (!extension_app)
+ return false;
+
+ // TODO(erikkay): Support refocus.
+ Extension::AppLaunchType launch_type =
+ extension_app->app_launch_type();
+ switch (launch_type) {
+ case Extension::LAUNCH_WINDOW:
+ case Extension::LAUNCH_PANEL:
+ Browser::OpenApplicationWindow(profile, extension_app);
+ break;
+ case Extension::LAUNCH_TAB: {
+ return Browser::OpenApplicationTab(profile, extension_app);
+ break;
+ }
+ default:
+ NOTREACHED();
+ return false;
+ }
+ return true;
+}
+
+// static
void Browser::OpenApplicationWindow(Profile* profile, const GURL& url,
bool as_panel) {
std::wstring app_name = web_app::GenerateApplicationNameFromURL(url);
@@ -393,6 +428,32 @@ void Browser::OpenApplicationWindow(Profile* profile, const GURL& url,
}
// static
+void Browser::OpenApplicationWindow(Profile* profile, Extension* extension) {
+ OpenApplicationWindow(profile,
+ extension->app_launch_url(),
+ (extension->app_launch_type() == Extension::LAUNCH_PANEL));
+}
+
+// static
+bool Browser::OpenApplicationTab(Profile* profile, Extension* extension) {
+ DCHECK_EQ(extension->app_launch_type(), Extension::LAUNCH_TAB);
+
+ Browser* browser = BrowserList::GetLastActiveWithProfile(profile);
+ if (!browser || browser->type() != Browser::TYPE_NORMAL)
+ return false;
+
+ // TODO(erikkay): This doesn't seem like the right transition in all cases.
+ PageTransition::Type transition = PageTransition::START_PAGE;
+ GURL url = extension->app_launch_url();
+ TabContents* tab_contents =
+ browser->CreateTabContentsForURL(url, GURL(), profile,
+ transition, false, NULL);
+ tab_contents->SetAppExtension(extension);
+ browser->AddTab(tab_contents, transition);
+ return true;
+}
+
+// static
void Browser::OpenBookmarkManagerWindow(Profile* profile) {
Browser* browser = Browser::Create(profile);
browser->ShowBookmarkManagerTab();
diff --git a/chrome/browser/browser.h b/chrome/browser/browser.h
index 6ac5f01..b3aba9a 100644
--- a/chrome/browser/browser.h
+++ b/chrome/browser/browser.h
@@ -27,6 +27,7 @@
class BrowserWindow;
class DebuggerWindow;
+class Extension;
class ExtensionShelfModel;
class FindBarController;
class GoButton;
@@ -180,6 +181,11 @@ class Browser : public TabStripModelDelegate,
// |profile|, that session is re-used.
static void OpenURLOffTheRecord(Profile* profile, const GURL& url);
+ // Open an application specified by |app_id| in the appropriate launch
+ // container. Returns false if the app_id is invalid or if ExtensionsService
+ // isn't ready/available.
+ static bool OpenApplication(Profile* profile, const std::string& app_id);
+
// Opens a new application window for the specified url. If |as_panel|
// is true, the application will be opened as a Browser::Type::APP_PANEL in
// app panel window, otherwise it will be opened as a Browser::Type::APP,
@@ -187,6 +193,13 @@ class Browser : public TabStripModelDelegate,
static void OpenApplicationWindow(Profile* profile, const GURL& url,
bool as_panel);
+ // Open an application for |extension| in a new application window or panel.
+ static void OpenApplicationWindow(Profile* profile, Extension* extension);
+
+ // Open an application for |extension| in a new application tab. Returns
+ // false if there are no appropriate existing browser windows for |profile|.
+ static bool OpenApplicationTab(Profile* profile, Extension* extension);
+
// Opens a new window and opens the bookmark manager.
static void OpenBookmarkManagerWindow(Profile* profile);
diff --git a/chrome/browser/browser_init.cc b/chrome/browser/browser_init.cc
index 8481acf..a983a76 100644
--- a/chrome/browser/browser_init.cc
+++ b/chrome/browser/browser_init.cc
@@ -460,8 +460,8 @@ bool BrowserInit::LaunchWithProfile::Launch(Profile* profile,
}
// Open the required browser windows and tabs.
- // First, see if we're being run as a web application (thin frame window).
- if (!OpenApplicationURL(profile)) {
+ // First, see if we're being run as an application window.
+ if (!OpenApplicationWindow(profile)) {
std::vector<GURL> urls_to_open = GetURLsFromCommandLine(profile_);
RecordLaunchModeHistogram(urls_to_open.empty()?
LM_TO_BE_DECIDED : LM_WITH_URLS);
@@ -477,6 +477,16 @@ bool BrowserInit::LaunchWithProfile::Launch(Profile* profile,
OpenURLsInBrowser(browser, process_startup, urls_to_open);
}
+
+ // If this is an app launch, but we didn't open an app window, it may
+ // be an app tab.
+ std::string app_id;
+ if (IsAppLaunch(NULL, &app_id) && !app_id.empty()) {
+ // TODO(erikkay): This could fail if |app_id| is invalid (the app was
+ // uninstalled). We may want to show some reasonable error here.
+ Browser::OpenApplication(profile, app_id);
+ }
+
if (process_startup) {
if (browser_defaults::kOSSupportsOtherBrowsers &&
!command_line_.HasSwitch(switches::kNoDefaultBrowserCheck)) {
@@ -525,43 +535,41 @@ bool BrowserInit::LaunchWithProfile::Launch(Profile* profile,
return true;
}
-bool BrowserInit::LaunchWithProfile::OpenApplicationURL(Profile* profile) {
- if (!command_line_.HasSwitch(switches::kApp) &&
- !command_line_.HasSwitch(switches::kAppId))
- return false;
-
- 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)) {
- // http://crbug.com/37548
- // 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;
+bool BrowserInit::LaunchWithProfile::IsAppLaunch(std::string* app_url,
+ std::string* app_id) {
+ if (command_line_.HasSwitch(switches::kApp)) {
+ if (app_url)
+ *app_url = command_line_.GetSwitchValueASCII(switches::kApp);
+ return true;
+ }
+ if (command_line_.HasSwitch(switches::kEnableExtensionApps) &&
+ command_line_.HasSwitch(switches::kAppId)) {
+ if (app_id)
+ *app_id = command_line_.GetSwitchValueASCII(switches::kAppId);
+ return true;
+ }
+ return false;
+}
- std::string app_id(command_line_.GetSwitchValueASCII(switches::kAppId));
- Extension* extension_app =
- extensions_service->GetExtensionById(app_id, false);
+bool BrowserInit::LaunchWithProfile::OpenApplicationWindow(Profile* profile) {
+ std::string url_string, app_id;
+ if (!IsAppLaunch(&url_string, &app_id))
+ return 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);
- }
- }
+ // http://crbug.com/37548
+ // 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.
+ // Note that this can also fail if the app_id is simply invalid.
+ // TODO(rafaelw): Do something reasonable here. Pop up a warning panel?
+ // Open an URL to the gallery page of the extension id?
+ if (!app_id.empty())
+ return Browser::OpenApplication(profile, app_id);
+
+ if (url_string.empty())
+ return false;
#if defined(OS_WIN) // Fix up Windows shortcuts.
ReplaceSubstringsAfterOffset(&url_string, 0, "\\x", "%");
@@ -574,7 +582,7 @@ bool BrowserInit::LaunchWithProfile::OpenApplicationURL(Profile* profile) {
ChildProcessSecurityPolicy::GetInstance();
if (policy->IsWebSafeScheme(url.scheme()) ||
url.SchemeIs(chrome::kFileScheme)) {
- Browser::OpenApplicationWindow(profile, url, launch_as_panel);
+ Browser::OpenApplicationWindow(profile, url, false);
return true;
}
}
diff --git a/chrome/browser/browser_init.h b/chrome/browser/browser_init.h
index 28653f1..1f736b5 100644
--- a/chrome/browser/browser_init.h
+++ b/chrome/browser/browser_init.h
@@ -110,11 +110,15 @@ class BrowserInit {
const std::vector<GURL>& urls);
private:
- // If the process was launched with the web application command line flag,
- // e.g. --app=http://www.google.com/, opens a web application browser and
- // returns true. If there is no web application command line flag speciifed,
+ // If the process was launched with the web application command line flags,
+ // e.g. --app=http://www.google.com/ or --app_id=... return true.
+ // In this case |app_url| or |app_id| are populated if they're non-null.
+ bool IsAppLaunch(std::string* app_url, std::string* app_id);
+
+ // If IsAppLaunch is true, tries to open an application window.
+ // If the app is specified to start in a tab, or IsAppLaunch is false,
// returns false to specify default processing.
- bool OpenApplicationURL(Profile* profile);
+ bool OpenApplicationWindow(Profile* profile);
// Does the following:
// . If the user's startup pref is to restore the last session (or the
diff --git a/chrome/common/extensions/extension.cc b/chrome/common/extensions/extension.cc
index 90158b9..a15669d 100644
--- a/chrome/common/extensions/extension.cc
+++ b/chrome/common/extensions/extension.cc
@@ -507,14 +507,16 @@ 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;
+ // launch type
+ app_launch_type_ = LAUNCH_WINDOW; // TODO(erikkay) LAUNCH_TAB?
+ std::string launch_type_string;
+ if (app->GetString(keys::kAppLaunchType, &launch_type_string)) {
+ if (launch_type_string == std::string(values::kLaunchTypePanel)) {
+ app_launch_type_ = LAUNCH_PANEL;
+ } else if (launch_type_string == std::string(values::kLaunchTypeTab)) {
+ app_launch_type_ = LAUNCH_TAB;
+ } else if (launch_type_string != std::string(values::kLaunchTypeWindow)) {
+ *error = errors::kInvalidAppLaunchType;
return false;
}
}
diff --git a/chrome/common/extensions/extension.h b/chrome/common/extensions/extension.h
index 0877369..51d6931 100644
--- a/chrome/common/extensions/extension.h
+++ b/chrome/common/extensions/extension.h
@@ -67,9 +67,10 @@ class Extension {
EXTENSION_ICON_BITTY = 16,
};
- enum AppLaunchWindowType {
- APP,
- PANEL
+ enum AppLaunchType {
+ LAUNCH_WINDOW,
+ LAUNCH_PANEL,
+ LAUNCH_TAB
};
// Icon sizes used by the extension system.
@@ -284,9 +285,7 @@ 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_;
- }
+ AppLaunchType app_launch_type() { return app_launch_type_; }
const GURL& app_origin() const { return app_origin_; }
// Runtime data:
@@ -439,8 +438,8 @@ 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_;
+ // How to start when the application is launched.
+ AppLaunchType app_launch_type_;
// The web security origin associated with the app. This origin will be
// granted the permissions the app requests.
diff --git a/chrome/common/extensions/extension_constants.cc b/chrome/common/extensions/extension_constants.cc
index 173b4fa..1c9c5c9 100644
--- a/chrome/common/extensions/extension_constants.cc
+++ b/chrome/common/extensions/extension_constants.cc
@@ -10,7 +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* kAppLaunchType = L"launch.window_type"; // TODO(erikkay) rename
const wchar_t* kAppOrigin = L"origin";
const wchar_t* kBackground = L"background_page";
const wchar_t* kBrowserAction = L"browser_action";
@@ -66,8 +66,9 @@ 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";
+const char* kLaunchTypePanel = "panel";
+const char* kLaunchTypeTab = "tab";
+const char* kLaunchTypeWindow = "window";
} // namespace extension_manifest_values
// Extension-related error messages. Some of these are simple patterns, where a
@@ -83,10 +84,10 @@ const char* kInvalidAllFrames =
const char* kInvalidApp = "Invalid app.";
const char* kInvalidAppExtent = "Invalid value for app.extent.";
const char* kInvalidAppExtentPattern = "Invalid value for app.extent[*].";
+const char* kInvalidAppLaunchType =
+ "Invalid value for 'app.launch.window_type'.";
const char* kInvalidAppLaunchUrl =
"Required value 'app.launch.url' is missing or invalid.";
-const char* kInvalidAppLaunchWindowType =
- "Invalid value for 'app.launch.window_type'.";
const char* kInvalidAppOrigin =
"Invalid value for 'app.origin'. Value must be a URL of the form "
"scheme://host[:port]/ where scheme is http or https.";
diff --git a/chrome/common/extensions/extension_constants.h b/chrome/common/extensions/extension_constants.h
index f06a0e5..453fb1c 100644
--- a/chrome/common/extensions/extension_constants.h
+++ b/chrome/common/extensions/extension_constants.h
@@ -11,7 +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* kAppLaunchType;
extern const wchar_t* kAppOrigin;
extern const wchar_t* kBackground;
extern const wchar_t* kBrowserAction;
@@ -68,8 +68,9 @@ namespace extension_manifest_values {
extern const char* kRunAtDocumentIdle;
extern const char* kPageActionTypeTab;
extern const char* kPageActionTypePermanent;
- extern const char* kWindowTypeApp;
- extern const char* kWindowTypePanel;
+ extern const char* kLaunchTypePanel;
+ extern const char* kLaunchTypeTab;
+ extern const char* kLaunchTypeWindow;
} // namespace extension_manifest_values
// Error messages returned from Extension::InitFromValue().
@@ -80,8 +81,8 @@ namespace extension_manifest_errors {
extern const char* kInvalidApp;
extern const char* kInvalidAppExtent;
extern const char* kInvalidAppExtentPattern;
+ extern const char* kInvalidAppLaunchType;
extern const char* kInvalidAppLaunchUrl;
- extern const char* kInvalidAppLaunchWindowType;
extern const char* kInvalidAppOrigin;
extern const char* kInvalidBackground;
extern const char* kInvalidBrowserAction;