summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-29 17:32:24 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-29 17:32:24 +0000
commit6779aa1d281cce1b77c96d5fb77535c9838b0949 (patch)
tree2eef595d07ab6d858dfffc27202d5e00a80f6934
parentba0483f513f5f28a7eeff34dafa4e89d2c232c61 (diff)
downloadchromium_src-6779aa1d281cce1b77c96d5fb77535c9838b0949.zip
chromium_src-6779aa1d281cce1b77c96d5fb77535c9838b0949.tar.gz
chromium_src-6779aa1d281cce1b77c96d5fb77535c9838b0949.tar.bz2
Move the dispatching of extension messages out of RenderThread. This also moves a bunch of extension related state out of RenderThread.
Review URL: http://codereview.chromium.org/6765011 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79699 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/renderer_host/browser_render_process_host.cc2
-rw-r--r--chrome/chrome_renderer.gypi2
-rw-r--r--chrome/common/extensions/extension_messages.h7
-rw-r--r--chrome/common/render_messages.h6
-rw-r--r--chrome/renderer/chrome_content_renderer_client.cc16
-rw-r--r--chrome/renderer/chrome_content_renderer_client.h2
-rw-r--r--chrome/renderer/extensions/chrome_app_bindings.cc4
-rw-r--r--chrome/renderer/extensions/event_bindings.cc3
-rw-r--r--chrome/renderer/extensions/extension_dispatcher.cc219
-rw-r--r--chrome/renderer/extensions/extension_dispatcher.h100
-rw-r--r--chrome/renderer/extensions/extension_process_bindings.cc6
-rw-r--r--chrome/renderer/mock_render_thread.cc8
-rw-r--r--chrome/renderer/mock_render_thread.h10
-rw-r--r--chrome/renderer/render_thread.cc208
-rw-r--r--chrome/renderer/render_thread.h86
-rw-r--r--chrome/test/render_view_test.cc7
-rw-r--r--chrome/test/render_view_test.h3
-rw-r--r--content/renderer/content_renderer_client.cc8
-rw-r--r--content/renderer/content_renderer_client.h12
-rw-r--r--content/renderer/render_process_observer.cc16
-rw-r--r--content/renderer/render_process_observer.h16
-rw-r--r--content/renderer/render_view.cc25
22 files changed, 476 insertions, 290 deletions
diff --git a/chrome/browser/renderer_host/browser_render_process_host.cc b/chrome/browser/renderer_host/browser_render_process_host.cc
index 14fedea..864f8b3 100644
--- a/chrome/browser/renderer_host/browser_render_process_host.cc
+++ b/chrome/browser/renderer_host/browser_render_process_host.cc
@@ -862,7 +862,7 @@ void BrowserRenderProcessHost::SendUserScriptsUpdate(
}
if (base::SharedMemory::IsHandleValid(handle_for_process)) {
- Send(new ViewMsg_UserScripts_UpdatedScripts(handle_for_process));
+ Send(new ExtensionMsg_UpdateUserScripts(handle_for_process));
}
}
diff --git a/chrome/chrome_renderer.gypi b/chrome/chrome_renderer.gypi
index ac81281..2ad02ff 100644
--- a/chrome/chrome_renderer.gypi
+++ b/chrome/chrome_renderer.gypi
@@ -59,6 +59,8 @@
'renderer/extensions/chrome_app_bindings.h',
'renderer/extensions/event_bindings.cc',
'renderer/extensions/event_bindings.h',
+ 'renderer/extensions/extension_dispatcher.cc',
+ 'renderer/extensions/extension_dispatcher.h',
'renderer/extensions/extension_helper.cc',
'renderer/extensions/extension_helper.h',
'renderer/extensions/extension_process_bindings.cc',
diff --git a/chrome/common/extensions/extension_messages.h b/chrome/common/extensions/extension_messages.h
index 2a6bcdb..f3091ba 100644
--- a/chrome/common/extensions/extension_messages.h
+++ b/chrome/common/extensions/extension_messages.h
@@ -5,6 +5,7 @@
// IPC messages for extensions.
// Multiply-included message file, hence no include guard.
+#include "base/shared_memory.h"
#include "base/values.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/extensions/extension_extent.h"
@@ -200,6 +201,12 @@ IPC_MESSAGE_CONTROL1(ExtensionMsg_SetScriptingWhitelist,
IPC_MESSAGE_ROUTED1(ExtensionMsg_ExecuteCode,
ExtensionMsg_ExecuteCode_Params)
+// Notification that the user scripts have been updated. It has one
+// SharedMemoryHandle argument consisting of the pickled script data. This
+// handle is valid in the context of the renderer.
+IPC_MESSAGE_CONTROL1(ExtensionMsg_UpdateUserScripts,
+ base::SharedMemoryHandle)
+
// Requests application info for the page. The renderer responds back with
// ExtensionHostMsg_DidGetApplicationInfo.
IPC_MESSAGE_ROUTED1(ExtensionMsg_GetApplicationInfo,
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index 61272d4..5212785 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -173,12 +173,6 @@ IPC_MESSAGE_CONTROL1(ViewMsg_VisitedLink_Add, std::vector<uint64>)
// re-calculated.
IPC_MESSAGE_CONTROL0(ViewMsg_VisitedLink_Reset)
-// Notification that the user scripts have been updated. It has one
-// SharedMemoryHandle argument consisting of the pickled script data. This
-// handle is valid in the context of the renderer.
-IPC_MESSAGE_CONTROL1(ViewMsg_UserScripts_UpdatedScripts,
- base::SharedMemoryHandle)
-
// Sent when user prompting is required before a ViewHostMsg_GetCookies
// message can complete. This message indicates that the renderer should
// pump messages while waiting for cookies.
diff --git a/chrome/renderer/chrome_content_renderer_client.cc b/chrome/renderer/chrome_content_renderer_client.cc
index 3ecc9ee..c2327602 100644
--- a/chrome/renderer/chrome_content_renderer_client.cc
+++ b/chrome/renderer/chrome_content_renderer_client.cc
@@ -12,8 +12,9 @@
#include "chrome/common/render_messages.h"
#include "chrome/common/url_constants.h"
#include "chrome/renderer/blocked_plugin.h"
+#include "chrome/renderer/extensions/bindings_utils.h"
+#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "chrome/renderer/localized_error.h"
-#include "chrome/renderer/render_thread.h"
#include "content/common/view_messages.h"
#include "content/renderer/render_view.h"
#include "grit/generated_resources.h"
@@ -169,7 +170,7 @@ std::string ChromeContentRendererClient::GetNavigationErrorHtml(
int resource_id;
DictionaryValue error_strings;
if (failed_url.is_valid() && !failed_url.SchemeIs(chrome::kExtensionScheme))
- extension = RenderThread::current()->GetExtensions()->GetByURL(failed_url);
+ extension = ExtensionDispatcher::Get()->extensions()->GetByURL(failed_url);
if (extension) {
LocalizedError::GetAppErrorStrings(error, failed_url, extension,
&error_strings);
@@ -228,4 +229,15 @@ std::string ChromeContentRendererClient::DetermineTextLanguage(
return language;
}
+bool ChromeContentRendererClient::RunIdleHandlerWhenWidgetsHidden() {
+ return !ExtensionDispatcher::Get()->is_extension_process();
+}
+
+bool ChromeContentRendererClient::AllowPopup(const GURL& creator) {
+ // Extensions and apps always allowed to create unrequested popups. The second
+ // check is necessary to include content scripts.
+ return ExtensionDispatcher::Get()->extensions()->GetByURL(creator) ||
+ bindings_utils::GetInfoForCurrentContext();
+}
+
} // namespace chrome
diff --git a/chrome/renderer/chrome_content_renderer_client.h b/chrome/renderer/chrome_content_renderer_client.h
index 4b39092..3489181 100644
--- a/chrome/renderer/chrome_content_renderer_client.h
+++ b/chrome/renderer/chrome_content_renderer_client.h
@@ -28,6 +28,8 @@ class ChromeContentRendererClient : public content::ContentRendererClient {
const WebKit::WebURLRequest& failed_request,
const WebKit::WebURLError& error);
virtual std::string DetermineTextLanguage(const string16& text);
+ virtual bool RunIdleHandlerWhenWidgetsHidden();
+ virtual bool AllowPopup(const GURL& creator);
private:
WebKit::WebPlugin* CreatePluginPlaceholder(
diff --git a/chrome/renderer/extensions/chrome_app_bindings.cc b/chrome/renderer/extensions/chrome_app_bindings.cc
index f6a169b..f5cdd38 100644
--- a/chrome/renderer/extensions/chrome_app_bindings.cc
+++ b/chrome/renderer/extensions/chrome_app_bindings.cc
@@ -8,7 +8,7 @@
#include "base/utf_string_conversions.h"
#include "chrome/common/extensions/extension_set.h"
#include "chrome/renderer/extensions/bindings_utils.h"
-#include "chrome/renderer/render_thread.h"
+#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "content/renderer/render_view.h"
#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
#include "v8/include/v8.h"
@@ -58,7 +58,7 @@ class ChromeAppExtensionWrapper : public v8::Extension {
return v8::Boolean::New(false);
bool has_web_extent =
- RenderThread::current()->GetExtensions()->GetByURL(url) != NULL;
+ ExtensionDispatcher::Get()->extensions()->GetByURL(url) != NULL;
return v8::Boolean::New(has_web_extent);
}
diff --git a/chrome/renderer/extensions/event_bindings.cc b/chrome/renderer/extensions/event_bindings.cc
index 7dd83ca..0e41f64 100644
--- a/chrome/renderer/extensions/event_bindings.cc
+++ b/chrome/renderer/extensions/event_bindings.cc
@@ -11,6 +11,7 @@
#include "chrome/common/url_constants.h"
#include "chrome/renderer/extensions/bindings_utils.h"
#include "chrome/renderer/extensions/event_bindings.h"
+#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "chrome/renderer/extensions/extension_process_bindings.h"
#include "chrome/renderer/extensions/js_only_v8_extensions.h"
#include "chrome/renderer/render_thread.h"
@@ -265,7 +266,7 @@ void EventBindings::HandleContextCreated(WebFrame* frame, bool content_script) {
if (!ds)
ds = frame->dataSource();
GURL url = ds->request().url();
- const ExtensionSet* extensions = GetRenderThread()->GetExtensions();
+ const ExtensionSet* extensions = ExtensionDispatcher::Get()->extensions();
std::string extension_id = extensions->GetIdByURL(url);
if (!extensions->ExtensionBindingsAllowed(url) &&
diff --git a/chrome/renderer/extensions/extension_dispatcher.cc b/chrome/renderer/extensions/extension_dispatcher.cc
new file mode 100644
index 0000000..cfaad3d
--- /dev/null
+++ b/chrome/renderer/extensions/extension_dispatcher.cc
@@ -0,0 +1,219 @@
+// Copyright (c) 2011 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/renderer/extensions/extension_dispatcher.h"
+
+#include "base/command_line.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_messages.h"
+#include "chrome/renderer/extension_groups.h"
+#include "chrome/renderer/extensions/chrome_app_bindings.h"
+#include "chrome/renderer/extensions/event_bindings.h"
+#include "chrome/renderer/extensions/extension_process_bindings.h"
+#include "chrome/renderer/extensions/js_only_v8_extensions.h"
+#include "chrome/renderer/extensions/renderer_extension_bindings.h"
+#include "chrome/renderer/render_thread.h"
+#include "chrome/renderer/user_script_slave.h"
+#include "v8/include/v8.h"
+
+namespace {
+static const double kInitialExtensionIdleHandlerDelayS = 5.0 /* seconds */;
+static const int64 kMaxExtensionIdleHandlerDelayS = 5*60 /* seconds */;
+static ExtensionDispatcher* g_extension_dispatcher;
+}
+
+ExtensionDispatcher* ExtensionDispatcher::Get() {
+ return g_extension_dispatcher;
+}
+
+ExtensionDispatcher::ExtensionDispatcher() {
+ DCHECK(!g_extension_dispatcher);
+ g_extension_dispatcher = this;
+
+ std::string type_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
+ switches::kProcessType);
+ is_extension_process_ = type_str == switches::kExtensionProcess ||
+ CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess);
+
+ if (is_extension_process_) {
+ RenderThread::current()->set_idle_notification_delay_in_s(
+ kInitialExtensionIdleHandlerDelayS);
+ }
+
+ user_script_slave_.reset(new UserScriptSlave(&extensions_));
+}
+
+ExtensionDispatcher::~ExtensionDispatcher() {
+ g_extension_dispatcher = NULL;
+}
+
+bool ExtensionDispatcher::OnControlMessageReceived(
+ const IPC::Message& message) {
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(ExtensionDispatcher, message)
+ IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnMessageInvoke)
+ IPC_MESSAGE_HANDLER(ExtensionMsg_SetFunctionNames, OnSetFunctionNames)
+ IPC_MESSAGE_HANDLER(ExtensionMsg_Loaded, OnLoaded)
+ IPC_MESSAGE_HANDLER(ExtensionMsg_Unloaded, OnUnloaded)
+ IPC_MESSAGE_HANDLER(ExtensionMsg_SetScriptingWhitelist,
+ OnSetScriptingWhitelist)
+ IPC_MESSAGE_HANDLER(ExtensionMsg_UpdatePageActions, OnPageActionsUpdated)
+ IPC_MESSAGE_HANDLER(ExtensionMsg_SetAPIPermissions, OnSetAPIPermissions)
+ IPC_MESSAGE_HANDLER(ExtensionMsg_SetHostPermissions, OnSetHostPermissions)
+ IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateUserScripts, OnUpdateUserScripts)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+
+ return handled;
+}
+
+void ExtensionDispatcher::OnRenderProcessShutdown() {
+ delete this;
+}
+
+void ExtensionDispatcher::WebKitInitialized() {
+ // For extensions, we want to ensure we call the IdleHandler every so often,
+ // even if the extension keeps up activity.
+ if (is_extension_process_) {
+ forced_idle_timer_.Start(
+ base::TimeDelta::FromSeconds(kMaxExtensionIdleHandlerDelayS),
+ RenderThread::current(), &RenderThread::IdleHandler);
+ }
+
+ RegisterExtension(extensions_v8::ChromeAppExtension::Get(), false);
+
+ // Add v8 extensions related to chrome extensions.
+ RegisterExtension(ExtensionProcessBindings::Get(), true);
+ RegisterExtension(BaseJsV8Extension::Get(), true);
+ RegisterExtension(JsonSchemaJsV8Extension::Get(), true);
+ RegisterExtension(EventBindings::Get(), true);
+ RegisterExtension(RendererExtensionBindings::Get(), true);
+ RegisterExtension(ExtensionApiTestV8Extension::Get(), true);
+}
+
+bool ExtensionDispatcher::AllowScriptExtension(
+ const std::string& v8_extension_name,
+ const GURL& url,
+ int extension_group) {
+ // If the V8 extension is not restricted, allow it to run anywhere.
+ if (!restricted_v8_extensions_.count(v8_extension_name))
+ return true;
+
+ // Extension-only bindings should be restricted to content scripts and
+ // extension-blessed URLs.
+ if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS ||
+ extensions_.ExtensionBindingsAllowed(url)) {
+ return true;
+ }
+
+ return false;
+}
+
+void ExtensionDispatcher::IdleNotification() {
+ if (is_extension_process_) {
+ // Dampen the forced delay as well if the extension stays idle for long
+ // periods of time.
+ int64 forced_delay_s = std::max(static_cast<int64>(
+ RenderThread::current()->idle_notification_delay_in_s()),
+ kMaxExtensionIdleHandlerDelayS);
+ forced_idle_timer_.Stop();
+ forced_idle_timer_.Start(
+ base::TimeDelta::FromSeconds(forced_delay_s),
+ RenderThread::current(), &RenderThread::IdleHandler);
+ }
+}
+
+void ExtensionDispatcher::OnSetFunctionNames(
+ const std::vector<std::string>& names) {
+ ExtensionProcessBindings::SetFunctionNames(names);
+}
+
+void ExtensionDispatcher::OnMessageInvoke(const std::string& extension_id,
+ const std::string& function_name,
+ const ListValue& args,
+ const GURL& event_url) {
+ RendererExtensionBindings::Invoke(
+ extension_id, function_name, args, NULL, event_url);
+
+ // 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_) {
+ RenderThread::current()->ScheduleIdleHandler(
+ kInitialExtensionIdleHandlerDelayS);
+ }
+}
+
+void ExtensionDispatcher::OnLoaded(const ExtensionMsg_Loaded_Params& params) {
+ scoped_refptr<const Extension> extension(params.ConvertToExtension());
+ if (!extension) {
+ // This can happen if extension parsing fails for any reason. One reason
+ // this can legitimately happen is if the
+ // --enable-experimental-extension-apis changes at runtime, which happens
+ // during browser tests. Existing renderers won't know about the change.
+ return;
+ }
+
+ extensions_.Insert(extension);
+}
+
+void ExtensionDispatcher::OnUnloaded(const std::string& id) {
+ extensions_.Remove(id);
+}
+
+void ExtensionDispatcher::OnSetScriptingWhitelist(
+ const Extension::ScriptingWhitelist& extension_ids) {
+ Extension::SetScriptingWhitelist(extension_ids);
+}
+
+void ExtensionDispatcher::OnPageActionsUpdated(
+ const std::string& extension_id,
+ const std::vector<std::string>& page_actions) {
+ ExtensionProcessBindings::SetPageActions(extension_id, page_actions);
+}
+
+void ExtensionDispatcher::OnSetAPIPermissions(
+ const std::string& extension_id,
+ const std::set<std::string>& permissions) {
+ ExtensionProcessBindings::SetAPIPermissions(extension_id, permissions);
+
+ // This is called when starting a new extension page, so start the idle
+ // handler ticking.
+ RenderThread::current()->ScheduleIdleHandler(
+ kInitialExtensionIdleHandlerDelayS);
+
+ UpdateActiveExtensions();
+}
+
+void ExtensionDispatcher::OnSetHostPermissions(
+ const GURL& extension_url, const std::vector<URLPattern>& permissions) {
+ ExtensionProcessBindings::SetHostPermissions(extension_url, permissions);
+}
+
+void ExtensionDispatcher::OnUpdateUserScripts(
+ base::SharedMemoryHandle scripts) {
+ DCHECK(base::SharedMemory::IsHandleValid(scripts)) << "Bad scripts handle";
+ user_script_slave_->UpdateScripts(scripts);
+ UpdateActiveExtensions();
+}
+
+void ExtensionDispatcher::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);
+}
+
+void ExtensionDispatcher::RegisterExtension(v8::Extension* extension,
+ bool restrict_to_extensions) {
+ if (restrict_to_extensions)
+ restricted_v8_extensions_.insert(extension->name());
+
+ RenderThread::current()->RegisterExtension(extension);
+}
diff --git a/chrome/renderer/extensions/extension_dispatcher.h b/chrome/renderer/extensions/extension_dispatcher.h
new file mode 100644
index 0000000..8f9cd53
--- /dev/null
+++ b/chrome/renderer/extensions/extension_dispatcher.h
@@ -0,0 +1,100 @@
+// Copyright (c) 2011 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_RENDERER_EXTENSIONS_EXTENSION_DISPATCHER_H_
+#define CHROME_RENDERER_EXTENSIONS_EXTENSION_DISPATCHER_H_
+#pragma once
+
+#include <set>
+#include <string>
+#include <vector>
+
+#include "base/shared_memory.h"
+#include "base/timer.h"
+#include "content/renderer/render_process_observer.h"
+#include "chrome/common/extensions/extension_set.h"
+
+class GURL;
+class ListValue;
+class RenderThread;
+class URLPattern;
+class UserScriptSlave;
+struct ExtensionMsg_Loaded_Params;
+
+namespace v8 {
+class Extension;
+}
+
+// Dispatches extension control messages sent to the renderer and stores
+// renderer extension related state. Object will delete itself when the
+// renderer shuts down.
+class ExtensionDispatcher : public RenderProcessObserver {
+ public:
+ // Returns the ExtensionDispatcher for this process.
+ static ExtensionDispatcher* Get();
+
+ ExtensionDispatcher();
+ virtual ~ExtensionDispatcher();
+
+ bool is_extension_process() const { return is_extension_process_; }
+ const ExtensionSet* extensions() const { return &extensions_; }
+ UserScriptSlave* user_script_slave() { return user_script_slave_.get(); }
+
+ private:
+ friend class RenderViewTest;
+
+ // RenderProcessObserver implementation:
+ virtual bool OnControlMessageReceived(const IPC::Message& message);
+ virtual void OnRenderProcessShutdown();
+ virtual void WebKitInitialized();
+ virtual bool AllowScriptExtension(const std::string& v8_extension_name,
+ const GURL& url,
+ int extension_group);
+ virtual void IdleNotification();
+
+ void OnMessageInvoke(const std::string& extension_id,
+ const std::string& function_name,
+ const ListValue& args,
+ const GURL& event_url);
+ void OnSetFunctionNames(const std::vector<std::string>& names);
+ void OnLoaded(const ExtensionMsg_Loaded_Params& params);
+ void OnUnloaded(const std::string& id);
+ void OnSetScriptingWhitelist(
+ const Extension::ScriptingWhitelist& extension_ids);
+ void OnPageActionsUpdated(const std::string& extension_id,
+ const std::vector<std::string>& page_actions);
+ void OnSetAPIPermissions(const std::string& extension_id,
+ const std::set<std::string>& permissions);
+ void OnSetHostPermissions(const GURL& extension_url,
+ const std::vector<URLPattern>& permissions);
+ void OnUpdateUserScripts(base::SharedMemoryHandle table);
+
+ // Update the list of active extensions that will be reported when we crash.
+ void UpdateActiveExtensions();
+
+ // Calls RenderThread's RegisterExtension and keeps tracks of which v8
+ // extension is for Chrome Extensions only.
+ void RegisterExtension(v8::Extension* extension, bool restrict_to_extensions);
+
+ // True if this renderer is running extensions.
+ bool is_extension_process_;
+
+ // Contains all loaded extensions. This is essentially the renderer
+ // counterpart to ExtensionService in the browser. It contains information
+ // about all extensions currently loaded by the browser.
+ ExtensionSet extensions_;
+
+ scoped_ptr<UserScriptSlave> user_script_slave_;
+
+ // Same as above, but on a longer timer and will run even if the process is
+ // not idle, to ensure that IdleHandle gets called eventually.
+ base::RepeatingTimer<RenderThread> forced_idle_timer_;
+
+ // The v8 extensions which are restricted to extension-related contexts.
+ std::set<std::string> restricted_v8_extensions_;
+
+ DISALLOW_COPY_AND_ASSIGN(ExtensionDispatcher);
+};
+
+#endif // CHROME_RENDERER_EXTENSIONS_EXTENSION_DISPATCHER_H_
diff --git a/chrome/renderer/extensions/extension_process_bindings.cc b/chrome/renderer/extensions/extension_process_bindings.cc
index 2e4adea..bedc77d 100644
--- a/chrome/renderer/extensions/extension_process_bindings.cc
+++ b/chrome/renderer/extensions/extension_process_bindings.cc
@@ -24,6 +24,7 @@
#include "chrome/common/url_constants.h"
#include "chrome/renderer/extensions/bindings_utils.h"
#include "chrome/renderer/extensions/event_bindings.h"
+#include "chrome/renderer/extensions/extension_dispatcher.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"
@@ -202,8 +203,7 @@ class ExtensionImpl : public ExtensionBase {
return std::string(); // this can happen as a tab is closing.
GURL url = renderview->webview()->mainFrame()->url();
- const ExtensionSet* extensions =
- EventBindings::GetRenderThread()->GetExtensions();
+ const ExtensionSet* extensions = ExtensionDispatcher::Get()->extensions();
if (!extensions->ExtensionBindingsAllowed(url))
return std::string();
@@ -518,7 +518,7 @@ class ExtensionImpl : public ExtensionBase {
static v8::Handle<v8::Value> IsExtensionProcess(const v8::Arguments& args) {
bool retval = false;
if (EventBindings::GetRenderThread())
- retval = EventBindings::GetRenderThread()->IsExtensionProcess();
+ retval = ExtensionDispatcher::Get()->is_extension_process();
return v8::Boolean::New(retval);
}
diff --git a/chrome/renderer/mock_render_thread.cc b/chrome/renderer/mock_render_thread.cc
index 0ae683d..c832177 100644
--- a/chrome/renderer/mock_render_thread.cc
+++ b/chrome/renderer/mock_render_thread.cc
@@ -23,17 +23,12 @@ MockRenderThread::MockRenderThread()
widget_(NULL),
reply_deserializer_(NULL),
printer_(new MockPrinter),
- is_extension_process_(false),
print_dialog_user_response_(true) {
}
MockRenderThread::~MockRenderThread() {
}
-const ExtensionSet* MockRenderThread::GetExtensions() const {
- return &extensions_;
-}
-
// Called by the Widget. The routing_id must match the routing id assigned
// to the Widget in reply to ViewHostMsg_CreateWidget message.
void MockRenderThread::AddRoute(int32 routing_id,
@@ -58,9 +53,6 @@ void MockRenderThread::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) {
filter->OnFilterRemoved();
}
-bool MockRenderThread::IsExtensionProcess() const {
- return is_extension_process_;
-}
bool MockRenderThread::IsIncognitoProcess() const {
return false;
diff --git a/chrome/renderer/mock_render_thread.h b/chrome/renderer/mock_render_thread.h
index b30d31e..1d04b97 100644
--- a/chrome/renderer/mock_render_thread.h
+++ b/chrome/renderer/mock_render_thread.h
@@ -31,8 +31,6 @@ class MockRenderThread : public RenderThreadBase {
MockRenderThread();
virtual ~MockRenderThread();
- virtual const ExtensionSet* GetExtensions() const;
-
// Provides access to the messages that have been received by this thread.
IPC::TestSink& sink() { return sink_; }
@@ -56,9 +54,7 @@ class MockRenderThread : public RenderThreadBase {
virtual void WidgetHidden() { }
virtual void WidgetRestored() { }
- virtual bool IsExtensionProcess() const;
virtual bool IsIncognitoProcess() const;
- void SetExtensionProcess(bool value) { is_extension_process_ = value; }
//////////////////////////////////////////////////////////////////////////
// The following functions are called by the test itself.
@@ -144,12 +140,6 @@ class MockRenderThread : public RenderThreadBase {
// A mock printer device used for printing tests.
scoped_ptr<MockPrinter> printer_;
- // Contains extensions currently loaded by browser. This is usually empty
- // for MockRenderThread.
- ExtensionSet extensions_;
-
- bool is_extension_process_;
-
// True to simulate user clicking print. False to cancel.
bool print_dialog_user_response_;
};
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index 24e61ed..e2c18c5 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -24,22 +24,14 @@
#include "base/values.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_localization_peer.h"
-#include "chrome/common/extensions/extension_messages.h"
-#include "chrome/common/extensions/extension_set.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/spellcheck_messages.h"
#include "chrome/common/safebrowsing_messages.h"
#include "chrome/common/url_constants.h"
#include "chrome/renderer/automation/dom_automation_v8_extension.h"
#include "chrome/renderer/devtools_agent_filter.h"
-#include "chrome/renderer/extension_groups.h"
-#include "chrome/renderer/extensions/chrome_app_bindings.h"
-#include "chrome/renderer/extensions/event_bindings.h"
-#include "chrome/renderer/extensions/extension_process_bindings.h"
-#include "chrome/renderer/extensions/js_only_v8_extensions.h"
-#include "chrome/renderer/extensions/renderer_extension_bindings.h"
+#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "chrome/renderer/external_extension.h"
#include "chrome/renderer/loadtimes_extension_bindings.h"
#include "chrome/renderer/net/renderer_net_predictor.h"
@@ -50,7 +42,6 @@
#include "chrome/renderer/searchbox_extension.h"
#include "chrome/renderer/security_filter_peer.h"
#include "chrome/renderer/spellchecker/spellcheck.h"
-#include "chrome/renderer/user_script_slave.h"
#include "content/common/appcache/appcache_dispatcher.h"
#include "content/common/database_messages.h"
#include "content/common/db_message_filter.h"
@@ -63,6 +54,7 @@
#include "content/common/view_messages.h"
#include "content/common/web_database_observer_impl.h"
#include "content/plugin/npobject_util.h"
+#include "content/renderer/content_renderer_client.h"
#include "content/renderer/cookie_message_filter.h"
#include "content/renderer/gpu_channel_host.h"
#include "content/renderer/gpu_video_service_host.h"
@@ -133,8 +125,6 @@ using WebKit::WebView;
namespace {
static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */;
static const double kInitialIdleHandlerDelayS = 1.0 /* seconds */;
-static const double kInitialExtensionIdleHandlerDelayS = 5.0 /* seconds */;
-static const int64 kMaxExtensionIdleHandlerDelayS = 5*60 /* seconds */;
// Keep the global RenderThread in a TLS slot so it is impossible to access
// incorrectly from the wrong thread.
@@ -289,11 +279,7 @@ void RenderThread::Init() {
CoInitialize(0);
#endif
- std::string type_str = CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
- switches::kProcessType);
// In single process the single process is all there is.
- is_extension_process_ = type_str == switches::kExtensionProcess ||
- CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess);
is_incognito_process_ = false;
suspend_webkit_shared_timer_ = true;
notify_webkit_of_modal_loop_ = true;
@@ -301,14 +287,12 @@ void RenderThread::Init() {
cache_stats_task_pending_ = false;
widget_count_ = 0;
hidden_widget_count_ = 0;
- idle_notification_delay_in_s_ = is_extension_process_ ?
- kInitialExtensionIdleHandlerDelayS : kInitialIdleHandlerDelayS;
+ idle_notification_delay_in_s_ = kInitialIdleHandlerDelayS;
task_factory_.reset(new ScopedRunnableMethodFactory<RenderThread>(this));
resource_dispatcher()->set_observer(new RenderResourceObserver());
visited_link_slave_.reset(new VisitedLinkSlave());
- user_script_slave_.reset(new UserScriptSlave(&extensions_));
renderer_net_predictor_.reset(new RendererNetPredictor());
histogram_snapshots_.reset(new RendererHistogramSnapshots());
appcache_dispatcher_.reset(new AppCacheDispatcher(this));
@@ -329,6 +313,8 @@ void RenderThread::Init() {
AddFilter(suicide_on_channel_error_filter_.get());
#endif
+ AddObserver(new ExtensionDispatcher());
+
TRACE_EVENT_END("RenderThread::Init", 0, "");
}
@@ -383,10 +369,6 @@ int32 RenderThread::RoutingIDForCurrentContext() {
return routing_id;
}
-const ExtensionSet* RenderThread::GetExtensions() const {
- return &extensions_;
-}
-
bool RenderThread::Send(IPC::Message* msg) {
// Certain synchronous messages cannot always be processed synchronously by
// the browser, e.g., Chrome frame communicating with the embedding browser.
@@ -508,20 +490,25 @@ void RenderThread::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) {
void RenderThread::WidgetHidden() {
DCHECK(hidden_widget_count_ < widget_count_);
hidden_widget_count_++;
- if (!is_extension_process_ &&
- widget_count_ && hidden_widget_count_ == widget_count_)
+
+ if (!content::GetContentClient()->renderer()->
+ RunIdleHandlerWhenWidgetsHidden()) {
+ return;
+ }
+
+ if (widget_count_ && hidden_widget_count_ == widget_count_)
ScheduleIdleHandler(kInitialIdleHandlerDelayS);
}
void RenderThread::WidgetRestored() {
DCHECK_GT(hidden_widget_count_, 0);
hidden_widget_count_--;
- if (!is_extension_process_)
- idle_timer_.Stop();
-}
+ if (!content::GetContentClient()->renderer()->
+ RunIdleHandlerWhenWidgetsHidden()) {
+ return;
+ }
-bool RenderThread::IsExtensionProcess() const {
- return is_extension_process_;
+ idle_timer_.Stop();
}
bool RenderThread::IsIncognitoProcess() const {
@@ -580,62 +567,6 @@ void RenderThread::OnSetZoomLevelForCurrentURL(const GURL& url,
RenderView::ForEach(&zoomer);
}
-void RenderThread::OnUpdateUserScripts(base::SharedMemoryHandle scripts) {
- DCHECK(base::SharedMemory::IsHandleValid(scripts)) << "Bad scripts handle";
- user_script_slave_->UpdateScripts(scripts);
- UpdateActiveExtensions();
-}
-
-void RenderThread::OnSetExtensionFunctionNames(
- const std::vector<std::string>& names) {
- ExtensionProcessBindings::SetFunctionNames(names);
-}
-
-void RenderThread::OnExtensionLoaded(const ExtensionMsg_Loaded_Params& params) {
- scoped_refptr<const Extension> extension(params.ConvertToExtension());
- if (!extension) {
- // This can happen if extension parsing fails for any reason. One reason
- // this can legitimately happen is if the
- // --enable-experimental-extension-apis changes at runtime, which happens
- // during browser tests. Existing renderers won't know about the change.
- return;
- }
-
- extensions_.Insert(extension);
-}
-
-void RenderThread::OnSetExtensionScriptingWhitelist(
- const Extension::ScriptingWhitelist& extension_ids) {
- Extension::SetScriptingWhitelist(extension_ids);
-}
-
-void RenderThread::OnExtensionUnloaded(const std::string& id) {
- extensions_.Remove(id);
-}
-
-void RenderThread::OnPageActionsUpdated(
- const std::string& extension_id,
- const std::vector<std::string>& page_actions) {
- ExtensionProcessBindings::SetPageActions(extension_id, page_actions);
-}
-
-void RenderThread::OnExtensionSetAPIPermissions(
- const std::string& extension_id,
- const std::set<std::string>& permissions) {
- ExtensionProcessBindings::SetAPIPermissions(extension_id, permissions);
-
- // This is called when starting a new extension page, so start the idle
- // handler ticking.
- ScheduleIdleHandler(kInitialExtensionIdleHandlerDelayS);
-
- UpdateActiveExtensions();
-}
-
-void RenderThread::OnExtensionSetHostPermissions(
- const GURL& extension_url, const std::vector<URLPattern>& permissions) {
- ExtensionProcessBindings::SetHostPermissions(extension_url, permissions);
-}
-
void RenderThread::OnDOMStorageEvent(
const DOMStorageMsg_Event_Params& params) {
if (!dom_storage_event_dispatcher_.get())
@@ -682,23 +613,8 @@ bool RenderThread::OnControlMessageReceived(const IPC::Message& msg) {
#endif
IPC_MESSAGE_HANDLER(ViewMsg_GetV8HeapStats, OnGetV8HeapStats)
IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats, OnGetCacheResourceStats)
- IPC_MESSAGE_HANDLER(ViewMsg_UserScripts_UpdatedScripts, OnUpdateUserScripts)
- // TODO(rafaelw): create an ExtensionDispatcher that handles extension
- // messages seperates their handling from the RenderThread.
- IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke, OnExtensionMessageInvoke)
- IPC_MESSAGE_HANDLER(ExtensionMsg_SetFunctionNames,
- OnSetExtensionFunctionNames)
- IPC_MESSAGE_HANDLER(ExtensionMsg_Loaded, OnExtensionLoaded)
- IPC_MESSAGE_HANDLER(ExtensionMsg_Unloaded, OnExtensionUnloaded)
- IPC_MESSAGE_HANDLER(ExtensionMsg_SetScriptingWhitelist,
- OnSetExtensionScriptingWhitelist)
IPC_MESSAGE_HANDLER(ViewMsg_PurgeMemory, OnPurgeMemory)
IPC_MESSAGE_HANDLER(ViewMsg_PurgePluginListCache, OnPurgePluginListCache)
- IPC_MESSAGE_HANDLER(ExtensionMsg_UpdatePageActions, OnPageActionsUpdated)
- IPC_MESSAGE_HANDLER(ExtensionMsg_SetAPIPermissions,
- OnExtensionSetAPIPermissions)
- IPC_MESSAGE_HANDLER(ExtensionMsg_SetHostPermissions,
- OnExtensionSetHostPermissions)
IPC_MESSAGE_HANDLER(DOMStorageMsg_Event, OnDOMStorageEvent)
IPC_MESSAGE_HANDLER(SpellCheckMsg_Init, OnInitSpellChecker)
IPC_MESSAGE_HANDLER(SpellCheckMsg_WordAdded, OnSpellCheckWordAdded)
@@ -842,17 +758,6 @@ void RenderThread::EnableSpdy(bool enable) {
Send(new ViewHostMsg_EnableSpdy(enable));
}
-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);
-}
-
void RenderThread::EstablishGpuChannel() {
if (gpu_channel_.get()) {
// Do nothing if we already have a GPU channel or are already
@@ -911,14 +816,6 @@ void RenderThread::EnsureWebKitInitialized() {
if (webkit_client_.get())
return;
- // For extensions, we want to ensure we call the IdleHandler every so often,
- // even if the extension keeps up activity.
- if (is_extension_process_) {
- forced_idle_timer_.Start(
- base::TimeDelta::FromSeconds(kMaxExtensionIdleHandlerDelayS),
- this, &RenderThread::IdleHandler);
- }
-
v8::V8::SetCounterFunction(base::StatsTable::FindLocation);
v8::V8::SetCreateHistogramFunction(CreateHistogram);
v8::V8::SetAddHistogramSampleFunction(AddHistogramSample);
@@ -943,34 +840,25 @@ void RenderThread::EnsureWebKitInitialized() {
WebString extension_scheme(ASCIIToUTF16(chrome::kExtensionScheme));
WebSecurityPolicy::registerURLSchemeAsSecure(extension_scheme);
- RegisterExtension(extensions_v8::LoadTimesExtension::Get(), false);
- RegisterExtension(extensions_v8::ChromeAppExtension::Get(), false);
- RegisterExtension(extensions_v8::ExternalExtension::Get(), false);
- RegisterExtension(extensions_v8::SearchBoxExtension::Get(), false);
+ RegisterExtension(extensions_v8::LoadTimesExtension::Get());
+ RegisterExtension(extensions_v8::ExternalExtension::Get());
+ RegisterExtension(extensions_v8::SearchBoxExtension::Get());
v8::Extension* search_extension = extensions_v8::SearchExtension::Get();
// search_extension is null if not enabled.
if (search_extension)
- RegisterExtension(search_extension, false);
+ RegisterExtension(search_extension);
if (command_line.HasSwitch(switches::kEnableBenchmarking))
- RegisterExtension(extensions_v8::BenchmarkingExtension::Get(), false);
+ RegisterExtension(extensions_v8::BenchmarkingExtension::Get());
if (command_line.HasSwitch(switches::kPlaybackMode) ||
command_line.HasSwitch(switches::kRecordMode) ||
command_line.HasSwitch(switches::kNoJsRandomness)) {
- RegisterExtension(extensions_v8::PlaybackExtension::Get(), false);
+ RegisterExtension(extensions_v8::PlaybackExtension::Get());
}
if (command_line.HasSwitch(switches::kDomAutomationController))
- RegisterExtension(DomAutomationV8Extension::Get(), false);
-
- // Add v8 extensions related to chrome extensions.
- RegisterExtension(ExtensionProcessBindings::Get(), true);
- RegisterExtension(BaseJsV8Extension::Get(), true);
- RegisterExtension(JsonSchemaJsV8Extension::Get(), true);
- RegisterExtension(EventBindings::Get(), true);
- RegisterExtension(RendererExtensionBindings::Get(), true);
- RegisterExtension(ExtensionApiTestV8Extension::Get(), true);
+ RegisterExtension(DomAutomationV8Extension::Get());
web_database_observer_impl_.reset(new WebDatabaseObserverImpl(this));
WebKit::WebDatabase::setObserver(web_database_observer_impl_.get());
@@ -1030,6 +918,8 @@ void RenderThread::EnsureWebKitInitialized() {
WebRuntimeFeatures::enableJavaScriptI18NAPI(
!command_line.HasSwitch(switches::kDisableJavaScriptI18NAPI));
+
+ FOR_EACH_OBSERVER(RenderProcessObserver, observers_, WebKitInitialized());
}
void RenderThread::IdleHandler() {
@@ -1048,17 +938,8 @@ 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_) {
- // Dampen the forced delay as well if the extension stays idle for long
- // periods of time.
- int64 forced_delay_s =
- std::max(static_cast<int64>(idle_notification_delay_in_s_),
- kMaxExtensionIdleHandlerDelayS);
- forced_idle_timer_.Stop();
- forced_idle_timer_.Start(
- base::TimeDelta::FromSeconds(forced_delay_s),
- this, &RenderThread::IdleHandler);
- }
+
+ FOR_EACH_OBSERVER(RenderProcessObserver, observers_, IdleNotification());
}
void RenderThread::ScheduleIdleHandler(double initial_delay_s) {
@@ -1069,19 +950,6 @@ void RenderThread::ScheduleIdleHandler(double initial_delay_s) {
this, &RenderThread::IdleHandler);
}
-void RenderThread::OnExtensionMessageInvoke(const std::string& extension_id,
- const std::string& function_name,
- const ListValue& args,
- const GURL& event_url) {
- RendererExtensionBindings::Invoke(
- extension_id, function_name, args, NULL, event_url);
-
- // 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_)
- ScheduleIdleHandler(kInitialExtensionIdleHandlerDelayS);
-}
-
void RenderThread::OnPurgeMemory() {
spellchecker_.reset(new SpellCheck());
@@ -1185,23 +1053,17 @@ bool RenderThread::AllowScriptExtension(const std::string& v8_extension_name,
if (v8_extensions_.find(v8_extension_name) == v8_extensions_.end())
return true;
- // If the V8 extension is not restricted, allow it to run anywhere.
- bool restrict_to_extensions = v8_extensions_[v8_extension_name];
- if (!restrict_to_extensions)
- return true;
-
- // Extension-only bindings should be restricted to content scripts and
- // extension-blessed URLs.
- if (extension_group == EXTENSION_GROUP_CONTENT_SCRIPTS ||
- extensions_.ExtensionBindingsAllowed(url)) {
- return true;
+ ObserverListBase<RenderProcessObserver>::Iterator it(observers_);
+ RenderProcessObserver* observer;
+ while ((observer = it.GetNext()) != NULL) {
+ if (observer->AllowScriptExtension(v8_extension_name, url, extension_group))
+ return true;
}
return false;
}
-void RenderThread::RegisterExtension(v8::Extension* extension,
- bool restrict_to_extensions) {
+void RenderThread::RegisterExtension(v8::Extension* extension) {
WebScriptController::registerExtension(extension);
- v8_extensions_[extension->name()] = restrict_to_extensions;
+ v8_extensions_.insert(extension->name());
}
diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h
index 4b0ae29..670115f 100644
--- a/chrome/renderer/render_thread.h
+++ b/chrome/renderer/render_thread.h
@@ -6,7 +6,7 @@
#define CHROME_RENDERER_RENDER_THREAD_H_
#pragma once
-#include <map>
+#include <set>
#include <string>
#include <vector>
@@ -15,7 +15,6 @@
#include "base/time.h"
#include "base/timer.h"
#include "build/build_config.h"
-#include "chrome/common/extensions/extension_set.h"
#include "chrome/renderer/chrome_content_renderer_client.h"
#include "chrome/renderer/visitedlink_slave.h"
#include "content/common/child_thread.h"
@@ -28,11 +27,9 @@ class AppCacheDispatcher;
class CookieMessageFilter;
class DBMessageFilter;
class DevToolsAgentFilter;
-class ExtensionSet;
class FilePath;
class GpuChannelHost;
class IndexedDBDispatcher;
-class ListValue;
class RendererHistogram;
class RendererHistogramSnapshots;
class RenderProcessObserver;
@@ -40,15 +37,12 @@ class RendererNetPredictor;
class RendererWebKitClientImpl;
class SpellCheck;
class SkBitmap;
-class UserScriptSlave;
-class URLPattern;
class WebDatabaseObserverImpl;
struct ContentSettings;
struct RendererPreferences;
struct DOMStorageMsg_Event_Params;
struct GPUInfo;
-struct ExtensionMsg_Loaded_Params;
struct ViewMsg_New_Params;
struct WebPreferences;
@@ -103,11 +97,6 @@ class RenderThreadBase {
public:
virtual ~RenderThreadBase() {}
- // Gets currently loaded extensions. This is essentially the renderer
- // counterpart to ExtensionService in the browser. It contains information
- // about all extensions currently loaded by the browser.
- virtual const ExtensionSet* GetExtensions() const = 0;
-
virtual bool Send(IPC::Message* msg) = 0;
// Called to add or remove a listener for a particular message routing ID.
@@ -122,9 +111,6 @@ class RenderThreadBase {
virtual void WidgetHidden() = 0;
virtual void WidgetRestored() = 0;
- // True if this process should be treated as an extension process.
- virtual bool IsExtensionProcess() const = 0;
-
// True if this process is running in an incognito profile.
virtual bool IsIncognitoProcess() const = 0;
};
@@ -160,7 +146,6 @@ class RenderThread : public RenderThreadBase,
static int32 RoutingIDForCurrentContext();
// Overridden from RenderThreadBase.
- virtual const ExtensionSet* GetExtensions() const;
virtual bool Send(IPC::Message* msg);
virtual void AddRoute(int32 routing_id, IPC::Channel::Listener* listener);
virtual void RemoveRoute(int32 routing_id);
@@ -168,7 +153,6 @@ class RenderThread : public RenderThreadBase,
virtual void RemoveFilter(IPC::ChannelProxy::MessageFilter* filter);
virtual void WidgetHidden();
virtual void WidgetRestored();
- virtual bool IsExtensionProcess() const;
virtual bool IsIncognitoProcess() const;
void AddObserver(RenderProcessObserver* observer);
@@ -186,10 +170,6 @@ class RenderThread : public RenderThreadBase,
return visited_link_slave_.get();
}
- UserScriptSlave* user_script_slave() const {
- return user_script_slave_.get();
- }
-
AppCacheDispatcher* appcache_dispatcher() const {
return appcache_dispatcher_.get();
}
@@ -204,6 +184,13 @@ class RenderThread : public RenderThreadBase,
bool plugin_refresh_allowed() const { return plugin_refresh_allowed_; }
+ double idle_notification_delay_in_s() const {
+ return idle_notification_delay_in_s_;
+ }
+ void set_idle_notification_delay_in_s(double idle_notification_delay_in_s) {
+ idle_notification_delay_in_s = idle_notification_delay_in_s;
+ }
+
// Do DNS prefetch resolution of a hostname.
void Resolve(const char* name, size_t length);
@@ -234,9 +221,6 @@ class RenderThread : public RenderThreadBase,
// Sends a message to the browser to enable/disable spdy.
void EnableSpdy(bool enable);
- // Update the list of active extensions that will be reported when we crash.
- void UpdateActiveExtensions();
-
// Asynchronously establish a channel to the GPU plugin if not previously
// established or if it has been lost (for example if the GPU plugin crashed).
// Use GetGpuChannel() to determine when the channel is ready for use.
@@ -270,6 +254,15 @@ class RenderThread : public RenderThreadBase,
return webkit_client_.get();
}
+ // Schedule a call to IdleHandler with the given initial delay.
+ void ScheduleIdleHandler(double initial_delay_s);
+
+ // A task we invoke periodically to assist with idle cleanup.
+ void IdleHandler();
+
+ // Registers the given V8 extension with WebKit.
+ void RegisterExtension(v8::Extension* extension);
+
private:
virtual bool OnControlMessageReceived(const IPC::Message& msg);
@@ -281,21 +274,7 @@ class RenderThread : public RenderThreadBase,
void OnSetZoomLevelForCurrentURL(const GURL& url, double zoom_level);
void OnSetContentSettingsForCurrentURL(
const GURL& url, const ContentSettings& content_settings);
- void OnUpdateUserScripts(base::SharedMemoryHandle table);
- void OnSetExtensionFunctionNames(const std::vector<std::string>& names);
- void OnExtensionLoaded(const ExtensionMsg_Loaded_Params& params);
- void OnExtensionUnloaded(const std::string& id);
- void OnSetExtensionScriptingWhitelist(
- const Extension::ScriptingWhitelist& extension_ids);
- void OnPageActionsUpdated(const std::string& extension_id,
- const std::vector<std::string>& page_actions);
void OnDOMStorageEvent(const DOMStorageMsg_Event_Params& params);
- void OnExtensionSetAPIPermissions(
- const std::string& extension_id,
- const std::set<std::string>& permissions);
- void OnExtensionSetHostPermissions(
- const GURL& extension_url,
- const std::vector<URLPattern>& permissions);
void OnSetNextPageID(int32 next_page_id);
void OnSetIsIncognitoProcess(bool is_incognito_process);
void OnSetCSSColors(const std::vector<CSSColors::CSSColorMapping>& colors);
@@ -314,10 +293,6 @@ class RenderThread : public RenderThreadBase,
void OnGetRendererTcmalloc();
void OnGetV8HeapStats();
- void OnExtensionMessageInvoke(const std::string& extension_id,
- const std::string& function_name,
- const ListValue& args,
- const GURL& event_url);
void OnPurgeMemory();
void OnPurgePluginListCache(bool reload_pages);
@@ -344,20 +319,9 @@ class RenderThread : public RenderThreadBase,
// We initialize WebKit as late as possible.
void EnsureWebKitInitialized();
- // A task we invoke periodically to assist with idle cleanup.
- void IdleHandler();
-
- // Schedule a call to IdleHandler with the given initial delay.
- void ScheduleIdleHandler(double initial_delay_s);
-
- // Registers the given V8 extension with WebKit, and also tracks what pages
- // it is allowed to run on.
- void RegisterExtension(v8::Extension* extension, bool restrict_to_extensions);
-
// These objects live solely on the render thread.
scoped_ptr<ScopedRunnableMethodFactory<RenderThread> > task_factory_;
scoped_ptr<VisitedLinkSlave> visited_link_slave_;
- scoped_ptr<UserScriptSlave> user_script_slave_;
scoped_ptr<RendererNetPredictor> renderer_net_predictor_;
scoped_ptr<AppCacheDispatcher> appcache_dispatcher_;
scoped_ptr<IndexedDBDispatcher> indexed_db_dispatcher_;
@@ -392,9 +356,6 @@ class RenderThread : public RenderThreadBase,
// The current value of the idle notification timer delay.
double idle_notification_delay_in_s_;
- // True if this renderer is running extensions.
- bool is_extension_process_;
-
// True if this renderer is incognito.
bool is_incognito_process_;
@@ -404,23 +365,14 @@ class RenderThread : public RenderThreadBase,
// Timer that periodically calls IdleHandler.
base::RepeatingTimer<RenderThread> idle_timer_;
- // Same as above, but on a longer timer and will run even if the process is
- // not idle, to ensure that IdleHandle gets called eventually.
- base::RepeatingTimer<RenderThread> forced_idle_timer_;
-
// The channel from the renderer process to the GPU process.
scoped_refptr<GpuChannelHost> gpu_channel_;
// A lazily initiated thread on which file operations are run.
scoped_ptr<base::Thread> file_thread_;
- // Map of registered v8 extensions. The key is the extension name. The value
- // is true if the extension should be restricted to extension-related
- // contexts.
- std::map<std::string, bool> v8_extensions_;
-
- // Contains all loaded extensions.
- ExtensionSet extensions_;
+ // Map of registered v8 extensions. The key is the extension name.
+ std::set<std::string> v8_extensions_;
chrome::ChromeContentRendererClient renderer_client_;
diff --git a/chrome/test/render_view_test.cc b/chrome/test/render_view_test.cc
index 1e15017..27798b0 100644
--- a/chrome/test/render_view_test.cc
+++ b/chrome/test/render_view_test.cc
@@ -12,6 +12,7 @@
#include "chrome/renderer/autofill/autofill_agent.h"
#include "chrome/renderer/autofill/password_autofill_manager.h"
#include "chrome/renderer/extensions/event_bindings.h"
+#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "chrome/renderer/extensions/extension_process_bindings.h"
#include "chrome/renderer/extensions/js_only_v8_extensions.h"
#include "chrome/renderer/extensions/renderer_extension_bindings.h"
@@ -50,7 +51,7 @@ const int32 kRouteId = 5;
const int32 kOpenerId = 7;
} // namespace
-RenderViewTest::RenderViewTest() {
+RenderViewTest::RenderViewTest() : extension_dispatcher_(NULL) {
}
RenderViewTest::~RenderViewTest() {
@@ -100,6 +101,7 @@ void RenderViewTest::SetUp() {
gfx::GfxModule::SetResourceProvider(chrome::GfxResourceProvider);
content::GetContentClient()->set_renderer(&content_renderer_client_);
+ extension_dispatcher_ = new ExtensionDispatcher();
sandbox_init_wrapper_.reset(new SandboxInitWrapper());
command_line_.reset(new CommandLine(CommandLine::NO_PROGRAM));
params_.reset(new MainFunctionParams(*command_line_, *sandbox_init_wrapper_,
@@ -184,6 +186,9 @@ void RenderViewTest::TearDown() {
params_.reset();
command_line_.reset();
sandbox_init_wrapper_.reset();
+
+ extension_dispatcher_->OnRenderProcessShutdown();
+ extension_dispatcher_ = NULL;
}
int RenderViewTest::SendKeyEvent(MockKeyboard::Layout layout,
diff --git a/chrome/test/render_view_test.h b/chrome/test/render_view_test.h
index 8eb6132..b70f042 100644
--- a/chrome/test/render_view_test.h
+++ b/chrome/test/render_view_test.h
@@ -26,6 +26,8 @@ namespace autofill {
class AutofillAgent;
class PasswordAutofillManager;
}
+
+class ExtensionDispatcher;
class MockRenderProcess;
class RenderViewTest : public testing::Test {
@@ -94,6 +96,7 @@ class RenderViewTest : public testing::Test {
MessageLoop msg_loop_;
content::ContentRendererClient content_renderer_client_;
+ ExtensionDispatcher* extension_dispatcher_;
MockRenderThread render_thread_;
scoped_ptr<MockRenderProcess> mock_process_;
scoped_refptr<RenderView> view_;
diff --git a/content/renderer/content_renderer_client.cc b/content/renderer/content_renderer_client.cc
index 96a53f6..c876f85 100644
--- a/content/renderer/content_renderer_client.cc
+++ b/content/renderer/content_renderer_client.cc
@@ -33,4 +33,12 @@ std::string ContentRendererClient::DetermineTextLanguage(const string16& text) {
return std::string();
}
+bool ContentRendererClient::RunIdleHandlerWhenWidgetsHidden() {
+ return true;
+}
+
+bool ContentRendererClient::AllowPopup(const GURL& creator) {
+ return false;
+}
+
} // namespace content
diff --git a/content/renderer/content_renderer_client.h b/content/renderer/content_renderer_client.h
index 4f41a78..268518e 100644
--- a/content/renderer/content_renderer_client.h
+++ b/content/renderer/content_renderer_client.h
@@ -11,6 +11,7 @@
#include "base/string16.h"
#include "content/common/content_client.h"
+class GURL;
class RenderView;
class SkBitmap;
@@ -28,20 +29,31 @@ namespace content {
class ContentRendererClient {
public:
virtual SkBitmap* GetSadPluginBitmap();
+
virtual std::string GetDefaultEncoding();
+
// Create a plugin in the given frame. Can return NULL, in which case
// RenderView will create a plugin itself.
virtual WebKit::WebPlugin* CreatePlugin(
RenderView* render_view,
WebKit::WebFrame* frame,
const WebKit::WebPluginParams& params);
+
// Returns the html to display when a navigation error occurs.
virtual std::string GetNavigationErrorHtml(
const WebKit::WebURLRequest& failed_request,
const WebKit::WebURLError& error);
+
// Returns the ISO 639_1 language code of the specified |text|, or 'unknown'
// if it failed.
virtual std::string DetermineTextLanguage(const string16& text);
+
+ // Returns true if the renderer process should schedule the idle handler when
+ // all widgets are hidden.
+ virtual bool RunIdleHandlerWhenWidgetsHidden();
+
+ // Returns true if the given url can create popup windows.
+ virtual bool AllowPopup(const GURL& creator);
};
} // namespace content
diff --git a/content/renderer/render_process_observer.cc b/content/renderer/render_process_observer.cc
index 3479d97..5796271 100644
--- a/content/renderer/render_process_observer.cc
+++ b/content/renderer/render_process_observer.cc
@@ -4,6 +4,9 @@
#include "content/renderer/render_process_observer.h"
+RenderProcessObserver::RenderProcessObserver() {
+}
+
RenderProcessObserver::~RenderProcessObserver() {
}
@@ -14,3 +17,16 @@ bool RenderProcessObserver::OnControlMessageReceived(
void RenderProcessObserver::OnRenderProcessShutdown() {
}
+
+void RenderProcessObserver::WebKitInitialized() {
+}
+
+bool RenderProcessObserver::AllowScriptExtension(
+ const std::string& v8_extension_name,
+ const GURL& url,
+ int extension_group) {
+ return false;
+}
+
+void RenderProcessObserver::IdleNotification() {
+}
diff --git a/content/renderer/render_process_observer.h b/content/renderer/render_process_observer.h
index 9127246..5c7a7a9 100644
--- a/content/renderer/render_process_observer.h
+++ b/content/renderer/render_process_observer.h
@@ -9,9 +9,13 @@
#include "base/basictypes.h"
#include "ipc/ipc_message.h"
-// Base class for objects that want to filter control IPC messages.
+class GURL;
+
+// Base class for objects that want to filter control IPC messages and get
+// notified of events.
class RenderProcessObserver {
public:
+ RenderProcessObserver();
virtual ~RenderProcessObserver();
// Allows filtering of control messages.
@@ -20,6 +24,16 @@ class RenderProcessObserver {
// Notification that the render process is shutting down.
virtual void OnRenderProcessShutdown();
+ // Called right after the WebKit API is initialized.
+ virtual void WebKitInitialized();
+
+ // See WebViewClient::allowScriptExtension
+ virtual bool AllowScriptExtension(const std::string& v8_extension_name,
+ const GURL& url,
+ int extension_group);
+
+ virtual void IdleNotification();
+
private:
DISALLOW_COPY_AND_ASSIGN(RenderProcessObserver);
};
diff --git a/content/renderer/render_view.cc b/content/renderer/render_view.cc
index 04fd392..28f7b9d 100644
--- a/content/renderer/render_view.cc
+++ b/content/renderer/render_view.cc
@@ -48,8 +48,8 @@
#include "chrome/renderer/devtools_agent.h"
#include "chrome/renderer/devtools_client.h"
#include "chrome/renderer/extension_groups.h"
-#include "chrome/renderer/extensions/bindings_utils.h"
#include "chrome/renderer/extensions/event_bindings.h"
+#include "chrome/renderer/extensions/extension_dispatcher.h"
#include "chrome/renderer/extensions/extension_helper.h"
#include "chrome/renderer/extensions/extension_process_bindings.h"
#include "chrome/renderer/extensions/extension_resource_request_policy.h"
@@ -2573,12 +2573,8 @@ void RenderView::show(WebNavigationPolicy policy) {
return;
did_show_ = true;
- // Extensions and apps always allowed to create unrequested popups. The second
- // check is necessary to include content scripts.
- if (render_thread_->GetExtensions()->GetByURL(creator_url_) ||
- bindings_utils::GetInfoForCurrentContext()) {
+ if (content::GetContentClient()->renderer()->AllowPopup(creator_url_))
opened_by_user_gesture_ = true;
- }
// Force new windows to a popup if they were not opened with a user gesture.
if (!opened_by_user_gesture_) {
@@ -2830,9 +2826,7 @@ WebNavigationPolicy RenderView::decidePolicyForNavigation(
// window.opener) if the window navigates back. See crbug.com/65953.
if (!should_fork &&
CrossesExtensionExtents(
- render_thread_->GetExtensions(),
- frame,
- url)) {
+ ExtensionDispatcher::Get()->extensions(), frame, url)) {
// Include the referrer in this case since we're going from a hosted web
// page. (the packaged case is handled previously by the extension
// navigation test)
@@ -2841,7 +2835,7 @@ WebNavigationPolicy RenderView::decidePolicyForNavigation(
if (is_content_initiated) {
const Extension* extension =
- render_thread_->GetExtensions()->GetByURL(url);
+ ExtensionDispatcher::Get()->extensions()->GetByURL(url);
if (extension && extension->is_app()) {
UMA_HISTOGRAM_ENUMERATION(
extension_misc::kAppLaunchHistogram,
@@ -3307,7 +3301,7 @@ void RenderView::didClearWindowObject(WebFrame* frame) {
void RenderView::didCreateDocumentElement(WebFrame* frame) {
if (RenderThread::current()) { // Will be NULL during unit tests.
- RenderThread::current()->user_script_slave()->InjectScripts(
+ ExtensionDispatcher::Get()->user_script_slave()->InjectScripts(
frame, UserScript::DOCUMENT_START);
}
@@ -3350,7 +3344,7 @@ void RenderView::didFinishDocumentLoad(WebFrame* frame) {
UpdateEncoding(frame, frame->view()->pageEncoding().utf8());
if (RenderThread::current()) { // Will be NULL during unit tests.
- RenderThread::current()->user_script_slave()->InjectScripts(
+ ExtensionDispatcher::Get()->user_script_slave()->InjectScripts(
frame, UserScript::DOCUMENT_END);
}
@@ -3362,7 +3356,7 @@ void RenderView::didFinishDocumentLoad(WebFrame* frame) {
void RenderView::OnUserScriptIdleTriggered(WebFrame* frame) {
if (RenderThread::current()) { // Will be NULL during unit tests.
- RenderThread::current()->user_script_slave()->InjectScripts(
+ ExtensionDispatcher::Get()->user_script_slave()->InjectScripts(
frame, UserScript::DOCUMENT_IDLE);
}
@@ -3448,7 +3442,7 @@ void RenderView::willSendRequest(
!ExtensionResourceRequestPolicy::CanRequestResource(
request_url,
GURL(frame->url()),
- render_thread_->GetExtensions())) {
+ ExtensionDispatcher::Get()->extensions())) {
request.setURL(WebURL(GURL("chrome-extension://invalid/")));
}
@@ -4993,7 +4987,8 @@ void RenderView::ExecuteCodeImpl(
WebFrame* frame = *frame_it;
if (params.is_javascript) {
const Extension* extension =
- render_thread_->GetExtensions()->GetByID(params.extension_id);
+ ExtensionDispatcher::Get()->extensions()->GetByID(
+ params.extension_id);
// Since extension info is sent separately from user script info, they can
// be out of sync. We just ignore this situation.