blob: 165af407838f79393180a0a2061b0edd7b5622ee [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]8930d472009-02-21 08:05:28150void RenderThread::OnControlMessageReceived(const IPC::Message& msg) {
151 IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)
152 IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)
153 IPC_MESSAGE_HANDLER(ViewMsg_SetNextPageID, OnSetNextPageID)
154 // TODO(port): removed from render_messages_internal.h;
155 // is there a new non-windows message I should add here?
156 IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)
157 IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)
[email protected]55e57d42009-02-25 06:10:17158 IPC_MESSAGE_HANDLER(ViewMsg_GetRendererHistograms,
159 OnGetRendererHistograms)
[email protected]8930d472009-02-21 08:05:28160 IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,
161 OnGetCacheResourceStats)
[email protected]8930d472009-02-21 08:05:28162 IPC_MESSAGE_HANDLER(ViewMsg_UserScripts_NewScripts,
163 OnUpdateUserScripts)
164 IPC_END_MESSAGE_MAP()
initial.commit09911bf2008-07-26 23:55:29165}
166
167void RenderThread::OnSetNextPageID(int32 next_page_id) {
168 // This should only be called at process initialization time, so we shouldn't
169 // have to worry about thread-safety.
[email protected]2c62b562009-01-27 19:04:50170 // TODO(port)
[email protected]be645db2009-02-06 20:36:33171#if !defined(OS_LINUX)
initial.commit09911bf2008-07-26 23:55:29172 RenderView::SetNextPageID(next_page_id);
[email protected]2c62b562009-01-27 19:04:50173#endif
initial.commit09911bf2008-07-26 23:55:29174}
175
[email protected]18bcc3c2009-01-27 21:39:15176void RenderThread::OnCreateNewView(gfx::NativeViewId parent_hwnd,
177 ModalDialogEvent modal_dialog_event,
initial.commit09911bf2008-07-26 23:55:29178 const WebPreferences& webkit_prefs,
179 int32 view_id) {
[email protected]90a3fbb12009-02-28 01:13:47180 EnsureWebKitInitialized();
181
[email protected]be645db2009-02-06 20:36:33182 // When bringing in render_view, also bring in webkit's glue and jsbindings.
[email protected]18bcc3c2009-01-27 21:39:15183 base::WaitableEvent* waitable_event = new base::WaitableEvent(
184#if defined(OS_WIN)
185 modal_dialog_event.event);
186#else
187 true, false);
188#endif
189
initial.commit09911bf2008-07-26 23:55:29190 // TODO(darin): once we have a RenderThread per RenderView, this will need to
191 // change to assert that we are not creating more than one view.
initial.commit09911bf2008-07-26 23:55:29192 RenderView::Create(
[email protected]1c4947f2009-01-15 22:25:11193 this, parent_hwnd, waitable_event, MSG_ROUTING_NONE, webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08194 new SharedRenderViewCounter(0), view_id);
[email protected]7f874dec2009-02-06 01:48:27195}
[email protected]4274e582009-01-27 22:09:56196
initial.commit09911bf2008-07-26 23:55:29197void RenderThread::OnSetCacheCapacities(size_t min_dead_capacity,
198 size_t max_dead_capacity,
199 size_t capacity) {
[email protected]90a3fbb12009-02-28 01:13:47200 EnsureWebKitInitialized();
[email protected]2c434b32009-03-19 06:27:47201 WebCache::setCapacities(
202 min_dead_capacity, max_dead_capacity, capacity);
initial.commit09911bf2008-07-26 23:55:29203}
204
205void RenderThread::OnGetCacheResourceStats() {
[email protected]90a3fbb12009-02-28 01:13:47206 EnsureWebKitInitialized();
[email protected]2c434b32009-03-19 06:27:47207 WebCache::ResourceTypeStats stats;
208 WebCache::getResourceTypeStats(&stats);
initial.commit09911bf2008-07-26 23:55:29209 Send(new ViewHostMsg_ResourceTypeStats(stats));
210}
211
[email protected]55e57d42009-02-25 06:10:17212void RenderThread::OnGetRendererHistograms() {
213 SendHistograms();
214}
215
initial.commit09911bf2008-07-26 23:55:29216void RenderThread::InformHostOfCacheStats() {
[email protected]90a3fbb12009-02-28 01:13:47217 EnsureWebKitInitialized();
[email protected]2c434b32009-03-19 06:27:47218 WebCache::UsageStats stats;
219 WebCache::getUsageStats(&stats);
initial.commit09911bf2008-07-26 23:55:29220 Send(new ViewHostMsg_UpdatedCacheStats(stats));
221}
222
223void RenderThread::InformHostOfCacheStatsLater() {
224 // Rate limit informing the host of our cache stats.
225 if (!cache_stats_factory_->empty())
226 return;
227
228 MessageLoop::current()->PostDelayedTask(FROM_HERE,
229 cache_stats_factory_->NewRunnableMethod(
230 &RenderThread::InformHostOfCacheStats),
231 kCacheStatsDelayMS);
232}
[email protected]90a3fbb12009-02-28 01:13:47233
234void RenderThread::EnsureWebKitInitialized() {
235 if (webkit_client_.get())
236 return;
[email protected]da00a2882009-03-09 17:51:19237
238 v8::V8::SetCounterFunction(StatsTable::FindLocation);
239
[email protected]90a3fbb12009-02-28 01:13:47240 webkit_client_.reset(new RendererWebKitClientImpl);
241 WebKit::initialize(webkit_client_.get());
[email protected]8881eca82009-03-12 18:20:44242
243 // chrome-ui pages should not be accessible by normal content, and should
244 // also be unable to script anything but themselves (to help limit the damage
245 // that a corrupt chrome-ui page could cause).
[email protected]2c434b32009-03-19 06:27:47246 WebString chrome_ui_scheme(ASCIIToUTF16(chrome::kChromeUIScheme));
[email protected]8881eca82009-03-12 18:20:44247 WebKit::registerURLSchemeAsLocal(chrome_ui_scheme);
248 WebKit::registerURLSchemeAsNoAccess(chrome_ui_scheme);
[email protected]da00a2882009-03-09 17:51:19249
[email protected]06533c0b2009-03-05 21:39:11250 WebKit::registerExtension(extensions_v8::GearsExtension::Get());
251 WebKit::registerExtension(extensions_v8::IntervalExtension::Get());
[email protected]0aa477bd2009-03-23 22:21:43252 WebKit::registerExtension(extensions_v8::RendererExtensionBindings::Get());
[email protected]06533c0b2009-03-05 21:39:11253
[email protected]309d7a282009-03-24 09:18:27254 WebKit::registerExtension(extensions_v8::ExtensionProcessBindings::Get(),
255 WebKit::WebString::fromUTF8(chrome::kExtensionScheme));
256
[email protected]06533c0b2009-03-05 21:39:11257 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
258 if (command_line.HasSwitch(switches::kPlaybackMode) ||
259 command_line.HasSwitch(switches::kRecordMode)) {
260 WebKit::registerExtension(extensions_v8::PlaybackExtension::Get());
261 }
[email protected]2cb82332009-03-18 17:24:55262
263 if (command_line.HasSwitch(switches::kEnableWebWorkers)) {
[email protected]0b9a1cc92009-03-19 00:55:53264 WebKit::enableWebWorkers();
[email protected]2cb82332009-03-18 17:24:55265 }
[email protected]90a3fbb12009-02-28 01:13:47266}