diff options
12 files changed, 85 insertions, 9 deletions
diff --git a/chrome/browser/extensions/content_script_all_frames_apitest.cc b/chrome/browser/extensions/content_script_all_frames_apitest.cc index 7dc636c..3903ff0 100644 --- a/chrome/browser/extensions/content_script_all_frames_apitest.cc +++ b/chrome/browser/extensions/content_script_all_frames_apitest.cc @@ -8,3 +8,8 @@ IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptAllFrames) { StartHTTPServer(); ASSERT_TRUE(RunExtensionTest("content_scripts/all_frames")) << message_; } + +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptExtensionIframe) { + StartHTTPServer(); + ASSERT_TRUE(RunExtensionTest("content_scripts/extension_iframe")) << message_; +} diff --git a/chrome/renderer/extensions/extension_api_client_unittest.cc b/chrome/renderer/extensions/extension_api_client_unittest.cc index 10b6993..86526cf 100644 --- a/chrome/renderer/extensions/extension_api_client_unittest.cc +++ b/chrome/renderer/extensions/extension_api_client_unittest.cc @@ -32,6 +32,7 @@ class ExtensionAPIClientTest : public RenderViewTest { virtual void SetUp() { RenderViewTest::SetUp(); + render_thread_.SetExtensionProcess(true); render_thread_.sink().ClearMessages(); LoadHTML("<body></body>"); } diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc index fe8abcd..a12ef09 100644 --- a/chrome/renderer/extensions/extension_process_bindings.cc +++ b/chrome/renderer/extensions/extension_process_bindings.cc @@ -23,6 +23,7 @@ #include "chrome/renderer/extensions/js_only_v8_extensions.h" #include "chrome/renderer/extensions/renderer_extension_bindings.h" #include "chrome/renderer/user_script_slave.h" +#include "chrome/renderer/render_thread.h" #include "chrome/renderer/render_view.h" #include "grit/common_resources.h" #include "grit/renderer_resources.h" @@ -246,6 +247,8 @@ class ExtensionImpl : public ExtensionBase { return v8::FunctionTemplate::New(GetPopupParentWindow); } else if (name->Equals(v8::String::New("SetExtensionActionIcon"))) { return v8::FunctionTemplate::New(SetExtensionActionIcon); + } else if (name->Equals(v8::String::New("IsExtensionProcess"))) { + return v8::FunctionTemplate::New(IsExtensionProcess); } return ExtensionBase::GetNativeFunction(name); @@ -520,6 +523,13 @@ class ExtensionImpl : public ExtensionBase { return v8::Undefined(); return v8::Integer::New(renderview->routing_id()); } + + static v8::Handle<v8::Value> IsExtensionProcess(const v8::Arguments& args) { + bool retval = false; + if (EventBindings::GetRenderThread()) + retval = EventBindings::GetRenderThread()->IsExtensionProcess(); + return v8::Boolean::New(retval); + } }; } // namespace diff --git a/chrome/renderer/mock_render_thread.cc b/chrome/renderer/mock_render_thread.cc index 49d59c7..0a64f11 100644 --- a/chrome/renderer/mock_render_thread.cc +++ b/chrome/renderer/mock_render_thread.cc @@ -14,7 +14,8 @@ MockRenderThread::MockRenderThread() opener_id_(0), widget_(NULL), reply_deserializer_(NULL), - printer_(new MockPrinter) { + printer_(new MockPrinter), + is_extension_process_(false) { } MockRenderThread::~MockRenderThread() { diff --git a/chrome/renderer/mock_render_thread.h b/chrome/renderer/mock_render_thread.h index 635174b..8e7d210 100644 --- a/chrome/renderer/mock_render_thread.h +++ b/chrome/renderer/mock_render_thread.h @@ -49,6 +49,9 @@ class MockRenderThread : public RenderThreadBase { virtual void WidgetHidden() { } virtual void WidgetRestored() { } + virtual bool IsExtensionProcess() const { return is_extension_process_; } + void SetExtensionProcess(bool value) { is_extension_process_ = value; } + ////////////////////////////////////////////////////////////////////////// // The following functions are called by the test itself. @@ -125,6 +128,8 @@ class MockRenderThread : public RenderThreadBase { // A mock printer device used for printing tests. scoped_ptr<MockPrinter> printer_; + + bool is_extension_process_; }; #endif // CHROME_RENDERER_MOCK_RENDER_THREAD_H_ diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index fc243d8..8a527ca 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -405,7 +405,7 @@ void RenderThread::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) { void RenderThread::WidgetHidden() { DCHECK(hidden_widget_count_ < widget_count_); hidden_widget_count_++; - if (!is_extension_process() && + if (!is_extension_process_ && widget_count_ && hidden_widget_count_ == widget_count_) ScheduleIdleHandler(kInitialIdleHandlerDelayS); } @@ -413,7 +413,7 @@ void RenderThread::WidgetHidden() { void RenderThread::WidgetRestored() { DCHECK_GT(hidden_widget_count_, 0); hidden_widget_count_--; - if (!is_extension_process()) + if (!is_extension_process_) idle_timer_.Stop(); } @@ -755,7 +755,7 @@ void RenderThread::EnsureWebKitInitialized() { // For extensions, we want to ensure we call the IdleHandler every so often, // even if the extension keeps up activity. - if (is_extension_process()) { + if (is_extension_process_) { forced_idle_timer_.Start( base::TimeDelta::FromSeconds(kMaxExtensionIdleHandlerDelayS), this, &RenderThread::IdleHandler); @@ -894,7 +894,7 @@ void RenderThread::IdleHandler() { // kInitialIdleHandlerDelayS in RenderThread::WidgetHidden. ScheduleIdleHandler(idle_notification_delay_in_s_ + 1.0 / (idle_notification_delay_in_s_ + 2.0)); - if (is_extension_process()) { + if (is_extension_process_) { // Dampen the forced delay as well if the extension stays idle for long // periods of time. int64 forced_delay_s = @@ -924,7 +924,7 @@ void RenderThread::OnExtensionMessageInvoke(const std::string& function_name, // Reset the idle handler each time there's any activity like event or message // dispatch, for which Invoke is the chokepoint. - if (is_extension_process()) + if (is_extension_process_) ScheduleIdleHandler(kInitialExtensionIdleHandlerDelayS); } diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h index 3c45dd5..e8396dd 100644 --- a/chrome/renderer/render_thread.h +++ b/chrome/renderer/render_thread.h @@ -77,6 +77,9 @@ class RenderThreadBase { // Called by a RenderWidget when it is hidden or restored. virtual void WidgetHidden() = 0; virtual void WidgetRestored() = 0; + + // True if this process should be treated as an extension process. + virtual bool IsExtensionProcess() const = 0; }; // The RenderThread class represents a background thread where RenderView @@ -144,7 +147,7 @@ class RenderThread : public RenderThreadBase, bool plugin_refresh_allowed() const { return plugin_refresh_allowed_; } - bool is_extension_process() const { return is_extension_process_; } + virtual bool IsExtensionProcess() const { return is_extension_process_; } bool is_incognito_process() const { return is_incognito_process_; } diff --git a/chrome/renderer/resources/extension_process_bindings.js b/chrome/renderer/resources/extension_process_bindings.js index d7b0aac..6fd334a 100644 --- a/chrome/renderer/resources/extension_process_bindings.js +++ b/chrome/renderer/resources/extension_process_bindings.js @@ -18,12 +18,23 @@ var chrome = chrome || {}; native function GetPopupParentWindow(); native function GetPopupView(); native function SetExtensionActionIcon(); + native function IsExtensionProcess(); + + var chromeHidden = GetChromeHidden(); + + // These bindings are for the extension process only. Since a chrome-extension + // URL can be loaded in an iframe of a regular renderer, we check here to + // ensure we don't expose the APIs in that case. + if (!IsExtensionProcess()) { + chromeHidden.onLoad.addListener(function (extensionId) { + chrome.initExtension(extensionId, false); + }); + return; + } if (!chrome) chrome = {}; - var chromeHidden = GetChromeHidden(); - // Validate arguments. chromeHidden.validationTypes = []; chromeHidden.validate = function(args, schemas) { diff --git a/chrome/test/data/extensions/api_test/content_scripts/extension_iframe/iframe.html b/chrome/test/data/extensions/api_test/content_scripts/extension_iframe/iframe.html new file mode 100644 index 0000000..9c43370 --- /dev/null +++ b/chrome/test/data/extensions/api_test/content_scripts/extension_iframe/iframe.html @@ -0,0 +1,6 @@ +<script> +// Simple success test: we want content-script APIs to be available (like +// sendRequest), but other APIs to be undefined. +var success = (chrome.tabs == undefined); +chrome.extension.sendRequest({success: success}); +</script> diff --git a/chrome/test/data/extensions/api_test/content_scripts/extension_iframe/manifest.json b/chrome/test/data/extensions/api_test/content_scripts/extension_iframe/manifest.json new file mode 100644 index 0000000..4b1a689 --- /dev/null +++ b/chrome/test/data/extensions/api_test/content_scripts/extension_iframe/manifest.json @@ -0,0 +1,13 @@ +{ + "name": "content_script_extension_iframe", + "version": "1.0", + "description": "Tests that a chrome-extension iframe gets messaging privileges", + "background_page": "test.html", + "permissions": ["tabs"], + "content_scripts": [ + { + "matches": ["http://*/*"], + "js": ["script.js"] + } + ] +} diff --git a/chrome/test/data/extensions/api_test/content_scripts/extension_iframe/script.js b/chrome/test/data/extensions/api_test/content_scripts/extension_iframe/script.js new file mode 100644 index 0000000..2b2613b --- /dev/null +++ b/chrome/test/data/extensions/api_test/content_scripts/extension_iframe/script.js @@ -0,0 +1,3 @@ +var ifr = document.createElement("iframe"); +ifr.src = chrome.extension.getURL("iframe.html"); +document.body.appendChild(ifr); diff --git a/chrome/test/data/extensions/api_test/content_scripts/extension_iframe/test.html b/chrome/test/data/extensions/api_test/content_scripts/extension_iframe/test.html new file mode 100644 index 0000000..72240e7 --- /dev/null +++ b/chrome/test/data/extensions/api_test/content_scripts/extension_iframe/test.html @@ -0,0 +1,18 @@ +<script> +chrome.test.runTests([ + // Tests receiving a request from a content script and responding. + function onRequest() { + chrome.extension.onRequest.addListener( + function(request, sender, sendResponse) { + chrome.test.assertTrue(request.success); + chrome.test.succeed(); + } + ); + } +]); + +chrome.test.log("Creating tab..."); +chrome.tabs.create({ + url: "http://localhost:1337/files/extensions/test_file.html" +}); +</script> |