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