| Index: chrome/browser/extensions/extension_tab_util.cc
|
| diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc
|
| index be7f4c9640555885503eecd615f2ef1a821322f8..1537a33e8ed4d0b4f06d9a57fcd96724029f4ca0 100644
|
| --- a/chrome/browser/extensions/extension_tab_util.cc
|
| +++ b/chrome/browser/extensions/extension_tab_util.cc
|
| @@ -6,7 +6,9 @@
|
|
|
| #include "apps/app_window.h"
|
| #include "apps/app_window_registry.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| #include "chrome/browser/extensions/api/tabs/tabs_constants.h"
|
| +#include "chrome/browser/extensions/chrome_extension_function.h"
|
| #include "chrome/browser/extensions/tab_helper.h"
|
| #include "chrome/browser/extensions/window_controller.h"
|
| #include "chrome/browser/extensions/window_controller_list.h"
|
| @@ -26,8 +28,11 @@
|
| #include "content/public/browser/navigation_entry.h"
|
| #include "content/public/browser/web_contents.h"
|
| #include "content/public/browser/web_contents_view.h"
|
| +#include "extensions/common/constants.h"
|
| +#include "extensions/common/error_utils.h"
|
| #include "extensions/common/extension.h"
|
| #include "extensions/common/manifest_constants.h"
|
| +#include "extensions/common/manifest_handlers/incognito_info.h"
|
| #include "extensions/common/permissions/api_permission.h"
|
| #include "extensions/common/permissions/permissions_data.h"
|
| #include "url/gurl.h"
|
| @@ -55,8 +60,222 @@ WindowController* GetAppWindowController(const WebContents* contents) {
|
| app_window->session_id().id());
|
| }
|
|
|
| +// |error_message| can optionally be passed in and will be set with an
|
| +// appropriate message if the window cannot be found by id.
|
| +Browser* GetBrowserInProfileWithId(Profile* profile,
|
| + const int window_id,
|
| + bool include_incognito,
|
| + std::string* error_message) {
|
| + Profile* incognito_profile =
|
| + include_incognito && profile->HasOffTheRecordProfile()
|
| + ? profile->GetOffTheRecordProfile()
|
| + : NULL;
|
| + for (chrome::BrowserIterator it; !it.done(); it.Next()) {
|
| + Browser* browser = *it;
|
| + if ((browser->profile() == profile ||
|
| + browser->profile() == incognito_profile) &&
|
| + ExtensionTabUtil::GetWindowId(browser) == window_id &&
|
| + browser->window()) {
|
| + return browser;
|
| + }
|
| + }
|
| +
|
| + if (error_message)
|
| + *error_message = ErrorUtils::FormatErrorMessage(
|
| + keys::kWindowNotFoundError, base::IntToString(window_id));
|
| +
|
| + return NULL;
|
| +}
|
| +
|
| +Browser* CreateBrowser(ChromeAsyncExtensionFunction* function,
|
| + int window_id,
|
| + std::string* error) {
|
| + content::WebContents* web_contents = function->GetAssociatedWebContents();
|
| + DCHECK(web_contents);
|
| + DCHECK(web_contents->GetView());
|
| + DCHECK(web_contents->GetView()->GetNativeView());
|
| + DCHECK(!chrome::FindBrowserWithWebContents(web_contents));
|
| +
|
| + chrome::HostDesktopType desktop_type =
|
| + chrome::GetHostDesktopTypeForNativeView(
|
| + web_contents->GetView()->GetNativeView());
|
| + Browser::CreateParams params(
|
| + Browser::TYPE_TABBED, function->GetProfile(), desktop_type);
|
| + Browser* browser = new Browser(params);
|
| + browser->window()->Show();
|
| + return browser;
|
| +}
|
| +
|
| } // namespace
|
|
|
| +ExtensionTabUtil::OpenTabParams::OpenTabParams()
|
| + : create_browser_if_needed(false) {
|
| +}
|
| +
|
| +ExtensionTabUtil::OpenTabParams::~OpenTabParams() {
|
| +}
|
| +
|
| +// Opens a new tab for a given extension. Returns NULL and sets |error| if an
|
| +// error occurs.
|
| +base::DictionaryValue* ExtensionTabUtil::OpenTab(
|
| + ChromeAsyncExtensionFunction* function,
|
| + const OpenTabParams& params,
|
| + std::string* error) {
|
| + // windowId defaults to "current" window.
|
| + int window_id = extension_misc::kCurrentWindowId;
|
| + if (params.window_id.get())
|
| + window_id = *params.window_id;
|
| +
|
| + Browser* browser = GetBrowserFromWindowID(function, window_id, error);
|
| + if (!browser) {
|
| + if (!params.create_browser_if_needed) {
|
| + return NULL;
|
| + }
|
| + browser = CreateBrowser(function, window_id, error);
|
| + if (!browser)
|
| + return NULL;
|
| + }
|
| +
|
| + // Ensure the selected browser is tabbed.
|
| + if (!browser->is_type_tabbed() && browser->IsAttemptingToCloseBrowser())
|
| + browser = chrome::FindTabbedBrowser(function->GetProfile(),
|
| + function->include_incognito(),
|
| + browser->host_desktop_type());
|
| +
|
| + if (!browser || !browser->window()) {
|
| + // TODO(rpaquay): Error message?
|
| + return NULL;
|
| + }
|
| +
|
| + // TODO(jstritar): Add a constant, chrome.tabs.TAB_ID_ACTIVE, that
|
| + // represents the active tab.
|
| + WebContents* opener = NULL;
|
| + if (params.opener_tab_id.get()) {
|
| + int opener_id = *params.opener_tab_id;
|
| +
|
| + if (!ExtensionTabUtil::GetTabById(opener_id,
|
| + function->GetProfile(),
|
| + function->include_incognito(),
|
| + NULL,
|
| + NULL,
|
| + &opener,
|
| + NULL)) {
|
| + // TODO(rpaquay): Error message?
|
| + return NULL;
|
| + }
|
| + }
|
| +
|
| + // TODO(rafaelw): handle setting remaining tab properties:
|
| + // -title
|
| + // -favIconUrl
|
| +
|
| + std::string url_string;
|
| + GURL url;
|
| + if (params.url.get()) {
|
| + url_string = *params.url;
|
| + url = ExtensionTabUtil::ResolvePossiblyRelativeURL(
|
| + url_string, function->GetExtension());
|
| + if (!url.is_valid()) {
|
| + *error =
|
| + ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, url_string);
|
| + return NULL;
|
| + }
|
| + }
|
| +
|
| + // Don't let extensions crash the browser or renderers.
|
| + if (ExtensionTabUtil::IsCrashURL(url)) {
|
| + *error = keys::kNoCrashBrowserError;
|
| + return NULL;
|
| + }
|
| +
|
| + // Default to foreground for the new tab. The presence of 'active' property
|
| + // will override this default.
|
| + bool active = true;
|
| + if (params.active.get())
|
| + active = *params.active;
|
| +
|
| + // Default to not pinning the tab. Setting the 'pinned' property to true
|
| + // will override this default.
|
| + bool pinned = false;
|
| + if (params.pinned.get())
|
| + pinned = *params.pinned;
|
| +
|
| + // We can't load extension URLs into incognito windows unless the extension
|
| + // uses split mode. Special case to fall back to a tabbed window.
|
| + if (url.SchemeIs(kExtensionScheme) &&
|
| + !IncognitoInfo::IsSplitMode(function->GetExtension()) &&
|
| + browser->profile()->IsOffTheRecord()) {
|
| + Profile* profile = browser->profile()->GetOriginalProfile();
|
| + chrome::HostDesktopType desktop_type = browser->host_desktop_type();
|
| +
|
| + browser = chrome::FindTabbedBrowser(profile, false, desktop_type);
|
| + if (!browser) {
|
| + browser = new Browser(
|
| + Browser::CreateParams(Browser::TYPE_TABBED, profile, desktop_type));
|
| + browser->window()->Show();
|
| + }
|
| + }
|
| +
|
| + // If index is specified, honor the value, but keep it bound to
|
| + // -1 <= index <= tab_strip->count() where -1 invokes the default behavior.
|
| + int index = -1;
|
| + if (params.index.get())
|
| + index = *params.index;
|
| +
|
| + TabStripModel* tab_strip = browser->tab_strip_model();
|
| +
|
| + index = std::min(std::max(index, -1), tab_strip->count());
|
| +
|
| + int add_types = active ? TabStripModel::ADD_ACTIVE : TabStripModel::ADD_NONE;
|
| + add_types |= TabStripModel::ADD_FORCE_INDEX;
|
| + if (pinned)
|
| + add_types |= TabStripModel::ADD_PINNED;
|
| + chrome::NavigateParams navigate_params(
|
| + browser, url, content::PAGE_TRANSITION_LINK);
|
| + navigate_params.disposition =
|
| + active ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB;
|
| + navigate_params.tabstrip_index = index;
|
| + navigate_params.tabstrip_add_types = add_types;
|
| + chrome::Navigate(&navigate_params);
|
| +
|
| + // The tab may have been created in a different window, so make sure we look
|
| + // at the right tab strip.
|
| + tab_strip = navigate_params.browser->tab_strip_model();
|
| + int new_index =
|
| + tab_strip->GetIndexOfWebContents(navigate_params.target_contents);
|
| + if (opener)
|
| + tab_strip->SetOpenerOfWebContentsAt(new_index, opener);
|
| +
|
| + if (active)
|
| + navigate_params.target_contents->GetView()->SetInitialFocus();
|
| +
|
| + // Return data about the newly created tab.
|
| + return ExtensionTabUtil::CreateTabValue(navigate_params.target_contents,
|
| + tab_strip,
|
| + new_index,
|
| + function->GetExtension());
|
| +}
|
| +
|
| +Browser* ExtensionTabUtil::GetBrowserFromWindowID(
|
| + ChromeAsyncExtensionFunction* function,
|
| + int window_id,
|
| + std::string* error) {
|
| + if (window_id == extension_misc::kCurrentWindowId) {
|
| + Browser* result = function->GetCurrentBrowser();
|
| + if (!result || !result->window()) {
|
| + if (error)
|
| + *error = keys::kNoCurrentWindowError;
|
| + return NULL;
|
| + }
|
| + return result;
|
| + } else {
|
| + return GetBrowserInProfileWithId(function->GetProfile(),
|
| + window_id,
|
| + function->include_incognito(),
|
| + error);
|
| + }
|
| +}
|
| +
|
| int ExtensionTabUtil::GetWindowId(const Browser* browser) {
|
| return browser->session_id().id();
|
| }
|
|
|