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