blob: 6c9fe61434bdee0f9de786eb2381ec1a0fb85dd2 [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]06533c0b2009-03-05 21:39:1113#include "chrome/common/chrome_switches.h"
[email protected]e09ba552009-02-05 03:26:2914#include "chrome/common/render_messages.h"
[email protected]173de1b2008-08-15 18:36:4615#include "chrome/common/notification_service.h"
[email protected]90a3fbb12009-02-28 01:13:4716#include "chrome/common/url_constants.h"
[email protected]8930d472009-02-21 08:05:2817#include "chrome/plugin/npobject_util.h"
[email protected]2c62b562009-01-27 19:04:5018// TODO(port)
19#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:2920#include "chrome/plugin/plugin_channel.h"
[email protected]2c62b562009-01-27 19:04:5021#else
[email protected]2c62b562009-01-27 19:04:5022#include "base/scoped_handle.h"
23#include "chrome/plugin/plugin_channel_base.h"
24#include "webkit/glue/weburlrequest.h"
25#endif
[email protected]309d7a282009-03-24 09:18:2726#include "chrome/renderer/extensions/extension_process_bindings.h"
[email protected]0aa477bd2009-03-23 22:21:4327#include "chrome/renderer/extensions/renderer_extension_bindings.h"
initial.commit09911bf2008-07-26 23:55:2928#include "chrome/renderer/net/render_dns_master.h"
29#include "chrome/renderer/render_process.h"
30#include "chrome/renderer/render_view.h"
[email protected]8d86fce2009-02-26 23:37:5531#include "chrome/renderer/renderer_webkitclient_impl.h"
[email protected]0938d3c2009-01-09 20:37:3532#include "chrome/renderer/user_script_slave.h"
initial.commit09911bf2008-07-26 23:55:2933#include "chrome/renderer/visitedlink_slave.h"
[email protected]2c434b32009-03-19 06:27:4734#include "third_party/WebKit/WebKit/chromium/public/WebCache.h"
35#include "third_party/WebKit/WebKit/chromium/public/WebKit.h"
36#include "third_party/WebKit/WebKit/chromium/public/WebString.h"
[email protected]06533c0b2009-03-05 21:39:1137#include "webkit/extensions/v8/gears_extension.h"
38#include "webkit/extensions/v8/interval_extension.h"
39#include "webkit/extensions/v8/playback_extension.h"
[email protected]2c62b562009-01-27 19:04:5040
[email protected]da00a2882009-03-09 17:51:1941#if defined(OS_WIN)
42#include <windows.h>
43#include <objbase.h>
44#endif
45
[email protected]2c434b32009-03-19 06:27:4746using WebKit::WebCache;
47using WebKit::WebString;
initial.commit09911bf2008-07-26 23:55:2948
[email protected]2c434b32009-03-19 06:27:4749static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */;
initial.commit09911bf2008-07-26 23:55:2950
initial.commit09911bf2008-07-26 23:55:2951//-----------------------------------------------------------------------------
52// Methods below are only called on the owner's thread:
53
[email protected]8930d472009-02-21 08:05:2854// When we run plugins in process, we actually run them on the render thread,
55// which means that we need to make the render thread pump UI events.
56RenderThread::RenderThread()
57 : ChildThread(
58 base::Thread::Options(RenderProcess::InProcessPlugins() ?
[email protected]eb47a132009-03-04 00:39:5659 MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT, kV8StackSize)) {
[email protected]8930d472009-02-21 08:05:2860}
61
62RenderThread::RenderThread(const std::wstring& channel_name)
63 : ChildThread(
64 base::Thread::Options(RenderProcess::InProcessPlugins() ?
[email protected]eb47a132009-03-04 00:39:5665 MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT, kV8StackSize)) {
[email protected]8930d472009-02-21 08:05:2866 SetChannelName(channel_name);
initial.commit09911bf2008-07-26 23:55:2967}
68
69RenderThread::~RenderThread() {
initial.commit09911bf2008-07-26 23:55:2970}
71
[email protected]8930d472009-02-21 08:05:2872RenderThread* RenderThread::current() {
73 DCHECK(!IsPluginProcess());
74 return static_cast<RenderThread*>(ChildThread::current());
initial.commit09911bf2008-07-26 23:55:2975}
76
77void RenderThread::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
[email protected]8930d472009-02-21 08:05:2878 channel()->AddFilter(filter);
initial.commit09911bf2008-07-26 23:55:2979}
80
81void RenderThread::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) {
[email protected]8930d472009-02-21 08:05:2882 channel()->RemoveFilter(filter);
initial.commit09911bf2008-07-26 23:55:2983}
84
85void RenderThread::Resolve(const char* name, size_t length) {
[email protected]8d86fce2009-02-26 23:37:5586 return dns_master_->Resolve(name, length);
[email protected]81a34412009-01-05 19:17:2487}
initial.commit09911bf2008-07-26 23:55:2988
[email protected]55e57d42009-02-25 06:10:1789void RenderThread::SendHistograms() {
[email protected]8d86fce2009-02-26 23:37:5590 return histogram_snapshots_->SendHistograms();
[email protected]55e57d42009-02-25 06:10:1791}
92
initial.commit09911bf2008-07-26 23:55:2993void RenderThread::Init() {
[email protected]8d86fce2009-02-26 23:37:5594 // TODO(darin): Why do we need COM here? This is probably bogus.
[email protected]2c62b562009-01-27 19:04:5095#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:2996 // The renderer thread should wind-up COM.
97 CoInitialize(0);
[email protected]2c62b562009-01-27 19:04:5098#endif
initial.commit09911bf2008-07-26 23:55:2999
[email protected]8d86fce2009-02-26 23:37:55100 ChildThread::Init();
101 notification_service_.reset(new NotificationService);
102 cache_stats_factory_.reset(
103 new ScopedRunnableMethodFactory<RenderThread>(this));
104
[email protected]8d86fce2009-02-26 23:37:55105 visited_link_slave_.reset(new VisitedLinkSlave());
106 user_script_slave_.reset(new UserScriptSlave());
107 dns_master_.reset(new RenderDnsMaster());
108 histogram_snapshots_.reset(new RendererHistogramSnapshots());
initial.commit09911bf2008-07-26 23:55:29109}
110
111void RenderThread::CleanUp() {
[email protected]8d86fce2009-02-26 23:37:55112 // Shutdown in reverse of the initialization order.
113
114 histogram_snapshots_.reset();
115 dns_master_.reset();
116 user_script_slave_.reset();
117 visited_link_slave_.reset();
118
[email protected]90a3fbb12009-02-28 01:13:47119 if (webkit_client_.get()) {
120 WebKit::shutdown();
121 webkit_client_.reset();
122 }
[email protected]8d86fce2009-02-26 23:37:55123
124 notification_service_.reset();
125
[email protected]8930d472009-02-21 08:05:28126 ChildThread::CleanUp();
[email protected]8fd8de92008-08-12 23:50:30127
[email protected]8d86fce2009-02-26 23:37:55128 // TODO(port)
[email protected]2c62b562009-01-27 19:04:50129#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29130 // Clean up plugin channels before this thread goes away.
131 PluginChannelBase::CleanupChannels();
[email protected]2c62b562009-01-27 19:04:50132#endif
initial.commit09911bf2008-07-26 23:55:29133
[email protected]2c62b562009-01-27 19:04:50134#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29135 CoUninitialize();
[email protected]2c62b562009-01-27 19:04:50136#endif
initial.commit09911bf2008-07-26 23:55:29137}
138
[email protected]176aa482008-11-14 03:25:15139void RenderThread::OnUpdateVisitedLinks(base::SharedMemoryHandle table) {
[email protected]5fe733de2009-02-11 18:59:20140 DCHECK(base::SharedMemory::IsHandleValid(table)) << "Bad table handle";
initial.commit09911bf2008-07-26 23:55:29141 visited_link_slave_->Init(table);
142}
143
[email protected]0938d3c2009-01-09 20:37:35144void RenderThread::OnUpdateUserScripts(
[email protected]176aa482008-11-14 03:25:15145 base::SharedMemoryHandle scripts) {
[email protected]5fe733de2009-02-11 18:59:20146 DCHECK(base::SharedMemory::IsHandleValid(scripts)) << "Bad scripts handle";
[email protected]0938d3c2009-01-09 20:37:35147 user_script_slave_->UpdateScripts(scripts);
[email protected]1e0f70402008-10-16 23:57:47148}
149
[email protected]703e807a2009-03-28 19:56:51150void RenderThread::OnSetExtensionFunctionNames(
151 const std::vector<std::string>& names) {
152 extensions_v8::ExtensionProcessBindings::SetFunctionNames(names);
153}
154
[email protected]8930d472009-02-21 08:05:28155void RenderThread::OnControlMessageReceived(const IPC::Message& msg) {
156 IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)
157 IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)
158 IPC_MESSAGE_HANDLER(ViewMsg_SetNextPageID, OnSetNextPageID)
159 // TODO(port): removed from render_messages_internal.h;
160 // is there a new non-windows message I should add here?
161 IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)
162 IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)
[email protected]55e57d42009-02-25 06:10:17163 IPC_MESSAGE_HANDLER(ViewMsg_GetRendererHistograms,
164 OnGetRendererHistograms)
[email protected]8930d472009-02-21 08:05:28165 IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,
166 OnGetCacheResourceStats)
[email protected]8930d472009-02-21 08:05:28167 IPC_MESSAGE_HANDLER(ViewMsg_UserScripts_NewScripts,
168 OnUpdateUserScripts)
[email protected]703e807a2009-03-28 19:56:51169 IPC_MESSAGE_HANDLER(ViewMsg_Extension_SetFunctionNames,
170 OnSetExtensionFunctionNames)
[email protected]8930d472009-02-21 08:05:28171 IPC_END_MESSAGE_MAP()
initial.commit09911bf2008-07-26 23:55:29172}
173
174void RenderThread::OnSetNextPageID(int32 next_page_id) {
175 // This should only be called at process initialization time, so we shouldn't
176 // have to worry about thread-safety.
[email protected]2c62b562009-01-27 19:04:50177 // TODO(port)
[email protected]be645db2009-02-06 20:36:33178#if !defined(OS_LINUX)
initial.commit09911bf2008-07-26 23:55:29179 RenderView::SetNextPageID(next_page_id);
[email protected]2c62b562009-01-27 19:04:50180#endif
initial.commit09911bf2008-07-26 23:55:29181}
182
[email protected]18bcc3c2009-01-27 21:39:15183void RenderThread::OnCreateNewView(gfx::NativeViewId parent_hwnd,
184 ModalDialogEvent modal_dialog_event,
initial.commit09911bf2008-07-26 23:55:29185 const WebPreferences& webkit_prefs,
186 int32 view_id) {
[email protected]90a3fbb12009-02-28 01:13:47187 EnsureWebKitInitialized();
188
[email protected]be645db2009-02-06 20:36:33189 // When bringing in render_view, also bring in webkit's glue and jsbindings.
[email protected]18bcc3c2009-01-27 21:39:15190 base::WaitableEvent* waitable_event = new base::WaitableEvent(
191#if defined(OS_WIN)
192 modal_dialog_event.event);
193#else
194 true, false);
195#endif
196
initial.commit09911bf2008-07-26 23:55:29197 // TODO(darin): once we have a RenderThread per RenderView, this will need to
198 // change to assert that we are not creating more than one view.
initial.commit09911bf2008-07-26 23:55:29199 RenderView::Create(
[email protected]1c4947f2009-01-15 22:25:11200 this, parent_hwnd, waitable_event, MSG_ROUTING_NONE, webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08201 new SharedRenderViewCounter(0), view_id);
[email protected]7f874dec2009-02-06 01:48:27202}
[email protected]4274e582009-01-27 22:09:56203
initial.commit09911bf2008-07-26 23:55:29204void RenderThread::OnSetCacheCapacities(size_t min_dead_capacity,
205 size_t max_dead_capacity,
206 size_t capacity) {
[email protected]90a3fbb12009-02-28 01:13:47207 EnsureWebKitInitialized();
[email protected]2c434b32009-03-19 06:27:47208 WebCache::setCapacities(
209 min_dead_capacity, max_dead_capacity, capacity);
initial.commit09911bf2008-07-26 23:55:29210}
211
212void RenderThread::OnGetCacheResourceStats() {
[email protected]90a3fbb12009-02-28 01:13:47213 EnsureWebKitInitialized();
[email protected]2c434b32009-03-19 06:27:47214 WebCache::ResourceTypeStats stats;
215 WebCache::getResourceTypeStats(&stats);
initial.commit09911bf2008-07-26 23:55:29216 Send(new ViewHostMsg_ResourceTypeStats(stats));
217}
218
[email protected]55e57d42009-02-25 06:10:17219void RenderThread::OnGetRendererHistograms() {
220 SendHistograms();
221}
222
initial.commit09911bf2008-07-26 23:55:29223void RenderThread::InformHostOfCacheStats() {
[email protected]90a3fbb12009-02-28 01:13:47224 EnsureWebKitInitialized();
[email protected]2c434b32009-03-19 06:27:47225 WebCache::UsageStats stats;
226 WebCache::getUsageStats(&stats);
initial.commit09911bf2008-07-26 23:55:29227 Send(new ViewHostMsg_UpdatedCacheStats(stats));
228}
229
230void RenderThread::InformHostOfCacheStatsLater() {
231 // Rate limit informing the host of our cache stats.
232 if (!cache_stats_factory_->empty())
233 return;
234
235 MessageLoop::current()->PostDelayedTask(FROM_HERE,
236 cache_stats_factory_->NewRunnableMethod(
237 &RenderThread::InformHostOfCacheStats),
238 kCacheStatsDelayMS);
239}
[email protected]90a3fbb12009-02-28 01:13:47240
[email protected]3df0c202009-03-31 23:51:26241static void* CreateHistogram(
242 const char *name, int min, int max, size_t buckets) {
243 return new Histogram(name, min, max, buckets);
244}
245
246static void AddHistogramSample(void* hist, int sample) {
247 Histogram* histogram = static_cast<Histogram *>(hist);
248 histogram->Add(sample);
249}
250
[email protected]90a3fbb12009-02-28 01:13:47251void RenderThread::EnsureWebKitInitialized() {
252 if (webkit_client_.get())
253 return;
[email protected]da00a2882009-03-09 17:51:19254
255 v8::V8::SetCounterFunction(StatsTable::FindLocation);
[email protected]3df0c202009-03-31 23:51:26256 v8::V8::SetCreateHistogramFunction(CreateHistogram);
257 v8::V8::SetAddHistogramSampleFunction(AddHistogramSample);
[email protected]da00a2882009-03-09 17:51:19258
[email protected]90a3fbb12009-02-28 01:13:47259 webkit_client_.reset(new RendererWebKitClientImpl);
260 WebKit::initialize(webkit_client_.get());
[email protected]8881eca82009-03-12 18:20:44261
262 // chrome-ui pages should not be accessible by normal content, and should
263 // also be unable to script anything but themselves (to help limit the damage
264 // that a corrupt chrome-ui page could cause).
[email protected]2c434b32009-03-19 06:27:47265 WebString chrome_ui_scheme(ASCIIToUTF16(chrome::kChromeUIScheme));
[email protected]8881eca82009-03-12 18:20:44266 WebKit::registerURLSchemeAsLocal(chrome_ui_scheme);
267 WebKit::registerURLSchemeAsNoAccess(chrome_ui_scheme);
[email protected]da00a2882009-03-09 17:51:19268
[email protected]06533c0b2009-03-05 21:39:11269 WebKit::registerExtension(extensions_v8::GearsExtension::Get());
270 WebKit::registerExtension(extensions_v8::IntervalExtension::Get());
[email protected]0aa477bd2009-03-23 22:21:43271 WebKit::registerExtension(extensions_v8::RendererExtensionBindings::Get());
[email protected]06533c0b2009-03-05 21:39:11272
[email protected]309d7a282009-03-24 09:18:27273 WebKit::registerExtension(extensions_v8::ExtensionProcessBindings::Get(),
274 WebKit::WebString::fromUTF8(chrome::kExtensionScheme));
275
[email protected]06533c0b2009-03-05 21:39:11276 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
277 if (command_line.HasSwitch(switches::kPlaybackMode) ||
278 command_line.HasSwitch(switches::kRecordMode)) {
279 WebKit::registerExtension(extensions_v8::PlaybackExtension::Get());
280 }
[email protected]2cb82332009-03-18 17:24:55281
282 if (command_line.HasSwitch(switches::kEnableWebWorkers)) {
[email protected]0b9a1cc92009-03-19 00:55:53283 WebKit::enableWebWorkers();
[email protected]2cb82332009-03-18 17:24:55284 }
[email protected]90a3fbb12009-02-28 01:13:47285}