render_thread_impl.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
1// Copyright (c) 2012 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. 4 5#include "content/renderer/render_thread_impl.h" 6 7#include <algorithm> 8#include <limits> 9#include <map> 10#include <vector> 11 12#include "base/allocator/allocator_extension.h" 13#include "base/command_line.h" 14#include "base/debug/trace_event.h" 15#include "base/lazy_instance.h" 16#include "base/logging.h" 17#include "base/metrics/field_trial.h" 18#include "base/metrics/histogram.h" 19#include "base/metrics/stats_table.h" 20#include "base/path_service.h" 21#include "base/shared_memory.h" 22#include "base/string16.h" 23#include "base/string_number_conversions.h" // Temporary 24#include "base/threading/thread_local.h" 25#include "base/threading/thread_restrictions.h" 26#include "base/utf_string_conversions.h" 27#include "base/values.h" 28#include "content/common/appcache/appcache_dispatcher.h" 29#include "content/common/child_histogram_message_filter.h" 30#include "content/common/child_process_messages.h" 31#include "content/common/database_messages.h" 32#include "content/common/db_message_filter.h" 33#include "content/common/dom_storage_messages.h" 34#include "content/common/gpu/client/context_provider_command_buffer.h" 35#include "content/common/gpu/client/gpu_channel_host.h" 36#include "content/common/gpu/gpu_messages.h" 37#include "content/common/resource_dispatcher.h" 38#include "content/common/resource_messages.h" 39#include "content/common/view_messages.h" 40#include "content/common_child/indexed_db/indexed_db_dispatcher.h" 41#include "content/common_child/indexed_db/indexed_db_message_filter.h" 42#include "content/common_child/npobject_util.h" 43#include "content/common_child/plugin_messages.h" 44#include "content/common_child/web_database_observer_impl.h" 45#include "content/public/common/content_constants.h" 46#include "content/public/common/content_paths.h" 47#include "content/public/common/content_switches.h" 48#include "content/public/common/renderer_preferences.h" 49#include "content/public/common/url_constants.h" 50#include "content/public/renderer/content_renderer_client.h" 51#include "content/public/renderer/render_process_observer.h" 52#include "content/public/renderer/render_view_visitor.h" 53#include "content/renderer/devtools/devtools_agent_filter.h" 54#include "content/renderer/dom_storage/dom_storage_dispatcher.h" 55#include "content/renderer/dom_storage/webstoragearea_impl.h" 56#include "content/renderer/dom_storage/webstoragenamespace_impl.h" 57#include "content/renderer/gpu/compositor_output_surface.h" 58#include "content/renderer/gpu/gpu_benchmarking_extension.h" 59#include "content/renderer/gpu/input_handler_manager.h" 60#include "content/renderer/media/audio_input_message_filter.h" 61#include "content/renderer/media/audio_message_filter.h" 62#include "content/renderer/media/audio_renderer_mixer_manager.h" 63#include "content/renderer/media/media_stream_center.h" 64#include "content/renderer/media/media_stream_dependency_factory.h" 65#include "content/renderer/media/peer_connection_tracker.h" 66#include "content/renderer/media/video_capture_impl_manager.h" 67#include "content/renderer/media/video_capture_message_filter.h" 68#include "content/renderer/media/webrtc_logging_message_filter.h" 69#include "content/renderer/memory_benchmarking_extension.h" 70#include "content/renderer/p2p/socket_dispatcher.h" 71#include "content/renderer/plugin_channel_host.h" 72#include "content/renderer/render_process_impl.h" 73#include "content/renderer/render_view_impl.h" 74#include "content/renderer/renderer_webkitplatformsupport_impl.h" 75#include "content/renderer/skia_benchmarking_extension.h" 76#include "grit/content_resources.h" 77#include "ipc/ipc_channel_handle.h" 78#include "ipc/ipc_forwarding_message_filter.h" 79#include "ipc/ipc_platform_file.h" 80#include "media/base/audio_hardware_config.h" 81#include "media/base/media.h" 82#include "media/base/media_switches.h" 83#include "net/base/net_errors.h" 84#include "net/base/net_util.h" 85#include "third_party/WebKit/Source/Platform/chromium/public/WebString.h" 86#include "third_party/WebKit/Source/WebKit/chromium/public/WebColorName.h" 87#include "third_party/WebKit/Source/WebKit/chromium/public/WebDatabase.h" 88#include "third_party/WebKit/Source/WebKit/chromium/public/WebDocument.h" 89#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 90#include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" 91#include "third_party/WebKit/Source/WebKit/chromium/public/WebNetworkStateNotifier.h" 92#include "third_party/WebKit/Source/WebKit/chromium/public/WebPopupMenu.h" 93#include "third_party/WebKit/Source/WebKit/chromium/public/WebRuntimeFeatures.h" 94#include "third_party/WebKit/Source/WebKit/chromium/public/WebScriptController.h" 95#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h" 96#include "third_party/WebKit/Source/WebKit/chromium/public/WebSharedWorkerRepository.h" 97#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" 98#include "ui/base/layout.h" 99#include "ui/base/ui_base_switches.h" 100#include "v8/include/v8.h" 101#include "webkit/glue/webkit_glue.h" 102 103#if defined(OS_WIN) 104#include <windows.h> 105#include <objbase.h> 106#include "base/win/scoped_com_initializer.h" 107#else 108// TODO(port) 109#include "base/memory/scoped_handle.h" 110#include "content/common_child/np_channel_base.h" 111#endif 112 113#if defined(OS_POSIX) 114#include "ipc/ipc_channel_posix.h" 115#endif 116 117#if defined(ENABLE_WEBRTC) 118#include "third_party/webrtc/system_wrappers/interface/event_tracer.h" 119#endif 120 121using base::ThreadRestrictions; 122using WebKit::WebDocument; 123using WebKit::WebFrame; 124using WebKit::WebNetworkStateNotifier; 125using WebKit::WebRuntimeFeatures; 126using WebKit::WebScriptController; 127using WebKit::WebSecurityPolicy; 128using WebKit::WebString; 129using WebKit::WebView; 130 131namespace content { 132 133namespace { 134 135const int64 kInitialIdleHandlerDelayMs = 1000; 136const int64 kShortIdleHandlerDelayMs = 1000; 137const int64 kLongIdleHandlerDelayMs = 30*1000; 138const int kIdleCPUUsageThresholdInPercents = 3; 139 140// Keep the global RenderThreadImpl in a TLS slot so it is impossible to access 141// incorrectly from the wrong thread. 142base::LazyInstance<base::ThreadLocalPointer<RenderThreadImpl> > 143 lazy_tls = LAZY_INSTANCE_INITIALIZER; 144 145class RenderViewZoomer : public RenderViewVisitor { 146 public: 147 RenderViewZoomer(const std::string& scheme, 148 const std::string& host, 149 double zoom_level) : scheme_(scheme), 150 host_(host), 151 zoom_level_(zoom_level) { 152 } 153 154 virtual bool Visit(RenderView* render_view) OVERRIDE { 155 WebView* webview = render_view->GetWebView(); 156 WebDocument document = webview->mainFrame()->document(); 157 158 // Don't set zoom level for full-page plugin since they don't use the same 159 // zoom settings. 160 if (document.isPluginDocument()) 161 return true; 162 GURL url(document.url()); 163 // Empty scheme works as wildcard that matches any scheme, 164 if ((net::GetHostOrSpecFromURL(url) == host_) && 165 (scheme_.empty() || scheme_ == url.scheme())) { 166 webview->setZoomLevel(false, zoom_level_); 167 } 168 return true; 169 } 170 171 private: 172 const std::string scheme_; 173 const std::string host_; 174 const double zoom_level_; 175 176 DISALLOW_COPY_AND_ASSIGN(RenderViewZoomer); 177}; 178 179std::string HostToCustomHistogramSuffix(const std::string& host) { 180 if (host == "mail.google.com") 181 return ".gmail"; 182 if (host == "docs.google.com" || host == "drive.google.com") 183 return ".docs"; 184 if (host == "plus.google.com") 185 return ".plus"; 186 return std::string(); 187} 188 189void* CreateHistogram( 190 const char *name, int min, int max, size_t buckets) { 191 if (min <= 0) 192 min = 1; 193 std::string histogram_name; 194 RenderThreadImpl* render_thread_impl = RenderThreadImpl::current(); 195 if (render_thread_impl) { // Can be null in tests. 196 histogram_name = render_thread_impl-> 197 histogram_customizer()->ConvertToCustomHistogramName(name); 198 } else { 199 histogram_name = std::string(name); 200 } 201 base::HistogramBase* histogram = base::Histogram::FactoryGet( 202 histogram_name, min, max, buckets, 203 base::Histogram::kUmaTargetedHistogramFlag); 204 return histogram; 205} 206 207void AddHistogramSample(void* hist, int sample) { 208 base::Histogram* histogram = static_cast<base::Histogram*>(hist); 209 histogram->Add(sample); 210} 211 212#if defined(ENABLE_WEBRTC) 213const unsigned char* GetCategoryGroupEnabled(const char* category_group) { 214 return TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED(category_group); 215} 216 217void AddTraceEvent(char phase, 218 const unsigned char* category_group_enabled, 219 const char* name, 220 unsigned long long id, 221 int num_args, 222 const char** arg_names, 223 const unsigned char* arg_types, 224 const unsigned long long* arg_values, 225 unsigned char flags) { 226 TRACE_EVENT_API_ADD_TRACE_EVENT(phase, category_group_enabled, name, id, 227 num_args, arg_names, arg_types, arg_values, 228 NULL, flags); 229} 230#endif 231 232} // namespace 233 234class RenderThreadImpl::GpuVDAContextLostCallback 235 : public WebKit::WebGraphicsContext3D::WebGraphicsContextLostCallback { 236 public: 237 GpuVDAContextLostCallback() {} 238 virtual ~GpuVDAContextLostCallback() {} 239 virtual void onContextLost() { 240 ChildThread::current()->message_loop()->PostTask(FROM_HERE, base::Bind( 241 &RenderThreadImpl::OnGpuVDAContextLoss)); 242 } 243}; 244 245class RenderThreadImpl::RendererContextProviderCommandBuffer 246 : public ContextProviderCommandBuffer { 247 public: 248 static scoped_refptr<RendererContextProviderCommandBuffer> Create() { 249 scoped_refptr<RendererContextProviderCommandBuffer> provider = 250 new RendererContextProviderCommandBuffer(); 251 if (!provider->InitializeOnMainThread()) 252 return NULL; 253 return provider; 254 } 255 256 protected: 257 virtual ~RendererContextProviderCommandBuffer() {} 258 259 virtual scoped_ptr<WebGraphicsContext3DCommandBufferImpl> 260 CreateOffscreenContext3d() OVERRIDE { 261 RenderThreadImpl* self = RenderThreadImpl::current(); 262 DCHECK(self); 263 return self->CreateOffscreenContext3d().Pass(); 264 } 265}; 266 267RenderThreadImpl::HistogramCustomizer::HistogramCustomizer() { 268 custom_histograms_.insert("V8.MemoryExternalFragmentationTotal"); 269 custom_histograms_.insert("V8.MemoryHeapSampleTotalCommitted"); 270 custom_histograms_.insert("V8.MemoryHeapSampleTotalUsed"); 271} 272 273RenderThreadImpl::HistogramCustomizer::~HistogramCustomizer() {} 274 275void RenderThreadImpl::HistogramCustomizer::RenderViewNavigatedToHost( 276 const std::string& host, size_t view_count) { 277 if (CommandLine::ForCurrentProcess()->HasSwitch( 278 switches::kDisableHistogramCustomizer)) { 279 return; 280 } 281 // Check if all RenderViews are displaying a page from the same host. If there 282 // is only one RenderView, the common host is this view's host. If there are 283 // many, check if this one shares the common host of the other 284 // RenderViews. It's ok to not detect some cases where the RenderViews share a 285 // common host. This information is only used for producing custom histograms. 286 if (view_count == 1) 287 SetCommonHost(host); 288 else if (host != common_host_) 289 SetCommonHost(std::string()); 290} 291 292std::string RenderThreadImpl::HistogramCustomizer::ConvertToCustomHistogramName( 293 const char* histogram_name) const { 294 std::string name(histogram_name); 295 if (!common_host_histogram_suffix_.empty() && 296 custom_histograms_.find(name) != custom_histograms_.end()) 297 name += common_host_histogram_suffix_; 298 return name; 299} 300 301void RenderThreadImpl::HistogramCustomizer::SetCommonHost( 302 const std::string& host) { 303 if (host != common_host_) { 304 common_host_ = host; 305 common_host_histogram_suffix_ = HostToCustomHistogramSuffix(host); 306 v8::V8::SetCreateHistogramFunction(CreateHistogram); 307 } 308} 309 310RenderThreadImpl* RenderThreadImpl::current() { 311 return lazy_tls.Pointer()->Get(); 312} 313 314// When we run plugins in process, we actually run them on the render thread, 315// which means that we need to make the render thread pump UI events. 316RenderThreadImpl::RenderThreadImpl() { 317 Init(); 318} 319 320RenderThreadImpl::RenderThreadImpl(const std::string& channel_name) 321 : ChildThread(channel_name) { 322 Init(); 323} 324 325void RenderThreadImpl::Init() { 326 TRACE_EVENT_BEGIN_ETW("RenderThreadImpl::Init", 0, ""); 327 328 v8::V8::SetCounterFunction(base::StatsTable::FindLocation); 329 v8::V8::SetCreateHistogramFunction(CreateHistogram); 330 v8::V8::SetAddHistogramSampleFunction(AddHistogramSample); 331 332#if defined(OS_MACOSX) || defined(OS_ANDROID) 333 // On Mac and Android, the select popups are rendered by the browser. 334 WebKit::WebView::setUseExternalPopupMenus(true); 335#endif 336 337 lazy_tls.Pointer()->Set(this); 338 339#if defined(OS_WIN) 340 // If you are running plugins in this thread you need COM active but in 341 // the normal case you don't. 342 if (RenderProcessImpl::InProcessPlugins()) 343 initialize_com_.reset(new base::win::ScopedCOMInitializer()); 344#endif 345 346 // Register this object as the main thread. 347 ChildProcess::current()->set_main_thread(this); 348 349 // In single process the single process is all there is. 350 suspend_webkit_shared_timer_ = true; 351 notify_webkit_of_modal_loop_ = true; 352 widget_count_ = 0; 353 hidden_widget_count_ = 0; 354 idle_notification_delay_in_ms_ = kInitialIdleHandlerDelayMs; 355 idle_notifications_to_skip_ = 0; 356 should_send_focus_ipcs_ = true; 357 short_circuit_size_updates_ = false; 358 skip_error_pages_ = false; 359 360 appcache_dispatcher_.reset(new AppCacheDispatcher(Get())); 361 dom_storage_dispatcher_.reset(new DomStorageDispatcher()); 362 main_thread_indexed_db_dispatcher_.reset(new IndexedDBDispatcher()); 363 364 media_stream_center_ = NULL; 365 366 db_message_filter_ = new DBMessageFilter(); 367 AddFilter(db_message_filter_.get()); 368 369#if defined(ENABLE_WEBRTC) 370 webrtc::SetupEventTracer(&GetCategoryGroupEnabled, &AddTraceEvent); 371 372 peer_connection_tracker_.reset(new PeerConnectionTracker()); 373 AddObserver(peer_connection_tracker_.get()); 374 375 p2p_socket_dispatcher_ = new P2PSocketDispatcher(GetIOMessageLoopProxy()); 376 AddFilter(p2p_socket_dispatcher_); 377#endif // defined(ENABLE_WEBRTC) 378 vc_manager_ = new VideoCaptureImplManager(); 379 AddFilter(vc_manager_->video_capture_message_filter()); 380 381 audio_input_message_filter_ = 382 new AudioInputMessageFilter(GetIOMessageLoopProxy()); 383 AddFilter(audio_input_message_filter_.get()); 384 385 audio_message_filter_ = new AudioMessageFilter(GetIOMessageLoopProxy()); 386 AddFilter(audio_message_filter_.get()); 387 388 AddFilter(new IndexedDBMessageFilter); 389 390#if defined(ENABLE_WEBRTC) 391 webrtc_logging_message_filter_ = 392 new WebRtcLoggingMessageFilter(GetIOMessageLoopProxy()); 393 AddFilter(webrtc_logging_message_filter_.get()); 394#endif 395 396 GetContentClient()->renderer()->RenderThreadStarted(); 397 398 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 399 if (command_line.HasSwitch(switches::kEnableGpuBenchmarking)) 400 RegisterExtension(GpuBenchmarkingExtension::Get()); 401 402#if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) 403 if (command_line.HasSwitch(switches::kEnableMemoryBenchmarking)) 404 RegisterExtension(MemoryBenchmarkingExtension::Get()); 405#endif // USE_TCMALLOC 406 407 if (command_line.HasSwitch(switches::kEnableSkiaBenchmarking)) { 408 LOG(WARNING) << "Enabling unsafe Skia benchmarking extension."; 409 RegisterExtension(SkiaBenchmarkingExtension::Get()); 410 } 411 412 context_lost_cb_.reset(new GpuVDAContextLostCallback()); 413 414 // Note that under Linux, the media library will normally already have 415 // been initialized by the Zygote before this instance became a Renderer. 416 base::FilePath media_path; 417 PathService::Get(DIR_MEDIA_LIBS, &media_path); 418 if (!media_path.empty()) 419 media::InitializeMediaLibrary(media_path); 420 421 TRACE_EVENT_END_ETW("RenderThreadImpl::Init", 0, ""); 422} 423 424RenderThreadImpl::~RenderThreadImpl() { 425} 426 427void RenderThreadImpl::Shutdown() { 428 FOR_EACH_OBSERVER( 429 RenderProcessObserver, observers_, OnRenderProcessShutdown()); 430 431 // Wait for all databases to be closed. 432 if (web_database_observer_impl_) 433 web_database_observer_impl_->WaitForAllDatabasesToClose(); 434 435 // Shutdown in reverse of the initialization order. 436 if (devtools_agent_message_filter_) { 437 RemoveFilter(devtools_agent_message_filter_.get()); 438 devtools_agent_message_filter_ = NULL; 439 } 440 441 RemoveFilter(audio_input_message_filter_.get()); 442 audio_input_message_filter_ = NULL; 443 444 RemoveFilter(audio_message_filter_.get()); 445 audio_message_filter_ = NULL; 446 447 RemoveFilter(vc_manager_->video_capture_message_filter()); 448 449 RemoveFilter(db_message_filter_.get()); 450 db_message_filter_ = NULL; 451 452 // Shutdown the file thread if it's running. 453 if (file_thread_) 454 file_thread_->Stop(); 455 456 if (compositor_output_surface_filter_) { 457 RemoveFilter(compositor_output_surface_filter_.get()); 458 compositor_output_surface_filter_ = NULL; 459 } 460 461 compositor_thread_.reset(); 462 if (input_handler_manager_) { 463 RemoveFilter(input_handler_manager_->GetMessageFilter()); 464 input_handler_manager_.reset(); 465 } 466 467 if (webkit_platform_support_) 468 WebKit::shutdown(); 469 470 lazy_tls.Pointer()->Set(NULL); 471 472 // TODO(port) 473#if defined(OS_WIN) 474 // Clean up plugin channels before this thread goes away. 475 NPChannelBase::CleanupChannels(); 476#endif 477 478 // Leak shared contexts on other threads, as we can not get to the correct 479 // thread to destroy them. 480 if (shared_contexts_compositor_thread_) 481 shared_contexts_compositor_thread_->set_leak_on_destroy(); 482} 483 484bool RenderThreadImpl::Send(IPC::Message* msg) { 485 // Certain synchronous messages cannot always be processed synchronously by 486 // the browser, e.g., Chrome frame communicating with the embedding browser. 487 // This could cause a complete hang of Chrome if a windowed plug-in is trying 488 // to communicate with the renderer thread since the browser's UI thread 489 // could be stuck (within a Windows API call) trying to synchronously 490 // communicate with the plug-in. The remedy is to pump messages on this 491 // thread while the browser is processing this request. This creates an 492 // opportunity for re-entrancy into WebKit, so we need to take care to disable 493 // callbacks, timers, and pending network loads that could trigger such 494 // callbacks. 495 bool pumping_events = false; 496 if (msg->is_sync()) { 497 if (msg->is_caller_pumping_messages()) { 498 pumping_events = true; 499 } else { 500 if ((msg->type() == ViewHostMsg_GetCookies::ID || 501 msg->type() == ViewHostMsg_GetRawCookies::ID || 502 msg->type() == ViewHostMsg_CookiesEnabled::ID) && 503 GetContentClient()->renderer()-> 504 ShouldPumpEventsDuringCookieMessage()) { 505 pumping_events = true; 506 } 507 } 508 } 509 510 bool suspend_webkit_shared_timer = true; // default value 511 std::swap(suspend_webkit_shared_timer, suspend_webkit_shared_timer_); 512 513 bool notify_webkit_of_modal_loop = true; // default value 514 std::swap(notify_webkit_of_modal_loop, notify_webkit_of_modal_loop_); 515 516 int render_view_id = MSG_ROUTING_NONE; 517 518 if (pumping_events) { 519 if (suspend_webkit_shared_timer) 520 webkit_platform_support_->SuspendSharedTimer(); 521 522 if (notify_webkit_of_modal_loop) 523 WebView::willEnterModalLoop(); 524 525 RenderViewImpl* render_view = 526 RenderViewImpl::FromRoutingID(msg->routing_id()); 527 if (render_view) { 528 render_view_id = msg->routing_id(); 529 PluginChannelHost::Broadcast( 530 new PluginMsg_SignalModalDialogEvent(render_view_id)); 531 } 532 } 533 534 bool rv = ChildThread::Send(msg); 535 536 if (pumping_events) { 537 if (render_view_id != MSG_ROUTING_NONE) { 538 PluginChannelHost::Broadcast( 539 new PluginMsg_ResetModalDialogEvent(render_view_id)); 540 } 541 542 if (notify_webkit_of_modal_loop) 543 WebView::didExitModalLoop(); 544 545 if (suspend_webkit_shared_timer) 546 webkit_platform_support_->ResumeSharedTimer(); 547 } 548 549 return rv; 550} 551 552MessageLoop* RenderThreadImpl::GetMessageLoop() { 553 return message_loop(); 554} 555 556IPC::SyncChannel* RenderThreadImpl::GetChannel() { 557 return channel(); 558} 559 560std::string RenderThreadImpl::GetLocale() { 561 // The browser process should have passed the locale to the renderer via the 562 // --lang command line flag. 563 const CommandLine& parsed_command_line = *CommandLine::ForCurrentProcess(); 564 const std::string& lang = 565 parsed_command_line.GetSwitchValueASCII(switches::kLang); 566 DCHECK(!lang.empty()); 567 return lang; 568} 569 570IPC::SyncMessageFilter* RenderThreadImpl::GetSyncMessageFilter() { 571 return sync_message_filter(); 572} 573 574scoped_refptr<base::MessageLoopProxy> 575 RenderThreadImpl::GetIOMessageLoopProxy() { 576 return ChildProcess::current()->io_message_loop_proxy(); 577} 578 579void RenderThreadImpl::AddRoute(int32 routing_id, IPC::Listener* listener) { 580 widget_count_++; 581 return ChildThread::AddRoute(routing_id, listener); 582} 583 584void RenderThreadImpl::RemoveRoute(int32 routing_id) { 585 widget_count_--; 586 return ChildThread::RemoveRoute(routing_id); 587} 588 589int RenderThreadImpl::GenerateRoutingID() { 590 int routing_id = MSG_ROUTING_NONE; 591 Send(new ViewHostMsg_GenerateRoutingID(&routing_id)); 592 return routing_id; 593} 594 595void RenderThreadImpl::AddFilter(IPC::ChannelProxy::MessageFilter* filter) { 596 channel()->AddFilter(filter); 597} 598 599void RenderThreadImpl::RemoveFilter(IPC::ChannelProxy::MessageFilter* filter) { 600 channel()->RemoveFilter(filter); 601} 602 603void RenderThreadImpl::SetOutgoingMessageFilter( 604 IPC::ChannelProxy::OutgoingMessageFilter* filter) { 605} 606 607void RenderThreadImpl::AddObserver(RenderProcessObserver* observer) { 608 observers_.AddObserver(observer); 609} 610 611void RenderThreadImpl::RemoveObserver(RenderProcessObserver* observer) { 612 observers_.RemoveObserver(observer); 613} 614 615void RenderThreadImpl::SetResourceDispatcherDelegate( 616 ResourceDispatcherDelegate* delegate) { 617 resource_dispatcher()->set_delegate(delegate); 618} 619 620void RenderThreadImpl::WidgetHidden() { 621 DCHECK(hidden_widget_count_ < widget_count_); 622 hidden_widget_count_++; 623 624 if (!GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden()) { 625 return; 626 } 627 628 if (widget_count_ && hidden_widget_count_ == widget_count_) 629 ScheduleIdleHandler(kInitialIdleHandlerDelayMs); 630} 631 632void RenderThreadImpl::WidgetRestored() { 633 DCHECK_GT(hidden_widget_count_, 0); 634 hidden_widget_count_--; 635 if (!GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden()) { 636 return; 637 } 638 639 ScheduleIdleHandler(kLongIdleHandlerDelayMs); 640} 641 642static void AdjustRuntimeFeatureDefaultsForPlatform() { 643#if defined(OS_ANDROID) && !defined(GOOGLE_TV) 644 WebRuntimeFeatures::enableWebKitMediaSource(false); 645#endif 646 647#if defined(OS_ANDROID) 648 WebRuntimeFeatures::enableWebAudio(false); 649 // Web Speech API Speech recognition is not implemented on Android yet. 650 WebRuntimeFeatures::enableScriptedSpeech(false); 651 // Android does not support the Gamepad API. 652 WebRuntimeFeatures::enableGamepad(false); 653 // input[type=week] in Android is incomplete. crbug.com/135938 654 WebRuntimeFeatures::enableInputTypeWeek(false); 655 // Android does not have support for PagePopup 656 WebRuntimeFeatures::enablePagePopup(false); 657 // datalist on Android is not enabled 658 WebRuntimeFeatures::enableDataListElement(false); 659#endif 660} 661 662static void AdjustRuntimeFeaturesFromArgs(const CommandLine& command_line) { 663 if (command_line.HasSwitch(switches::kDisableDatabases)) 664 WebRuntimeFeatures::enableDatabase(false); 665 666 if (command_line.HasSwitch(switches::kDisableApplicationCache)) 667 WebRuntimeFeatures::enableApplicationCache(false); 668 669 if (command_line.HasSwitch(switches::kDisableDesktopNotifications)) 670 WebRuntimeFeatures::enableNotifications(false); 671 672 if (command_line.HasSwitch(switches::kDisableLocalStorage)) 673 WebRuntimeFeatures::enableLocalStorage(false); 674 675 if (command_line.HasSwitch(switches::kDisableSessionStorage)) 676 WebRuntimeFeatures::enableSessionStorage(false); 677 678 if (command_line.HasSwitch(switches::kDisableGeolocation)) 679 WebRuntimeFeatures::enableGeolocation(false); 680 681#if !defined(OS_ANDROID) || defined(GOOGLE_TV) 682 if (command_line.HasSwitch(switches::kDisableWebKitMediaSource)) 683 WebRuntimeFeatures::enableWebKitMediaSource(false); 684#endif 685 686#if defined(OS_ANDROID) 687 if (command_line.HasSwitch(switches::kDisableWebRTC)) 688 WebRuntimeFeatures::enableMediaStream(false); 689#endif 690 691#if defined(OS_ANDROID) 692 if (command_line.HasSwitch(switches::kDisableWebRTC)) 693 WebRuntimeFeatures::enablePeerConnection(false); 694#endif 695 696 if (command_line.HasSwitch(switches::kDisableFullScreen)) 697 WebRuntimeFeatures::enableFullscreen(false); 698 699 if (command_line.HasSwitch(switches::kDisableEncryptedMedia)) 700 WebRuntimeFeatures::enableEncryptedMedia(false); 701 702#if defined(OS_ANDROID) 703 if (command_line.HasSwitch(switches::kEnableWebAudio)) 704 WebRuntimeFeatures::enableWebAudio(true); 705#else 706 if (command_line.HasSwitch(switches::kDisableWebAudio)) 707 WebRuntimeFeatures::enableWebAudio(false); 708#endif 709 710 if (command_line.HasSwitch(switches::kEnableWebMIDI)) 711 WebRuntimeFeatures::enableWebMIDI(true); 712 713 if (command_line.HasSwitch(switches::kEnableDeviceMotion)) 714 WebRuntimeFeatures::enableDeviceMotion(true); 715 716 if (command_line.HasSwitch(switches::kDisableDeviceOrientation)) 717 WebRuntimeFeatures::enableDeviceOrientation(false); 718 719 if (command_line.HasSwitch(switches::kDisableSpeechInput)) 720 WebRuntimeFeatures::enableSpeechInput(false); 721 722 if (command_line.HasSwitch(switches::kDisableFileSystem)) 723 WebRuntimeFeatures::enableFileSystem(false); 724 725 if (command_line.HasSwitch(switches::kDisableJavaScriptI18NAPI)) 726 WebRuntimeFeatures::enableJavaScriptI18NAPI(false); 727 728 if (command_line.HasSwitch(switches::kEnableExperimentalCanvasFeatures)) 729 WebRuntimeFeatures::enableExperimentalCanvasFeatures(true); 730 731 if (command_line.HasSwitch(switches::kEnableSpeechSynthesis)) 732 WebRuntimeFeatures::enableSpeechSynthesis(true); 733} 734 735void RenderThreadImpl::EnsureWebKitInitialized() { 736 if (webkit_platform_support_) 737 return; 738 739 webkit_platform_support_.reset(new RendererWebKitPlatformSupportImpl); 740 WebKit::initialize(webkit_platform_support_.get()); 741 WebKit::setSharedWorkerRepository( 742 webkit_platform_support_.get()->sharedWorkerRepository()); 743 WebKit::setIDBFactory( 744 webkit_platform_support_.get()->idbFactory()); 745 746 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 747 748 bool enable = command_line.HasSwitch(switches::kEnableThreadedCompositing); 749 if (enable) { 750 base::MessageLoop* override_loop = 751 GetContentClient()->renderer()->OverrideCompositorMessageLoop(); 752 if (override_loop) { 753 compositor_message_loop_proxy_ = override_loop->message_loop_proxy(); 754 } else { 755 compositor_thread_.reset(new base::Thread("Compositor")); 756 compositor_thread_->Start(); 757#if defined(OS_ANDROID) 758 compositor_thread_->SetPriority(base::kThreadPriority_Display); 759#endif 760 compositor_message_loop_proxy_ = 761 compositor_thread_->message_loop_proxy(); 762 compositor_message_loop_proxy_->PostTask( 763 FROM_HERE, 764 base::Bind(base::IgnoreResult(&ThreadRestrictions::SetIOAllowed), 765 false)); 766 } 767 768 if (GetContentClient()->renderer()->ShouldCreateCompositorInputHandler()) { 769 input_handler_manager_.reset( 770 new InputHandlerManager(this, compositor_message_loop_proxy_)); 771 AddFilter(input_handler_manager_->GetMessageFilter()); 772 } 773 } 774 775 scoped_refptr<base::MessageLoopProxy> output_surface_loop; 776 if (enable) 777 output_surface_loop = compositor_message_loop_proxy_; 778 else 779 output_surface_loop = base::MessageLoopProxy::current(); 780 781 compositor_output_surface_filter_ = 782 CompositorOutputSurface::CreateFilter(output_surface_loop); 783 AddFilter(compositor_output_surface_filter_.get()); 784 785 WebScriptController::enableV8SingleThreadMode(); 786 787 RenderThreadImpl::RegisterSchemes(); 788 789 webkit_glue::EnableWebCoreLogChannels( 790 command_line.GetSwitchValueASCII(switches::kWebCoreLogChannels)); 791 792 web_database_observer_impl_.reset( 793 new WebDatabaseObserverImpl(sync_message_filter())); 794 WebKit::WebDatabase::setObserver(web_database_observer_impl_.get()); 795 796 WebRuntimeFeatures::enableStableFeatures(true); 797 798 if (command_line.HasSwitch(switches::kEnableExperimentalWebKitFeatures)) 799 WebRuntimeFeatures::enableExperimentalFeatures(true); 800 801 AdjustRuntimeFeatureDefaultsForPlatform(); 802 AdjustRuntimeFeaturesFromArgs(command_line); 803 804 // Enabled by default for testing. 805 // TODO(urvang): Go back to using the command-line option after a few days. 806 // https://code.google.com/p/chromium/issues/detail?id=234437 807 WebRuntimeFeatures::enableWebPInAcceptHeader(true); 808 809 if (!media::IsMediaLibraryInitialized()) { 810 WebRuntimeFeatures::enableMediaPlayer(false); 811 WebRuntimeFeatures::enableWebAudio(false); 812 } 813 814 FOR_EACH_OBSERVER(RenderProcessObserver, observers_, WebKitInitialized()); 815 816 devtools_agent_message_filter_ = new DevToolsAgentFilter(); 817 AddFilter(devtools_agent_message_filter_.get()); 818 819 if (GetContentClient()->renderer()->RunIdleHandlerWhenWidgetsHidden()) 820 ScheduleIdleHandler(kLongIdleHandlerDelayMs); 821} 822 823void RenderThreadImpl::RegisterSchemes() { 824 // swappedout: pages should not be accessible, and should also 825 // be treated as empty documents that can commit synchronously. 826 WebString swappedout_scheme(ASCIIToUTF16(chrome::kSwappedOutScheme)); 827 WebSecurityPolicy::registerURLSchemeAsDisplayIsolated(swappedout_scheme); 828 WebSecurityPolicy::registerURLSchemeAsEmptyDocument(swappedout_scheme); 829} 830 831void RenderThreadImpl::RecordUserMetrics(const std::string& action) { 832 Send(new ViewHostMsg_UserMetricsRecordAction(action)); 833} 834 835scoped_ptr<base::SharedMemory> 836 RenderThreadImpl::HostAllocateSharedMemoryBuffer(size_t size) { 837 if (size > static_cast<size_t>(std::numeric_limits<int>::max())) 838 return scoped_ptr<base::SharedMemory>(); 839 840 base::SharedMemoryHandle handle; 841 bool success; 842 IPC::Message* message = 843 new ChildProcessHostMsg_SyncAllocateSharedMemory(size, &handle); 844 845 // Allow calling this from the compositor thread. 846 if (base::MessageLoop::current() == message_loop()) 847 success = ChildThread::Send(message); 848 else 849 success = sync_message_filter()->Send(message); 850 851 if (!success) 852 return scoped_ptr<base::SharedMemory>(); 853 854 if (!base::SharedMemory::IsHandleValid(handle)) 855 return scoped_ptr<base::SharedMemory>(); 856 857 return scoped_ptr<base::SharedMemory>(new base::SharedMemory(handle, false)); 858} 859 860void RenderThreadImpl::RegisterExtension(v8::Extension* extension) { 861 WebScriptController::registerExtension(extension); 862} 863 864void RenderThreadImpl::ScheduleIdleHandler(int64 initial_delay_ms) { 865 idle_notification_delay_in_ms_ = initial_delay_ms; 866 idle_timer_.Stop(); 867 idle_timer_.Start(FROM_HERE, 868 base::TimeDelta::FromMilliseconds(initial_delay_ms), 869 this, &RenderThreadImpl::IdleHandler); 870} 871 872void RenderThreadImpl::IdleHandler() { 873 bool run_in_foreground_tab = (widget_count_ > hidden_widget_count_) && 874 GetContentClient()->renderer()-> 875 RunIdleHandlerWhenWidgetsHidden(); 876 if (run_in_foreground_tab) { 877 IdleHandlerInForegroundTab(); 878 return; 879 } 880 881 base::allocator::ReleaseFreeMemory(); 882 883 v8::V8::IdleNotification(); 884 885 // Schedule next invocation. 886 // Dampen the delay using the algorithm (if delay is in seconds): 887 // delay = delay + 1 / (delay + 2) 888 // Using floor(delay) has a dampening effect such as: 889 // 1s, 1, 1, 2, 2, 2, 2, 3, 3, ... 890 // If the delay is in milliseconds, the above formula is equivalent to: 891 // delay_ms / 1000 = delay_ms / 1000 + 1 / (delay_ms / 1000 + 2) 892 // which is equivalent to 893 // delay_ms = delay_ms + 1000*1000 / (delay_ms + 2000). 894 // Note that idle_notification_delay_in_ms_ would be reset to 895 // kInitialIdleHandlerDelayMs in RenderThreadImpl::WidgetHidden. 896 ScheduleIdleHandler(idle_notification_delay_in_ms_ + 897 1000000 / (idle_notification_delay_in_ms_ + 2000)); 898 899 FOR_EACH_OBSERVER(RenderProcessObserver, observers_, IdleNotification()); 900} 901 902void RenderThreadImpl::IdleHandlerInForegroundTab() { 903 // Increase the delay in the same way as in IdleHandler, 904 // but make it periodic by reseting it once it is too big. 905 int64 new_delay_ms = idle_notification_delay_in_ms_ + 906 1000000 / (idle_notification_delay_in_ms_ + 2000); 907 if (new_delay_ms >= kLongIdleHandlerDelayMs) 908 new_delay_ms = kShortIdleHandlerDelayMs; 909 910 if (idle_notifications_to_skip_ > 0) { 911 idle_notifications_to_skip_--; 912 } else { 913 int cpu_usage = 0; 914 Send(new ViewHostMsg_GetCPUUsage(&cpu_usage)); 915 // Idle notification hint roughly specifies the expected duration of the 916 // idle pause. We set it proportional to the idle timer delay. 917 int idle_hint = static_cast<int>(new_delay_ms / 10); 918 if (cpu_usage < kIdleCPUUsageThresholdInPercents) { 919 base::allocator::ReleaseFreeMemory(); 920 if (v8::V8::IdleNotification(idle_hint)) { 921 // V8 finished collecting garbage. 922 new_delay_ms = kLongIdleHandlerDelayMs; 923 } 924 } 925 } 926 ScheduleIdleHandler(new_delay_ms); 927} 928 929int64 RenderThreadImpl::GetIdleNotificationDelayInMs() const { 930 return idle_notification_delay_in_ms_; 931} 932 933void RenderThreadImpl::SetIdleNotificationDelayInMs( 934 int64 idle_notification_delay_in_ms) { 935 idle_notification_delay_in_ms_ = idle_notification_delay_in_ms; 936} 937 938void RenderThreadImpl::ToggleWebKitSharedTimer(bool suspend) { 939 if (suspend_webkit_shared_timer_) { 940 EnsureWebKitInitialized(); 941 if (suspend) { 942 webkit_platform_support_->SuspendSharedTimer(); 943 } else { 944 webkit_platform_support_->ResumeSharedTimer(); 945 } 946 } 947} 948 949void RenderThreadImpl::UpdateHistograms(int sequence_number) { 950 child_histogram_message_filter()->SendHistograms(sequence_number); 951} 952 953bool RenderThreadImpl::ResolveProxy(const GURL& url, std::string* proxy_list) { 954 bool result = false; 955 Send(new ViewHostMsg_ResolveProxy(url, &result, proxy_list)); 956 return result; 957} 958 959void RenderThreadImpl::PostponeIdleNotification() { 960 idle_notifications_to_skip_ = 2; 961} 962 963/* static */ 964void RenderThreadImpl::OnGpuVDAContextLoss() { 965 RenderThreadImpl* self = RenderThreadImpl::current(); 966 DCHECK(self); 967 if (!self->gpu_vda_context3d_) 968 return; 969 if (self->compositor_message_loop_proxy()) { 970 self->compositor_message_loop_proxy()->DeleteSoon( 971 FROM_HERE, self->gpu_vda_context3d_.release()); 972 } else { 973 self->gpu_vda_context3d_.reset(); 974 } 975} 976 977WebGraphicsContext3DCommandBufferImpl* 978RenderThreadImpl::GetGpuVDAContext3D() { 979 if (!gpu_vda_context3d_) { 980 gpu_vda_context3d_.reset( 981 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext( 982 this, WebKit::WebGraphicsContext3D::Attributes(), 983 GURL("chrome://gpu/RenderThreadImpl::GetGpuVDAContext3D"))); 984 if (gpu_vda_context3d_) 985 gpu_vda_context3d_->setContextLostCallback(context_lost_cb_.get()); 986 } 987 return gpu_vda_context3d_.get(); 988} 989 990scoped_ptr<WebGraphicsContext3DCommandBufferImpl> 991RenderThreadImpl::CreateOffscreenContext3d() { 992 WebKit::WebGraphicsContext3D::Attributes attributes; 993 attributes.shareResources = true; 994 attributes.depth = false; 995 attributes.stencil = false; 996 attributes.antialias = false; 997 attributes.noAutomaticFlushes = true; 998 999 return make_scoped_ptr( 1000 WebGraphicsContext3DCommandBufferImpl::CreateOffscreenContext( 1001 this, 1002 attributes, 1003 GURL("chrome://gpu/RenderThreadImpl::CreateOffscreenContext3d"))); 1004} 1005 1006scoped_refptr<ContextProviderCommandBuffer> 1007RenderThreadImpl::OffscreenContextProviderForMainThread() { 1008 DCHECK(IsMainThread()); 1009 1010 if (!shared_contexts_main_thread_ || 1011 shared_contexts_main_thread_->DestroyedOnMainThread()) { 1012 shared_contexts_main_thread_ = 1013 RendererContextProviderCommandBuffer::Create(); 1014 if (shared_contexts_main_thread_ && 1015 !shared_contexts_main_thread_->BindToCurrentThread()) 1016 shared_contexts_main_thread_ = NULL; 1017 } 1018 return shared_contexts_main_thread_; 1019} 1020 1021scoped_refptr<ContextProviderCommandBuffer> 1022RenderThreadImpl::OffscreenContextProviderForCompositorThread() { 1023 DCHECK(IsMainThread()); 1024 1025 if (!shared_contexts_compositor_thread_ || 1026 shared_contexts_compositor_thread_->DestroyedOnMainThread()) { 1027 shared_contexts_compositor_thread_ = 1028 RendererContextProviderCommandBuffer::Create(); 1029 } 1030 return shared_contexts_compositor_thread_; 1031} 1032 1033AudioRendererMixerManager* RenderThreadImpl::GetAudioRendererMixerManager() { 1034 if (!audio_renderer_mixer_manager_) { 1035 audio_renderer_mixer_manager_.reset(new AudioRendererMixerManager( 1036 GetAudioHardwareConfig())); 1037 } 1038 1039 return audio_renderer_mixer_manager_.get(); 1040} 1041 1042media::AudioHardwareConfig* RenderThreadImpl::GetAudioHardwareConfig() { 1043 if (!audio_hardware_config_) { 1044 media::AudioParameters input_params; 1045 media::AudioParameters output_params; 1046 Send(new ViewHostMsg_GetAudioHardwareConfig( 1047 &input_params, &output_params)); 1048 1049 audio_hardware_config_.reset(new media::AudioHardwareConfig( 1050 input_params, output_params)); 1051 audio_message_filter_->SetAudioHardwareConfig(audio_hardware_config_.get()); 1052 } 1053 1054 return audio_hardware_config_.get(); 1055} 1056 1057#if defined(OS_WIN) 1058void RenderThreadImpl::PreCacheFontCharacters(const LOGFONT& log_font, 1059 const string16& str) { 1060 Send(new ViewHostMsg_PreCacheFontCharacters(log_font, str)); 1061} 1062 1063void RenderThreadImpl::PreCacheFont(const LOGFONT& log_font) { 1064 Send(new ChildProcessHostMsg_PreCacheFont(log_font)); 1065} 1066 1067void RenderThreadImpl::ReleaseCachedFonts() { 1068 Send(new ChildProcessHostMsg_ReleaseCachedFonts()); 1069} 1070 1071#endif // OS_WIN 1072 1073bool RenderThreadImpl::IsWebFrameValid(WebKit::WebFrame* web_frame) { 1074 if (!web_frame) 1075 return false; // We must be shutting down. 1076 1077 RenderViewImpl* render_view = RenderViewImpl::FromWebView(web_frame->view()); 1078 if (!render_view) 1079 return false; // We must be shutting down. 1080 1081 return true; 1082} 1083 1084bool RenderThreadImpl::IsMainThread() { 1085 return !!current(); 1086} 1087 1088bool RenderThreadImpl::IsIOThread() { 1089 return base::MessageLoop::current() == 1090 ChildProcess::current()->io_message_loop(); 1091} 1092 1093MessageLoop* RenderThreadImpl::GetMainLoop() { 1094 return message_loop(); 1095} 1096 1097scoped_refptr<base::MessageLoopProxy> RenderThreadImpl::GetIOLoopProxy() { 1098 return ChildProcess::current()->io_message_loop_proxy(); 1099} 1100 1101base::WaitableEvent* RenderThreadImpl::GetShutDownEvent() { 1102 return ChildProcess::current()->GetShutDownEvent(); 1103} 1104 1105scoped_ptr<base::SharedMemory> RenderThreadImpl::AllocateSharedMemory( 1106 size_t size) { 1107 return scoped_ptr<base::SharedMemory>( 1108 HostAllocateSharedMemoryBuffer(size)); 1109} 1110 1111int32 RenderThreadImpl::CreateViewCommandBuffer( 1112 int32 surface_id, const GPUCreateCommandBufferConfig& init_params) { 1113 TRACE_EVENT1("gpu", 1114 "RenderThreadImpl::CreateViewCommandBuffer", 1115 "surface_id", 1116 surface_id); 1117 1118 int32 route_id = MSG_ROUTING_NONE; 1119 IPC::Message* message = new GpuHostMsg_CreateViewCommandBuffer( 1120 surface_id, 1121 init_params, 1122 &route_id); 1123 1124 // Allow calling this from the compositor thread. 1125 if (base::MessageLoop::current() == message_loop()) 1126 ChildThread::Send(message); 1127 else 1128 sync_message_filter()->Send(message); 1129 1130 return route_id; 1131} 1132 1133void RenderThreadImpl::CreateImage( 1134 gfx::PluginWindowHandle window, 1135 int32 image_id, 1136 const CreateImageCallback& callback) { 1137 NOTREACHED(); 1138} 1139 1140void RenderThreadImpl::DeleteImage(int32 image_id, int32 sync_point) { 1141 NOTREACHED(); 1142} 1143 1144void RenderThreadImpl::DoNotSuspendWebKitSharedTimer() { 1145 suspend_webkit_shared_timer_ = false; 1146} 1147 1148void RenderThreadImpl::DoNotNotifyWebKitOfModalLoop() { 1149 notify_webkit_of_modal_loop_ = false; 1150} 1151 1152void RenderThreadImpl::OnSetZoomLevelForCurrentURL(const std::string& scheme, 1153 const std::string& host, 1154 double zoom_level) { 1155 RenderViewZoomer zoomer(scheme, host, zoom_level); 1156 RenderView::ForEach(&zoomer); 1157} 1158 1159bool RenderThreadImpl::OnControlMessageReceived(const IPC::Message& msg) { 1160 ObserverListBase<RenderProcessObserver>::Iterator it(observers_); 1161 RenderProcessObserver* observer; 1162 while ((observer = it.GetNext()) != NULL) { 1163 if (observer->OnControlMessageReceived(msg)) 1164 return true; 1165 } 1166 1167 // Some messages are handled by delegates. 1168 if (appcache_dispatcher_->OnMessageReceived(msg) || 1169 dom_storage_dispatcher_->OnMessageReceived(msg)) { 1170 return true; 1171 } 1172 1173 bool handled = true; 1174 IPC_BEGIN_MESSAGE_MAP(RenderThreadImpl, msg) 1175 IPC_MESSAGE_HANDLER(ViewMsg_SetZoomLevelForCurrentURL, 1176 OnSetZoomLevelForCurrentURL) 1177 // TODO(port): removed from render_messages_internal.h; 1178 // is there a new non-windows message I should add here? 1179 IPC_MESSAGE_HANDLER(ViewMsg_New, OnCreateNewView) 1180 IPC_MESSAGE_HANDLER(ViewMsg_PurgePluginListCache, OnPurgePluginListCache) 1181 IPC_MESSAGE_HANDLER(ViewMsg_NetworkStateChanged, OnNetworkStateChanged) 1182 IPC_MESSAGE_HANDLER(ViewMsg_TempCrashWithData, OnTempCrashWithData) 1183 IPC_MESSAGE_HANDLER(ViewMsg_SetWebKitSharedTimersSuspended, 1184 OnSetWebKitSharedTimersSuspended) 1185 IPC_MESSAGE_UNHANDLED(handled = false) 1186 IPC_END_MESSAGE_MAP() 1187 return handled; 1188} 1189 1190void RenderThreadImpl::OnCreateNewView(const ViewMsg_New_Params& params) { 1191 EnsureWebKitInitialized(); 1192 // When bringing in render_view, also bring in webkit's glue and jsbindings. 1193 RenderViewImpl::Create( 1194 params.opener_route_id, 1195 params.renderer_preferences, 1196 params.web_preferences, 1197 new SharedRenderViewCounter(0), 1198 params.view_id, 1199 params.surface_id, 1200 params.session_storage_namespace_id, 1201 params.frame_name, 1202 false, 1203 params.swapped_out, 1204 params.next_page_id, 1205 params.screen_info, 1206 params.accessibility_mode, 1207 params.allow_partial_swap); 1208} 1209 1210GpuChannelHost* RenderThreadImpl::EstablishGpuChannelSync( 1211 CauseForGpuLaunch cause_for_gpu_launch) { 1212 TRACE_EVENT0("gpu", "RenderThreadImpl::EstablishGpuChannelSync"); 1213 1214 if (gpu_channel_) { 1215 // Do nothing if we already have a GPU channel or are already 1216 // establishing one. 1217 if (gpu_channel_->state() == GpuChannelHost::kUnconnected || 1218 gpu_channel_->state() == GpuChannelHost::kConnected) 1219 return GetGpuChannel(); 1220 1221 // Recreate the channel if it has been lost. 1222 gpu_channel_ = NULL; 1223 } 1224 1225 // Ask the browser for the channel name. 1226 int client_id = 0; 1227 IPC::ChannelHandle channel_handle; 1228 gpu::GPUInfo gpu_info; 1229 if (!Send(new GpuHostMsg_EstablishGpuChannel(cause_for_gpu_launch, 1230 &client_id, 1231 &channel_handle, 1232 &gpu_info)) || 1233#if defined(OS_POSIX) 1234 channel_handle.socket.fd == -1 || 1235#endif 1236 channel_handle.name.empty()) { 1237 // Otherwise cancel the connection. 1238 gpu_channel_ = NULL; 1239 return NULL; 1240 } 1241 1242 gpu_channel_ = new GpuChannelHost(this, 0, client_id); 1243 gpu_channel_->set_gpu_info(gpu_info); 1244 GetContentClient()->SetGpuInfo(gpu_info); 1245 1246 // Connect to the GPU process if a channel name was received. 1247 gpu_channel_->Connect(channel_handle); 1248 1249 return GetGpuChannel(); 1250} 1251 1252WebKit::WebMediaStreamCenter* RenderThreadImpl::CreateMediaStreamCenter( 1253 WebKit::WebMediaStreamCenterClient* client) { 1254#if defined(OS_ANDROID) 1255 if (CommandLine::ForCurrentProcess()->HasSwitch( 1256 switches::kDisableWebRTC)) 1257 return NULL; 1258#endif 1259 1260#if defined(ENABLE_WEBRTC) 1261 if (!media_stream_center_) { 1262 media_stream_center_ = GetContentClient()->renderer() 1263 ->OverrideCreateWebMediaStreamCenter(client); 1264 if (!media_stream_center_) { 1265 media_stream_center_ = new MediaStreamCenter( 1266 client, GetMediaStreamDependencyFactory()); 1267 } 1268 } 1269#endif 1270 return media_stream_center_; 1271} 1272 1273MediaStreamDependencyFactory* 1274RenderThreadImpl::GetMediaStreamDependencyFactory() { 1275#if defined(ENABLE_WEBRTC) 1276 if (!media_stream_factory_) { 1277 media_stream_factory_.reset(new MediaStreamDependencyFactory( 1278 vc_manager_, p2p_socket_dispatcher_)); 1279 } 1280#endif 1281 return media_stream_factory_.get(); 1282} 1283 1284GpuChannelHost* RenderThreadImpl::GetGpuChannel() { 1285 if (!gpu_channel_) 1286 return NULL; 1287 1288 if (gpu_channel_->state() != GpuChannelHost::kConnected) 1289 return NULL; 1290 1291 return gpu_channel_.get(); 1292} 1293 1294void RenderThreadImpl::OnPurgePluginListCache(bool reload_pages) { 1295 EnsureWebKitInitialized(); 1296 // The call below will cause a GetPlugins call with refresh=true, but at this 1297 // point we already know that the browser has refreshed its list, so disable 1298 // refresh temporarily to prevent each renderer process causing the list to be 1299 // regenerated. 1300 webkit_platform_support_->set_plugin_refresh_allowed(false); 1301 WebKit::resetPluginCache(reload_pages); 1302 webkit_platform_support_->set_plugin_refresh_allowed(true); 1303 1304 FOR_EACH_OBSERVER(RenderProcessObserver, observers_, PluginListChanged()); 1305} 1306 1307void RenderThreadImpl::OnNetworkStateChanged(bool online) { 1308 EnsureWebKitInitialized(); 1309 WebNetworkStateNotifier::setOnLine(online); 1310} 1311 1312void RenderThreadImpl::OnTempCrashWithData(const GURL& data) { 1313 GetContentClient()->SetActiveURL(data); 1314 CHECK(false); 1315} 1316 1317void RenderThreadImpl::OnSetWebKitSharedTimersSuspended(bool suspend) { 1318 ToggleWebKitSharedTimer(suspend); 1319} 1320 1321scoped_refptr<base::MessageLoopProxy> 1322RenderThreadImpl::GetFileThreadMessageLoopProxy() { 1323 DCHECK(message_loop() == base::MessageLoop::current()); 1324 if (!file_thread_) { 1325 file_thread_.reset(new base::Thread("Renderer::FILE")); 1326 file_thread_->Start(); 1327 } 1328 return file_thread_->message_loop_proxy(); 1329} 1330 1331void RenderThreadImpl::SetFlingCurveParameters( 1332 const std::vector<float>& new_touchpad, 1333 const std::vector<float>& new_touchscreen) { 1334 webkit_platform_support_->SetFlingCurveParameters(new_touchpad, 1335 new_touchscreen); 1336 1337} 1338 1339} // namespace content 1340