diff options
Diffstat (limited to 'chrome')
11 files changed, 261 insertions, 51 deletions
diff --git a/chrome/browser/extensions/api/execute_code_function.h b/chrome/browser/extensions/api/execute_code_function.h index 5cd0445..f5227f5 100644 --- a/chrome/browser/extensions/api/execute_code_function.h +++ b/chrome/browser/extensions/api/execute_code_function.h @@ -5,8 +5,8 @@ #ifndef CHROME_BROWSER_EXTENSIONS_API_EXECUTE_CODE_FUNCTION_H_ #define CHROME_BROWSER_EXTENSIONS_API_EXECUTE_CODE_FUNCTION_H_ -#include "chrome/browser/extensions/chrome_extension_function.h" #include "chrome/common/extensions/api/tabs.h" +#include "extensions/browser/extension_function.h" #include "extensions/browser/script_executor.h" namespace extensions { @@ -14,7 +14,7 @@ namespace extensions { // Base class for javascript code injection. // This is used by both chrome.webview.executeScript and // chrome.tabs.executeScript. -class ExecuteCodeFunction : public ChromeAsyncExtensionFunction { +class ExecuteCodeFunction : public AsyncExtensionFunction { public: ExecuteCodeFunction(); diff --git a/chrome/browser/extensions/api/tabs/tabs_api.cc b/chrome/browser/extensions/api/tabs/tabs_api.cc index 0663f4c..2cb286b 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.cc +++ b/chrome/browser/extensions/api/tabs/tabs_api.cc @@ -1636,7 +1636,7 @@ void TabsDetectLanguageFunction::GotLanguage(const std::string& language) { } ExecuteCodeInTabFunction::ExecuteCodeInTabFunction() - : execute_tab_id_(-1) { + : chrome_details_(this), execute_tab_id_(-1) { } ExecuteCodeInTabFunction::~ExecuteCodeInTabFunction() {} @@ -1650,6 +1650,39 @@ bool ExecuteCodeInTabFunction::HasPermission() { return ExtensionFunction::HasPermission(); } +bool ExecuteCodeInTabFunction::Init() { + if (details_.get()) + return true; + + // |tab_id| is optional so it's ok if it's not there. + int tab_id = -1; + if (args_->GetInteger(0, &tab_id)) + EXTENSION_FUNCTION_VALIDATE(tab_id >= 0); + + // |details| are not optional. + base::DictionaryValue* details_value = NULL; + if (!args_->GetDictionary(1, &details_value)) + return false; + scoped_ptr<InjectDetails> details(new InjectDetails()); + if (!InjectDetails::Populate(*details_value, details.get())) + return false; + + // If the tab ID wasn't given then it needs to be converted to the + // currently active tab's ID. + if (tab_id == -1) { + Browser* browser = chrome_details_.GetCurrentBrowser(); + if (!browser) + return false; + content::WebContents* web_contents = NULL; + if (!ExtensionTabUtil::GetDefaultTab(browser, &web_contents, &tab_id)) + return false; + } + + execute_tab_id_ = tab_id; + details_ = details.Pass(); + return true; +} + bool ExecuteCodeInTabFunction::CanExecuteScriptOnPage() { content::WebContents* contents = NULL; @@ -1657,7 +1690,7 @@ bool ExecuteCodeInTabFunction::CanExecuteScriptOnPage() { // tab in the current window. CHECK_GE(execute_tab_id_, 0); if (!GetTabById(execute_tab_id_, - GetProfile(), + chrome_details_.GetProfile(), include_incognito(), NULL, NULL, @@ -1690,7 +1723,7 @@ ScriptExecutor* ExecuteCodeInTabFunction::GetScriptExecutor() { content::WebContents* contents = NULL; bool success = GetTabById(execute_tab_id_, - GetProfile(), + chrome_details_.GetProfile(), include_incognito(), &browser, NULL, @@ -1726,39 +1759,6 @@ void TabsExecuteScriptFunction::OnExecuteCodeFinished( ExecuteCodeInTabFunction::OnExecuteCodeFinished(error, on_url, result); } -bool ExecuteCodeInTabFunction::Init() { - if (details_.get()) - return true; - - // |tab_id| is optional so it's ok if it's not there. - int tab_id = -1; - if (args_->GetInteger(0, &tab_id)) - EXTENSION_FUNCTION_VALIDATE(tab_id >= 0); - - // |details| are not optional. - base::DictionaryValue* details_value = NULL; - if (!args_->GetDictionary(1, &details_value)) - return false; - scoped_ptr<InjectDetails> details(new InjectDetails()); - if (!InjectDetails::Populate(*details_value, details.get())) - return false; - - // If the tab ID wasn't given then it needs to be converted to the - // currently active tab's ID. - if (tab_id == -1) { - Browser* browser = GetCurrentBrowser(); - if (!browser) - return false; - content::WebContents* web_contents = NULL; - if (!ExtensionTabUtil::GetDefaultTab(browser, &web_contents, &tab_id)) - return false; - } - - execute_tab_id_ = tab_id; - details_ = details.Pass(); - return true; -} - bool TabsInsertCSSFunction::ShouldInsertCSS() const { return true; } diff --git a/chrome/browser/extensions/api/tabs/tabs_api.h b/chrome/browser/extensions/api/tabs/tabs_api.h index 06c1728..a666a99 100644 --- a/chrome/browser/extensions/api/tabs/tabs_api.h +++ b/chrome/browser/extensions/api/tabs/tabs_api.h @@ -11,6 +11,7 @@ #include "base/compiler_specific.h" #include "chrome/browser/extensions/api/execute_code_function.h" #include "chrome/browser/extensions/chrome_extension_function.h" +#include "chrome/browser/extensions/chrome_extension_function_details.h" #include "chrome/browser/ui/zoom/zoom_controller.h" #include "chrome/common/extensions/api/tabs.h" #include "content/public/browser/notification_observer.h" @@ -232,6 +233,8 @@ class ExecuteCodeInTabFunction : public ExecuteCodeFunction { virtual const GURL& GetWebViewSrc() const OVERRIDE; private: + const ChromeExtensionFunctionDetails chrome_details_; + // Id of tab which executes code. int execute_tab_id_; }; diff --git a/chrome/browser/extensions/api/tabs/windows_util.cc b/chrome/browser/extensions/api/tabs/windows_util.cc index a2b640d..0cb10e3 100644 --- a/chrome/browser/extensions/api/tabs/windows_util.cc +++ b/chrome/browser/extensions/api/tabs/windows_util.cc @@ -7,6 +7,7 @@ #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/chrome_extension_function_details.h" #include "chrome/browser/extensions/window_controller.h" #include "chrome/browser/extensions/window_controller_list.h" #include "extensions/browser/extension_function_dispatcher.h" @@ -18,6 +19,7 @@ namespace windows_util { bool GetWindowFromWindowID(ChromeUIThreadExtensionFunction* function, int window_id, extensions::WindowController** controller) { + ChromeExtensionFunctionDetails function_details(function); if (window_id == extension_misc::kCurrentWindowId) { extensions::WindowController* extension_window_controller = function->dispatcher()->delegate()->GetExtensionWindowController(); @@ -26,16 +28,16 @@ bool GetWindowFromWindowID(ChromeUIThreadExtensionFunction* function, *controller = extension_window_controller; } else { // Otherwise get the focused or most recently added window. - *controller = extensions::WindowControllerList::GetInstance()-> - CurrentWindowForFunction(function); + *controller = extensions::WindowControllerList::GetInstance() + ->CurrentWindowForFunction(function_details); } if (!(*controller)) { function->SetError(extensions::tabs_constants::kNoCurrentWindowError); return false; } } else { - *controller = extensions::WindowControllerList::GetInstance()-> - FindWindowForFunctionById(function, window_id); + *controller = extensions::WindowControllerList::GetInstance() + ->FindWindowForFunctionById(function_details, window_id); if (!(*controller)) { function->SetError(extensions::ErrorUtils::FormatErrorMessage( extensions::tabs_constants::kWindowNotFoundError, diff --git a/chrome/browser/extensions/chrome_extension_function.cc b/chrome/browser/extensions/chrome_extension_function.cc index 8f8abad..15cbe1f 100644 --- a/chrome/browser/extensions/chrome_extension_function.cc +++ b/chrome/browser/extensions/chrome_extension_function.cc @@ -4,6 +4,7 @@ #include "chrome/browser/extensions/chrome_extension_function.h" +#include "chrome/browser/extensions/chrome_extension_function_details.h" #include "chrome/browser/extensions/window_controller.h" #include "chrome/browser/extensions/window_controller_list.h" #include "chrome/browser/profiles/profile.h" @@ -92,7 +93,7 @@ ChromeUIThreadExtensionFunction::GetExtensionWindowController() { } return extensions::WindowControllerList::GetInstance() - ->CurrentWindowForFunction(this); + ->CurrentWindowForFunction(ChromeExtensionFunctionDetails(this)); } content::WebContents* diff --git a/chrome/browser/extensions/chrome_extension_function.h b/chrome/browser/extensions/chrome_extension_function.h index dc35815..98002b4 100644 --- a/chrome/browser/extensions/chrome_extension_function.h +++ b/chrome/browser/extensions/chrome_extension_function.h @@ -20,6 +20,10 @@ class WindowController; // A chrome specific analog to AsyncExtensionFunction. This has access to a // chrome Profile. +// +// DEPRECATED: Please consider inherting UIThreadExtensionFunction directly. +// Then if you need access to Chrome details, you can construct a +// ChromeExtensionFunctionDetails object within your function implementation. class ChromeUIThreadExtensionFunction : public UIThreadExtensionFunction { public: ChromeUIThreadExtensionFunction(); @@ -64,6 +68,11 @@ class ChromeUIThreadExtensionFunction : public UIThreadExtensionFunction { // A chrome specific analog to AsyncExtensionFunction. This has access to a // chrome Profile. +// +// DEPRECATED: Please consider inherting UIThreadExtensionFunction or +// AsyncExtensionFunction directly. Then if you need access to Chrome details, +// you can construct a ChromeExtensionFunctionDetails object within your +// function implementation. class ChromeAsyncExtensionFunction : public ChromeUIThreadExtensionFunction { public: ChromeAsyncExtensionFunction(); @@ -83,6 +92,11 @@ class ChromeAsyncExtensionFunction : public ChromeUIThreadExtensionFunction { // A chrome specific analog to SyncExtensionFunction. This has access to a // chrome Profile. +// +// DEPRECATED: Please consider inherting UIThreadExtensionFunction or +// SyncExtensionFunction directly. Then if you need access to Chrome details, +// you can construct a ChromeExtensionFunctionDetails object within your +// function implementation. class ChromeSyncExtensionFunction : public ChromeUIThreadExtensionFunction { public: ChromeSyncExtensionFunction(); diff --git a/chrome/browser/extensions/chrome_extension_function_details.cc b/chrome/browser/extensions/chrome_extension_function_details.cc new file mode 100644 index 0000000..d80c0812 --- /dev/null +++ b/chrome/browser/extensions/chrome_extension_function_details.cc @@ -0,0 +1,115 @@ +// 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/chrome_extension_function_details.h" + +#include "chrome/browser/extensions/window_controller.h" +#include "chrome/browser/extensions/window_controller_list.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/ui/browser.h" +#include "chrome/browser/ui/browser_finder.h" +#include "chrome/browser/ui/tabs/tab_strip_model.h" +#include "content/public/browser/render_process_host.h" +#include "content/public/browser/render_view_host.h" +#include "extensions/browser/extension_function.h" +#include "extensions/browser/extension_function_dispatcher.h" + +using content::WebContents; +using content::RenderViewHost; +using extensions::WindowController; + +ChromeExtensionFunctionDetails::ChromeExtensionFunctionDetails( + UIThreadExtensionFunction* function) + : function_(function) { +} + +ChromeExtensionFunctionDetails::~ChromeExtensionFunctionDetails() { +} + +Profile* ChromeExtensionFunctionDetails::GetProfile() const { + return Profile::FromBrowserContext(function_->browser_context()); +} + +bool ChromeExtensionFunctionDetails::CanOperateOnWindow( + const extensions::WindowController* window_controller) const { + // |extension()| is NULL for unit tests only. + if (function_->extension() != NULL && + !window_controller->IsVisibleToExtension(function_->extension())) { + return false; + } + + if (GetProfile() == window_controller->profile()) + return true; + + if (!function_->include_incognito()) + return false; + + return GetProfile()->HasOffTheRecordProfile() && + GetProfile()->GetOffTheRecordProfile() == window_controller->profile(); +} + +// TODO(stevenjb): Replace this with GetExtensionWindowController(). +Browser* ChromeExtensionFunctionDetails::GetCurrentBrowser() const { + // If the delegate has an associated browser, return it. + if (function_->dispatcher()) { + extensions::WindowController* window_controller = + function_->dispatcher()->delegate()->GetExtensionWindowController(); + if (window_controller) { + Browser* browser = window_controller->GetBrowser(); + if (browser) + return browser; + } + } + + // Otherwise, try to default to a reasonable browser. If |include_incognito_| + // is true, we will also search browsers in the incognito version of this + // profile. Note that the profile may already be incognito, in which case + // we will search the incognito version only, regardless of the value of + // |include_incognito|. Look only for browsers on the active desktop as it is + // preferable to pretend no browser is open then to return a browser on + // another desktop. + if (function_->render_view_host()) { + Profile* profile = Profile::FromBrowserContext( + function_->render_view_host()->GetProcess()->GetBrowserContext()); + Browser* browser = chrome::FindAnyBrowser( + profile, function_->include_incognito(), chrome::GetActiveDesktop()); + if (browser) + return browser; + } + + // NOTE(rafaelw): This can return NULL in some circumstances. In particular, + // a background_page onload chrome.tabs api call can make it into here + // before the browser is sufficiently initialized to return here, or + // all of this profile's browser windows may have been closed. + // A similar situation may arise during shutdown. + // TODO(rafaelw): Delay creation of background_page until the browser + // is available. http://code.google.com/p/chromium/issues/detail?id=13284 + return NULL; +} + +extensions::WindowController* +ChromeExtensionFunctionDetails::GetExtensionWindowController() const { + // If the delegate has an associated window controller, return it. + if (function_->dispatcher()) { + extensions::WindowController* window_controller = + function_->dispatcher()->delegate()->GetExtensionWindowController(); + if (window_controller) + return window_controller; + } + + return extensions::WindowControllerList::GetInstance() + ->CurrentWindowForFunction(*this); +} + +content::WebContents* +ChromeExtensionFunctionDetails::GetAssociatedWebContents() { + content::WebContents* web_contents = function_->GetAssociatedWebContents(); + if (web_contents) + return web_contents; + + Browser* browser = GetCurrentBrowser(); + if (!browser) + return NULL; + return browser->tab_strip_model()->GetActiveWebContents(); +} diff --git a/chrome/browser/extensions/chrome_extension_function_details.h b/chrome/browser/extensions/chrome_extension_function_details.h new file mode 100644 index 0000000..6e1bf92c --- /dev/null +++ b/chrome/browser/extensions/chrome_extension_function_details.h @@ -0,0 +1,73 @@ +// 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_CHROME_EXTENSION_FUNCTION_DETAILS_H_ +#define CHROME_BROWSER_EXTENSIONS_CHROME_EXTENSION_FUNCTION_DETAILS_H_ + +#include "base/macros.h" + +class Browser; +class Profile; +class UIThreadExtensionFunction; + +namespace content { +class WebContents; +} + +namespace extensions { +class WindowController; +} // namespace extensions + +// Provides Chrome-specific details to UIThreadExtensionFunction +// implementations. +class ChromeExtensionFunctionDetails { + public: + // Constructs a new ChromeExtensionFunctionDetails instance for |function|. + // This instance does not own |function| and must outlive it. + explicit ChromeExtensionFunctionDetails(UIThreadExtensionFunction* function); + ~ChromeExtensionFunctionDetails(); + + Profile* GetProfile() const; + + // Returns true if this function (and the profile and extension that it was + // invoked from) can operate on the window wrapped by |window_controller|. + bool CanOperateOnWindow( + const extensions::WindowController* window_controller) const; + + // Gets the "current" browser, if any. + // + // Many extension APIs operate relative to the current browser, which is the + // browser the calling code is running inside of. For example, popups, tabs, + // and infobars all have a containing browser, but background pages and + // notification bubbles do not. + // + // If there is no containing window, the current browser defaults to the + // foremost one. + // + // Incognito browsers are not considered unless the calling extension has + // incognito access enabled. + // + // This method can return NULL if there is no matching browser, which can + // happen if only incognito windows are open, or early in startup or shutdown + // shutdown when there are no active windows. + // + // TODO(stevenjb): Replace this with GetExtensionWindowController(). + Browser* GetCurrentBrowser() const; + + // Same as above but uses WindowControllerList instead of BrowserList. + extensions::WindowController* GetExtensionWindowController() const; + + // Gets the "current" web contents if any. If there is no associated web + // contents then defaults to the foremost one. + content::WebContents* GetAssociatedWebContents(); + + private: + // The function for which these details have been created. Must outlive the + // ChromeExtensionFunctionDetails instance. + UIThreadExtensionFunction* function_; + + DISALLOW_COPY_AND_ASSIGN(ChromeExtensionFunctionDetails); +}; + +#endif // CHROME_BROWSER_EXTENSIONS_CHROME_EXTENSION_FUNCTION_DETAILS_H_ diff --git a/chrome/browser/extensions/window_controller_list.cc b/chrome/browser/extensions/window_controller_list.cc index bfaefe1..0eadbea 100644 --- a/chrome/browser/extensions/window_controller_list.cc +++ b/chrome/browser/extensions/window_controller_list.cc @@ -6,7 +6,7 @@ #include <algorithm> -#include "chrome/browser/extensions/chrome_extension_function.h" +#include "chrome/browser/extensions/chrome_extension_function_details.h" #include "chrome/browser/extensions/window_controller_list_observer.h" #include "components/sessions/session_id.h" #include "ui/base/base_window.h" @@ -62,21 +62,21 @@ WindowController* WindowControllerList::FindWindowById(int id) const { } WindowController* WindowControllerList::FindWindowForFunctionById( - const ChromeUIThreadExtensionFunction* function, + const ChromeExtensionFunctionDetails& function_details, int id) const { WindowController* controller = FindWindowById(id); - if (controller && function->CanOperateOnWindow(controller)) + if (controller && function_details.CanOperateOnWindow(controller)) return controller; return NULL; } WindowController* WindowControllerList::CurrentWindowForFunction( - const ChromeUIThreadExtensionFunction* function) const { + const ChromeExtensionFunctionDetails& function_details) const { WindowController* result = NULL; // Returns either the focused window (if any), or the last window in the list. for (ControllerList::const_iterator iter = windows().begin(); iter != windows().end(); ++iter) { - if (function->CanOperateOnWindow(*iter)) { + if (function_details.CanOperateOnWindow(*iter)) { result = *iter; if (result->window()->IsActive()) break; // use focused window diff --git a/chrome/browser/extensions/window_controller_list.h b/chrome/browser/extensions/window_controller_list.h index a68c59f..feeb42ad 100644 --- a/chrome/browser/extensions/window_controller_list.h +++ b/chrome/browser/extensions/window_controller_list.h @@ -13,7 +13,7 @@ #include "chrome/browser/extensions/window_controller.h" class Profile; -class ChromeUIThreadExtensionFunction; +class ChromeExtensionFunctionDetails; namespace extensions { @@ -38,13 +38,13 @@ class WindowControllerList { // Returns a window matching the context the function was invoked in. WindowController* FindWindowForFunctionById( - const ChromeUIThreadExtensionFunction* function, + const ChromeExtensionFunctionDetails& function_details, int id) const; // Returns the focused or last added window matching the context the function // was invoked in. WindowController* CurrentWindowForFunction( - const ChromeUIThreadExtensionFunction* function) const; + const ChromeExtensionFunctionDetails& function_details) const; const ControllerList& windows() const { return windows_; } diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi index 36bae50..c163267 100644 --- a/chrome/chrome_browser_extensions.gypi +++ b/chrome/chrome_browser_extensions.gypi @@ -562,6 +562,8 @@ 'browser/extensions/chrome_content_browser_client_extensions_part.h', 'browser/extensions/chrome_extension_function.cc', 'browser/extensions/chrome_extension_function.h', + 'browser/extensions/chrome_extension_function_details.cc', + 'browser/extensions/chrome_extension_function_details.h', 'browser/extensions/chrome_extension_host_delegate.cc', 'browser/extensions/chrome_extension_host_delegate.h', 'browser/extensions/chrome_extension_web_contents_observer.cc', |