blob: af81a02cadd02e65d60d02f2374033a4a4ba6cc9 [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]a8624712009-04-17 00:51:3528#include "chrome/renderer/devtools_agent_filter.h"
[email protected]a40caa972009-04-08 18:35:3429#include "chrome/renderer/extensions/event_bindings.h"
[email protected]309d7a282009-03-24 09:18:2730#include "chrome/renderer/extensions/extension_process_bindings.h"
[email protected]0aa477bd2009-03-23 22:21:4331#include "chrome/renderer/extensions/renderer_extension_bindings.h"
[email protected]3c8e3702009-05-01 16:27:4232#include "chrome/renderer/external_extension.h"
[email protected]a1a0df02009-04-09 08:18:0433#include "chrome/renderer/js_only_v8_extensions.h"
[email protected]0bc46552009-04-07 21:56:4234#include "chrome/renderer/loadtimes_extension_bindings.h"
initial.commit09911bf2008-07-26 23:55:2935#include "chrome/renderer/net/render_dns_master.h"
36#include "chrome/renderer/render_process.h"
37#include "chrome/renderer/render_view.h"
[email protected]8d86fce2009-02-26 23:37:5538#include "chrome/renderer/renderer_webkitclient_impl.h"
[email protected]0938d3c2009-01-09 20:37:3539#include "chrome/renderer/user_script_slave.h"
initial.commit09911bf2008-07-26 23:55:2940#include "chrome/renderer/visitedlink_slave.h"
[email protected]afdcf5c2009-05-10 20:30:4141#include "webkit/api/public/WebCache.h"
42#include "webkit/api/public/WebKit.h"
43#include "webkit/api/public/WebString.h"
[email protected]06533c0b2009-03-05 21:39:1144#include "webkit/extensions/v8/gears_extension.h"
45#include "webkit/extensions/v8/interval_extension.h"
46#include "webkit/extensions/v8/playback_extension.h"
[email protected]2c62b562009-01-27 19:04:5047
[email protected]da00a2882009-03-09 17:51:1948#if defined(OS_WIN)
49#include <windows.h>
50#include <objbase.h>
51#endif
52
[email protected]2c434b32009-03-19 06:27:4753using WebKit::WebCache;
54using WebKit::WebString;
initial.commit09911bf2008-07-26 23:55:2955
[email protected]2c434b32009-03-19 06:27:4756static const unsigned int kCacheStatsDelayMS = 2000 /* milliseconds */;
initial.commit09911bf2008-07-26 23:55:2957
initial.commit09911bf2008-07-26 23:55:2958//-----------------------------------------------------------------------------
59// Methods below are only called on the owner's thread:
60
[email protected]8930d472009-02-21 08:05:2861// When we run plugins in process, we actually run them on the render thread,
62// which means that we need to make the render thread pump UI events.
63RenderThread::RenderThread()
64 : ChildThread(
65 base::Thread::Options(RenderProcess::InProcessPlugins() ?
[email protected]b547fd42009-04-23 23:16:2766 MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT, kV8StackSize)),
67 plugin_refresh_allowed_(true) {
[email protected]8930d472009-02-21 08:05:2868}
69
70RenderThread::RenderThread(const std::wstring& channel_name)
71 : ChildThread(
72 base::Thread::Options(RenderProcess::InProcessPlugins() ?
[email protected]b547fd42009-04-23 23:16:2773 MessageLoop::TYPE_UI : MessageLoop::TYPE_DEFAULT, kV8StackSize)),
74 plugin_refresh_allowed_(true) {
[email protected]8930d472009-02-21 08:05:2875 SetChannelName(channel_name);
initial.commit09911bf2008-07-26 23:55:2976}
77
78RenderThread::~RenderThread() {
initial.commit09911bf2008-07-26 23:55:2979}
80
[email protected]8930d472009-02-21 08:05:2881RenderThread* RenderThread::current() {
82 DCHECK(!IsPluginProcess());
83 return static_cast<RenderThread*>(ChildThread::current());
initial.commit09911bf2008-07-26 23:55:2984}
85
86void RenderThread::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
[email protected]8930d472009-02-21 08:05:2887 channel()->AddFilter(filter);
initial.commit09911bf2008-07-26 23:55:2988}
89
90void RenderThread::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) {
[email protected]8930d472009-02-21 08:05:2891 channel()->RemoveFilter(filter);
initial.commit09911bf2008-07-26 23:55:2992}
93
94void RenderThread::Resolve(const char* name, size_t length) {
[email protected]8d86fce2009-02-26 23:37:5595 return dns_master_->Resolve(name, length);
[email protected]81a34412009-01-05 19:17:2496}
initial.commit09911bf2008-07-26 23:55:2997
[email protected]55e57d42009-02-25 06:10:1798void RenderThread::SendHistograms() {
[email protected]8d86fce2009-02-26 23:37:5599 return histogram_snapshots_->SendHistograms();
[email protected]55e57d42009-02-25 06:10:17100}
101
[email protected]1edc16b82009-04-07 17:45:54102static WebAppCacheContext* CreateAppCacheContextForRenderer() {
103 return new AppCacheContextImpl(RenderThread::current());
104}
105
[email protected]5fa1c542009-05-05 20:36:07106#if defined(OS_POSIX)
107class SuicideOnChannelErrorFilter : public IPC::ChannelProxy::MessageFilter {
108 void OnChannelError() {
109 // On POSIX, at least, one can install an unload handler which loops
110 // forever and leave behind a renderer process which eats 100% CPU forever.
111 //
112 // This is because the terminate signals (ViewMsg_ShouldClose and the error
113 // from the IPC channel) are routed to the main message loop but never
114 // processed (because that message loop is stuck in V8).
115 //
116 // One could make the browser SIGKILL the renderers, but that leaves open a
117 // large window where a browser failure (or a user, manually terminating
118 // the browser because "it's stuck") will leave behind a process eating all
119 // the CPU.
120 //
121 // So, we install a filter on the channel so that we can process this event
122 // here and kill the process.
123 _exit(0);
124 }
125};
126#endif
127
initial.commit09911bf2008-07-26 23:55:29128void RenderThread::Init() {
[email protected]2c62b562009-01-27 19:04:50129#if defined(OS_WIN)
[email protected]bdef78b52009-04-16 19:31:34130 // If you are running plugins in this thread you need COM active but in
131 // the normal case you don't.
132 if (RenderProcess::InProcessPlugins())
133 CoInitialize(0);
[email protected]2c62b562009-01-27 19:04:50134#endif
initial.commit09911bf2008-07-26 23:55:29135
[email protected]8d86fce2009-02-26 23:37:55136 ChildThread::Init();
137 notification_service_.reset(new NotificationService);
138 cache_stats_factory_.reset(
139 new ScopedRunnableMethodFactory<RenderThread>(this));
140
[email protected]8d86fce2009-02-26 23:37:55141 visited_link_slave_.reset(new VisitedLinkSlave());
142 user_script_slave_.reset(new UserScriptSlave());
143 dns_master_.reset(new RenderDnsMaster());
144 histogram_snapshots_.reset(new RendererHistogramSnapshots());
[email protected]1edc16b82009-04-07 17:45:54145 app_cache_dispatcher_.reset(new AppCacheDispatcher());
146 WebAppCacheContext::SetFactory(CreateAppCacheContextForRenderer);
[email protected]a8624712009-04-17 00:51:35147 devtools_agent_filter_ = new DevToolsAgentFilter();
148 AddFilter(devtools_agent_filter_.get());
[email protected]5fa1c542009-05-05 20:36:07149
150#if defined(OS_POSIX)
151 suicide_on_channel_error_filter_ = new SuicideOnChannelErrorFilter;
152 AddFilter(suicide_on_channel_error_filter_.get());
153#endif
initial.commit09911bf2008-07-26 23:55:29154}
155
156void RenderThread::CleanUp() {
[email protected]8d86fce2009-02-26 23:37:55157 // Shutdown in reverse of the initialization order.
[email protected]a8624712009-04-17 00:51:35158 RemoveFilter(devtools_agent_filter_.get());
159 devtools_agent_filter_ = NULL;
[email protected]1edc16b82009-04-07 17:45:54160 WebAppCacheContext::SetFactory(NULL);
161 app_cache_dispatcher_.reset();
[email protected]8d86fce2009-02-26 23:37:55162 histogram_snapshots_.reset();
163 dns_master_.reset();
164 user_script_slave_.reset();
165 visited_link_slave_.reset();
166
[email protected]90a3fbb12009-02-28 01:13:47167 if (webkit_client_.get()) {
168 WebKit::shutdown();
169 webkit_client_.reset();
170 }
[email protected]8d86fce2009-02-26 23:37:55171
172 notification_service_.reset();
173
[email protected]8930d472009-02-21 08:05:28174 ChildThread::CleanUp();
[email protected]8fd8de92008-08-12 23:50:30175
[email protected]8d86fce2009-02-26 23:37:55176 // TODO(port)
[email protected]2c62b562009-01-27 19:04:50177#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29178 // Clean up plugin channels before this thread goes away.
179 PluginChannelBase::CleanupChannels();
[email protected]bdef78b52009-04-16 19:31:34180 // Don't call COM if the renderer is in the sandbox.
181 if (RenderProcess::InProcessPlugins())
182 CoUninitialize();
[email protected]2c62b562009-01-27 19:04:50183#endif
initial.commit09911bf2008-07-26 23:55:29184}
185
[email protected]176aa482008-11-14 03:25:15186void RenderThread::OnUpdateVisitedLinks(base::SharedMemoryHandle table) {
[email protected]5fe733de2009-02-11 18:59:20187 DCHECK(base::SharedMemory::IsHandleValid(table)) << "Bad table handle";
initial.commit09911bf2008-07-26 23:55:29188 visited_link_slave_->Init(table);
189}
190
[email protected]0938d3c2009-01-09 20:37:35191void RenderThread::OnUpdateUserScripts(
[email protected]176aa482008-11-14 03:25:15192 base::SharedMemoryHandle scripts) {
[email protected]5fe733de2009-02-11 18:59:20193 DCHECK(base::SharedMemory::IsHandleValid(scripts)) << "Bad scripts handle";
[email protected]0938d3c2009-01-09 20:37:35194 user_script_slave_->UpdateScripts(scripts);
[email protected]1e0f70402008-10-16 23:57:47195}
196
[email protected]703e807a2009-03-28 19:56:51197void RenderThread::OnSetExtensionFunctionNames(
198 const std::vector<std::string>& names) {
[email protected]a1a0df02009-04-09 08:18:04199 ExtensionProcessBindings::SetFunctionNames(names);
[email protected]703e807a2009-03-28 19:56:51200}
201
[email protected]8930d472009-02-21 08:05:28202void RenderThread::OnControlMessageReceived(const IPC::Message& msg) {
[email protected]1edc16b82009-04-07 17:45:54203 // App cache messages are handled by a delegate.
204 if (app_cache_dispatcher_->OnMessageReceived(msg))
205 return;
206
[email protected]8930d472009-02-21 08:05:28207 IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)
208 IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)
209 IPC_MESSAGE_HANDLER(ViewMsg_SetNextPageID, OnSetNextPageID)
210 // TODO(port): removed from render_messages_internal.h;
211 // is there a new non-windows message I should add here?
212 IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)
213 IPC_MESSAGE_HANDLER(ViewMsg_SetCacheCapacities, OnSetCacheCapacities)
[email protected]55e57d42009-02-25 06:10:17214 IPC_MESSAGE_HANDLER(ViewMsg_GetRendererHistograms,
215 OnGetRendererHistograms)
[email protected]8930d472009-02-21 08:05:28216 IPC_MESSAGE_HANDLER(ViewMsg_GetCacheResourceStats,
217 OnGetCacheResourceStats)
[email protected]2f2243e2009-05-26 02:27:02218 IPC_MESSAGE_HANDLER(ViewMsg_UserScripts_UpdatedScripts,
[email protected]8930d472009-02-21 08:05:28219 OnUpdateUserScripts)
[email protected]b68d5ed2009-04-16 02:41:28220 // TODO(rafaelw): create an ExtensionDispatcher that handles extension
221 // messages seperates their handling from the RenderThread.
[email protected]75e5a872009-04-02 23:56:11222 IPC_MESSAGE_HANDLER(ViewMsg_ExtensionHandleConnect,
223 OnExtensionHandleConnect)
224 IPC_MESSAGE_HANDLER(ViewMsg_ExtensionHandleMessage,
225 OnExtensionHandleMessage)
[email protected]b68d5ed2009-04-16 02:41:28226 IPC_MESSAGE_HANDLER(ViewMsg_ExtensionHandleEvent,
227 OnExtensionHandleEvent)
[email protected]703e807a2009-03-28 19:56:51228 IPC_MESSAGE_HANDLER(ViewMsg_Extension_SetFunctionNames,
229 OnSetExtensionFunctionNames)
[email protected]b547fd42009-04-23 23:16:27230 IPC_MESSAGE_HANDLER(ViewMsg_PurgePluginListCache,
231 OnPurgePluginListCache)
[email protected]8930d472009-02-21 08:05:28232 IPC_END_MESSAGE_MAP()
initial.commit09911bf2008-07-26 23:55:29233}
234
235void RenderThread::OnSetNextPageID(int32 next_page_id) {
236 // This should only be called at process initialization time, so we shouldn't
237 // have to worry about thread-safety.
238 RenderView::SetNextPageID(next_page_id);
239}
240
[email protected]18bcc3c2009-01-27 21:39:15241void RenderThread::OnCreateNewView(gfx::NativeViewId parent_hwnd,
242 ModalDialogEvent modal_dialog_event,
initial.commit09911bf2008-07-26 23:55:29243 const WebPreferences& webkit_prefs,
244 int32 view_id) {
[email protected]90a3fbb12009-02-28 01:13:47245 EnsureWebKitInitialized();
246
[email protected]be645db2009-02-06 20:36:33247 // When bringing in render_view, also bring in webkit's glue and jsbindings.
[email protected]18bcc3c2009-01-27 21:39:15248 base::WaitableEvent* waitable_event = new base::WaitableEvent(
249#if defined(OS_WIN)
250 modal_dialog_event.event);
251#else
252 true, false);
253#endif
254
initial.commit09911bf2008-07-26 23:55:29255 // TODO(darin): once we have a RenderThread per RenderView, this will need to
256 // change to assert that we are not creating more than one view.
initial.commit09911bf2008-07-26 23:55:29257 RenderView::Create(
[email protected]1c4947f2009-01-15 22:25:11258 this, parent_hwnd, waitable_event, MSG_ROUTING_NONE, webkit_prefs,
[email protected]0aa55312008-10-17 21:53:08259 new SharedRenderViewCounter(0), view_id);
[email protected]7f874dec2009-02-06 01:48:27260}
[email protected]4274e582009-01-27 22:09:56261
initial.commit09911bf2008-07-26 23:55:29262void RenderThread::OnSetCacheCapacities(size_t min_dead_capacity,
263 size_t max_dead_capacity,
264 size_t capacity) {
[email protected]90a3fbb12009-02-28 01:13:47265 EnsureWebKitInitialized();
[email protected]2c434b32009-03-19 06:27:47266 WebCache::setCapacities(
267 min_dead_capacity, max_dead_capacity, capacity);
initial.commit09911bf2008-07-26 23:55:29268}
269
270void RenderThread::OnGetCacheResourceStats() {
[email protected]90a3fbb12009-02-28 01:13:47271 EnsureWebKitInitialized();
[email protected]2c434b32009-03-19 06:27:47272 WebCache::ResourceTypeStats stats;
273 WebCache::getResourceTypeStats(&stats);
initial.commit09911bf2008-07-26 23:55:29274 Send(new ViewHostMsg_ResourceTypeStats(stats));
275}
276
[email protected]55e57d42009-02-25 06:10:17277void RenderThread::OnGetRendererHistograms() {
278 SendHistograms();
279}
280
initial.commit09911bf2008-07-26 23:55:29281void RenderThread::InformHostOfCacheStats() {
[email protected]90a3fbb12009-02-28 01:13:47282 EnsureWebKitInitialized();
[email protected]2c434b32009-03-19 06:27:47283 WebCache::UsageStats stats;
284 WebCache::getUsageStats(&stats);
initial.commit09911bf2008-07-26 23:55:29285 Send(new ViewHostMsg_UpdatedCacheStats(stats));
286}
287
288void RenderThread::InformHostOfCacheStatsLater() {
289 // Rate limit informing the host of our cache stats.
290 if (!cache_stats_factory_->empty())
291 return;
292
293 MessageLoop::current()->PostDelayedTask(FROM_HERE,
294 cache_stats_factory_->NewRunnableMethod(
295 &RenderThread::InformHostOfCacheStats),
296 kCacheStatsDelayMS);
297}
[email protected]90a3fbb12009-02-28 01:13:47298
[email protected]3df0c202009-03-31 23:51:26299static void* CreateHistogram(
300 const char *name, int min, int max, size_t buckets) {
[email protected]56a27b22009-05-21 00:44:37301 Histogram* histogram = new Histogram(name, min, max, buckets);
302 if (histogram) {
303 histogram->SetFlags(kUmaTargetedHistogramFlag);
304 }
305 return histogram;
[email protected]3df0c202009-03-31 23:51:26306}
307
308static void AddHistogramSample(void* hist, int sample) {
309 Histogram* histogram = static_cast<Histogram *>(hist);
310 histogram->Add(sample);
311}
312
[email protected]90a3fbb12009-02-28 01:13:47313void RenderThread::EnsureWebKitInitialized() {
314 if (webkit_client_.get())
315 return;
[email protected]da00a2882009-03-09 17:51:19316
317 v8::V8::SetCounterFunction(StatsTable::FindLocation);
[email protected]3df0c202009-03-31 23:51:26318 v8::V8::SetCreateHistogramFunction(CreateHistogram);
319 v8::V8::SetAddHistogramSampleFunction(AddHistogramSample);
[email protected]da00a2882009-03-09 17:51:19320
[email protected]90a3fbb12009-02-28 01:13:47321 webkit_client_.reset(new RendererWebKitClientImpl);
322 WebKit::initialize(webkit_client_.get());
[email protected]8881eca82009-03-12 18:20:44323
[email protected]60e448982009-05-06 04:21:16324 // chrome: pages should not be accessible by normal content, and should
[email protected]8881eca82009-03-12 18:20:44325 // also be unable to script anything but themselves (to help limit the damage
[email protected]60e448982009-05-06 04:21:16326 // that a corrupt chrome: page could cause).
[email protected]2c434b32009-03-19 06:27:47327 WebString chrome_ui_scheme(ASCIIToUTF16(chrome::kChromeUIScheme));
[email protected]8881eca82009-03-12 18:20:44328 WebKit::registerURLSchemeAsLocal(chrome_ui_scheme);
329 WebKit::registerURLSchemeAsNoAccess(chrome_ui_scheme);
[email protected]da00a2882009-03-09 17:51:19330
[email protected]06533c0b2009-03-05 21:39:11331 WebKit::registerExtension(extensions_v8::GearsExtension::Get());
332 WebKit::registerExtension(extensions_v8::IntervalExtension::Get());
[email protected]c20210e62009-04-03 21:39:26333 WebKit::registerExtension(extensions_v8::LoadTimesExtension::Get());
[email protected]3c8e3702009-05-01 16:27:42334 WebKit::registerExtension(extensions_v8::ExternalExtension::Get());
[email protected]309d7a282009-03-24 09:18:27335
[email protected]a1a0df02009-04-09 08:18:04336 WebKit::registerExtension(ExtensionProcessBindings::Get(),
337 WebKit::WebString::fromUTF8(chrome::kExtensionScheme));
338
[email protected]06533c0b2009-03-05 21:39:11339 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]a1a0df02009-04-09 08:18:04340
341 // TODO(aa): Add a way to restrict extensions to the content script context
342 // only so that we don't have to gate these on --enable-extensions.
[email protected]a40caa972009-04-08 18:35:34343 if (command_line.HasSwitch(switches::kEnableExtensions)) {
[email protected]a1a0df02009-04-09 08:18:04344 WebKit::registerExtension(BaseJsV8Extension::Get());
345 WebKit::registerExtension(JsonJsV8Extension::Get());
[email protected]4c29efd2009-04-14 23:40:41346 WebKit::registerExtension(JsonSchemaJsV8Extension::Get());
[email protected]a40caa972009-04-08 18:35:34347 WebKit::registerExtension(EventBindings::Get());
[email protected]4b5d64ff2009-05-01 21:17:49348 WebKit::registerExtension(RendererExtensionBindings::Get());
[email protected]a40caa972009-04-08 18:35:34349 }
350
[email protected]06533c0b2009-03-05 21:39:11351 if (command_line.HasSwitch(switches::kPlaybackMode) ||
[email protected]ca12c842009-04-14 22:20:18352 command_line.HasSwitch(switches::kRecordMode) ||
353 command_line.HasSwitch(switches::kNoJsRandomness)) {
[email protected]06533c0b2009-03-05 21:39:11354 WebKit::registerExtension(extensions_v8::PlaybackExtension::Get());
355 }
[email protected]2cb82332009-03-18 17:24:55356
[email protected]b08eebe2009-05-18 22:37:21357 if (command_line.HasSwitch(switches::kEnableWebWorkers))
[email protected]0b9a1cc92009-03-19 00:55:53358 WebKit::enableWebWorkers();
[email protected]b08eebe2009-05-18 22:37:21359
360 if (RenderProcess::current()->initialized_media_library())
361 WebKit::enableMediaPlayer();
[email protected]90a3fbb12009-02-28 01:13:47362}
[email protected]75e5a872009-04-02 23:56:11363
[email protected]4b5d64ff2009-05-01 21:17:49364void RenderThread::OnExtensionHandleConnect(int port_id,
365 const std::string& tab_json) {
366 RendererExtensionBindings::HandleConnect(port_id, tab_json);
[email protected]75e5a872009-04-02 23:56:11367}
368
369void RenderThread::OnExtensionHandleMessage(const std::string& message,
370 int port_id) {
[email protected]a1a0df02009-04-09 08:18:04371 RendererExtensionBindings::HandleMessage(message, port_id);
[email protected]75e5a872009-04-02 23:56:11372}
[email protected]b68d5ed2009-04-16 02:41:28373
374void RenderThread::OnExtensionHandleEvent(const std::string event_name,
375 const std::string event_data) {
376 RendererExtensionBindings::HandleEvent(event_name, event_data);
377}
[email protected]b547fd42009-04-23 23:16:27378
379void RenderThread::OnPurgePluginListCache() {
380 // The call below will cause a GetPlugins call with refresh=true, but at this
381 // point we already know that the browser has refreshed its list, so disable
382 // refresh temporarily to prevent each renderer process causing the list to be
383 // regenerated.
384 plugin_refresh_allowed_ = false;
385 WebKit::resetPluginCache();
386 plugin_refresh_allowed_ = true;
387}