diff options
author | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-16 07:47:39 +0000 |
---|---|---|
committer | aa@chromium.org <aa@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-12-16 07:47:39 +0000 |
commit | c8865964330959b40718c0e6148288da64f14fec (patch) | |
tree | 78a39905db0a850690c673a76ef59eadb28f54d6 /chrome | |
parent | 3ce10b7c419cc4522f885008cbb3c76b02256ba3 (diff) | |
download | chromium_src-c8865964330959b40718c0e6148288da64f14fec.zip chromium_src-c8865964330959b40718c0e6148288da64f14fec.tar.gz chromium_src-c8865964330959b40718c0e6148288da64f14fec.tar.bz2 |
Fix regression where we stopped running content scripts in
extension processes.
BUG=29621
Review URL: http://codereview.chromium.org/505012
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34668 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
17 files changed, 112 insertions, 49 deletions
diff --git a/chrome/browser/extensions/content_script_extension_process_apitest.cc b/chrome/browser/extensions/content_script_extension_process_apitest.cc new file mode 100644 index 0000000..18ee070 --- /dev/null +++ b/chrome/browser/extensions/content_script_extension_process_apitest.cc @@ -0,0 +1,15 @@ +// Copyright (c) 2009 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/browser.h" +#include "chrome/browser/extensions/extension_apitest.h" +#include "chrome/browser/extensions/extensions_service.h" +#include "chrome/browser/profile.h" +#include "chrome/common/extensions/extension.h" +#include "chrome/test/ui_test_utils.h" + +IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ContentScriptExtensionProcess) { + StartHTTPServer(); + ASSERT_TRUE(RunExtensionTest("content_script_extension_process")) << message_; +} diff --git a/chrome/browser/extensions/extensions_service.cc b/chrome/browser/extensions/extensions_service.cc index 578b8ef..99a97f2a 100644 --- a/chrome/browser/extensions/extensions_service.cc +++ b/chrome/browser/extensions/extensions_service.cc @@ -643,10 +643,10 @@ void ExtensionsService::OnExtensionLoaded(Extension* extension, } void ExtensionsService::UpdateActiveExtensionsInCrashReporter() { - std::vector<std::string> extension_ids; + std::set<std::string> extension_ids; for (size_t i = 0; i < extensions_.size(); ++i) { if (!extensions_[i]->IsTheme()) - extension_ids.push_back(extensions_[i]->id()); + extension_ids.insert(extensions_[i]->id()); } child_process_logging::SetActiveExtensions(extension_ids); diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc index 05a452d..bb7e99d 100644 --- a/chrome/browser/renderer_host/browser_render_process_host.cc +++ b/chrome/browser/renderer_host/browser_render_process_host.cc @@ -595,14 +595,6 @@ void BrowserRenderProcessHost::InitExtensions() { void BrowserRenderProcessHost::SendUserScriptsUpdate( base::SharedMemory *shared_memory) { - // Don't send user scripts to extension processes. We currently don't allow - // user scripts to run in extensions, so it would be pointless. It would also - // mess up the crash reporting, which sends a different set of "active" - // extensions depending on whether the process is an extension or renderer - // process. - if (extension_process_) - return; - // Process is being started asynchronously. We'll end up calling // InitUserScripts when it's created which will call this again. if (child_process_.get() && child_process_->IsStarting()) diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index acf6410..5883286 100755 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1075,6 +1075,7 @@ 'browser/extensions/browser_action_apitest.cc', 'browser/extensions/browser_action_test_util.h', 'browser/extensions/content_script_all_frames_apitest.cc', + 'browser/extensions/content_script_extension_process_apitest.cc', 'browser/extensions/cross_origin_xhr_apitest.cc', 'browser/extensions/execute_script_apitest.cc', 'browser/extensions/extension_apitest.cc', diff --git a/chrome/common/child_process_logging.h b/chrome/common/child_process_logging.h index 513359f..9bc386e 100644 --- a/chrome/common/child_process_logging.h +++ b/chrome/common/child_process_logging.h @@ -5,7 +5,7 @@ #ifndef CHROME_COMMON_CHILD_PROCESS_LOGGING_H_ #define CHROME_COMMON_CHILD_PROCESS_LOGGING_H_ -#include <vector> +#include <set> #include "base/basictypes.h" #include "googleurl/src/gurl.h" @@ -25,7 +25,7 @@ void SetClientId(const std::string& client_id); // - renderer: the unique set of extension ids from all content scripts // - extension: the id of each extension running in this process (there can be // multiple because of process collapsing). -void SetActiveExtensions(const std::vector<std::string>& extension_ids); +void SetActiveExtensions(const std::set<std::string>& extension_ids); // Simple wrapper class that sets the active URL in it's constructor and clears // the active URL in the destructor. diff --git a/chrome/common/child_process_logging_linux.cc b/chrome/common/child_process_logging_linux.cc index bbe18fd..a60788f 100644 --- a/chrome/common/child_process_logging_linux.cc +++ b/chrome/common/child_process_logging_linux.cc @@ -32,7 +32,7 @@ void SetClientId(const std::string& client_id) { GoogleUpdateSettings::SetMetricsId(wstr); } -void SetActiveExtensions(const std::vector<std::string>& extension_ids) { +void SetActiveExtensions(const std::set<std::string>& extension_ids) { // TODO(port) } } // namespace child_process_logging diff --git a/chrome/common/child_process_logging_mac.mm b/chrome/common/child_process_logging_mac.mm index 5d46e01..c0c93e41 100644 --- a/chrome/common/child_process_logging_mac.mm +++ b/chrome/common/child_process_logging_mac.mm @@ -92,7 +92,7 @@ void SetClientId(const std::string& client_id) { GoogleUpdateSettings::SetMetricsId(wstr); } -void SetActiveExtensions(const std::vector<std::string>& extension_ids) { +void SetActiveExtensions(const std::set<std::string>& extension_ids) { // TODO(port) } diff --git a/chrome/common/child_process_logging_win.cc b/chrome/common/child_process_logging_win.cc index 9a11e8f..654b4fb 100644 --- a/chrome/common/child_process_logging_win.cc +++ b/chrome/common/child_process_logging_win.cc @@ -66,7 +66,7 @@ void SetClientId(const std::string& client_id) { (set_client_id)(wstr.c_str()); } -void SetActiveExtensions(const std::vector<std::string>& extension_ids) { +void SetActiveExtensions(const std::set<std::string>& extension_ids) { static MainSetExtensionID set_extension_id = NULL; if (!set_extension_id) { HMODULE exe_module = GetModuleHandle(chrome::kBrowserProcessExecutableName); @@ -78,11 +78,14 @@ void SetActiveExtensions(const std::vector<std::string>& extension_ids) { return; } + std::set<std::string>::const_iterator iter = extension_ids.begin(); for (size_t i = 0; i < kMaxReportedActiveExtensions; ++i) { - if (i < extension_ids.size()) - (set_extension_id)(i, ASCIIToWide(extension_ids[i].c_str()).c_str()); - else + if (iter != extension_ids.end()) { + (set_extension_id)(i, ASCIIToWide(iter->c_str()).c_str()); + ++iter; + } else { (set_extension_id)(i, L""); + } } } diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc index 7af9b5f..e7aef4b 100644 --- a/chrome/renderer/extensions/extension_process_bindings.cc +++ b/chrome/renderer/extensions/extension_process_bindings.cc @@ -12,7 +12,6 @@ #include "base/command_line.h" #include "base/json/json_reader.h" #include "base/singleton.h" -#include "chrome/common/child_process_logging.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_message_bundle.h" @@ -23,6 +22,7 @@ #include "chrome/renderer/extensions/event_bindings.h" #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_view.h" #include "grit/common_resources.h" #include "grit/renderer_resources.h" @@ -105,17 +105,14 @@ static L10nMessagesMap* GetL10nMessagesMap(const std::string extension_id) { } } -static std::vector<std::string> GetActiveExtensionIDs() { - std::vector<std::string> extension_ids; +static void GetActiveExtensionIDs(std::set<std::string>* extension_ids) { ExtensionPermissionsMap& permissions = Singleton<SingletonData>()->permissions_; for (ExtensionPermissionsMap::iterator iter = permissions.begin(); iter != permissions.end(); ++iter) { - extension_ids.push_back(iter->first); + extension_ids->insert(iter->first); } - - return extension_ids; } // A RenderViewVisitor class that iterates through the set of available @@ -585,6 +582,11 @@ v8::Extension* ExtensionProcessBindings::Get() { return extension; } +void ExtensionProcessBindings::GetActiveExtensions( + std::set<std::string>* extension_ids) { + GetActiveExtensionIDs(extension_ids); +} + void ExtensionProcessBindings::SetFunctionNames( const std::vector<std::string>& names) { ExtensionImpl::SetFunctionNames(names); @@ -653,12 +655,6 @@ void ExtensionProcessBindings::SetAPIPermissions( permissions_map[Extension::kPermissionNames[i]] = false; for (size_t i = 0; i < permissions.size(); ++i) permissions_map[permissions[i]] = true; - - // Ugly hack. We also update our list of active extensions here. This always - // gets called, even if the extension has no api permissions. In single - // process, this has already been done in the browser code. - if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) - child_process_logging::SetActiveExtensions(GetActiveExtensionIDs()); } // static diff --git a/chrome/renderer/extensions/extension_process_bindings.h b/chrome/renderer/extensions/extension_process_bindings.h index 1009932..08f068d2 100644 --- a/chrome/renderer/extensions/extension_process_bindings.h +++ b/chrome/renderer/extensions/extension_process_bindings.h @@ -8,6 +8,7 @@ #define CHROME_RENDERER_EXTENSIONS_EXTENSION_PROCESS_BINDINGS_H_ #include <map> +#include <set> #include <string> #include <vector> @@ -26,6 +27,9 @@ class ExtensionProcessBindings { static void SetFunctionNames(const std::vector<std::string>& names); static v8::Extension* Get(); + // Gets the set of extensions running in this process. + static void GetActiveExtensions(std::set<std::string>* extension_ids); + // Handles a response to an API request. static void HandleResponse(int request_id, bool success, const std::string& response, diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc index dafe2a2..df6dc42 100644 --- a/chrome/renderer/render_thread.cc +++ b/chrome/renderer/render_thread.cc @@ -26,6 +26,7 @@ #include "base/string_util.h" #include "base/thread_local.h" #include "chrome/common/appcache/appcache_dispatcher.h" +#include "chrome/common/child_process_logging.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/db_message_filter.h" #include "chrome/common/render_messages.h" @@ -288,6 +289,7 @@ void RenderThread::OnUpdateUserScripts( base::SharedMemoryHandle scripts) { DCHECK(base::SharedMemory::IsHandleValid(scripts)) << "Bad scripts handle"; user_script_slave_->UpdateScripts(scripts); + UpdateActiveExtensions(); } void RenderThread::OnSetExtensionFunctionNames( @@ -309,6 +311,8 @@ void RenderThread::OnExtensionSetAPIPermissions( // This is called when starting a new extension page, so start the idle // handler ticking. ScheduleIdleHandler(kInitialExtensionIdleHandlerDelayS); + + UpdateActiveExtensions(); } void RenderThread::OnExtensionSetHostPermissions( @@ -494,6 +498,17 @@ void RenderThread::SetCacheMode(bool enabled) { Send(new ViewHostMsg_SetCacheMode(enabled)); } +void RenderThread::UpdateActiveExtensions() { + // In single-process mode, the browser process reports the active extensions. + if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) + return; + + std::set<std::string> active_extensions; + user_script_slave_->GetActiveExtensions(&active_extensions); + ExtensionProcessBindings::GetActiveExtensions(&active_extensions); + child_process_logging::SetActiveExtensions(active_extensions); +} + static void* CreateHistogram( const char *name, int min, int max, size_t buckets) { if (min <= 0) diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h index 8a376aa..2b5693a 100644 --- a/chrome/renderer/render_thread.h +++ b/chrome/renderer/render_thread.h @@ -5,6 +5,7 @@ #ifndef CHROME_RENDERER_RENDER_THREAD_H_ #define CHROME_RENDERER_RENDER_THREAD_H_ +#include <set> #include <string> #include <vector> @@ -145,6 +146,9 @@ class RenderThread : public RenderThreadBase, // Sends a message to the browser to enable or disable the disk cache. void SetCacheMode(bool enabled); + // Update the list of active extensions that will be reported when we crash. + void UpdateActiveExtensions(); + private: virtual void OnControlMessageReceived(const IPC::Message& msg); diff --git a/chrome/renderer/user_script_slave.cc b/chrome/renderer/user_script_slave.cc index 7ddbd71..a06d856 100644 --- a/chrome/renderer/user_script_slave.cc +++ b/chrome/renderer/user_script_slave.cc @@ -12,7 +12,6 @@ #include "base/pickle.h" #include "base/shared_memory.h" #include "base/string_util.h" -#include "chrome/common/child_process_logging.h" #include "chrome/common/chrome_switches.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_constants.h" @@ -62,6 +61,13 @@ UserScriptSlave::UserScriptSlave() IDR_GREASEMONKEY_API_JS); } +void UserScriptSlave::GetActiveExtensions(std::set<std::string>* extension_ids) { + for (size_t i = 0; i < scripts_.size(); ++i) { + DCHECK(!scripts_[i]->extension_id().empty()); + extension_ids->insert(scripts_[i]->extension_id()); + } +} + bool UserScriptSlave::UpdateScripts(base::SharedMemoryHandle shared_memory) { scripts_.clear(); @@ -114,24 +120,6 @@ bool UserScriptSlave::UpdateScripts(base::SharedMemoryHandle shared_memory) { } } - // Update the crash reporter with all loaded extensions. In single process, - // this has already been done in the browser code. - if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) { - std::vector<std::string> extension_ids; - for (size_t i = 0; i < num_scripts; ++i) { - DCHECK(!scripts_[i]->extension_id().empty()); - - // We must check this because there can be multiple scripts from a single - // extension. n^2, but meh, it's a small list. - if (std::find(extension_ids.begin(), extension_ids.end(), - scripts_[i]->extension_id()) == extension_ids.end()) { - extension_ids.push_back(scripts_[i]->extension_id()); - } - } - - child_process_logging::SetActiveExtensions(extension_ids); - } - return true; } diff --git a/chrome/renderer/user_script_slave.h b/chrome/renderer/user_script_slave.h index 6c32c42..cf8fb8d 100644 --- a/chrome/renderer/user_script_slave.h +++ b/chrome/renderer/user_script_slave.h @@ -6,6 +6,7 @@ #define CHROME_RENDERER_USER_SCRIPT_SLAVE_H_ #include <map> +#include <set> #include <string> #include <vector> @@ -27,6 +28,9 @@ class UserScriptSlave { public: UserScriptSlave(); + // Returns the unique set of extension IDs this UserScriptSlave knows about. + void GetActiveExtensions(std::set<std::string>* extension_ids); + // Update the parsed scripts from shared memory. bool UpdateScripts(base::SharedMemoryHandle shared_memory); diff --git a/chrome/test/data/extensions/api_test/content_script_extension_process/background.html b/chrome/test/data/extensions/api_test/content_script_extension_process/background.html new file mode 100644 index 0000000..a33b1b1 --- /dev/null +++ b/chrome/test/data/extensions/api_test/content_script_extension_process/background.html @@ -0,0 +1,23 @@ +<!-- +Copyright (c) 2009 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. +--> + +<!-- +Two common ways that we can end up with web pages running in an extension +process are iframes and popup windows. +--> +<script> +var numPings = 0; +chrome.extension.onRequest.addListener(function(data) { + if (data != "ping") + chrome.test.fail("Unexpected request: " + JSON.stringify(data)); + + if (++numPings == 2) + chrome.test.notifyPass(); +}); + +var w = window.open("http://localhost:1337/files/extensions/test_file.html"); +</script> +<iframe src="http://localhost:1337/files/extensions/test_file.html"></iframe> diff --git a/chrome/test/data/extensions/api_test/content_script_extension_process/injectionator.js b/chrome/test/data/extensions/api_test/content_script_extension_process/injectionator.js new file mode 100644 index 0000000..8a2725d --- /dev/null +++ b/chrome/test/data/extensions/api_test/content_script_extension_process/injectionator.js @@ -0,0 +1,5 @@ +// Copyright (c) 2009 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. + +chrome.extension.sendRequest("ping"); diff --git a/chrome/test/data/extensions/api_test/content_script_extension_process/manifest.json b/chrome/test/data/extensions/api_test/content_script_extension_process/manifest.json new file mode 100644 index 0000000..dec288e --- /dev/null +++ b/chrome/test/data/extensions/api_test/content_script_extension_process/manifest.json @@ -0,0 +1,13 @@ +{ + "name": "content_script_extension_process", + "version": "1.0", + "description": "Content scripts should get injected into web pages, even when the webpages are in an extension process.", + "background_page": "background.html", + "content_scripts": [ + { + "matches": ["http://*/*"], + "js": ["injectionator.js"], + "all_frames": true + } + ] +} |