diff options
author | erikkay@chromium.org <erikkay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-12 17:28:56 +0000 |
---|---|---|
committer | erikkay@chromium.org <erikkay@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-12 17:28:56 +0000 |
commit | c28071ad39fdf60db886e6d6844da7c3331825a6 (patch) | |
tree | 89edfcbf7bd70f18191496fbefafe843316e6139 | |
parent | a883f8fc702c2cb37130361b7ddc6fc86a8f2edf (diff) | |
download | chromium_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.cc | 61 | ||||
-rw-r--r-- | chrome/browser/browser.h | 13 | ||||
-rw-r--r-- | chrome/browser/browser_init.cc | 84 | ||||
-rw-r--r-- | chrome/browser/browser_init.h | 12 | ||||
-rw-r--r-- | chrome/common/extensions/extension.cc | 18 | ||||
-rw-r--r-- | chrome/common/extensions/extension.h | 15 | ||||
-rw-r--r-- | chrome/common/extensions/extension_constants.cc | 11 | ||||
-rw-r--r-- | chrome/common/extensions/extension_constants.h | 9 |
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; |