diff options
15 files changed, 100 insertions, 40 deletions
diff --git a/chrome/browser/extensions/execute_script_apitest.cc b/chrome/browser/extensions/execute_script_apitest.cc index 4ef3d81..3b07add 100644 --- a/chrome/browser/extensions/execute_script_apitest.cc +++ b/chrome/browser/extensions/execute_script_apitest.cc @@ -18,3 +18,12 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, DISABLED_ExecuteScript) { ASSERT_TRUE(RunExtensionTest("executescript/in_frame")) << message_; ASSERT_TRUE(RunExtensionTest("executescript/permissions")) << message_; } + +// TODO(rafaelw) - This case is split out per Pawel's request. When the above +// (ExecuteScript) tests are de-flakified, reunite this case with it's brethern. +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ExecuteScriptFileAfterClose) { + host_resolver()->AddRule("b.com", "127.0.0.1"); + StartHTTPServer(); + + ASSERT_TRUE(RunExtensionTest("executescript/file_after_close")) << message_; +} diff --git a/chrome/browser/extensions/extension_browser_actions_api.cc b/chrome/browser/extensions/extension_browser_actions_api.cc index c415d02..c1ffe8e 100644 --- a/chrome/browser/extensions/extension_browser_actions_api.cc +++ b/chrome/browser/extensions/extension_browser_actions_api.cc @@ -25,7 +25,7 @@ bool BrowserActionFunction::RunImpl() { if (details_->HasKey(L"tabId")) EXTENSION_FUNCTION_VALIDATE(details_->GetInteger(L"tabId", &tab_id_)); - Extension* extension = dispatcher()->GetExtension(); + Extension* extension = GetExtension(); browser_action_ = extension->browser_action(); if (!browser_action_) { error_ = kNoBrowserActionError; @@ -67,7 +67,7 @@ bool BrowserActionSetPopupFunction::RunBrowserAction() { GURL popup_url; if (!popup_string.empty()) - popup_url = dispatcher()->GetExtension()->GetResourceURL(popup_string); + popup_url = GetExtension()->GetResourceURL(popup_string); browser_action_->SetPopupUrl(tab_id_, popup_url); return true; diff --git a/chrome/browser/extensions/extension_function.cc b/chrome/browser/extensions/extension_function.cc index f319315..f3c3532 100644 --- a/chrome/browser/extensions/extension_function.cc +++ b/chrome/browser/extensions/extension_function.cc @@ -37,13 +37,3 @@ bool AsyncExtensionFunction::HasOptionalArgument(size_t index) { Value* value; return args_list->Get(index, &value) && !value->IsType(Value::TYPE_NULL); } - -std::string AsyncExtensionFunction::extension_id() { - DCHECK(dispatcher()); - return dispatcher()->extension_id(); -} - -Profile* AsyncExtensionFunction::profile() const { - DCHECK(dispatcher()); - return dispatcher()->profile(); -} diff --git a/chrome/browser/extensions/extension_function.h b/chrome/browser/extensions/extension_function.h index 1727ae0..0e51321 100644 --- a/chrome/browser/extensions/extension_function.h +++ b/chrome/browser/extensions/extension_function.h @@ -12,6 +12,8 @@ #include "base/scoped_ptr.h" #include "base/ref_counted.h" #include "chrome/browser/extensions/extension_function_dispatcher.h" +#include "chrome/browser/extensions/extensions_service.h" +#include "chrome/browser/profile.h" class ExtensionFunctionDispatcher; class Profile; @@ -46,6 +48,17 @@ class ExtensionFunction : public base::RefCounted<ExtensionFunction> { void set_name(const std::string& name) { name_ = name; } const std::string name() const { return name_; } + // Set the profile which contains the extension that has originated this + // function call. + void set_profile(Profile* profile) { profile_ = profile; } + Profile* profile() const { return profile_; } + + // Set the id of this function call's extension. + void set_extension_id(std::string extension_id) { + extension_id_ = extension_id; + } + std::string extension_id() const { return extension_id_; } + // Specifies the raw arguments to the function, as a JSON value. virtual void SetArgs(const Value* args) = 0; @@ -92,12 +105,12 @@ class ExtensionFunction : public base::RefCounted<ExtensionFunction> { virtual ~ExtensionFunction() {} // Gets the extension that called this function. This can return NULL for - // async functions. + // async functions, for example if the extension is unloaded while the + // function is running. Extension* GetExtension() { - if (dispatcher()) - return dispatcher()->GetExtension(); - else - return NULL; + ExtensionsService* service = profile_->GetExtensionsService(); + DCHECK(service); + return service->GetExtensionById(extension_id_, false); } // Gets the "current" browser, if any. @@ -126,6 +139,12 @@ class ExtensionFunction : public base::RefCounted<ExtensionFunction> { // Id of this request, used to map the response back to the caller. int request_id_; + // The Profile of this function's extension. + Profile* profile_; + + // The id of this function's extension. + std::string extension_id_; + // The name of this function. std::string name_; @@ -176,13 +195,10 @@ class AsyncExtensionFunction : public ExtensionFunction { return static_cast<DictionaryValue*>(args_.get()); } + // Return true if the argument to this function at |index| was provided and + // is non-null. bool HasOptionalArgument(size_t index); - // Note: After Run() returns, dispatcher() can be NULL. Since these getters - // rely on dispatcher(), make sure it is valid before using them. - std::string extension_id(); - Profile* profile() const; - // The arguments to the API. Only non-null if argument were specified. scoped_ptr<Value> args_; diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index 8abc84c..7476cb0 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -360,16 +360,6 @@ Browser* ExtensionFunctionDispatcher::GetCurrentBrowser( return browser; } -Extension* ExtensionFunctionDispatcher::GetExtension() { - ExtensionsService* service = profile()->GetExtensionsService(); - DCHECK(service); - - Extension* extension = service->GetExtensionById(extension_id(), false); - DCHECK(extension); - - return extension; -} - void ExtensionFunctionDispatcher::HandleRequest(const std::string& name, const Value* args, const GURL& source_url, @@ -378,6 +368,8 @@ void ExtensionFunctionDispatcher::HandleRequest(const std::string& name, scoped_refptr<ExtensionFunction> function( FactoryRegistry::instance()->NewFunction(name)); function->set_dispatcher_peer(peer_); + function->set_profile(profile_); + function->set_extension_id(extension_id()); function->SetArgs(args); function->set_source_url(source_url); function->set_request_id(request_id); diff --git a/chrome/browser/extensions/extension_function_dispatcher.h b/chrome/browser/extensions/extension_function_dispatcher.h index 08e74bc1..fc50c17 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.h +++ b/chrome/browser/extensions/extension_function_dispatcher.h @@ -105,10 +105,6 @@ class ExtensionFunctionDispatcher { // details. Browser* GetCurrentBrowser(bool include_incognito); - // Gets the extension the function is being invoked by. This should not ever - // return NULL. - Extension* GetExtension(); - // Handle a malformed message. Possibly the result of an attack, so kill // the renderer. void HandleBadMessage(ExtensionFunction* api); diff --git a/chrome/browser/extensions/extension_infobar_module.cc b/chrome/browser/extensions/extension_infobar_module.cc index 73768fb..d8cea95 100644 --- a/chrome/browser/extensions/extension_infobar_module.cc +++ b/chrome/browser/extensions/extension_infobar_module.cc @@ -26,7 +26,7 @@ bool ShowInfoBarFunction::RunImpl() { std::string html_path; EXTENSION_FUNCTION_VALIDATE(args->GetString(keys::kHtmlPath, &html_path)); - Extension* extension = dispatcher()->GetExtension(); + Extension* extension = GetExtension(); GURL url = extension->GetResourceURL(extension->url(), html_path); Browser* browser = NULL; diff --git a/chrome/browser/extensions/extension_page_actions_module.cc b/chrome/browser/extensions/extension_page_actions_module.cc index 5fcbf45..01ca992 100644 --- a/chrome/browser/extensions/extension_page_actions_module.cc +++ b/chrome/browser/extensions/extension_page_actions_module.cc @@ -56,7 +56,7 @@ bool PageActionFunction::SetPageActionEnabled(bool enable) { } } - ExtensionAction* page_action = dispatcher()->GetExtension()->page_action(); + ExtensionAction* page_action = GetExtension()->page_action(); if (!page_action) { error_ = kNoPageActionError; return false; @@ -95,7 +95,7 @@ bool PageActionFunction::SetPageActionEnabled(bool enable) { } bool PageActionFunction::InitCommon(int tab_id) { - page_action_ = dispatcher()->GetExtension()->page_action(); + page_action_ = GetExtension()->page_action(); if (!page_action_) { error_ = kNoPageActionError; return false; diff --git a/chrome/browser/extensions/extension_popup_api.cc b/chrome/browser/extensions/extension_popup_api.cc index c7b28ed..f73dc7f 100644 --- a/chrome/browser/extensions/extension_popup_api.cc +++ b/chrome/browser/extensions/extension_popup_api.cc @@ -266,7 +266,7 @@ bool PopupShowFunction::RunImpl() { // Disallow non-extension requests, or requests outside of the requesting // extension view's extension. const std::string& extension_id = url.host(); - if (extension_id != dispatcher()->GetExtension()->id() || + if (extension_id != GetExtension()->id() || !url.SchemeIs(chrome::kExtensionScheme)) { error_ = kInvalidURLError; return false; diff --git a/chrome/test/data/extensions/api_test/executescript/file_after_close/extension_page.html b/chrome/test/data/extensions/api_test/executescript/file_after_close/extension_page.html new file mode 100644 index 0000000..3dd949d --- /dev/null +++ b/chrome/test/data/extensions/api_test/executescript/file_after_close/extension_page.html @@ -0,0 +1,14 @@ +<script> +window.onload = function() { + chrome.tabs.getAllInWindow(undefined, function(tabs) { + for (var i = 0; i < tabs.length; i++) { + var tab = tabs[i]; + if (tab.url.indexOf('web_page1') > -1) { + chrome.tabs.executeScript(tab.id, { file: 'script.js' }); + window.close(); + break; + } + } + }); +} +</script>
\ No newline at end of file diff --git a/chrome/test/data/extensions/api_test/executescript/file_after_close/manifest.json b/chrome/test/data/extensions/api_test/executescript/file_after_close/manifest.json new file mode 100644 index 0000000..85266e21 --- /dev/null +++ b/chrome/test/data/extensions/api_test/executescript/file_after_close/manifest.json @@ -0,0 +1,7 @@ +{ + "version": "1.0.0.0", + "name": "executeScript.file then close", + "description": "Tests that executeScript with a file source can be fired from a page that immediately closes without crashing the browser", + "background_page": "test.html", + "permissions": ["tabs", "http://b.com/"] +} diff --git a/chrome/test/data/extensions/api_test/executescript/file_after_close/script.js b/chrome/test/data/extensions/api_test/executescript/file_after_close/script.js new file mode 100644 index 0000000..25c9b73 --- /dev/null +++ b/chrome/test/data/extensions/api_test/executescript/file_after_close/script.js @@ -0,0 +1 @@ +location.href = 'web_page2.html'; diff --git a/chrome/test/data/extensions/api_test/executescript/file_after_close/test.html b/chrome/test/data/extensions/api_test/executescript/file_after_close/test.html new file mode 100644 index 0000000..c9e97fc --- /dev/null +++ b/chrome/test/data/extensions/api_test/executescript/file_after_close/test.html @@ -0,0 +1,29 @@ +<script> +var server = 'http://b.com:1337'; +var relativePath = '/files/extensions/api_test/executescript/file_after_close/'; +var extensionPage = chrome.extension.getURL('extension_page.html'); +var webPage1 = server + relativePath + 'web_page1.html'; +var webPage2 = server + relativePath + 'web_page2.html'; +var extensionPageOpened = false; + +var listener = function(tabId, changeInfo, tab) { + if (changeInfo.status != 'complete') + return; + + // web_page1 loaded, open extension page to inject script + if (!extensionPageOpened && tab.url == webPage1) { + chrome.tabs.create({ url: extensionPage }); + extensionPageOpened = true; + return; + } + + if (tab.url == webPage2) { + console.log('webPage1 navigated to webPage1. Yeah!'); + chrome.tabs.onUpdated.removeListener(listener); + chrome.test.notifyPass(); + } +}; + +chrome.tabs.onUpdated.addListener(listener); +chrome.tabs.create({ url: webPage1 }); +</script> diff --git a/chrome/test/data/extensions/api_test/executescript/file_after_close/web_page1.html b/chrome/test/data/extensions/api_test/executescript/file_after_close/web_page1.html new file mode 100644 index 0000000..5a5f62d --- /dev/null +++ b/chrome/test/data/extensions/api_test/executescript/file_after_close/web_page1.html @@ -0,0 +1,3 @@ +<html> + <title>WebPage 1</title> +</html> diff --git a/chrome/test/data/extensions/api_test/executescript/file_after_close/web_page2.html b/chrome/test/data/extensions/api_test/executescript/file_after_close/web_page2.html new file mode 100644 index 0000000..399db65 --- /dev/null +++ b/chrome/test/data/extensions/api_test/executescript/file_after_close/web_page2.html @@ -0,0 +1,3 @@ +<html> + <title>WebPage 2</title> +</html> |