blob: 755a524a95e50ed8d24550a93345afbf7054c790 [file] [log] [blame]
[email protected]d3d6325d2012-01-03 21:17:361// Copyright (c) 2012 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// 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
[email protected]f1a29a02011-10-06 23:08:445#include "content/renderer/render_thread_impl.h"
initial.commit09911bf2008-07-26 23:55:296
[email protected]da00a2882009-03-09 17:51:197#include <algorithm>
[email protected]61a9b2d82010-02-26 00:31:088#include <limits>
[email protected]75e126b932009-09-28 19:38:499#include <map>
[email protected]da00a2882009-03-09 17:51:1910#include <vector>
11
[email protected]237a14852012-04-28 02:56:3812#include "base/allocator/allocator_extension.h"
[email protected]06533c0b2009-03-05 21:39:1113#include "base/command_line.h"
[email protected]58580352010-10-26 04:07:5014#include "base/debug/trace_event.h"
[email protected]94f9a0f682009-06-15 18:30:3015#include "base/lazy_instance.h"
[email protected]bee16aab2009-08-26 15:55:0316#include "base/logging.h"
[email protected]835d7c82010-10-14 04:38:3817#include "base/metrics/field_trial.h"
[email protected]6cf19311f2011-04-14 23:06:0218#include "base/metrics/histogram.h"
[email protected]835d7c82010-10-14 04:38:3819#include "base/metrics/stats_table.h"
[email protected]433df472012-03-07 20:33:3920#include "base/path_service.h"
initial.commit09911bf2008-07-26 23:55:2921#include "base/shared_memory.h"
[email protected]feb32372012-11-21 01:14:5622#include "base/string16.h"
[email protected]8c380582011-12-02 03:16:1023#include "base/string_number_conversions.h" // Temporary
[email protected]1357c322010-12-30 22:18:5624#include "base/threading/thread_local.h"
[email protected]58436a12012-03-21 17:10:2625#include "base/utf_string_conversions.h"
[email protected]7a4de7a62010-08-17 18:38:2426#include "base/values.h"
[email protected]e93e04e2011-03-14 00:27:1027#include "content/common/appcache/appcache_dispatcher.h"
[email protected]83ab4a282012-07-12 18:19:4528#include "content/common/child_histogram_message_filter.h"
[email protected]bdae9812011-10-15 00:33:0329#include "content/common/child_process_messages.h"
[email protected]37666cf2011-03-13 21:51:4230#include "content/common/database_messages.h"
31#include "content/common/db_message_filter.h"
[email protected]127dd582011-03-16 21:32:1032#include "content/common/dom_storage_messages.h"
[email protected]c26ad882012-02-07 06:41:2033#include "content/common/gpu/client/gpu_channel_host.h"
[email protected]202b54ff2011-04-22 21:36:3834#include "content/common/gpu/gpu_messages.h"
[email protected]988aacf2012-02-12 18:10:0335#include "content/common/indexed_db/indexed_db_dispatcher.h"
36#include "content/common/indexed_db/indexed_db_message_filter.h"
[email protected]d3fd748b2011-09-20 17:39:1737#include "content/common/npobject_util.h"
[email protected]105303e2011-03-14 22:16:1038#include "content/common/plugin_messages.h"
[email protected]359dfa32011-10-12 01:10:1539#include "content/common/resource_dispatcher.h"
[email protected]94dc971d2011-03-05 19:08:3240#include "content/common/resource_messages.h"
[email protected]778574e2011-03-21 22:03:5041#include "content/common/view_messages.h"
[email protected]e93e04e2011-03-14 00:27:1042#include "content/common/web_database_observer_impl.h"
[email protected]a458504b2012-07-23 19:57:0643#include "content/public/common/content_constants.h"
[email protected]433df472012-03-07 20:33:3944#include "content/public/common/content_paths.h"
[email protected]c08950d22011-10-13 22:20:2945#include "content/public/common/content_switches.h"
[email protected]daf82f82011-10-31 22:35:3146#include "content/public/common/renderer_preferences.h"
[email protected]58436a12012-03-21 17:10:2647#include "content/public/common/url_constants.h"
[email protected]d344114c2011-10-01 01:24:3448#include "content/public/renderer/content_renderer_client.h"
[email protected]64ffa0442011-10-03 22:08:3649#include "content/public/renderer/render_process_observer.h"
50#include "content/public/renderer/render_view_visitor.h"
[email protected]82622452011-07-22 09:57:2051#include "content/renderer/devtools_agent_filter.h"
[email protected]1910fe82012-05-10 00:04:1052#include "content/renderer/dom_storage/dom_storage_dispatcher.h"
53#include "content/renderer/dom_storage/webstoragearea_impl.h"
54#include "content/renderer/dom_storage/webstoragenamespace_impl.h"
[email protected]a9fb30aa2011-10-06 06:58:4655#include "content/renderer/gpu/compositor_thread.h"
[email protected]1842fe22012-08-13 23:24:3556#include "content/renderer/gpu/compositor_output_surface.h"
[email protected]e54ab492012-06-12 19:40:0157#include "content/renderer/gpu/gpu_benchmarking_extension.h"
[email protected]3958e972012-07-17 00:25:4158#include "content/renderer/media/audio_hardware.h"
[email protected]f7eb0a392011-07-12 10:19:5159#include "content/renderer/media/audio_input_message_filter.h"
60#include "content/renderer/media/audio_message_filter.h"
[email protected]3958e972012-07-17 00:25:4161#include "content/renderer/media/audio_renderer_mixer_manager.h"
[email protected]d8cd8372012-03-09 10:49:5162#include "content/renderer/media/media_stream_center.h"
[email protected]6ee10bd2012-09-13 09:01:5363#include "content/renderer/media/media_stream_dependency_factory.h"
[email protected]80b161a2011-06-27 17:42:1164#include "content/renderer/media/video_capture_impl_manager.h"
[email protected]ba164c912011-06-14 22:07:3465#include "content/renderer/media/video_capture_message_filter.h"
[email protected]4761cf12012-09-12 10:37:5566#include "content/renderer/p2p/socket_dispatcher.h"
[email protected]6f516082011-03-17 19:15:3567#include "content/renderer/plugin_channel_host.h"
[email protected]8704f89b2011-04-15 00:30:0568#include "content/renderer/render_process_impl.h"
[email protected]310ebd6302011-10-10 19:06:2869#include "content/renderer/render_view_impl.h"
[email protected]8d6cba42011-09-02 10:05:1970#include "content/renderer/renderer_webkitplatformsupport_impl.h"
[email protected]766a7082012-02-03 23:39:1571#include "grit/content_resources.h"
[email protected]46f36a492010-07-28 19:36:4172#include "ipc/ipc_channel_handle.h"
[email protected]1842fe22012-08-13 23:24:3573#include "ipc/ipc_forwarding_message_filter.h"
[email protected]cb6037d2009-11-16 22:55:1774#include "ipc/ipc_platform_file.h"
[email protected]433df472012-03-07 20:33:3975#include "media/base/media.h"
[email protected]47ebb0e2012-11-30 08:28:2976#include "media/base/media_switches.h"
[email protected]620161e2011-03-07 18:05:2677#include "net/base/net_errors.h"
[email protected]9d797f32010-04-23 07:17:5478#include "net/base/net_util.h"
[email protected]cd7ce3be2012-09-10 05:19:4179#include "third_party/WebKit/Source/Platform/chromium/public/Platform.h"
80#include "third_party/WebKit/Source/Platform/chromium/public/WebCompositorSupport.h"
[email protected]1332623f12012-08-10 03:45:1381#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h"
[email protected]f8c648b2012-02-28 03:46:4582#include "third_party/WebKit/Source/WebKit/chromium/public/WebColorName.h"
[email protected]8bd0fe62011-01-17 06:44:3783#include "third_party/WebKit/Source/WebKit/chromium/public/WebDatabase.h"
84#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h"
[email protected]8bd0fe62011-01-17 06:44:3785#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
86#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h"
[email protected]6eac57a2011-07-12 21:15:0987#include "third_party/WebKit/Source/WebKit/chromium/public/WebNetworkStateNotifier.h"
[email protected]4bd55a32011-07-28 13:28:3888#include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h"
[email protected]8bd0fe62011-01-17 06:44:3789#include "third_party/WebKit/Source/WebKit/chromium/public/WebRuntimeFeatures.h"
90#include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptController.h"
[email protected]58436a12012-03-21 17:10:2691#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h"
[email protected]61a796c42012-05-17 21:28:2092#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
[email protected]c49201a2012-05-24 11:04:5793#include "ui/base/layout.h"
[email protected]18ad6772011-09-20 21:51:3294#include "ui/base/ui_base_switches.h"
[email protected]7f3a2cf2011-04-06 00:10:5095#include "v8/include/v8.h"
[email protected]d471190a2011-02-16 14:52:3096#include "webkit/glue/webkit_glue.h"
[email protected]2c62b562009-01-27 19:04:5097
[email protected]da00a2882009-03-09 17:51:1998#if defined(OS_WIN)
99#include <windows.h>
100#include <objbase.h>
[email protected]5f7e4512012-10-01 20:51:37101#include "base/win/scoped_com_initializer.h"
102#else
103// TODO(port)
104#include "base/memory/scoped_handle.h"
105#include "content/common/np_channel_base.h"
[email protected]da00a2882009-03-09 17:51:19106#endif
107
[email protected]6217d392010-03-25 22:08:35108#if defined(OS_POSIX)
109#include "ipc/ipc_channel_posix.h"
110#endif
111
[email protected]b6cb3a842011-06-24 18:28:41112using WebKit::WebDocument;
[email protected]f85f0702010-01-30 09:31:01113using WebKit::WebFrame;
[email protected]6eac57a2011-07-12 21:15:09114using WebKit::WebNetworkStateNotifier;
[email protected]adf00bc2009-11-02 18:35:00115using WebKit::WebRuntimeFeatures;
[email protected]98d7127b2009-10-23 18:26:51116using WebKit::WebScriptController;
[email protected]58436a12012-03-21 17:10:26117using WebKit::WebSecurityPolicy;
[email protected]2c434b32009-03-19 06:27:47118using WebKit::WebString;
[email protected]50ae00ef2009-10-19 05:11:03119using WebKit::WebView;
[email protected]e9ff79c2012-10-19 21:31:26120
121namespace content {
initial.commit09911bf2008-07-26 23:55:29122
[email protected]42f1d7822009-07-23 18:17:55123namespace {
[email protected]da9ccfb2012-01-28 00:34:40124
125const int64 kInitialIdleHandlerDelayMs = 1000;
126const int64 kShortIdleHandlerDelayMs = 1000;
127const int64 kLongIdleHandlerDelayMs = 30*1000;
128const int kIdleCPUUsageThresholdInPercents = 3;
[email protected]bee16aab2009-08-26 15:55:03129
[email protected]f1a29a02011-10-06 23:08:44130// Keep the global RenderThreadImpl in a TLS slot so it is impossible to access
[email protected]f3ede412010-06-21 22:52:16131// incorrectly from the wrong thread.
[email protected]da9ccfb2012-01-28 00:34:40132base::LazyInstance<base::ThreadLocalPointer<RenderThreadImpl> >
[email protected]6de0fd1d2011-11-15 13:31:49133 lazy_tls = LAZY_INSTANCE_INITIALIZER;
[email protected]1edc16b82009-04-07 17:45:54134
[email protected]e9ff79c2012-10-19 21:31:26135class RenderViewZoomer : public RenderViewVisitor {
[email protected]40bd6582009-12-04 23:49:51136 public:
[email protected]4e2a25a2012-01-27 00:42:08137 RenderViewZoomer(const std::string& host, double zoom_level)
138 : host_(host), zoom_level_(zoom_level) {
[email protected]40bd6582009-12-04 23:49:51139 }
140
[email protected]e9ff79c2012-10-19 21:31:26141 virtual bool Visit(RenderView* render_view) {
[email protected]a2ef54c2011-10-10 16:20:31142 WebView* webview = render_view->GetWebView();
[email protected]b6cb3a842011-06-24 18:28:41143 WebDocument document = webview->mainFrame()->document();
[email protected]b75b8292010-10-01 07:28:25144
145 // Don't set zoom level for full-page plugin since they don't use the same
146 // zoom settings.
[email protected]b6cb3a842011-06-24 18:28:41147 if (document.isPluginDocument())
[email protected]b75b8292010-10-01 07:28:25148 return true;
149
[email protected]b6cb3a842011-06-24 18:28:41150 if (net::GetHostOrSpecFromURL(GURL(document.url())) == host_)
[email protected]40bd6582009-12-04 23:49:51151 webview->setZoomLevel(false, zoom_level_);
152 return true;
153 }
154
155 private:
156 std::string host_;
[email protected]b75b8292010-10-01 07:28:25157 double zoom_level_;
[email protected]40bd6582009-12-04 23:49:51158
159 DISALLOW_COPY_AND_ASSIGN(RenderViewZoomer);
160};
[email protected]0478d0162010-08-28 08:29:40161
[email protected]b2d98762012-09-03 17:04:06162std::string HostToCustomHistogramSuffix(const std::string& host) {
163 if (host == "mail.google.com")
164 return ".gmail";
165 if (host == "docs.google.com" || host == "drive.google.com")
166 return ".docs";
167 if (host == "plus.google.com")
168 return ".plus";
169 return "";
170}
[email protected]42f1d7822009-07-23 18:17:55171
[email protected]b2d98762012-09-03 17:04:06172void* CreateHistogram(
[email protected]d1b8fccc2011-08-03 01:20:13173 const char *name, int min, int max, size_t buckets) {
174 if (min <= 0)
175 min = 1;
[email protected]b2d98762012-09-03 17:04:06176 std::string histogram_name;
177 RenderThreadImpl* render_thread_impl = RenderThreadImpl::current();
178 if (render_thread_impl) { // Can be null in tests.
179 histogram_name = render_thread_impl->
180 histogram_customizer()->ConvertToCustomHistogramName(name);
181 } else {
182 histogram_name = std::string(name);
183 }
[email protected]d1b8fccc2011-08-03 01:20:13184 base::Histogram* histogram = base::Histogram::FactoryGet(
[email protected]b2d98762012-09-03 17:04:06185 histogram_name, min, max, buckets,
186 base::Histogram::kUmaTargetedHistogramFlag);
[email protected]d1b8fccc2011-08-03 01:20:13187 return histogram;
188}
189
[email protected]b2d98762012-09-03 17:04:06190void AddHistogramSample(void* hist, int sample) {
[email protected]d1b8fccc2011-08-03 01:20:13191 base::Histogram* histogram = static_cast<base::Histogram*>(hist);
192 histogram->Add(sample);
193}
194
[email protected]b2d98762012-09-03 17:04:06195} // namespace
196
[email protected]fe476b02012-08-13 21:21:38197class RenderThreadImpl::GpuVDAContextLostCallback
198 : public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback {
199 public:
200 GpuVDAContextLostCallback() {}
201 virtual ~GpuVDAContextLostCallback() {}
202 virtual void onContextLost() {
203 ChildThread::current()->message_loop()->PostTask(FROM_HERE, base::Bind(
204 &RenderThreadImpl::OnGpuVDAContextLoss));
205 }
206};
207
[email protected]b2d98762012-09-03 17:04:06208RenderThreadImpl::HistogramCustomizer::HistogramCustomizer() {
209 custom_histograms_.insert("V8.MemoryExternalFragmentationTotal");
210 custom_histograms_.insert("V8.MemoryHeapSampleTotalCommitted");
211 custom_histograms_.insert("V8.MemoryHeapSampleTotalUsed");
212}
213
214RenderThreadImpl::HistogramCustomizer::~HistogramCustomizer() {}
215
216void RenderThreadImpl::HistogramCustomizer::RenderViewNavigatedToHost(
217 const std::string& host, size_t view_count) {
218 // Check if all RenderViews are displaying a page from the same host. If there
219 // is only one RenderView, the common host is this view's host. If there are
220 // many, check if this one shares the common host of the other
221 // RenderViews. It's ok to not detect some cases where the RenderViews share a
222 // common host. This information is only used for producing custom histograms.
223 if (view_count == 1)
224 SetCommonHost(host);
225 else if (host != common_host_)
226 SetCommonHost(std::string());
227}
228
229std::string RenderThreadImpl::HistogramCustomizer::ConvertToCustomHistogramName(
230 const char* histogram_name) const {
231 std::string name(histogram_name);
232 if (!common_host_histogram_suffix_.empty() &&
233 custom_histograms_.find(name) != custom_histograms_.end())
234 name += common_host_histogram_suffix_;
235 return name;
236}
237
238void RenderThreadImpl::HistogramCustomizer::SetCommonHost(
239 const std::string& host) {
240 if (host != common_host_) {
241 common_host_ = host;
242 common_host_histogram_suffix_ = HostToCustomHistogramSuffix(host);
243 v8::V8::SetCreateHistogramFunction(CreateHistogram);
244 }
245}
246
[email protected]f1a29a02011-10-06 23:08:44247RenderThreadImpl* RenderThreadImpl::current() {
[email protected]526476902011-10-06 20:34:06248 return lazy_tls.Pointer()->Get();
249}
250
[email protected]42f1d7822009-07-23 18:17:55251// When we run plugins in process, we actually run them on the render thread,
252// which means that we need to make the render thread pump UI events.
[email protected]f1a29a02011-10-06 23:08:44253RenderThreadImpl::RenderThreadImpl() {
[email protected]42f1d7822009-07-23 18:17:55254 Init();
255}
256
[email protected]f1a29a02011-10-06 23:08:44257RenderThreadImpl::RenderThreadImpl(const std::string& channel_name)
[email protected]42f1d7822009-07-23 18:17:55258 : ChildThread(channel_name) {
259 Init();
260}
[email protected]5fa1c542009-05-05 20:36:07261
[email protected]f1a29a02011-10-06 23:08:44262void RenderThreadImpl::Init() {
263 TRACE_EVENT_BEGIN_ETW("RenderThreadImpl::Init", 0, "");
[email protected]a872ea1f2010-08-11 04:45:33264
[email protected]c7e948b42012-07-12 09:20:20265 v8::V8::SetCounterFunction(base::StatsTable::FindLocation);
266 v8::V8::SetCreateHistogramFunction(CreateHistogram);
267 v8::V8::SetAddHistogramSampleFunction(AddHistogramSample);
268
[email protected]d3f09092012-02-16 01:52:17269#if defined(OS_MACOSX) || defined(OS_ANDROID)
270 // On Mac and Android, the select popups are rendered by the browser.
[email protected]53c607c2011-03-21 23:19:04271 WebKit::WebView::setUseExternalPopupMenus(true);
272#endif
273
[email protected]94f9a0f682009-06-15 18:30:30274 lazy_tls.Pointer()->Set(this);
[email protected]b3e83de2012-02-07 03:33:28275
[email protected]2c62b562009-01-27 19:04:50276#if defined(OS_WIN)
[email protected]bdef78b52009-04-16 19:31:34277 // If you are running plugins in this thread you need COM active but in
278 // the normal case you don't.
[email protected]00c39612010-03-06 02:53:28279 if (RenderProcessImpl::InProcessPlugins())
[email protected]1a771262011-10-31 09:11:12280 initialize_com_.reset(new base::win::ScopedCOMInitializer());
[email protected]2c62b562009-01-27 19:04:50281#endif
initial.commit09911bf2008-07-26 23:55:29282
[email protected]06c694d2012-02-01 22:26:16283 // Register this object as the main thread.
284 ChildProcess::current()->set_main_thread(this);
285
[email protected]31f87132010-04-21 23:36:21286 // In single process the single process is all there is.
[email protected]80fc08c52010-03-09 07:43:50287 suspend_webkit_shared_timer_ = true;
288 notify_webkit_of_modal_loop_ = true;
[email protected]bee16aab2009-08-26 15:55:03289 widget_count_ = 0;
290 hidden_widget_count_ = 0;
[email protected]6593ae12011-11-14 12:09:44291 idle_notification_delay_in_ms_ = kInitialIdleHandlerDelayMs;
[email protected]1784b2f2011-11-24 10:53:48292 idle_notifications_to_skip_ = 0;
[email protected]2db58cf92011-12-01 21:39:01293 compositor_initialized_ = false;
[email protected]8d86fce2009-02-26 23:37:55294
[email protected]eb398192012-10-22 20:16:19295 appcache_dispatcher_.reset(new content::AppCacheDispatcher(Get()));
[email protected]1910fe82012-05-10 00:04:10296 dom_storage_dispatcher_.reset(new DomStorageDispatcher());
[email protected]eb398192012-10-22 20:16:19297 main_thread_indexed_db_dispatcher_.reset(new content::IndexedDBDispatcher());
[email protected]dd9241932010-02-24 19:23:13298
[email protected]d8cd8372012-03-09 10:49:51299 media_stream_center_ = NULL;
300
[email protected]017022b2009-07-27 23:06:34301 db_message_filter_ = new DBMessageFilter();
302 AddFilter(db_message_filter_.get());
[email protected]dd9241932010-02-24 19:23:13303
[email protected]4761cf12012-09-12 10:37:55304#if defined(ENABLE_WEBRTC)
[email protected]e9ff79c2012-10-19 21:31:26305 p2p_socket_dispatcher_ = new P2PSocketDispatcher(GetIOMessageLoopProxy());
[email protected]4761cf12012-09-12 10:37:55306 AddFilter(p2p_socket_dispatcher_);
307#endif // defined(ENABLE_WEBRTC)
[email protected]80b161a2011-06-27 17:42:11308 vc_manager_ = new VideoCaptureImplManager();
309 AddFilter(vc_manager_->video_capture_message_filter());
[email protected]e25f4d72011-06-08 20:58:46310
[email protected]f7eb0a392011-07-12 10:19:51311 audio_input_message_filter_ = new AudioInputMessageFilter();
312 AddFilter(audio_input_message_filter_.get());
313
314 audio_message_filter_ = new AudioMessageFilter();
315 AddFilter(audio_message_filter_.get());
316
[email protected]31bfae72011-12-16 02:04:38317 AddFilter(new IndexedDBMessageFilter);
318
[email protected]e9ff79c2012-10-19 21:31:26319 GetContentClient()->renderer()->RenderThreadStarted();
[email protected]6779aa12011-03-29 17:32:24320
[email protected]302fe422012-06-11 14:49:11321 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]e54ab492012-06-12 19:40:01322 if (command_line.HasSwitch(switches::kEnableGpuBenchmarking))
[email protected]e9ff79c2012-10-19 21:31:26323 RegisterExtension(GpuBenchmarkingExtension::Get());
[email protected]e54ab492012-06-12 19:40:01324
[email protected]fe476b02012-08-13 21:21:38325 context_lost_cb_.reset(new GpuVDAContextLostCallback());
326
[email protected]433df472012-03-07 20:33:39327 // Note that under Linux, the media library will normally already have
328 // been initialized by the Zygote before this instance became a Renderer.
329 FilePath media_path;
[email protected]e9ff79c2012-10-19 21:31:26330 PathService::Get(DIR_MEDIA_LIBS, &media_path);
[email protected]433df472012-03-07 20:33:39331 if (!media_path.empty())
332 media::InitializeMediaLibrary(media_path);
333
[email protected]f1a29a02011-10-06 23:08:44334 TRACE_EVENT_END_ETW("RenderThreadImpl::Init", 0, "");
initial.commit09911bf2008-07-26 23:55:29335}
336
[email protected]f1a29a02011-10-06 23:08:44337RenderThreadImpl::~RenderThreadImpl() {
[email protected]1223d6ef2011-03-28 16:47:50338 FOR_EACH_OBSERVER(
339 RenderProcessObserver, observers_, OnRenderProcessShutdown());
340
[email protected]12cbfda32010-01-30 01:04:25341 // Wait for all databases to be closed.
[email protected]2b437e232010-04-02 01:30:08342 if (web_database_observer_impl_.get())
343 web_database_observer_impl_->WaitForAllDatabasesToClose();
[email protected]12cbfda32010-01-30 01:04:25344
[email protected]8d86fce2009-02-26 23:37:55345 // Shutdown in reverse of the initialization order.
[email protected]b146d6d2012-09-11 10:20:05346 if (devtools_agent_message_filter_.get()) {
347 RemoveFilter(devtools_agent_message_filter_.get());
348 devtools_agent_message_filter_ = NULL;
349 }
[email protected]82622452011-07-22 09:57:20350
[email protected]f7eb0a392011-07-12 10:19:51351 RemoveFilter(audio_input_message_filter_.get());
352 audio_input_message_filter_ = NULL;
353
354 RemoveFilter(audio_message_filter_.get());
355 audio_message_filter_ = NULL;
356
[email protected]80b161a2011-06-27 17:42:11357 RemoveFilter(vc_manager_->video_capture_message_filter());
358
[email protected]017022b2009-07-27 23:06:34359 RemoveFilter(db_message_filter_.get());
360 db_message_filter_ = NULL;
[email protected]12cbfda32010-01-30 01:04:25361
[email protected]c6a7b862010-08-20 22:19:38362 // Shutdown the file thread if it's running.
363 if (file_thread_.get())
364 file_thread_->Stop();
365
[email protected]23d2b7e2012-08-14 00:34:09366 if (compositor_output_surface_filter_.get()) {
367 RemoveFilter(compositor_output_surface_filter_.get());
368 compositor_output_surface_filter_ = NULL;
369 }
[email protected]1842fe22012-08-13 23:24:35370
[email protected]2db58cf92011-12-01 21:39:01371 if (compositor_initialized_) {
[email protected]cd7ce3be2012-09-10 05:19:41372 WebKit::Platform::current()->compositorSupport()->shutdown();
[email protected]2db58cf92011-12-01 21:39:01373 compositor_initialized_ = false;
374 }
[email protected]a9fb30aa2011-10-06 06:58:46375 if (compositor_thread_.get()) {
376 RemoveFilter(compositor_thread_->GetMessageFilter());
377 compositor_thread_.reset();
378 }
379
[email protected]8d6cba42011-09-02 10:05:19380 if (webkit_platform_support_.get())
[email protected]9291ed12009-07-23 17:33:22381 WebKit::shutdown();
[email protected]9291ed12009-07-23 17:33:22382
[email protected]94f9a0f682009-06-15 18:30:30383 lazy_tls.Pointer()->Set(NULL);
[email protected]8fd8de92008-08-12 23:50:30384
[email protected]8d86fce2009-02-26 23:37:55385 // TODO(port)
[email protected]2c62b562009-01-27 19:04:50386#if defined(OS_WIN)
initial.commit09911bf2008-07-26 23:55:29387 // Clean up plugin channels before this thread goes away.
[email protected]099587b72011-09-20 00:40:50388 NPChannelBase::CleanupChannels();
[email protected]2c62b562009-01-27 19:04:50389#endif
initial.commit09911bf2008-07-26 23:55:29390}
391
[email protected]f1a29a02011-10-06 23:08:44392bool RenderThreadImpl::Send(IPC::Message* msg) {
[email protected]f23d4da92010-11-24 21:36:14393 // Certain synchronous messages cannot always be processed synchronously by
394 // the browser, e.g., Chrome frame communicating with the embedding browser.
[email protected]80fc08c52010-03-09 07:43:50395 // This could cause a complete hang of Chrome if a windowed plug-in is trying
396 // to communicate with the renderer thread since the browser's UI thread
397 // could be stuck (within a Windows API call) trying to synchronously
398 // communicate with the plug-in. The remedy is to pump messages on this
[email protected]f23d4da92010-11-24 21:36:14399 // thread while the browser is processing this request. This creates an
400 // opportunity for re-entrancy into WebKit, so we need to take care to disable
401 // callbacks, timers, and pending network loads that could trigger such
402 // callbacks.
[email protected]38b592902011-04-16 02:08:42403 bool pumping_events = false;
[email protected]80fc08c52010-03-09 07:43:50404 if (msg->is_sync()) {
405 if (msg->is_caller_pumping_messages()) {
406 pumping_events = true;
407 } else {
[email protected]38b592902011-04-16 02:08:42408 if ((msg->type() == ViewHostMsg_GetCookies::ID ||
409 msg->type() == ViewHostMsg_GetRawCookies::ID ||
410 msg->type() == ViewHostMsg_CookiesEnabled::ID) &&
[email protected]e9ff79c2012-10-19 21:31:26411 GetContentClient()->renderer()->
[email protected]38b592902011-04-16 02:08:42412 ShouldPumpEventsDuringCookieMessage()) {
413 pumping_events = true;
[email protected]80fc08c52010-03-09 07:43:50414 }
415 }
[email protected]c1f50aa2010-02-18 03:46:57416 }
417
[email protected]80fc08c52010-03-09 07:43:50418 bool suspend_webkit_shared_timer = true; // default value
419 std::swap(suspend_webkit_shared_timer, suspend_webkit_shared_timer_);
[email protected]c1f50aa2010-02-18 03:46:57420
[email protected]80fc08c52010-03-09 07:43:50421 bool notify_webkit_of_modal_loop = true; // default value
422 std::swap(notify_webkit_of_modal_loop, notify_webkit_of_modal_loop_);
423
[email protected]c48de1a2012-11-02 19:06:56424 int render_view_id = MSG_ROUTING_NONE;
[email protected]c1f50aa2010-02-18 03:46:57425
426 if (pumping_events) {
[email protected]80fc08c52010-03-09 07:43:50427 if (suspend_webkit_shared_timer)
[email protected]8d6cba42011-09-02 10:05:19428 webkit_platform_support_->SuspendSharedTimer();
[email protected]c1f50aa2010-02-18 03:46:57429
[email protected]39065d012010-07-09 11:22:46430 if (notify_webkit_of_modal_loop)
[email protected]c1f50aa2010-02-18 03:46:57431 WebView::willEnterModalLoop();
[email protected]c1f50aa2010-02-18 03:46:57432
[email protected]80fc08c52010-03-09 07:43:50433 RenderWidget* widget =
434 static_cast<RenderWidget*>(ResolveRoute(msg->routing_id()));
435 if (widget) {
[email protected]c48de1a2012-11-02 19:06:56436 render_view_id = widget->routing_id();
[email protected]c1f50aa2010-02-18 03:46:57437 PluginChannelHost::Broadcast(
[email protected]c48de1a2012-11-02 19:06:56438 new PluginMsg_SignalModalDialogEvent(render_view_id));
[email protected]c1f50aa2010-02-18 03:46:57439 }
440 }
441
442 bool rv = ChildThread::Send(msg);
443
444 if (pumping_events) {
[email protected]c48de1a2012-11-02 19:06:56445 if (render_view_id != MSG_ROUTING_NONE) {
[email protected]c1f50aa2010-02-18 03:46:57446 PluginChannelHost::Broadcast(
[email protected]c48de1a2012-11-02 19:06:56447 new PluginMsg_ResetModalDialogEvent(render_view_id));
[email protected]c1f50aa2010-02-18 03:46:57448 }
449
[email protected]39065d012010-07-09 11:22:46450 if (notify_webkit_of_modal_loop)
[email protected]c1f50aa2010-02-18 03:46:57451 WebView::didExitModalLoop();
[email protected]c1f50aa2010-02-18 03:46:57452
[email protected]80fc08c52010-03-09 07:43:50453 if (suspend_webkit_shared_timer)
[email protected]8d6cba42011-09-02 10:05:19454 webkit_platform_support_->ResumeSharedTimer();
[email protected]c1f50aa2010-02-18 03:46:57455 }
456
457 return rv;
458}
459
[email protected]f1a29a02011-10-06 23:08:44460MessageLoop* RenderThreadImpl::GetMessageLoop() {
[email protected]526476902011-10-06 20:34:06461 return message_loop();
462}
463
[email protected]f1a29a02011-10-06 23:08:44464IPC::SyncChannel* RenderThreadImpl::GetChannel() {
[email protected]526476902011-10-06 20:34:06465 return channel();
466}
467
[email protected]f1a29a02011-10-06 23:08:44468std::string RenderThreadImpl::GetLocale() {
[email protected]526476902011-10-06 20:34:06469 // The browser process should have passed the locale to the renderer via the
[email protected]dfd53652012-10-25 00:20:02470 // --lang command line flag.
[email protected]526476902011-10-06 20:34:06471 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess();
472 const std::string& lang =
473 parsed_command_line.GetSwitchValueASCII(switches::kLang);
[email protected]dfd53652012-10-25 00:20:02474 DCHECK(!lang.empty());
[email protected]526476902011-10-06 20:34:06475 return lang;
476}
477
[email protected]07bb6332012-01-21 01:07:57478IPC::SyncMessageFilter* RenderThreadImpl::GetSyncMessageFilter() {
479 return sync_message_filter();
480}
481
[email protected]96191d52012-05-17 01:37:11482scoped_refptr<base::MessageLoopProxy>
483 RenderThreadImpl::GetIOMessageLoopProxy() {
484 return ChildProcess::current()->io_message_loop_proxy();
485}
486
[email protected]c47317e2012-06-20 22:35:31487void RenderThreadImpl::AddRoute(int32 routing_id, IPC::Listener* listener) {
[email protected]c1f50aa2010-02-18 03:46:57488 widget_count_++;
489 return ChildThread::AddRoute(routing_id, listener);
490}
491
[email protected]f1a29a02011-10-06 23:08:44492void RenderThreadImpl::RemoveRoute(int32 routing_id) {
[email protected]c1f50aa2010-02-18 03:46:57493 widget_count_--;
494 return ChildThread::RemoveRoute(routing_id);
495}
496
[email protected]77fc9b92011-10-15 16:20:37497int RenderThreadImpl::GenerateRoutingID() {
498 int routing_id = MSG_ROUTING_NONE;
499 Send(new ViewHostMsg_GenerateRoutingID(&routing_id));
500 return routing_id;
501}
502
[email protected]f1a29a02011-10-06 23:08:44503void RenderThreadImpl::AddFilter(IPC::ChannelProxy::MessageFilter* filter) {
[email protected]42f1d7822009-07-23 18:17:55504 channel()->AddFilter(filter);
505}
506
[email protected]f1a29a02011-10-06 23:08:44507void RenderThreadImpl::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) {
[email protected]42f1d7822009-07-23 18:17:55508 channel()->RemoveFilter(filter);
509}
510
[email protected]f1a29a02011-10-06 23:08:44511void RenderThreadImpl::SetOutgoingMessageFilter(
[email protected]526476902011-10-06 20:34:06512 IPC::ChannelProxy::OutgoingMessageFilter* filter) {
513}
514
[email protected]e9ff79c2012-10-19 21:31:26515void RenderThreadImpl::AddObserver(RenderProcessObserver* observer) {
[email protected]526476902011-10-06 20:34:06516 observers_.AddObserver(observer);
517}
518
[email protected]e9ff79c2012-10-19 21:31:26519void RenderThreadImpl::RemoveObserver(RenderProcessObserver* observer) {
[email protected]526476902011-10-06 20:34:06520 observers_.RemoveObserver(observer);
521}
522
[email protected]359dfa32011-10-12 01:10:15523void RenderThreadImpl::SetResourceDispatcherDelegate(
[email protected]e9ff79c2012-10-19 21:31:26524 ResourceDispatcherDelegate* delegate) {
[email protected]359dfa32011-10-12 01:10:15525 resource_dispatcher()->set_delegate(delegate);
526}
527
[email protected]f1a29a02011-10-06 23:08:44528void RenderThreadImpl::WidgetHidden() {
[email protected]bee16aab2009-08-26 15:55:03529 DCHECK(hidden_widget_count_ < widget_count_);
[email protected]4a3dab22009-11-11 17:36:50530 hidden_widget_count_++;
[email protected]6779aa12011-03-29 17:32:24531
[email protected]e9ff79c2012-10-19 21:31:26532 if (!GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden()) {
[email protected]6779aa12011-03-29 17:32:24533 return;
534 }
535
536 if (widget_count_ && hidden_widget_count_ == widget_count_)
[email protected]6593ae12011-11-14 12:09:44537 ScheduleIdleHandler(kInitialIdleHandlerDelayMs);
[email protected]bee16aab2009-08-26 15:55:03538}
539
[email protected]f1a29a02011-10-06 23:08:44540void RenderThreadImpl::WidgetRestored() {
[email protected]61a9b2d82010-02-26 00:31:08541 DCHECK_GT(hidden_widget_count_, 0);
[email protected]bee16aab2009-08-26 15:55:03542 hidden_widget_count_--;
[email protected]e9ff79c2012-10-19 21:31:26543 if (!GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden()) {
[email protected]6779aa12011-03-29 17:32:24544 return;
545 }
[email protected]bee16aab2009-08-26 15:55:03546
[email protected]1784b2f2011-11-24 10:53:48547 ScheduleIdleHandler(kLongIdleHandlerDelayMs);
[email protected]e4be2dd2010-12-14 00:44:39548}
549
[email protected]f1a29a02011-10-06 23:08:44550void RenderThreadImpl::EnsureWebKitInitialized() {
[email protected]8d6cba42011-09-02 10:05:19551 if (webkit_platform_support_.get())
[email protected]d1b8fccc2011-08-03 01:20:13552 return;
553
[email protected]8d6cba42011-09-02 10:05:19554 webkit_platform_support_.reset(new RendererWebKitPlatformSupportImpl);
555 WebKit::initialize(webkit_platform_support_.get());
[email protected]d1b8fccc2011-08-03 01:20:13556
[email protected]cd7ce3be2012-09-10 05:19:41557 WebKit::WebCompositorSupport* compositor_support =
558 WebKit::Platform::current()->compositorSupport();
559 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
[email protected]cd7ce3be2012-09-10 05:19:41560
[email protected]3e407b42012-06-25 20:43:26561 // TODO(fsamuel): Guests don't currently support threaded compositing.
562 // This should go away with the new design of the browser plugin.
563 // The new design can be tracked at: http://crbug.com/134492.
564 bool is_guest = CommandLine::ForCurrentProcess()->HasSwitch(
565 switches::kGuestRenderer);
[email protected]cb6430932012-10-31 00:53:36566 bool threaded = CommandLine::ForCurrentProcess()->HasSwitch(
567 switches::kEnableThreadedCompositing);
568
569 bool enable = threaded && !is_guest;
[email protected]72787e392012-03-23 05:55:43570 if (enable) {
[email protected]f3150172011-10-22 02:28:45571 compositor_thread_.reset(new CompositorThread(this));
572 AddFilter(compositor_thread_->GetMessageFilter());
[email protected]cd7ce3be2012-09-10 05:19:41573 compositor_support->initialize(compositor_thread_->GetWebThread());
[email protected]a458504b2012-07-23 19:57:06574 } else {
[email protected]cd7ce3be2012-09-10 05:19:41575 compositor_support->initialize(NULL);
[email protected]a458504b2012-07-23 19:57:06576 }
[email protected]2db58cf92011-12-01 21:39:01577 compositor_initialized_ = true;
[email protected]a9fb30aa2011-10-06 06:58:46578
[email protected]1842fe22012-08-13 23:24:35579 MessageLoop* output_surface_loop = enable ?
580 compositor_thread_->message_loop() :
581 MessageLoop::current();
582
583 compositor_output_surface_filter_ = CompositorOutputSurface::CreateFilter(
584 output_surface_loop->message_loop_proxy());
585 AddFilter(compositor_output_surface_filter_.get());
586
[email protected]d1b8fccc2011-08-03 01:20:13587 WebScriptController::enableV8SingleThreadMode();
588
[email protected]58436a12012-03-21 17:10:26589 RenderThreadImpl::RegisterSchemes();
590
[email protected]d1b8fccc2011-08-03 01:20:13591 webkit_glue::EnableWebCoreLogChannels(
592 command_line.GetSwitchValueASCII(switches::kWebCoreLogChannels));
593
[email protected]766a7082012-02-03 23:39:15594 if (CommandLine::ForCurrentProcess()->HasSwitch(
595 switches::kDomAutomationController)) {
[email protected]e9ff79c2012-10-19 21:31:26596 base::StringPiece extension = GetContentClient()->GetDataResource(
[email protected]c49201a2012-05-24 11:04:57597 IDR_DOM_AUTOMATION_JS, ui::SCALE_FACTOR_NONE);
[email protected]766a7082012-02-03 23:39:15598 RegisterExtension(new v8::Extension(
599 "dom_automation.js", extension.data(), 0, NULL, extension.size()));
600 }
601
[email protected]fa1c17e42012-03-06 22:29:54602 web_database_observer_impl_.reset(
603 new WebDatabaseObserverImpl(sync_message_filter()));
[email protected]d1b8fccc2011-08-03 01:20:13604 WebKit::WebDatabase::setObserver(web_database_observer_impl_.get());
605
606 WebRuntimeFeatures::enableSockets(
607 !command_line.HasSwitch(switches::kDisableWebSockets));
608
609 WebRuntimeFeatures::enableDatabase(
610 !command_line.HasSwitch(switches::kDisableDatabases));
611
612 WebRuntimeFeatures::enableDataTransferItems(
613 !command_line.HasSwitch(switches::kDisableDataTransferItems));
614
615 WebRuntimeFeatures::enableApplicationCache(
616 !command_line.HasSwitch(switches::kDisableApplicationCache));
617
618 WebRuntimeFeatures::enableNotifications(
619 !command_line.HasSwitch(switches::kDisableDesktopNotifications));
620
621 WebRuntimeFeatures::enableLocalStorage(
622 !command_line.HasSwitch(switches::kDisableLocalStorage));
623 WebRuntimeFeatures::enableSessionStorage(
624 !command_line.HasSwitch(switches::kDisableSessionStorage));
625
[email protected]b3796c82012-01-19 08:34:33626 WebRuntimeFeatures::enableIndexedDatabase(true);
[email protected]d1b8fccc2011-08-03 01:20:13627
628 WebRuntimeFeatures::enableGeolocation(
629 !command_line.HasSwitch(switches::kDisableGeolocation));
630
[email protected]6aa03b32011-10-27 21:44:44631 WebKit::WebRuntimeFeatures::enableMediaSource(
[email protected]da43c082012-09-07 18:56:11632 !command_line.HasSwitch(switches::kDisableMediaSource));
[email protected]6aa03b32011-10-27 21:44:44633
[email protected]433df472012-03-07 20:33:39634 WebRuntimeFeatures::enableMediaPlayer(
635 media::IsMediaLibraryInitialized());
636
[email protected]7082fb942012-05-16 23:44:59637 WebKit::WebRuntimeFeatures::enableMediaStream(true);
[email protected]cdb609e72012-08-30 10:49:58638 WebKit::WebRuntimeFeatures::enablePeerConnection(true);
[email protected]8ea05a12012-05-02 09:17:47639
[email protected]efdc0282011-08-26 00:36:12640 WebKit::WebRuntimeFeatures::enableFullScreenAPI(
[email protected]5e5671a2011-09-08 02:12:21641 !command_line.HasSwitch(switches::kDisableFullScreen));
[email protected]efdc0282011-08-26 00:36:12642
[email protected]9f5b7822012-04-18 23:39:03643 WebKit::WebRuntimeFeatures::enableEncryptedMedia(
644 command_line.HasSwitch(switches::kEnableEncryptedMedia));
645
[email protected]634a3bd2012-07-26 04:49:01646#if defined(OS_ANDROID)
647 WebRuntimeFeatures::enableWebAudio(
648 command_line.HasSwitch(switches::kEnableWebAudio) &&
649 media::IsMediaLibraryInitialized());
650#else
[email protected]d1b8fccc2011-08-03 01:20:13651 WebRuntimeFeatures::enableWebAudio(
[email protected]6a1f9cf2012-05-24 21:23:45652 !command_line.HasSwitch(switches::kDisableWebAudio) &&
653 media::IsMediaLibraryInitialized());
[email protected]634a3bd2012-07-26 04:49:01654#endif
[email protected]d1b8fccc2011-08-03 01:20:13655
[email protected]d1b8fccc2011-08-03 01:20:13656 WebRuntimeFeatures::enableDeviceMotion(
657 command_line.HasSwitch(switches::kEnableDeviceMotion));
658
659 WebRuntimeFeatures::enableDeviceOrientation(
660 !command_line.HasSwitch(switches::kDisableDeviceOrientation));
661
662 WebRuntimeFeatures::enableSpeechInput(
663 !command_line.HasSwitch(switches::kDisableSpeechInput));
664
[email protected]14f843ea2012-12-01 20:26:29665 WebRuntimeFeatures::enableScriptedSpeech(true);
[email protected]9b7b57d2012-03-21 13:17:48666
[email protected]d1b8fccc2011-08-03 01:20:13667 WebRuntimeFeatures::enableFileSystem(
668 !command_line.HasSwitch(switches::kDisableFileSystem));
669
670 WebRuntimeFeatures::enableJavaScriptI18NAPI(
671 !command_line.HasSwitch(switches::kDisableJavaScriptI18NAPI));
672
[email protected]d7a35b72012-05-17 15:59:57673 WebRuntimeFeatures::enableGamepad(true);
[email protected]0205fbf2011-11-30 21:51:36674
[email protected]d1b8fccc2011-08-03 01:20:13675 WebRuntimeFeatures::enableQuota(true);
676
[email protected]739d08d32012-10-12 07:38:14677 WebRuntimeFeatures::enableShadowDOM(true);
[email protected]d2edc6702012-01-30 09:13:16678
[email protected]4961218f2012-02-23 10:11:07679 WebRuntimeFeatures::enableStyleScoped(
[email protected]ff7b6dd2012-09-15 20:20:03680 command_line.HasSwitch(switches::kEnableExperimentalWebKitFeatures));
[email protected]4961218f2012-02-23 10:11:07681
[email protected]c76f58ba2012-08-11 01:11:57682 WebRuntimeFeatures::enableCSSExclusions(
[email protected]ff7b6dd2012-09-15 20:20:03683 command_line.HasSwitch(switches::kEnableExperimentalWebKitFeatures));
[email protected]c76f58ba2012-08-11 01:11:57684
[email protected]d1b8fccc2011-08-03 01:20:13685 FOR_EACH_OBSERVER(RenderProcessObserver, observers_, WebKitInitialized());
[email protected]1784b2f2011-11-24 10:53:48686
[email protected]b146d6d2012-09-11 10:20:05687 devtools_agent_message_filter_ = new DevToolsAgentFilter();
688 AddFilter(devtools_agent_message_filter_.get());
689
[email protected]e9ff79c2012-10-19 21:31:26690 if (GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden())
[email protected]1784b2f2011-11-24 10:53:48691 ScheduleIdleHandler(kLongIdleHandlerDelayMs);
[email protected]d1b8fccc2011-08-03 01:20:13692}
693
[email protected]58436a12012-03-21 17:10:26694void RenderThreadImpl::RegisterSchemes() {
695 // swappedout: pages should not be accessible, and should also
696 // be treated as empty documents that can commit synchronously.
697 WebString swappedout_scheme(ASCIIToUTF16(chrome::kSwappedOutScheme));
698 WebSecurityPolicy::registerURLSchemeAsDisplayIsolated(swappedout_scheme);
699 WebSecurityPolicy::registerURLSchemeAsEmptyDocument(swappedout_scheme);
700}
701
[email protected]f1a29a02011-10-06 23:08:44702void RenderThreadImpl::RecordUserMetrics(const std::string& action) {
[email protected]526476902011-10-06 20:34:06703 Send(new ViewHostMsg_UserMetricsRecordAction(action));
704}
705
[email protected]00614a82011-10-07 22:39:31706base::SharedMemoryHandle RenderThreadImpl::HostAllocateSharedMemoryBuffer(
[email protected]bdae9812011-10-15 00:33:03707 uint32 buffer_size) {
[email protected]cb62dc12012-10-13 00:26:44708 base::SharedMemoryHandle mem_handle = base::SharedMemoryHandle();
[email protected]bdae9812011-10-15 00:33:03709 Send(new ChildProcessHostMsg_SyncAllocateSharedMemory(
710 buffer_size, &mem_handle));
[email protected]00614a82011-10-07 22:39:31711 return mem_handle;
712}
713
[email protected]f1a29a02011-10-06 23:08:44714void RenderThreadImpl::RegisterExtension(v8::Extension* extension) {
[email protected]526476902011-10-06 20:34:06715 WebScriptController::registerExtension(extension);
[email protected]526476902011-10-06 20:34:06716}
717
[email protected]6593ae12011-11-14 12:09:44718void RenderThreadImpl::ScheduleIdleHandler(int64 initial_delay_ms) {
719 idle_notification_delay_in_ms_ = initial_delay_ms;
[email protected]526476902011-10-06 20:34:06720 idle_timer_.Stop();
721 idle_timer_.Start(FROM_HERE,
[email protected]6593ae12011-11-14 12:09:44722 base::TimeDelta::FromMilliseconds(initial_delay_ms),
[email protected]f1a29a02011-10-06 23:08:44723 this, &RenderThreadImpl::IdleHandler);
[email protected]526476902011-10-06 20:34:06724}
725
[email protected]f1a29a02011-10-06 23:08:44726void RenderThreadImpl::IdleHandler() {
[email protected]1784b2f2011-11-24 10:53:48727 bool run_in_foreground_tab = (widget_count_ > hidden_widget_count_) &&
[email protected]e9ff79c2012-10-19 21:31:26728 GetContentClient()->renderer()->
[email protected]1784b2f2011-11-24 10:53:48729 RunIdleHandlerWhenWidgetsHidden();
730 if (run_in_foreground_tab) {
731 IdleHandlerInForegroundTab();
732 return;
733 }
[email protected]237a14852012-04-28 02:56:38734
735 base::allocator::ReleaseFreeMemory();
[email protected]526476902011-10-06 20:34:06736
737 v8::V8::IdleNotification();
738
739 // Schedule next invocation.
[email protected]6593ae12011-11-14 12:09:44740 // Dampen the delay using the algorithm (if delay is in seconds):
[email protected]526476902011-10-06 20:34:06741 // delay = delay + 1 / (delay + 2)
742 // Using floor(delay) has a dampening effect such as:
743 // 1s, 1, 1, 2, 2, 2, 2, 3, 3, ...
[email protected]6593ae12011-11-14 12:09:44744 // If the delay is in milliseconds, the above formula is equivalent to:
745 // delay_ms / 1000 = delay_ms / 1000 + 1 / (delay_ms / 1000 + 2)
746 // which is equivalent to
747 // delay_ms = delay_ms + 1000*1000 / (delay_ms + 2000).
748 // Note that idle_notification_delay_in_ms_ would be reset to
749 // kInitialIdleHandlerDelayMs in RenderThreadImpl::WidgetHidden.
750 ScheduleIdleHandler(idle_notification_delay_in_ms_ +
751 1000000 / (idle_notification_delay_in_ms_ + 2000));
[email protected]526476902011-10-06 20:34:06752
753 FOR_EACH_OBSERVER(RenderProcessObserver, observers_, IdleNotification());
754}
755
[email protected]1784b2f2011-11-24 10:53:48756void RenderThreadImpl::IdleHandlerInForegroundTab() {
757 // Increase the delay in the same way as in IdleHandler,
758 // but make it periodic by reseting it once it is too big.
759 int64 new_delay_ms = idle_notification_delay_in_ms_ +
760 1000000 / (idle_notification_delay_in_ms_ + 2000);
761 if (new_delay_ms >= kLongIdleHandlerDelayMs)
762 new_delay_ms = kShortIdleHandlerDelayMs;
763
[email protected]1784b2f2011-11-24 10:53:48764 if (idle_notifications_to_skip_ > 0) {
765 idle_notifications_to_skip_--;
[email protected]7e967f82011-12-01 09:35:14766 } else {
[email protected]a47105c832011-12-07 17:24:30767 int cpu_usage = 0;
[email protected]7e967f82011-12-01 09:35:14768 Send(new ViewHostMsg_GetCPUUsage(&cpu_usage));
[email protected]1393c4a2012-02-07 10:12:58769 // Idle notification hint roughly specifies the expected duration of the
770 // idle pause. We set it proportional to the idle timer delay.
771 int idle_hint = static_cast<int>(new_delay_ms / 10);
[email protected]d7e59252012-03-06 22:26:02772 if (cpu_usage < kIdleCPUUsageThresholdInPercents) {
[email protected]237a14852012-04-28 02:56:38773 base::allocator::ReleaseFreeMemory();
[email protected]d7e59252012-03-06 22:26:02774 if (v8::V8::IdleNotification(idle_hint)) {
775 // V8 finished collecting garbage.
776 new_delay_ms = kLongIdleHandlerDelayMs;
777 }
[email protected]1784b2f2011-11-24 10:53:48778 }
779 }
[email protected]1784b2f2011-11-24 10:53:48780 ScheduleIdleHandler(new_delay_ms);
781}
782
[email protected]6593ae12011-11-14 12:09:44783int64 RenderThreadImpl::GetIdleNotificationDelayInMs() const {
784 return idle_notification_delay_in_ms_;
[email protected]526476902011-10-06 20:34:06785}
786
[email protected]6593ae12011-11-14 12:09:44787void RenderThreadImpl::SetIdleNotificationDelayInMs(
788 int64 idle_notification_delay_in_ms) {
789 idle_notification_delay_in_ms_ = idle_notification_delay_in_ms;
[email protected]4a7d6392011-09-19 20:55:08790}
791
[email protected]a1a7ff32012-07-19 14:03:51792void RenderThreadImpl::ToggleWebKitSharedTimer(bool suspend) {
793 if (suspend_webkit_shared_timer_) {
794 EnsureWebKitInitialized();
795 if (suspend) {
796 webkit_platform_support_->SuspendSharedTimer();
797 } else {
798 webkit_platform_support_->ResumeSharedTimer();
799 }
800 }
801}
802
803void RenderThreadImpl::UpdateHistograms(int sequence_number) {
804 child_histogram_message_filter()->SendHistograms(sequence_number);
805}
806
[email protected]1784b2f2011-11-24 10:53:48807void RenderThreadImpl::PostponeIdleNotification() {
808 idle_notifications_to_skip_ = 2;
809}
810
[email protected]fe476b02012-08-13 21:21:38811/* static */
812void RenderThreadImpl::OnGpuVDAContextLoss() {
813 RenderThreadImpl* self = RenderThreadImpl::current();
814 DCHECK(self);
815 if (!self->gpu_vda_context3d_.get())
816 return;
817 if (self->compositor_thread()) {
818 self->compositor_thread()->GetWebThread()->message_loop()->DeleteSoon(
819 FROM_HERE, self->gpu_vda_context3d_.release());
820 } else {
821 self->gpu_vda_context3d_.reset();
[email protected]3b2afc32012-06-18 21:31:16822 }
[email protected]fe476b02012-08-13 21:21:38823}
824
825WebGraphicsContext3DCommandBufferImpl*
826RenderThreadImpl::GetGpuVDAContext3D() {
[email protected]3b2afc32012-06-18 21:31:16827 if (!gpu_vda_context3d_.get()) {
828 gpu_vda_context3d_.reset(
829 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext(
[email protected]d1a9e062012-07-13 00:45:14830 this, WebKit::WebGraphicsContext3D::Attributes(),
831 GURL("chrome://gpu/RenderThreadImpl::GetGpuVDAContext3D")));
[email protected]fde3e2f2012-08-14 06:51:37832 if (gpu_vda_context3d_.get())
833 gpu_vda_context3d_->setContextLostCallback(context_lost_cb_.get());
[email protected]3b2afc32012-06-18 21:31:16834 }
[email protected]fe476b02012-08-13 21:21:38835 return gpu_vda_context3d_.get();
[email protected]3b2afc32012-06-18 21:31:16836}
837
[email protected]e9ff79c2012-10-19 21:31:26838AudioRendererMixerManager* RenderThreadImpl::GetAudioRendererMixerManager() {
[email protected]3958e972012-07-17 00:25:41839 if (!audio_renderer_mixer_manager_.get()) {
840 audio_renderer_mixer_manager_.reset(new AudioRendererMixerManager(
[email protected]fe81ba4e2012-10-23 18:06:51841 GetAudioOutputSampleRate(),
842 GetAudioOutputBufferSize()));
[email protected]3958e972012-07-17 00:25:41843 }
844
845 return audio_renderer_mixer_manager_.get();
846}
847
[email protected]4a7d6392011-09-19 20:55:08848#if defined(OS_WIN)
[email protected]feb32372012-11-21 01:14:56849void RenderThreadImpl::PreCacheFontCharacters(const LOGFONT& log_font,
850 const string16& str) {
851 Send(new ViewHostMsg_PreCacheFontCharacters(log_font, str));
852}
853
[email protected]f1a29a02011-10-06 23:08:44854void RenderThreadImpl::PreCacheFont(const LOGFONT& log_font) {
[email protected]526476902011-10-06 20:34:06855 Send(new ChildProcessHostMsg_PreCacheFont(log_font));
[email protected]79fff822011-09-20 03:33:21856}
857
[email protected]f1a29a02011-10-06 23:08:44858void RenderThreadImpl::ReleaseCachedFonts() {
[email protected]526476902011-10-06 20:34:06859 Send(new ChildProcessHostMsg_ReleaseCachedFonts());
[email protected]4a7d6392011-09-19 20:55:08860}
[email protected]526476902011-10-06 20:34:06861
[email protected]4a7d6392011-09-19 20:55:08862#endif // OS_WIN
863
[email protected]988aacf2012-02-12 18:10:03864bool RenderThreadImpl::IsWebFrameValid(WebKit::WebFrame* web_frame) {
865 if (!web_frame)
[email protected]4761cf12012-09-12 10:37:55866 return false; // We must be shutting down.
[email protected]988aacf2012-02-12 18:10:03867
868 RenderViewImpl* render_view = RenderViewImpl::FromWebView(web_frame->view());
869 if (!render_view)
[email protected]4761cf12012-09-12 10:37:55870 return false; // We must be shutting down.
[email protected]988aacf2012-02-12 18:10:03871
872 return true;
873}
874
[email protected]b3e83de2012-02-07 03:33:28875bool RenderThreadImpl::IsMainThread() {
876 return !!current();
877}
878
879bool RenderThreadImpl::IsIOThread() {
880 return MessageLoop::current() == ChildProcess::current()->io_message_loop();
881}
882
883MessageLoop* RenderThreadImpl::GetMainLoop() {
884 return message_loop();
885}
[email protected]5b040e592012-02-10 02:56:10886
887scoped_refptr<base::MessageLoopProxy> RenderThreadImpl::GetIOLoopProxy() {
[email protected]b3e83de2012-02-07 03:33:28888 return ChildProcess::current()->io_message_loop_proxy();
889}
890
891base::WaitableEvent* RenderThreadImpl::GetShutDownEvent() {
892 return ChildProcess::current()->GetShutDownEvent();
893}
894
895scoped_ptr<base::SharedMemory> RenderThreadImpl::AllocateSharedMemory(
896 uint32 size) {
[email protected]b3e83de2012-02-07 03:33:28897 base::SharedMemoryHandle handle;
[email protected]8b10b332012-02-29 21:02:14898 bool success;
899 IPC::Message* message =
900 new ChildProcessHostMsg_SyncAllocateSharedMemory(size, &handle);
901
902 // Allow calling this from the compositor thread.
903 if (MessageLoop::current() == message_loop())
904 success = ChildThread::Send(message);
905 else
906 success = sync_message_filter()->Send(message);
907
908 if (!success)
[email protected]b3e83de2012-02-07 03:33:28909 return scoped_ptr<base::SharedMemory>();
[email protected]8b10b332012-02-29 21:02:14910
[email protected]b3e83de2012-02-07 03:33:28911 if (!base::SharedMemory::IsHandleValid(handle))
912 return scoped_ptr<base::SharedMemory>();
913 return scoped_ptr<base::SharedMemory>(new base::SharedMemory(handle, false));
914}
915
916int32 RenderThreadImpl::CreateViewCommandBuffer(
917 int32 surface_id, const GPUCreateCommandBufferConfig& init_params) {
[email protected]d13f35d2012-05-18 02:28:15918 TRACE_EVENT1("gpu",
919 "RenderThreadImpl::CreateViewCommandBuffer",
920 "surface_id",
921 surface_id);
922
[email protected]b3e83de2012-02-07 03:33:28923 int32 route_id = MSG_ROUTING_NONE;
[email protected]8b10b332012-02-29 21:02:14924 IPC::Message* message = new GpuHostMsg_CreateViewCommandBuffer(
[email protected]b3e83de2012-02-07 03:33:28925 surface_id,
926 init_params,
[email protected]8b10b332012-02-29 21:02:14927 &route_id);
928
929 // Allow calling this from the compositor thread.
930 if (MessageLoop::current() == message_loop())
931 ChildThread::Send(message);
932 else
933 sync_message_filter()->Send(message);
934
[email protected]b3e83de2012-02-07 03:33:28935 return route_id;
936}
937
[email protected]09d50362012-10-18 20:54:37938void RenderThreadImpl::CreateImage(
939 gfx::PluginWindowHandle window,
940 int32 image_id,
941 const CreateImageCallback& callback) {
942 NOTREACHED();
943}
944
945void RenderThreadImpl::DeleteImage(int32 image_id, int32 sync_point) {
946 NOTREACHED();
947}
948
[email protected]f1a29a02011-10-06 23:08:44949void RenderThreadImpl::DoNotSuspendWebKitSharedTimer() {
[email protected]526476902011-10-06 20:34:06950 suspend_webkit_shared_timer_ = false;
951}
952
[email protected]f1a29a02011-10-06 23:08:44953void RenderThreadImpl::DoNotNotifyWebKitOfModalLoop() {
[email protected]526476902011-10-06 20:34:06954 notify_webkit_of_modal_loop_ = false;
955}
956
[email protected]4e2a25a2012-01-27 00:42:08957void RenderThreadImpl::OnSetZoomLevelForCurrentURL(const std::string& host,
[email protected]f1a29a02011-10-06 23:08:44958 double zoom_level) {
[email protected]4e2a25a2012-01-27 00:42:08959 RenderViewZoomer zoomer(host, zoom_level);
[email protected]e9ff79c2012-10-19 21:31:26960 RenderView::ForEach(&zoomer);
[email protected]526476902011-10-06 20:34:06961}
962
[email protected]f1a29a02011-10-06 23:08:44963bool RenderThreadImpl::OnControlMessageReceived(const IPC::Message& msg) {
[email protected]1223d6ef2011-03-28 16:47:50964 ObserverListBase<RenderProcessObserver>::Iterator it(observers_);
965 RenderProcessObserver* observer;
966 while ((observer = it.GetNext()) != NULL) {
967 if (observer->OnControlMessageReceived(msg))
968 return true;
969 }
970
[email protected]70c19a932010-05-14 12:59:11971 // Some messages are handled by delegates.
[email protected]1910fe82012-05-10 00:04:10972 if (appcache_dispatcher_->OnMessageReceived(msg) ||
973 dom_storage_dispatcher_->OnMessageReceived(msg)) {
[email protected]a95986a82010-12-24 06:19:28974 return true;
[email protected]1910fe82012-05-10 00:04:10975 }
[email protected]1edc16b82009-04-07 17:45:54976
[email protected]a95986a82010-12-24 06:19:28977 bool handled = true;
[email protected]f1a29a02011-10-06 23:08:44978 IPC_BEGIN_MESSAGE_MAP(RenderThreadImpl, msg)
[email protected]9d797f32010-04-23 07:17:54979 IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevelForCurrentURL,
980 OnSetZoomLevelForCurrentURL)
[email protected]8930d472009-02-21 08:05:28981 // TODO(port): removed from render_messages_internal.h;
982 // is there a new non-windows message I should add here?
983 IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView)
[email protected]3e267192011-03-25 01:55:45984 IPC_MESSAGE_HANDLER(ViewMsg_PurgePluginListCache, OnPurgePluginListCache)
[email protected]6eac57a2011-07-12 21:15:09985 IPC_MESSAGE_HANDLER(ViewMsg_NetworkStateChanged, OnNetworkStateChanged)
[email protected]b69934e2011-10-29 02:51:52986 IPC_MESSAGE_HANDLER(ViewMsg_TempCrashWithData, OnTempCrashWithData)
[email protected]a95986a82010-12-24 06:19:28987 IPC_MESSAGE_UNHANDLED(handled = false)
[email protected]8930d472009-02-21 08:05:28988 IPC_END_MESSAGE_MAP()
[email protected]a95986a82010-12-24 06:19:28989 return handled;
initial.commit09911bf2008-07-26 23:55:29990}
991
[email protected]f1a29a02011-10-06 23:08:44992void RenderThreadImpl::OnCreateNewView(const ViewMsg_New_Params& params) {
[email protected]90a3fbb12009-02-28 01:13:47993 EnsureWebKitInitialized();
[email protected]be645db2009-02-06 20:36:33994 // When bringing in render_view, also bring in webkit's glue and jsbindings.
[email protected]6cd7c6b2012-10-25 03:26:23995 RenderViewImpl::Create(
[email protected]6cd7c6b2012-10-25 03:26:23996 params.opener_route_id,
997 params.renderer_preferences,
998 params.web_preferences,
999 new SharedRenderViewCounter(0),
1000 params.view_id,
1001 params.surface_id,
1002 params.session_storage_namespace_id,
1003 params.frame_name,
1004 false,
1005 params.swapped_out,
1006 params.next_page_id,
1007 params.screen_info,
1008 params.accessibility_mode);
[email protected]7f874dec2009-02-06 01:48:271009}
[email protected]4274e582009-01-27 22:09:561010
[email protected]f1a29a02011-10-06 23:08:441011GpuChannelHost* RenderThreadImpl::EstablishGpuChannelSync(
[email protected]e9ff79c2012-10-19 21:31:261012 CauseForGpuLaunch cause_for_gpu_launch) {
[email protected]d13f35d2012-05-18 02:28:151013 TRACE_EVENT0("gpu", "RenderThreadImpl::EstablishGpuChannelSync");
1014
[email protected]6217d392010-03-25 22:08:351015 if (gpu_channel_.get()) {
[email protected]1082b1d2010-03-30 00:31:221016 // Do nothing if we already have a GPU channel or are already
1017 // establishing one.
[email protected]e09cee42010-11-09 01:50:081018 if (gpu_channel_->state() == GpuChannelHost::kUnconnected ||
1019 gpu_channel_->state() == GpuChannelHost::kConnected)
[email protected]b42a9f62011-06-08 20:36:041020 return GetGpuChannel();
[email protected]6217d392010-03-25 22:08:351021
1022 // Recreate the channel if it has been lost.
[email protected]894e8fc2012-02-24 13:29:501023 gpu_channel_ = NULL;
[email protected]6217d392010-03-25 22:08:351024 }
1025
[email protected]6217d392010-03-25 22:08:351026 // Ask the browser for the channel name.
[email protected]894e8fc2012-02-24 13:29:501027 int client_id = 0;
[email protected]b42a9f62011-06-08 20:36:041028 IPC::ChannelHandle channel_handle;
[email protected]e9ff79c2012-10-19 21:31:261029 GPUInfo gpu_info;
[email protected]b42a9f62011-06-08 20:36:041030 if (!Send(new GpuHostMsg_EstablishGpuChannel(cause_for_gpu_launch,
[email protected]894e8fc2012-02-24 13:29:501031 &client_id,
[email protected]b42a9f62011-06-08 20:36:041032 &channel_handle,
[email protected]b42a9f62011-06-08 20:36:041033 &gpu_info)) ||
[email protected]8bc550e2012-02-07 11:05:561034#if defined(OS_POSIX)
1035 channel_handle.socket.fd == -1 ||
1036#endif
[email protected]cd0bd792012-04-14 00:52:161037 channel_handle.name.empty()) {
[email protected]b42a9f62011-06-08 20:36:041038 // Otherwise cancel the connection.
1039 gpu_channel_ = NULL;
1040 return NULL;
1041 }
[email protected]6217d392010-03-25 22:08:351042
[email protected]03dc8882012-03-08 23:46:291043 gpu_channel_ = new GpuChannelHost(this, 0, client_id);
[email protected]b42a9f62011-06-08 20:36:041044 gpu_channel_->set_gpu_info(gpu_info);
[email protected]e9ff79c2012-10-19 21:31:261045 GetContentClient()->SetGpuInfo(gpu_info);
[email protected]b42a9f62011-06-08 20:36:041046
1047 // Connect to the GPU process if a channel name was received.
[email protected]cd0bd792012-04-14 00:52:161048 gpu_channel_->Connect(channel_handle);
[email protected]b42a9f62011-06-08 20:36:041049
[email protected]f9a2b2fe2010-07-15 21:13:231050 return GetGpuChannel();
[email protected]3bf4d532010-03-27 00:23:341051}
1052
[email protected]d8cd8372012-03-09 10:49:511053WebKit::WebMediaStreamCenter* RenderThreadImpl::CreateMediaStreamCenter(
1054 WebKit::WebMediaStreamCenterClient* client) {
1055#if defined(ENABLE_WEBRTC)
[email protected]d8cd8372012-03-09 10:49:511056 if (!media_stream_center_)
[email protected]e9ff79c2012-10-19 21:31:261057 media_stream_center_ = new MediaStreamCenter(
[email protected]6ee10bd2012-09-13 09:01:531058 client, GetMediaStreamDependencyFactory());
[email protected]d8cd8372012-03-09 10:49:511059#endif
1060 return media_stream_center_;
1061}
1062
[email protected]6ee10bd2012-09-13 09:01:531063MediaStreamDependencyFactory*
1064RenderThreadImpl::GetMediaStreamDependencyFactory() {
1065#if defined(ENABLE_WEBRTC)
1066 if (!media_stream_factory_.get()) {
1067 media_stream_factory_.reset(new MediaStreamDependencyFactory(
1068 vc_manager_, p2p_socket_dispatcher_));
1069 }
1070#endif
1071 return media_stream_factory_.get();
1072}
1073
[email protected]f1a29a02011-10-06 23:08:441074GpuChannelHost* RenderThreadImpl::GetGpuChannel() {
[email protected]6217d392010-03-25 22:08:351075 if (!gpu_channel_.get())
1076 return NULL;
1077
[email protected]e09cee42010-11-09 01:50:081078 if (gpu_channel_->state() != GpuChannelHost::kConnected)
[email protected]6217d392010-03-25 22:08:351079 return NULL;
1080
1081 return gpu_channel_.get();
1082}
1083
[email protected]f1a29a02011-10-06 23:08:441084void RenderThreadImpl::OnPurgePluginListCache(bool reload_pages) {
[email protected]f5e4b9bf2009-10-08 00:59:591085 EnsureWebKitInitialized();
[email protected]b547fd42009-04-23 23:16:271086 // The call below will cause a GetPlugins call with refresh=true, but at this
1087 // point we already know that the browser has refreshed its list, so disable
1088 // refresh temporarily to prevent each renderer process causing the list to be
1089 // regenerated.
[email protected]a70b4352012-07-31 22:34:531090 webkit_platform_support_->set_plugin_refresh_allowed(false);
[email protected]b78e168b2009-09-21 22:05:451091 WebKit::resetPluginCache(reload_pages);
[email protected]a70b4352012-07-31 22:34:531092 webkit_platform_support_->set_plugin_refresh_allowed(true);
[email protected]3b48dbc2012-01-06 16:34:171093
1094 FOR_EACH_OBSERVER(RenderProcessObserver, observers_, PluginListChanged());
[email protected]b547fd42009-04-23 23:16:271095}
[email protected]85c55dc2009-11-06 03:05:461096
[email protected]f1a29a02011-10-06 23:08:441097void RenderThreadImpl::OnNetworkStateChanged(bool online) {
[email protected]6eac57a2011-07-12 21:15:091098 EnsureWebKitInitialized();
1099 WebNetworkStateNotifier::setOnLine(online);
1100}
1101
[email protected]b69934e2011-10-29 02:51:521102void RenderThreadImpl::OnTempCrashWithData(const GURL& data) {
[email protected]e9ff79c2012-10-19 21:31:261103 GetContentClient()->SetActiveURL(data);
[email protected]b69934e2011-10-29 02:51:521104 CHECK(false);
1105}
1106
[email protected]c6a7b862010-08-20 22:19:381107scoped_refptr<base::MessageLoopProxy>
[email protected]f1a29a02011-10-06 23:08:441108RenderThreadImpl::GetFileThreadMessageLoopProxy() {
[email protected]c6a7b862010-08-20 22:19:381109 DCHECK(message_loop() == MessageLoop::current());
1110 if (!file_thread_.get()) {
1111 file_thread_.reset(new base::Thread("Renderer::FILE"));
1112 file_thread_->Start();
1113 }
1114 return file_thread_->message_loop_proxy();
1115}
[email protected]e9ff79c2012-10-19 21:31:261116
1117} // namespace content