diff options
17 files changed, 424 insertions, 169 deletions
diff --git a/chrome/browser/extensions/api/browser/browser_api.cc b/chrome/browser/extensions/api/browser/browser_api.cc new file mode 100644 index 0000000..7e1a64b --- /dev/null +++ b/chrome/browser/extensions/api/browser/browser_api.cc @@ -0,0 +1,36 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/extensions/api/browser/browser_api.h" + +#include "chrome/browser/extensions/extension_tab_util.h" + +namespace extensions { +namespace api { + +BrowserOpenTabFunction::~BrowserOpenTabFunction() { +} + +bool BrowserOpenTabFunction::RunSync() { + scoped_ptr<browser::OpenTab::Params> params( + browser::OpenTab::Params::Create(*args_)); + EXTENSION_FUNCTION_VALIDATE(params.get()); + + ExtensionTabUtil::OpenTabParams options; + options.create_browser_if_needed = true; + options.url.reset(new std::string(params->options.url)); + + std::string error; + scoped_ptr<base::DictionaryValue> result( + ExtensionTabUtil::OpenTab(this, options, &error)); + if (!result) { + SetError(error); + return false; + } + + return true; +} + +} // namespace api +} // namespace extensions diff --git a/chrome/browser/extensions/api/browser/browser_api.h b/chrome/browser/extensions/api/browser/browser_api.h new file mode 100644 index 0000000..5707857 --- /dev/null +++ b/chrome/browser/extensions/api/browser/browser_api.h @@ -0,0 +1,27 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTENSIONS_API_BROWSER_BROWSER_API_H_ +#define CHROME_BROWSER_EXTENSIONS_API_BROWSER_BROWSER_API_H_ + +#include "chrome/browser/extensions/chrome_extension_function.h" +#include "chrome/common/extensions/api/browser.h" + +namespace extensions { +namespace api { + +class BrowserOpenTabFunction : public ChromeSyncExtensionFunction { + public: + DECLARE_EXTENSION_FUNCTION("browser.openTab", BROWSER_OPENTAB) + + protected: + virtual ~BrowserOpenTabFunction(); + + virtual bool RunSync() OVERRIDE; +}; + +} // namespace api +} // namespace extensions + +#endif // CHROME_BROWSER_EXTENSIONS_API_BROWSER_BROWSER_API_H_ diff --git a/chrome/browser/extensions/api/browser/browser_apitest.cc b/chrome/browser/extensions/api/browser/browser_apitest.cc new file mode 100644 index 0000000..88754b8 --- /dev/null +++ b/chrome/browser/extensions/api/browser/browser_apitest.cc @@ -0,0 +1,41 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <string> + +#include "base/memory/scoped_ptr.h" +#include "base/strings/stringprintf.h" +#include "base/values.h" +#include "chrome/browser/extensions/api/browser/browser_api.h" +#include "chrome/browser/extensions/extension_function_test_utils.h" +#include "chrome/test/base/in_process_browser_test.h" + +namespace extensions { + +namespace utils = extension_function_test_utils; + +namespace { + +class BrowserApiTest : public InProcessBrowserTest { +}; + +} + +IN_PROC_BROWSER_TEST_F(BrowserApiTest, OpenTab) { + std::string url = "about:blank"; + + scoped_refptr<api::BrowserOpenTabFunction> function = + new api::BrowserOpenTabFunction(); + scoped_refptr<Extension> extension(utils::CreateEmptyExtension()); + function->set_extension(extension.get()); + base::Value* result = utils::RunFunctionAndReturnSingleResult( + function.get(), + base::StringPrintf("[{\"url\":\"%s\"}]", url.c_str()), + browser()); + + // result is currently NULL on success. + EXPECT_FALSE(result); +} + +} // namespace extensions diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc index e30904d..e551852 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api.cc @@ -68,13 +68,11 @@ #include "extensions/browser/extension_function_util.h" #include "extensions/browser/extension_host.h" #include "extensions/browser/file_reader.h" -#include "extensions/common/constants.h" #include "extensions/common/error_utils.h" #include "extensions/common/extension.h" #include "extensions/common/extension_l10n_util.h" #include "extensions/common/extension_messages.h" #include "extensions/common/manifest_constants.h" -#include "extensions/common/manifest_handlers/incognito_info.h" #include "extensions/common/message_bundle.h" #include "extensions/common/permissions/permissions_data.h" #include "extensions/common/user_script.h" @@ -108,52 +106,19 @@ using api::tabs::InjectDetails; namespace { -// |error_message| can optionally be passed in a 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; -} - bool GetBrowserFromWindowID(ChromeAsyncExtensionFunction* function, int window_id, Browser** browser) { - if (window_id == extension_misc::kCurrentWindowId) { - *browser = function->GetCurrentBrowser(); - if (!(*browser) || !(*browser)->window()) { - function->SetError(keys::kNoCurrentWindowError); - return false; - } - } else { - std::string error; - *browser = GetBrowserInProfileWithId(function->GetProfile(), - window_id, - function->include_incognito(), - &error); - if (!*browser) { - function->SetError(error); - return false; - } + std::string error; + Browser* result; + result = + ExtensionTabUtil::GetBrowserFromWindowID(function, window_id, &error); + if (!result) { + function->SetError(error); + return false; } + + *browser = result; return true; } @@ -185,6 +150,14 @@ bool MatchesBool(bool* boolean, bool value) { return !boolean || *boolean == value; } +template <typename T> +void AssignOptionalValue(const scoped_ptr<T>& source, + scoped_ptr<T>& destination) { + if (source.get()) { + destination.reset(new T(*source.get())); + } +} + } // namespace // Windows --------------------------------------------------------------------- @@ -904,137 +877,29 @@ bool TabsCreateFunction::RunSync() { scoped_ptr<tabs::Create::Params> params(tabs::Create::Params::Create(*args_)); EXTENSION_FUNCTION_VALIDATE(params.get()); - // windowId defaults to "current" window. - int window_id = extension_misc::kCurrentWindowId; - if (params->create_properties.window_id.get()) - window_id = *params->create_properties.window_id; - - Browser* browser = NULL; - if (!GetBrowserFromWindowID(this, window_id, &browser)) - return false; - - // Ensure the selected browser is tabbed. - if (!browser->is_type_tabbed() && browser->IsAttemptingToCloseBrowser()) - browser = chrome::FindTabbedBrowser( - GetProfile(), include_incognito(), browser->host_desktop_type()); - - if (!browser || !browser->window()) - return false; - - // TODO(jstritar): Add a constant, chrome.tabs.TAB_ID_ACTIVE, that - // represents the active tab. - WebContents* opener = NULL; - if (params->create_properties.opener_tab_id.get()) { - int opener_id = *params->create_properties.opener_tab_id; - - if (!ExtensionTabUtil::GetTabById(opener_id, - GetProfile(), - include_incognito(), - NULL, - NULL, - &opener, - NULL)) { - return false; - } - } - - // TODO(rafaelw): handle setting remaining tab properties: - // -title - // -favIconUrl - - std::string url_string; - GURL url; - if (params->create_properties.url.get()) { - url_string = *params->create_properties.url; - url = ExtensionTabUtil::ResolvePossiblyRelativeURL(url_string, - GetExtension()); - if (!url.is_valid()) { - error_ = ErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, - url_string); - return false; - } - } - - // Don't let extensions crash the browser or renderers. - if (ExtensionTabUtil::IsCrashURL(url)) { - error_ = keys::kNoCrashBrowserError; - return false; - } - - // Default to foreground for the new tab. The presence of 'selected' property - // will override this default. This property is deprecated ('active' should - // be used instead). - bool active = true; - if (params->create_properties.selected.get()) - active = *params->create_properties.selected; - + ExtensionTabUtil::OpenTabParams options; + AssignOptionalValue(params->create_properties.window_id, options.window_id); + AssignOptionalValue(params->create_properties.opener_tab_id, + options.opener_tab_id); + AssignOptionalValue(params->create_properties.selected, options.active); // The 'active' property has replaced the 'selected' property. - if (params->create_properties.active.get()) - active = *params->create_properties.active; - - // Default to not pinning the tab. Setting the 'pinned' property to true - // will override this default. - bool pinned = false; - if (params->create_properties.pinned.get()) - pinned = *params->create_properties.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(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(); - } + AssignOptionalValue(params->create_properties.active, options.active); + AssignOptionalValue(params->create_properties.pinned, options.pinned); + AssignOptionalValue(params->create_properties.index, options.index); + AssignOptionalValue(params->create_properties.url, options.url); + + std::string error; + scoped_ptr<base::DictionaryValue> result( + ExtensionTabUtil::OpenTab(this, options, &error)); + if (!result) { + SetError(error); + return false; } - // 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->create_properties.index.get()) - index = *params->create_properties.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. if (has_callback()) { - SetResult(ExtensionTabUtil::CreateTabValue( - navigate_params.target_contents, - tab_strip, new_index, GetExtension())); + SetResult(result.release()); } - return true; } diff --git a/chrome/browser/extensions/extension_tab_util.cc b/chrome/browser/extensions/extension_tab_util.cc index be7f4c9..1537a33 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(); } diff --git a/chrome/browser/extensions/extension_tab_util.h b/chrome/browser/extensions/extension_tab_util.h index 0b3092a..bbf042b 100644 --- a/chrome/browser/extensions/extension_tab_util.h +++ b/chrome/browser/extensions/extension_tab_util.h @@ -12,6 +12,7 @@ #include "ui/base/window_open_disposition.h" class Browser; +class ChromeAsyncExtensionFunction; class GURL; class Profile; class TabStripModel; @@ -36,6 +37,26 @@ class WindowController; // Provides various utility functions that help manipulate tabs. class ExtensionTabUtil { public: + struct OpenTabParams { + OpenTabParams(); + ~OpenTabParams(); + + bool create_browser_if_needed; + scoped_ptr<int> window_id; + scoped_ptr<int> opener_tab_id; + scoped_ptr<std::string> url; + scoped_ptr<bool> active; + scoped_ptr<bool> pinned; + scoped_ptr<int> index; + }; + + // Opens a new tab given an extension function |function| and creation + // parameters |params|. Returns a Tab object if successful, or NULL and + // optionally sets |error| if an error occurs. + static base::DictionaryValue* OpenTab(ChromeAsyncExtensionFunction* function, + const OpenTabParams& params, + std::string* error); + static int GetWindowId(const Browser* browser); static int GetWindowIdOfTabStripModel(const TabStripModel* tab_strip_model); static int GetTabId(const content::WebContents* web_contents); @@ -43,6 +64,9 @@ class ExtensionTabUtil { static int GetWindowIdOfTab(const content::WebContents* web_contents); static base::ListValue* CreateTabList(const Browser* browser, const Extension* extension); + static Browser* GetBrowserFromWindowID(ChromeAsyncExtensionFunction* function, + int window_id, + std::string* error_message); // Creates a Tab object (see chrome/common/extensions/api/tabs.json) with // information about the state of a browser tab. Depending on the diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index 779f594..c740c77 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi @@ -184,6 +184,8 @@ 'browser/extensions/api/braille_display_private/brlapi_connection.h', 'browser/extensions/api/braille_display_private/stub_braille_controller.cc', 'browser/extensions/api/braille_display_private/stub_braille_controller.h', + 'browser/extensions/api/browser/browser_api.cc', + 'browser/extensions/api/browser/browser_api.h', 'browser/extensions/api/browsing_data/browsing_data_api.cc', 'browser/extensions/api/browsing_data/browsing_data_api.h', 'browser/extensions/api/capture_web_contents_function.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 15e8b08..8fd2444 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1001,6 +1001,7 @@ 'browser/extensions/api/braille_display_private/braille_display_private_apitest.cc', 'browser/extensions/api/braille_display_private/mock_braille_controller.cc', 'browser/extensions/api/braille_display_private/mock_braille_controller.h', + 'browser/extensions/api/browser/browser_apitest.cc', 'browser/extensions/api/bookmarks/bookmark_apitest.cc', 'browser/extensions/api/browsing_data/browsing_data_test.cc', 'browser/extensions/api/cast_channel/cast_channel_apitest.cc', diff --git a/chrome/common/extensions/api/_api_features.json b/chrome/common/extensions/api/_api_features.json index e1775c4..ba3a54f 100644 --- a/chrome/common/extensions/api/_api_features.json +++ b/chrome/common/extensions/api/_api_features.json @@ -140,6 +140,10 @@ "dependencies": ["permission:brailleDisplayPrivate"], "contexts": ["blessed_extension"] }, + "browser": { + "dependencies": ["permission:browser"], + "contexts": ["blessed_extension"] + }, "browserAction": { "dependencies": ["manifest:browser_action"], "contexts": ["blessed_extension"] diff --git a/chrome/common/extensions/api/_permission_features.json b/chrome/common/extensions/api/_permission_features.json index fb979c4..8b63d30 100644 --- a/chrome/common/extensions/api/_permission_features.json +++ b/chrome/common/extensions/api/_permission_features.json @@ -152,6 +152,10 @@ "extension_types": ["extension", "legacy_packaged_app", "platform_app"], "location": "component" }, + "browser": { + "channel": "dev", + "extension_types": ["platform_app"] + }, "browsingData": { "channel": "stable", "extension_types": ["extension", "legacy_packaged_app"] diff --git a/chrome/common/extensions/api/api.gyp b/chrome/common/extensions/api/api.gyp index 7ba5fa1..6a20fa5 100644 --- a/chrome/common/extensions/api/api.gyp +++ b/chrome/common/extensions/api/api.gyp @@ -50,6 +50,7 @@ 'bluetooth_socket.idl', 'bookmark_manager_private.json', 'bookmarks.json', + 'browser.idl', 'braille_display_private.idl', 'cast_channel.idl', 'cloud_print_private.json', diff --git a/chrome/common/extensions/api/browser.idl b/chrome/common/extensions/api/browser.idl new file mode 100644 index 0000000..99515dc --- /dev/null +++ b/chrome/common/extensions/api/browser.idl @@ -0,0 +1,26 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Use the <code>chrome.browser</code> API to interact with the Chrome browser +// associated with the current application and Chrome profile. +[nodoc] namespace browser { + // Options for the $(ref:openTab) function. + dictionary OpenTabOptions { + // The URL to navigate to when the new tab is initially opened. + DOMString url; + }; + + callback Callback = void(); + + interface Functions { + // Opens a new tab in a browser window associated with the current + // application and Chrome profile. If no browser window for the Chrome + // profile is opened, a new one is opened prior to creating the new tab. The + // initial URL of the new tab is specified in |options|. + // |options| : The $(ref:OpenTabOptions) for this function. + // |callback| : Called to indicate success or failure. + static void openTab(OpenTabOptions options, + Callback callback); + }; +}; diff --git a/chrome/common/extensions/permissions/chrome_api_permissions.cc b/chrome/common/extensions/permissions/chrome_api_permissions.cc index f999969..b815ffd 100644 --- a/chrome/common/extensions/permissions/chrome_api_permissions.cc +++ b/chrome/common/extensions/permissions/chrome_api_permissions.cc @@ -368,6 +368,7 @@ std::vector<APIPermissionInfo*> ChromeAPIPermissions::GetAllPermissions() {APIPermission::kOverrideEscFullscreen, "app.window.fullscreen.overrideEsc"}, {APIPermission::kWindowShape, "app.window.shape"}, + {APIPermission::kBrowser, "browser"}, // Settings override permissions. {APIPermission::kHomepage, "homepage", diff --git a/chrome/common/extensions/permissions/permission_set_unittest.cc b/chrome/common/extensions/permissions/permission_set_unittest.cc index 7884a2c..967de7b 100644 --- a/chrome/common/extensions/permissions/permission_set_unittest.cc +++ b/chrome/common/extensions/permissions/permission_set_unittest.cc @@ -751,6 +751,7 @@ TEST(PermissionsTest, PermissionMessages) { skip.insert(APIPermission::kDevtools); // Platform apps. + skip.insert(APIPermission::kBrowser); skip.insert(APIPermission::kFileSystem); skip.insert(APIPermission::kFileSystemProvider); skip.insert(APIPermission::kFileSystemRetainEntries); diff --git a/extensions/browser/extension_function_histogram_value.h b/extensions/browser/extension_function_histogram_value.h index 90f8d7f..10665898 100644 --- a/extensions/browser/extension_function_histogram_value.h +++ b/extensions/browser/extension_function_histogram_value.h @@ -810,6 +810,7 @@ enum HistogramValue { SHELL_CREATEWINDOW, FILESYSTEMPROVIDERINTERNAL_GETMETADATAREQUESTEDSUCCESS, FILESYSTEMPROVIDERINTERNAL_GETMETADATAREQUESTEDERROR, + BROWSER_OPENTAB, // Last entry: Add new entries above and ensure to update // tools/metrics/histograms/histograms/histograms.xml. ENUM_BOUNDARY diff --git a/extensions/common/permissions/api_permission.h b/extensions/common/permissions/api_permission.h index a660f79..487cb2c 100644 --- a/extensions/common/permissions/api_permission.h +++ b/extensions/common/permissions/api_permission.h @@ -174,6 +174,7 @@ class APIPermission { kSystemInfoCpu, kSystemInfoMemory, kFirstRunPrivate, + kBrowser, kEnumBoundary }; diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml index e51d519..53995d0 100644 --- a/tools/metrics/histograms/histograms.xml +++ b/tools/metrics/histograms/histograms.xml @@ -33790,6 +33790,7 @@ Therefore, the affected-histogram name has to have at least one dot in it. label="FILESYSTEMPROVIDERINTERNAL_GETMETADATAREQUESTEDSUCCESS"/> <int value="751" label="FILESYSTEMPROVIDERINTERNAL_GETMETADATAREQUESTEDERROR"/> + <int value="752" label="BROWSER_OPENTAB"/> </enum> <enum name="ExtensionInstallCause" type="int"> |