blob: ea0cf9451b2e8b84af7b7704b8fcde99e7d9391e [file] [log] [blame]
license.botbf09a502008-08-24 00:55:551// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
initial.commit09911bf2008-07-26 23:55:295#include "chrome/renderer/render_thread.h"
6
[email protected]da00a2882009-03-09 17:51:197#include <algorithm>
8#include <vector>
9
[email protected]06533c0b2009-03-05 21:39:1110#include "base/command_line.h"
initial.commit09911bf2008-07-26 23:55:2911#include "base/shared_memory.h"
[email protected]da00a2882009-03-09 17:51:1912#include "base/stats_table.h"
[email protected]1edc16b82009-04-07 17:45:5413#include "chrome/common/app_cache/app_cache_context_impl.h"
14#include "chrome/common/app_cache/app_cache_dispatcher.h"
[email protected]06533c0b2009-03-05 21:39:1115#include "chrome/common/chrome_switches.h"
[email protected]e09ba552009-02-05 03:26:2916#include "chrome/common/render_messages.h"
[email protected]173de1b2008-08-15 18:36:4617#include "chrome/common/notification_service.h"
[email protected]90a3fbb12009-02-28 01:13:4718#include "chrome/common/url_constants.h"
[email protected]8930d472009-02-21 08:05:2819#include "chrome/plugin/npobject_util.h"
[email protected]2c62b562009-01-27 19:04:5020// TODO(port)
21#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:2922#include "chrome/plugin/plugin_channel.h"
[email protected]2c62b562009-01-27 19:04:5023#else
[email protected]2c62b562009-01-27 19:04:5024#include "base/scoped_handle.h"
25#include "chrome/plugin/plugin_channel_base.h"
26#include "webkit/glue/weburlrequest.h"
27#endif
[email protected]a40caa972009-04-08 18:35:3428#include "chrome/renderer/extensions/event_bindings.h"
[email protected]309d7a282009-03-24 09:18:2729#include "chrome/renderer/extensions/extension_process_bindings.h"
[email protected]0aa477bd2009-03-23 22:21:4330#include "chrome/renderer/extensions/renderer_extension_bindings.h"
[email protected]0bc46552009-04-07 21:56:4231#include "chrome/renderer/loadtimes_extension_bindings.h"
initial.commit09911bf2008-07-26 23:55:2932#include "chrome/renderer/net/render_dns_master.h"
33#include "chrome/renderer/render_process.h"
34#include "chrome/renderer/render_view.h"
[email protected]8d86fce2009-02-26 23:37:5535#include "chrome/renderer/renderer_webkitclient_impl.h"
[email protected]0938d3c2009-01-09 20:37:3536#include "chrome/renderer/user_script_slave.h"
initial.commit09911bf2008-07-26 23:55:2937#include "chrome/renderer/visitedlink_slave.h"
[email protected]2c434b32009-03-19 06:27:4738#include "third_party/WebKit/WebKit/chromium/public/WebCache.h"
39#include "third_party/WebKit/WebKit/chromium/public/WebKit.h"
40#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
[email protected]06533c0b2009-03-05 21:39:1141#include "webkit/extensions/v8/gears_extension.h"
42#include "webkit/extensions/v8/interval_extension.h"
43#include "webkit/extensions/v8/playback_extension.h"
[email protected]2c62b562009-01-27 19:04:5044
[email protected]da00a2882009-03-09 17:51:1945#if defined(OS_WIN)
46#include <windows.h>
47#include <objbase.h>
48#endif
49
[email protected]2c434b32009-03-19 06:27:4750using WebKit::WebCache;
51using WebKit::WebString;
initial.commit09911bf2008-07-26 23:55:2952
[email protected]2c434b32009-03-19 06:27:4753static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */;
initial.commit09911bf2008-07-26 23:55:2954
initial.commit09911bf2008-07-26 23:55:2955//-----------------------------------------------------------------------------
56// Methods below are only called on the owner's thread:
57
[email protected]8930d472009-02-21 08:05:2858// When we run plugins in process, we actually run them on the render thread,
59// which means that we need to make the render thread pump UI events.
60RenderThread::RenderThread()
61 : ChildThread(
62 base::Thread::Options(RenderProcess::InProcessPlugins() ?
[email protected]eb47a132009-03-04 00:39:5663 MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT, kV8StackSize)) {
[email protected]8930d472009-02-21 08:05:2864}
65
66RenderThread::RenderThread(const std::wstring& channel_name)
67 : ChildThread(
68 base::Thread::Options(RenderProcess::InProcessPlugins() ?
[email protected]eb47a132009-03-04 00:39:5669 MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT, kV8StackSize)) {
[email protected]8930d472009-02-21 08:05:2870 SetChannelName(channel_name);
initial.commit09911bf2008-07-26 23:55:2971}
72
73RenderThread::~RenderThread() {
initial.commit09911bf2008-07-26 23:55:2974}
75
[email protected]8930d472009-02-21 08:05:2876RenderThread* RenderThread::current() {
77 DCHECK(!IsPluginProcess());
78 return static_cast<RenderThread*>(ChildThread::current());
initial.commit09911bf2008-07-26 23:55:2979}
80
81void RenderThread::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
[email protected]8930d472009-02-21 08:05:2882 channel()->AddFilter(filter);
initial.commit09911bf2008-07-26 23:55:2983}
84
85void RenderThread::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) {
[email protected]8930d472009-02-21 08:05:2886 channel()->RemoveFilter(filter);
initial.commit09911bf2008-07-26 23:55:2987}
88
89void RenderThread::Resolve(const char* name, size_t length) {
[email protected]8d86fce2009-02-26 23:37:5590 return dns_master_->Resolve(name, length);
[email protected]81a34412009-01-05 19:17:2491}
initial.commit09911bf2008-07-26 23:55:2992
[email protected]55e57d42009-02-25 06:10:1793void RenderThread::SendHistograms() {
[email protected]8d86fce2009-02-26 23:37:5594 return histogram_snapshots_->SendHistograms();
[email protected]55e57d42009-02-25 06:10:1795}
96
[email protected]1edc16b82009-04-07 17:45:5497static WebAppCacheContext* CreateAppCacheContextForRenderer() {
98 return new AppCacheContextImpl(RenderThread::current());
99}
100
initial.commit09911bf2008-07-26 23:55:29101void RenderThread::Init() {
[email protected]1edc16b82009-04-07 17:45:54102 // TODO(darin): Why do we need COM here? This is probably bogus. Perhaps
103 // this is for InProcessPlugin support?
[email protected]2c62b562009-01-27 19:04:50104#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29105 // The renderer thread should wind-up COM.
106 CoInitialize(0);
[email protected]2c62b562009-01-27 19:04:50107#endif
initial.commit09911bf2008-07-26 23:55:29108
[email protected]8d86fce2009-02-26 23:37:55109 ChildThread::Init();
110 notification_service_.reset(new NotificationService);
111 cache_stats_factory_.reset(
112 new ScopedRunnableMethodFactory<RenderThread>(this));
113
[email protected]8d86fce2009-02-26 23:37:55114 visited_link_slave_.reset(new VisitedLinkSlave());
115 user_script_slave_.reset(new UserScriptSlave());
116 dns_master_.reset(new RenderDnsMaster());
117 histogram_snapshots_.reset(new RendererHistogramSnapshots());
[email protected]1edc16b82009-04-07 17:45:54118 app_cache_dispatcher_.reset(new AppCacheDispatcher());
119 WebAppCacheContext::SetFactory(CreateAppCacheContextForRenderer);
initial.commit09911bf2008-07-26 23:55:29120}
121
122void RenderThread::CleanUp() {
[email protected]8d86fce2009-02-26 23:37:55123 // Shutdown in reverse of the initialization order.
124
[email protected]1edc16b82009-04-07 17:45:54125 WebAppCacheContext::SetFactory(NULL);
126 app_cache_dispatcher_.reset();
[email protected]8d86fce2009-02-26 23:37:55127 histogram_snapshots_.reset();
128 dns_master_.reset();
129 user_script_slave_.reset();
130 visited_link_slave_.reset();
131
[email protected]90a3fbb12009-02-28 01:13:47132 if (webkit_client_.get()) {
133 WebKit::shutdown();
134 webkit_client_.reset();
135 }
[email protected]8d86fce2009-02-26 23:37:55136
137 notification_service_.reset();
138
[email protected]8930d472009-02-21 08:05:28139 ChildThread::CleanUp();
[email protected]8fd8de92008-08-12 23:50:30140
[email protected]8d86fce2009-02-26 23:37:55141 // TODO(port)
[email protected]2c62b562009-01-27 19:04:50142#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29143 // Clean up plugin channels before this thread goes away.
144 PluginChannelBase::CleanupChannels();
[email protected]2c62b562009-01-27 19:04:50145#endif
initial.commit09911bf2008-07-26 23:55:29146
[email protected]2c62b562009-01-27 19:04:50147#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29148 CoUninitialize();
[email protected]2c62b562009-01-27 19:04:50149#endif
initial.commit09911bf2008-07-26 23:55:29150}
151
[email protected]176aa482008-11-14 03:25:15152void RenderThread::OnUpdateVisitedLinks(base::SharedMemoryHandle table) {
[email protected]5fe733de2009-02-11 18:59:20153 DCHECK(base::SharedMemory::IsHandleValid(table)) << "Bad table handle";
initial.commit09911bf2008-07-26 23:55:29154 visited_link_slave_->Init(table);
155}
156
[email protected]0938d3c2009-01-09 20:37:35157void RenderThread::OnUpdateUserScripts(
[email protected]176aa482008-11-14 03:25:15158 base::SharedMemoryHandle scripts) {
[email protected]5fe733de2009-02-11 18:59:20159 DCHECK(base::SharedMemory::IsHandleValid(scripts)) << "Bad scripts handle";
[email protected]0938d3c2009-01-09 20:37:35160 user_script_slave_->UpdateScripts(scripts);
[email protected]1e0f70402008-10-16 23:57:47161}
162
[email protected]703e807a2009-03-28 19:56:51163void RenderThread::OnSetExtensionFunctionNames(
164 const std::vector<std::string>& names) {
165 extensions_v8::ExtensionProcessBindings::SetFunctionNames(names);
166}
167
[email protected]8930d472009-02-21 08:05:28168void RenderThread::OnControlMessageReceived(const IPC::Message& msg) {
[email protected]1edc16b82009-04-07 17:45:54169 // App cache messages are handled by a delegate.
170 if (app_cache_dispatcher_->OnMessageReceived(msg))
171 return;
172
[email protected]8930d472009-02-21 08:05:28173 IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)
174 IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)
175 IPC_MESSAGE_HANDLER(ViewMsg_SetNextPageID, OnSetNextPageID)
176 // TODO(port): removed from render_messages_internal.h;
177 // is there a new non-windows message I should add here?
178 IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)
179 IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)
[email protected]55e57d42009-02-25 06:10:17180 IPC_MESSAGE_HANDLER(ViewMsg_GetRendererHistograms,
181 OnGetRendererHistograms)
[email protected]8930d472009-02-21 08:05:28182 IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,
183 OnGetCacheResourceStats)
[email protected]8930d472009-02-21 08:05:28184 IPC_MESSAGE_HANDLER(ViewMsg_UserScripts_NewScripts,
185 OnUpdateUserScripts)
[email protected]75e5a872009-04-02 23:56:11186 IPC_MESSAGE_HANDLER(ViewMsg_ExtensionHandleConnect,
187 OnExtensionHandleConnect)
188 IPC_MESSAGE_HANDLER(ViewMsg_ExtensionHandleMessage,
189 OnExtensionHandleMessage)
[email protected]703e807a2009-03-28 19:56:51190 IPC_MESSAGE_HANDLER(ViewMsg_Extension_SetFunctionNames,
191 OnSetExtensionFunctionNames)
[email protected]8930d472009-02-21 08:05:28192 IPC_END_MESSAGE_MAP()
initial.commit09911bf2008-07-26 23:55:29193}
194
195void RenderThread::OnSetNextPageID(int32 next_page_id) {
196 // This should only be called at process initialization time, so we shouldn't
197 // have to worry about thread-safety.
198 RenderView::SetNextPageID(next_page_id);
199}
200
[email protected]18bcc3c2009-01-27 21:39:15201void RenderThread::OnCreateNewView(gfx::NativeViewId parent_hwnd,
202 ModalDialogEvent modal_dialog_event,
initial.commit09911bf2008-07-26 23:55:29203 const WebPreferences& webkit_prefs,
204 int32 view_id) {
[email protected]90a3fbb12009-02-28 01:13:47205 EnsureWebKitInitialized();
206
[email protected]be645db2009-02-06 20:36:33207 // When bringing in render_view, also bring in webkit's glue and jsbindings.
[email protected]18bcc3c2009-01-27 21:39:15208 base::WaitableEvent* waitable_event = new base::WaitableEvent(
209#if defined(OS_WIN)
210 modal_dialog_event.event);
211#else
212 true, false);
213#endif
214
initial.commit09911bf2008-07-26 23:55:29215 // TODO(darin): once we have a RenderThread per RenderView, this will need to
216 // change to assert that we are not creating more than one view.
initial.commit09911bf2008-07-26 23:55:29217 RenderView::Create(
[email protected]1c4947f2009-01-15 22:25:11218 this, parent_hwnd, waitable_event, MSG_ROUTING_NONE, webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08219 new SharedRenderViewCounter(0), view_id);
[email protected]7f874dec2009-02-06 01:48:27220}
[email protected]4274e582009-01-27 22:09:56221
initial.commit09911bf2008-07-26 23:55:29222void RenderThread::OnSetCacheCapacities(size_t min_dead_capacity,
223 size_t max_dead_capacity,
224 size_t capacity) {
[email protected]90a3fbb12009-02-28 01:13:47225 EnsureWebKitInitialized();
[email protected]2c434b32009-03-19 06:27:47226 WebCache::setCapacities(
227 min_dead_capacity, max_dead_capacity, capacity);
initial.commit09911bf2008-07-26 23:55:29228}
229
230void RenderThread::OnGetCacheResourceStats() {
[email protected]90a3fbb12009-02-28 01:13:47231 EnsureWebKitInitialized();
[email protected]2c434b32009-03-19 06:27:47232 WebCache::ResourceTypeStats stats;
233 WebCache::getResourceTypeStats(&stats);
initial.commit09911bf2008-07-26 23:55:29234 Send(new ViewHostMsg_ResourceTypeStats(stats));
235}
236
[email protected]55e57d42009-02-25 06:10:17237void RenderThread::OnGetRendererHistograms() {
238 SendHistograms();
239}
240
initial.commit09911bf2008-07-26 23:55:29241void RenderThread::InformHostOfCacheStats() {
[email protected]90a3fbb12009-02-28 01:13:47242 EnsureWebKitInitialized();
[email protected]2c434b32009-03-19 06:27:47243 WebCache::UsageStats stats;
244 WebCache::getUsageStats(&stats);
initial.commit09911bf2008-07-26 23:55:29245 Send(new ViewHostMsg_UpdatedCacheStats(stats));
246}
247
248void RenderThread::InformHostOfCacheStatsLater() {
249 // Rate limit informing the host of our cache stats.
250 if (!cache_stats_factory_->empty())
251 return;
252
253 MessageLoop::current()->PostDelayedTask(FROM_HERE,
254 cache_stats_factory_->NewRunnableMethod(
255 &RenderThread::InformHostOfCacheStats),
256 kCacheStatsDelayMS);
257}
[email protected]90a3fbb12009-02-28 01:13:47258
[email protected]3df0c202009-03-31 23:51:26259static void* CreateHistogram(
260 const char *name, int min, int max, size_t buckets) {
261 return new Histogram(name, min, max, buckets);
262}
263
264static void AddHistogramSample(void* hist, int sample) {
265 Histogram* histogram = static_cast<Histogram *>(hist);
266 histogram->Add(sample);
267}
268
[email protected]90a3fbb12009-02-28 01:13:47269void RenderThread::EnsureWebKitInitialized() {
270 if (webkit_client_.get())
271 return;
[email protected]da00a2882009-03-09 17:51:19272
273 v8::V8::SetCounterFunction(StatsTable::FindLocation);
[email protected]3df0c202009-03-31 23:51:26274 v8::V8::SetCreateHistogramFunction(CreateHistogram);
275 v8::V8::SetAddHistogramSampleFunction(AddHistogramSample);
[email protected]da00a2882009-03-09 17:51:19276
[email protected]90a3fbb12009-02-28 01:13:47277 webkit_client_.reset(new RendererWebKitClientImpl);
278 WebKit::initialize(webkit_client_.get());
[email protected]8881eca82009-03-12 18:20:44279
280 // chrome-ui pages should not be accessible by normal content, and should
281 // also be unable to script anything but themselves (to help limit the damage
282 // that a corrupt chrome-ui page could cause).
[email protected]2c434b32009-03-19 06:27:47283 WebString chrome_ui_scheme(ASCIIToUTF16(chrome::kChromeUIScheme));
[email protected]8881eca82009-03-12 18:20:44284 WebKit::registerURLSchemeAsLocal(chrome_ui_scheme);
285 WebKit::registerURLSchemeAsNoAccess(chrome_ui_scheme);
[email protected]da00a2882009-03-09 17:51:19286
[email protected]06533c0b2009-03-05 21:39:11287 WebKit::registerExtension(extensions_v8::GearsExtension::Get());
288 WebKit::registerExtension(extensions_v8::IntervalExtension::Get());
[email protected]c20210e62009-04-03 21:39:26289 WebKit::registerExtension(extensions_v8::LoadTimesExtension::Get());
[email protected]309d7a282009-03-24 09:18:27290
[email protected]06533c0b2009-03-05 21:39:11291 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]a40caa972009-04-08 18:35:34292 if (command_line.HasSwitch(switches::kEnableExtensions)) {
293 WebKit::registerExtension(EventBindings::Get());
294 WebKit::registerExtension(
295 extensions_v8::RendererExtensionBindings::Get(this));
296 WebKit::registerExtension(extensions_v8::ExtensionProcessBindings::Get(),
297 WebKit::WebString::fromUTF8(chrome::kExtensionScheme));
298 }
299
[email protected]06533c0b2009-03-05 21:39:11300 if (command_line.HasSwitch(switches::kPlaybackMode) ||
301 command_line.HasSwitch(switches::kRecordMode)) {
302 WebKit::registerExtension(extensions_v8::PlaybackExtension::Get());
303 }
[email protected]2cb82332009-03-18 17:24:55304
305 if (command_line.HasSwitch(switches::kEnableWebWorkers)) {
[email protected]0b9a1cc92009-03-19 00:55:53306 WebKit::enableWebWorkers();
[email protected]2cb82332009-03-18 17:24:55307 }
[email protected]90a3fbb12009-02-28 01:13:47308}
[email protected]75e5a872009-04-02 23:56:11309
310void RenderThread::OnExtensionHandleConnect(int port_id) {
311 extensions_v8::RendererExtensionBindings::HandleConnect(port_id);
312}
313
314void RenderThread::OnExtensionHandleMessage(const std::string& message,
315 int port_id) {
316 extensions_v8::RendererExtensionBindings::HandleMessage(message, port_id);
317}