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