render_process_host_impl.cc revision d0247b1b59f9c528cb6df88b4f2b9afaf80d181e
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// Represents the browser side of the browser <--> renderer communication 6// channel. There will be one RenderProcessHost per renderer process. 7 8#include "content/browser/renderer_host/render_process_host_impl.h" 9 10#include <algorithm> 11#include <limits> 12#include <vector> 13 14#if defined(OS_POSIX) 15#include <utility> // for pair<> 16#endif 17 18#include "base/base_switches.h" 19#include "base/bind.h" 20#include "base/bind_helpers.h" 21#include "base/callback.h" 22#include "base/command_line.h" 23#include "base/debug/trace_event.h" 24#include "base/lazy_instance.h" 25#include "base/logging.h" 26#include "base/metrics/field_trial.h" 27#include "base/metrics/histogram.h" 28#include "base/path_service.h" 29#include "base/platform_file.h" 30#include "base/rand_util.h" 31#include "base/stl_util.h" 32#include "base/strings/string_util.h" 33#include "base/supports_user_data.h" 34#include "base/sys_info.h" 35#include "base/threading/thread.h" 36#include "base/threading/thread_restrictions.h" 37#include "base/tracked_objects.h" 38#include "cc/base/switches.h" 39#include "content/browser/appcache/appcache_dispatcher_host.h" 40#include "content/browser/appcache/chrome_appcache_service.h" 41#include "content/browser/browser_main.h" 42#include "content/browser/browser_main_loop.h" 43#include "content/browser/browser_plugin/browser_plugin_geolocation_permission_context.h" 44#include "content/browser/browser_plugin/browser_plugin_message_filter.h" 45#include "content/browser/child_process_security_policy_impl.h" 46#include "content/browser/device_orientation/device_motion_message_filter.h" 47#include "content/browser/device_orientation/device_orientation_message_filter.h" 48#include "content/browser/device_orientation/orientation_message_filter.h" 49#include "content/browser/dom_storage/dom_storage_context_wrapper.h" 50#include "content/browser/dom_storage/dom_storage_message_filter.h" 51#include "content/browser/download/mhtml_generation_manager.h" 52#include "content/browser/fileapi/chrome_blob_storage_context.h" 53#include "content/browser/fileapi/fileapi_message_filter.h" 54#include "content/browser/geolocation/geolocation_dispatcher_host.h" 55#include "content/browser/gpu/compositor_util.h" 56#include "content/browser/gpu/gpu_data_manager_impl.h" 57#include "content/browser/gpu/gpu_process_host.h" 58#include "content/browser/gpu/shader_disk_cache.h" 59#include "content/browser/histogram_message_filter.h" 60#include "content/browser/indexed_db/indexed_db_context_impl.h" 61#include "content/browser/indexed_db/indexed_db_dispatcher_host.h" 62#include "content/browser/loader/resource_message_filter.h" 63#include "content/browser/loader/resource_scheduler_filter.h" 64#include "content/browser/media/media_internals.h" 65#include "content/browser/mime_registry_message_filter.h" 66#include "content/browser/plugin_service_impl.h" 67#include "content/browser/profiler_message_filter.h" 68#include "content/browser/quota_dispatcher_host.h" 69#include "content/browser/renderer_host/clipboard_message_filter.h" 70#include "content/browser/renderer_host/database_message_filter.h" 71#include "content/browser/renderer_host/file_utilities_message_filter.h" 72#include "content/browser/renderer_host/gamepad_browser_message_filter.h" 73#include "content/browser/renderer_host/gpu_message_filter.h" 74#include "content/browser/renderer_host/media/audio_input_renderer_host.h" 75#include "content/browser/renderer_host/media/audio_mirroring_manager.h" 76#include "content/browser/renderer_host/media/audio_renderer_host.h" 77#include "content/browser/renderer_host/media/device_request_message_filter.h" 78#include "content/browser/renderer_host/media/media_stream_dispatcher_host.h" 79#include "content/browser/renderer_host/media/midi_dispatcher_host.h" 80#include "content/browser/renderer_host/media/midi_host.h" 81#include "content/browser/renderer_host/media/peer_connection_tracker_host.h" 82#include "content/browser/renderer_host/media/video_capture_host.h" 83#include "content/browser/renderer_host/memory_benchmark_message_filter.h" 84#include "content/browser/renderer_host/p2p/socket_dispatcher_host.h" 85#include "content/browser/renderer_host/pepper/pepper_message_filter.h" 86#include "content/browser/renderer_host/pepper/pepper_renderer_connection.h" 87#include "content/browser/renderer_host/render_message_filter.h" 88#include "content/browser/renderer_host/render_view_host_delegate.h" 89#include "content/browser/renderer_host/render_view_host_impl.h" 90#include "content/browser/renderer_host/render_widget_helper.h" 91#include "content/browser/renderer_host/render_widget_host_impl.h" 92#include "content/browser/renderer_host/socket_stream_dispatcher_host.h" 93#include "content/browser/renderer_host/text_input_client_message_filter.h" 94#include "content/browser/resolve_proxy_msg_helper.h" 95#include "content/browser/speech/input_tag_speech_dispatcher_host.h" 96#include "content/browser/speech/speech_recognition_dispatcher_host.h" 97#include "content/browser/storage_partition_impl.h" 98#include "content/browser/streams/stream_context.h" 99#include "content/browser/tracing/trace_message_filter.h" 100#include "content/browser/webui/web_ui_controller_factory_registry.h" 101#include "content/browser/worker_host/worker_message_filter.h" 102#include "content/browser/worker_host/worker_storage_partition.h" 103#include "content/common/child_process_host_impl.h" 104#include "content/common/child_process_messages.h" 105#include "content/common/gpu/gpu_messages.h" 106#include "content/common/resource_messages.h" 107#include "content/common/view_messages.h" 108#include "content/port/browser/render_widget_host_view_frame_subscriber.h" 109#include "content/public/browser/browser_context.h" 110#include "content/public/browser/content_browser_client.h" 111#include "content/public/browser/notification_service.h" 112#include "content/public/browser/notification_types.h" 113#include "content/public/browser/render_process_host_factory.h" 114#include "content/public/browser/render_widget_host.h" 115#include "content/public/browser/render_widget_host_iterator.h" 116#include "content/public/browser/resource_context.h" 117#include "content/public/browser/user_metrics.h" 118#include "content/public/common/content_constants.h" 119#include "content/public/common/content_switches.h" 120#include "content/public/common/process_type.h" 121#include "content/public/common/result_codes.h" 122#include "content/public/common/url_constants.h" 123#include "gpu/command_buffer/service/gpu_switches.h" 124#include "ipc/ipc_channel.h" 125#include "ipc/ipc_logging.h" 126#include "ipc/ipc_platform_file.h" 127#include "ipc/ipc_switches.h" 128#include "media/base/media_switches.h" 129#include "net/url_request/url_request_context_getter.h" 130#include "ppapi/shared_impl/ppapi_switches.h" 131#include "ui/base/ui_base_switches.h" 132#include "ui/gfx/switches.h" 133#include "ui/gl/gl_switches.h" 134#include "webkit/browser/fileapi/sandbox_file_system_backend.h" 135#include "webkit/common/resource_type.h" 136 137#if defined(OS_ANDROID) 138#include "content/browser/android/vibration_message_filter.h" 139#endif 140 141#if defined(OS_WIN) 142#include "base/win/scoped_com_initializer.h" 143#include "content/common/font_cache_dispatcher_win.h" 144#include "content/common/sandbox_win.h" 145#include "content/public/common/sandboxed_process_launcher_delegate.h" 146#endif 147 148#if defined(ENABLE_WEBRTC) 149#include "content/browser/renderer_host/media/webrtc_identity_service_host.h" 150#endif 151 152#include "third_party/skia/include/core/SkBitmap.h" 153 154extern bool g_exited_main_message_loop; 155 156static const char* kSiteProcessMapKeyName = "content_site_process_map"; 157 158namespace content { 159namespace { 160 161void CacheShaderInfo(int32 id, base::FilePath path) { 162 ShaderCacheFactory::GetInstance()->SetCacheInfo(id, path); 163} 164 165void RemoveShaderInfo(int32 id) { 166 ShaderCacheFactory::GetInstance()->RemoveCacheInfo(id); 167} 168 169net::URLRequestContext* GetRequestContext( 170 scoped_refptr<net::URLRequestContextGetter> request_context, 171 scoped_refptr<net::URLRequestContextGetter> media_request_context, 172 ResourceType::Type resource_type) { 173 // If the request has resource type of ResourceType::MEDIA, we use a request 174 // context specific to media for handling it because these resources have 175 // specific needs for caching. 176 if (resource_type == ResourceType::MEDIA) 177 return media_request_context->GetURLRequestContext(); 178 return request_context->GetURLRequestContext(); 179} 180 181void GetContexts( 182 ResourceContext* resource_context, 183 scoped_refptr<net::URLRequestContextGetter> request_context, 184 scoped_refptr<net::URLRequestContextGetter> media_request_context, 185 const ResourceHostMsg_Request& request, 186 ResourceContext** resource_context_out, 187 net::URLRequestContext** request_context_out) { 188 *resource_context_out = resource_context; 189 *request_context_out = 190 GetRequestContext(request_context, media_request_context, 191 request.resource_type); 192} 193 194// the global list of all renderer processes 195base::LazyInstance<IDMap<RenderProcessHost> >::Leaky 196 g_all_hosts = LAZY_INSTANCE_INITIALIZER; 197 198base::LazyInstance<scoped_refptr<BrowserPluginGeolocationPermissionContext> > 199 g_browser_plugin_geolocation_context = LAZY_INSTANCE_INITIALIZER; 200 201// Map of site to process, to ensure we only have one RenderProcessHost per 202// site in process-per-site mode. Each map is specific to a BrowserContext. 203class SiteProcessMap : public base::SupportsUserData::Data { 204 public: 205 typedef base::hash_map<std::string, RenderProcessHost*> SiteToProcessMap; 206 SiteProcessMap() {} 207 208 void RegisterProcess(const std::string& site, RenderProcessHost* process) { 209 map_[site] = process; 210 } 211 212 RenderProcessHost* FindProcess(const std::string& site) { 213 SiteToProcessMap::iterator i = map_.find(site); 214 if (i != map_.end()) 215 return i->second; 216 return NULL; 217 } 218 219 void RemoveProcess(RenderProcessHost* host) { 220 // Find all instances of this process in the map, then separately remove 221 // them. 222 std::set<std::string> sites; 223 for (SiteToProcessMap::const_iterator i = map_.begin(); 224 i != map_.end(); 225 i++) { 226 if (i->second == host) 227 sites.insert(i->first); 228 } 229 for (std::set<std::string>::iterator i = sites.begin(); 230 i != sites.end(); 231 i++) { 232 SiteToProcessMap::iterator iter = map_.find(*i); 233 if (iter != map_.end()) { 234 DCHECK_EQ(iter->second, host); 235 map_.erase(iter); 236 } 237 } 238 } 239 240 private: 241 SiteToProcessMap map_; 242}; 243 244// Find the SiteProcessMap specific to the given context. 245SiteProcessMap* GetSiteProcessMapForBrowserContext(BrowserContext* context) { 246 DCHECK(context); 247 SiteProcessMap* map = static_cast<SiteProcessMap*>( 248 context->GetUserData(kSiteProcessMapKeyName)); 249 if (!map) { 250 map = new SiteProcessMap(); 251 context->SetUserData(kSiteProcessMapKeyName, map); 252 } 253 return map; 254} 255 256#if defined(OS_WIN) 257// NOTE: changes to this class need to be reviewed by the security team. 258class RendererSandboxedProcessLauncherDelegate 259 : public content::SandboxedProcessLauncherDelegate { 260 public: 261 RendererSandboxedProcessLauncherDelegate() {} 262 virtual ~RendererSandboxedProcessLauncherDelegate() {} 263 264 virtual void ShouldSandbox(bool* in_sandbox) OVERRIDE { 265#if !defined (GOOGLE_CHROME_BUILD) 266 if (CommandLine::ForCurrentProcess()->HasSwitch( 267 switches::kInProcessPlugins)) { 268 *in_sandbox = false; 269 } 270#endif 271 } 272 273 virtual void PreSpawnTarget(sandbox::TargetPolicy* policy, 274 bool* success) { 275 AddBaseHandleClosePolicy(policy); 276 GetContentClient()->browser()->PreSpawnRenderer(policy, success); 277 } 278}; 279#endif // OS_WIN 280 281} // namespace 282 283RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL; 284 285void RenderProcessHost::RegisterRendererMainThreadFactory( 286 RendererMainThreadFactoryFunction create) { 287 g_renderer_main_thread_factory = create; 288} 289 290base::MessageLoop* g_in_process_thread; 291 292base::MessageLoop* 293 RenderProcessHostImpl::GetInProcessRendererThreadForTesting() { 294 return g_in_process_thread; 295} 296 297// Stores the maximum number of renderer processes the content module can 298// create. 299static size_t g_max_renderer_count_override = 0; 300 301// static 302size_t RenderProcessHost::GetMaxRendererProcessCount() { 303 if (g_max_renderer_count_override) 304 return g_max_renderer_count_override; 305 306 // Defines the maximum number of renderer processes according to the 307 // amount of installed memory as reported by the OS. The calculation 308 // assumes that you want the renderers to use half of the installed 309 // RAM and assuming that each WebContents uses ~40MB. 310 // If you modify this assumption, you need to adjust the 311 // ThirtyFourTabs test to match the expected number of processes. 312 // 313 // With the given amounts of installed memory below on a 32-bit CPU, 314 // the maximum renderer count will roughly be as follows: 315 // 316 // 128 MB -> 3 317 // 512 MB -> 6 318 // 1024 MB -> 12 319 // 4096 MB -> 51 320 // 16384 MB -> 82 (kMaxRendererProcessCount) 321 322 static size_t max_count = 0; 323 if (!max_count) { 324 const size_t kEstimatedWebContentsMemoryUsage = 325#if defined(ARCH_CPU_64_BITS) 326 60; // In MB 327#else 328 40; // In MB 329#endif 330 max_count = base::SysInfo::AmountOfPhysicalMemoryMB() / 2; 331 max_count /= kEstimatedWebContentsMemoryUsage; 332 333 const size_t kMinRendererProcessCount = 3; 334 max_count = std::max(max_count, kMinRendererProcessCount); 335 max_count = std::min(max_count, kMaxRendererProcessCount); 336 } 337 return max_count; 338} 339 340// static 341bool g_run_renderer_in_process_ = false; 342 343// static 344void RenderProcessHost::SetMaxRendererProcessCount(size_t count) { 345 g_max_renderer_count_override = count; 346} 347 348RenderProcessHostImpl::RenderProcessHostImpl( 349 BrowserContext* browser_context, 350 StoragePartitionImpl* storage_partition_impl, 351 bool supports_browser_plugin, 352 bool is_guest) 353 : fast_shutdown_started_(false), 354 deleting_soon_(false), 355 pending_views_(0), 356 visible_widgets_(0), 357 backgrounded_(true), 358 cached_dibs_cleaner_( 359 FROM_HERE, base::TimeDelta::FromSeconds(5), 360 this, &RenderProcessHostImpl::ClearTransportDIBCache), 361 is_initialized_(false), 362 id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()), 363 browser_context_(browser_context), 364 storage_partition_impl_(storage_partition_impl), 365 sudden_termination_allowed_(true), 366 ignore_input_events_(false), 367 supports_browser_plugin_(supports_browser_plugin), 368 is_guest_(is_guest), 369 gpu_observer_registered_(false), 370 power_monitor_broadcaster_(this) { 371 widget_helper_ = new RenderWidgetHelper(); 372 373 ChildProcessSecurityPolicyImpl::GetInstance()->Add(GetID()); 374 375 CHECK(!g_exited_main_message_loop); 376 RegisterHost(GetID(), this); 377 g_all_hosts.Get().set_check_on_null_data(true); 378 // Initialize |child_process_activity_time_| to a reasonable value. 379 mark_child_process_activity_time(); 380 381 if (!GetBrowserContext()->IsOffTheRecord() && 382 !CommandLine::ForCurrentProcess()->HasSwitch( 383 switches::kDisableGpuShaderDiskCache)) { 384 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 385 base::Bind(&CacheShaderInfo, GetID(), 386 storage_partition_impl_->GetPath())); 387 } 388 389 // Note: When we create the RenderProcessHostImpl, it's technically 390 // backgrounded, because it has no visible listeners. But the process 391 // doesn't actually exist yet, so we'll Background it later, after 392 // creation. 393} 394 395RenderProcessHostImpl::~RenderProcessHostImpl() { 396 DCHECK(!run_renderer_in_process()); 397 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(GetID()); 398 399 if (gpu_observer_registered_) { 400 GpuDataManagerImpl::GetInstance()->RemoveObserver(this); 401 gpu_observer_registered_ = false; 402 } 403 404 // We may have some unsent messages at this point, but that's OK. 405 channel_.reset(); 406 while (!queued_messages_.empty()) { 407 delete queued_messages_.front(); 408 queued_messages_.pop(); 409 } 410 411 ClearTransportDIBCache(); 412 UnregisterHost(GetID()); 413 414 if (!CommandLine::ForCurrentProcess()->HasSwitch( 415 switches::kDisableGpuShaderDiskCache)) { 416 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, 417 base::Bind(&RemoveShaderInfo, GetID())); 418 } 419} 420 421void RenderProcessHostImpl::EnableSendQueue() { 422 is_initialized_ = false; 423} 424 425bool RenderProcessHostImpl::Init() { 426 // calling Init() more than once does nothing, this makes it more convenient 427 // for the view host which may not be sure in some cases 428 if (channel_) 429 return true; 430 431 CommandLine::StringType renderer_prefix; 432#if defined(OS_POSIX) 433 // A command prefix is something prepended to the command line of the spawned 434 // process. It is supported only on POSIX systems. 435 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); 436 renderer_prefix = 437 browser_command_line.GetSwitchValueNative(switches::kRendererCmdPrefix); 438#endif // defined(OS_POSIX) 439 440#if defined(OS_LINUX) 441 int flags = renderer_prefix.empty() ? ChildProcessHost::CHILD_ALLOW_SELF : 442 ChildProcessHost::CHILD_NORMAL; 443#else 444 int flags = ChildProcessHost::CHILD_NORMAL; 445#endif 446 447 // Find the renderer before creating the channel so if this fails early we 448 // return without creating the channel. 449 base::FilePath renderer_path = ChildProcessHost::GetChildPath(flags); 450 if (renderer_path.empty()) 451 return false; 452 453 // Setup the IPC channel. 454 const std::string channel_id = 455 IPC::Channel::GenerateVerifiedChannelID(std::string()); 456 channel_.reset( 457 new IPC::ChannelProxy(channel_id, 458 IPC::Channel::MODE_SERVER, 459 this, 460 BrowserThread::GetMessageLoopProxyForThread( 461 BrowserThread::IO).get())); 462 463 // Call the embedder first so that their IPC filters have priority. 464 GetContentClient()->browser()->RenderProcessHostCreated(this); 465 466 CreateMessageFilters(); 467 468 // Single-process mode not supported in multiple-dll mode currently. 469 if (run_renderer_in_process() && g_renderer_main_thread_factory) { 470 // Crank up a thread and run the initialization there. With the way that 471 // messages flow between the browser and renderer, this thread is required 472 // to prevent a deadlock in single-process mode. Since the primordial 473 // thread in the renderer process runs the WebKit code and can sometimes 474 // make blocking calls to the UI thread (i.e. this thread), they need to run 475 // on separate threads. 476 in_process_renderer_.reset(g_renderer_main_thread_factory(channel_id)); 477 478 base::Thread::Options options; 479#if defined(OS_WIN) && !defined(OS_MACOSX) 480 // In-process plugins require this to be a UI message loop. 481 options.message_loop_type = base::MessageLoop::TYPE_UI; 482#else 483 // We can't have multiple UI loops on Linux and Android, so we don't support 484 // in-process plugins. 485 options.message_loop_type = base::MessageLoop::TYPE_DEFAULT; 486#endif 487 in_process_renderer_->StartWithOptions(options); 488 489 g_in_process_thread = in_process_renderer_->message_loop(); 490 491 OnProcessLaunched(); // Fake a callback that the process is ready. 492 } else { 493 // Build command line for renderer. We call AppendRendererCommandLine() 494 // first so the process type argument will appear first. 495 CommandLine* cmd_line = new CommandLine(renderer_path); 496 if (!renderer_prefix.empty()) 497 cmd_line->PrependWrapper(renderer_prefix); 498 AppendRendererCommandLine(cmd_line); 499 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id); 500 501 // Spawn the child process asynchronously to avoid blocking the UI thread. 502 // As long as there's no renderer prefix, we can use the zygote process 503 // at this stage. 504 child_process_launcher_.reset(new ChildProcessLauncher( 505#if defined(OS_WIN) 506 new RendererSandboxedProcessLauncherDelegate, 507#elif defined(OS_POSIX) 508 renderer_prefix.empty(), 509 base::EnvironmentMap(), 510 channel_->TakeClientFileDescriptor(), 511#endif 512 cmd_line, 513 GetID(), 514 this)); 515 516 fast_shutdown_started_ = false; 517 } 518 519 if (!gpu_observer_registered_) { 520 gpu_observer_registered_ = true; 521 GpuDataManagerImpl::GetInstance()->AddObserver(this); 522 } 523 524 is_initialized_ = true; 525 return true; 526} 527 528void RenderProcessHostImpl::CreateMessageFilters() { 529 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 530 channel_->AddFilter(new ResourceSchedulerFilter(GetID())); 531 MediaInternals* media_internals = MediaInternals::GetInstance();; 532 media::AudioManager* audio_manager = 533 BrowserMainLoop::GetInstance()->audio_manager(); 534 // Add BrowserPluginMessageFilter to ensure it gets the first stab at messages 535 // from guests. 536 if (supports_browser_plugin_) { 537 scoped_refptr<BrowserPluginMessageFilter> bp_message_filter( 538 new BrowserPluginMessageFilter(GetID(), IsGuest())); 539 channel_->AddFilter(bp_message_filter.get()); 540 } 541 542 scoped_refptr<RenderMessageFilter> render_message_filter( 543 new RenderMessageFilter( 544 GetID(), 545 IsGuest(), 546#if defined(ENABLE_PLUGINS) 547 PluginServiceImpl::GetInstance(), 548#else 549 NULL, 550#endif 551 GetBrowserContext(), 552 GetBrowserContext()->GetRequestContextForRenderProcess(GetID()), 553 widget_helper_.get(), 554 audio_manager, 555 media_internals, 556 storage_partition_impl_->GetDOMStorageContext())); 557 channel_->AddFilter(render_message_filter.get()); 558 BrowserContext* browser_context = GetBrowserContext(); 559 ResourceContext* resource_context = browser_context->GetResourceContext(); 560 561 scoped_refptr<net::URLRequestContextGetter> request_context( 562 browser_context->GetRequestContextForRenderProcess(GetID())); 563 scoped_refptr<net::URLRequestContextGetter> media_request_context( 564 browser_context->GetMediaRequestContextForRenderProcess(GetID())); 565 566 ResourceMessageFilter::GetContextsCallback get_contexts_callback( 567 base::Bind(&GetContexts, browser_context->GetResourceContext(), 568 request_context, media_request_context)); 569 570 ResourceMessageFilter* resource_message_filter = new ResourceMessageFilter( 571 GetID(), PROCESS_TYPE_RENDERER, 572 storage_partition_impl_->GetAppCacheService(), 573 ChromeBlobStorageContext::GetFor(browser_context), 574 storage_partition_impl_->GetFileSystemContext(), 575 get_contexts_callback); 576 577 channel_->AddFilter(resource_message_filter); 578 MediaStreamManager* media_stream_manager = 579 BrowserMainLoop::GetInstance()->media_stream_manager(); 580 channel_->AddFilter(new AudioInputRendererHost( 581 audio_manager, 582 media_stream_manager, 583 BrowserMainLoop::GetInstance()->audio_mirroring_manager(), 584 BrowserMainLoop::GetInstance()->user_input_monitor())); 585 channel_->AddFilter(new AudioRendererHost( 586 GetID(), 587 audio_manager, 588 BrowserMainLoop::GetInstance()->audio_mirroring_manager(), 589 media_internals, 590 media_stream_manager)); 591 channel_->AddFilter( 592 new MIDIHost(GetID(), BrowserMainLoop::GetInstance()->midi_manager())); 593 channel_->AddFilter(new MIDIDispatcherHost(GetID(), browser_context)); 594 channel_->AddFilter(new VideoCaptureHost(media_stream_manager)); 595 channel_->AddFilter(new AppCacheDispatcherHost( 596 storage_partition_impl_->GetAppCacheService(), 597 GetID())); 598 channel_->AddFilter(new ClipboardMessageFilter); 599 channel_->AddFilter(new DOMStorageMessageFilter( 600 GetID(), 601 storage_partition_impl_->GetDOMStorageContext())); 602 channel_->AddFilter(new IndexedDBDispatcherHost( 603 GetID(), 604 storage_partition_impl_->GetIndexedDBContext())); 605 if (IsGuest()) { 606 if (!g_browser_plugin_geolocation_context.Get().get()) { 607 g_browser_plugin_geolocation_context.Get() = 608 new BrowserPluginGeolocationPermissionContext(); 609 } 610 channel_->AddFilter(GeolocationDispatcherHost::New( 611 GetID(), g_browser_plugin_geolocation_context.Get().get())); 612 } else { 613 channel_->AddFilter(GeolocationDispatcherHost::New( 614 GetID(), browser_context->GetGeolocationPermissionContext())); 615 } 616 gpu_message_filter_ = new GpuMessageFilter(GetID(), widget_helper_.get()); 617 channel_->AddFilter(gpu_message_filter_); 618#if defined(ENABLE_WEBRTC) 619 channel_->AddFilter(new WebRTCIdentityServiceHost( 620 GetID(), storage_partition_impl_->GetWebRTCIdentityStore())); 621 peer_connection_tracker_host_ = new PeerConnectionTrackerHost(GetID()); 622 channel_->AddFilter(peer_connection_tracker_host_.get()); 623 channel_->AddFilter(new MediaStreamDispatcherHost( 624 GetID(), media_stream_manager)); 625 channel_->AddFilter( 626 new DeviceRequestMessageFilter(resource_context, media_stream_manager)); 627#endif 628#if defined(ENABLE_PLUGINS) 629 channel_->AddFilter(new PepperRendererConnection(GetID())); 630#endif 631#if defined(ENABLE_INPUT_SPEECH) 632 channel_->AddFilter(new InputTagSpeechDispatcherHost( 633 IsGuest(), GetID(), storage_partition_impl_->GetURLRequestContext())); 634#endif 635 channel_->AddFilter(new SpeechRecognitionDispatcherHost( 636 GetID(), storage_partition_impl_->GetURLRequestContext())); 637 channel_->AddFilter(new FileAPIMessageFilter( 638 GetID(), 639 storage_partition_impl_->GetURLRequestContext(), 640 storage_partition_impl_->GetFileSystemContext(), 641 ChromeBlobStorageContext::GetFor(browser_context), 642 StreamContext::GetFor(browser_context))); 643 channel_->AddFilter(new OrientationMessageFilter()); 644 channel_->AddFilter(new FileUtilitiesMessageFilter(GetID())); 645 channel_->AddFilter(new MimeRegistryMessageFilter()); 646 channel_->AddFilter(new DatabaseMessageFilter( 647 storage_partition_impl_->GetDatabaseTracker())); 648#if defined(OS_MACOSX) 649 channel_->AddFilter(new TextInputClientMessageFilter(GetID())); 650#elif defined(OS_WIN) 651 channel_->AddFilter(new FontCacheDispatcher()); 652#endif 653 654 SocketStreamDispatcherHost::GetRequestContextCallback 655 request_context_callback( 656 base::Bind(&GetRequestContext, request_context, 657 media_request_context)); 658 659 SocketStreamDispatcherHost* socket_stream_dispatcher_host = 660 new SocketStreamDispatcherHost( 661 GetID(), request_context_callback, resource_context); 662 channel_->AddFilter(socket_stream_dispatcher_host); 663 664 channel_->AddFilter(new WorkerMessageFilter( 665 GetID(), 666 resource_context, 667 WorkerStoragePartition( 668 storage_partition_impl_->GetURLRequestContext(), 669 storage_partition_impl_->GetMediaURLRequestContext(), 670 storage_partition_impl_->GetAppCacheService(), 671 storage_partition_impl_->GetQuotaManager(), 672 storage_partition_impl_->GetFileSystemContext(), 673 storage_partition_impl_->GetDatabaseTracker(), 674 storage_partition_impl_->GetIndexedDBContext()), 675 base::Bind(&RenderWidgetHelper::GetNextRoutingID, 676 base::Unretained(widget_helper_.get())))); 677 678#if defined(ENABLE_WEBRTC) 679 channel_->AddFilter(new P2PSocketDispatcherHost( 680 resource_context, 681 browser_context->GetRequestContextForRenderProcess(GetID()))); 682#endif 683 684 channel_->AddFilter(new TraceMessageFilter()); 685 channel_->AddFilter(new ResolveProxyMsgHelper( 686 browser_context->GetRequestContextForRenderProcess(GetID()))); 687 channel_->AddFilter(new QuotaDispatcherHost( 688 GetID(), 689 storage_partition_impl_->GetQuotaManager(), 690 GetContentClient()->browser()->CreateQuotaPermissionContext())); 691 channel_->AddFilter(new GamepadBrowserMessageFilter()); 692 channel_->AddFilter(new DeviceMotionMessageFilter()); 693 channel_->AddFilter(new DeviceOrientationMessageFilter()); 694 channel_->AddFilter(new ProfilerMessageFilter(PROCESS_TYPE_RENDERER)); 695 channel_->AddFilter(new HistogramMessageFilter()); 696#if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID)) 697 if (CommandLine::ForCurrentProcess()->HasSwitch( 698 switches::kEnableMemoryBenchmarking)) 699 channel_->AddFilter(new MemoryBenchmarkMessageFilter()); 700#endif 701#if defined(OS_ANDROID) 702 channel_->AddFilter(new VibrationMessageFilter()); 703#endif 704} 705 706int RenderProcessHostImpl::GetNextRoutingID() { 707 return widget_helper_->GetNextRoutingID(); 708} 709 710 711void RenderProcessHostImpl::ResumeDeferredNavigation( 712 const GlobalRequestID& request_id) { 713 widget_helper_->ResumeDeferredNavigation(request_id); 714} 715 716void RenderProcessHostImpl::AddRoute( 717 int32 routing_id, 718 IPC::Listener* listener) { 719 listeners_.AddWithID(listener, routing_id); 720} 721 722void RenderProcessHostImpl::RemoveRoute(int32 routing_id) { 723 DCHECK(listeners_.Lookup(routing_id) != NULL); 724 listeners_.Remove(routing_id); 725 726#if defined(OS_WIN) 727 // Dump the handle table if handle auditing is enabled. 728 const CommandLine& browser_command_line = 729 *CommandLine::ForCurrentProcess(); 730 if (browser_command_line.HasSwitch(switches::kAuditHandles) || 731 browser_command_line.HasSwitch(switches::kAuditAllHandles)) { 732 DumpHandles(); 733 734 // We wait to close the channels until the child process has finished 735 // dumping handles and sends us ChildProcessHostMsg_DumpHandlesDone. 736 return; 737 } 738#endif 739 // Keep the one renderer thread around forever in single process mode. 740 if (!run_renderer_in_process()) 741 Cleanup(); 742} 743 744bool RenderProcessHostImpl::WaitForBackingStoreMsg( 745 int render_widget_id, 746 const base::TimeDelta& max_delay, 747 IPC::Message* msg) { 748 // The post task to this thread with the process id could be in queue, and we 749 // don't want to dispatch a message before then since it will need the handle. 750 if (child_process_launcher_.get() && child_process_launcher_->IsStarting()) 751 return false; 752 753 return widget_helper_->WaitForBackingStoreMsg(render_widget_id, 754 max_delay, msg); 755} 756 757void RenderProcessHostImpl::ReceivedBadMessage() { 758 if (run_renderer_in_process()) { 759 // In single process mode it is better if we don't suicide but just 760 // crash. 761 CHECK(false); 762 } 763 // We kill the renderer but don't include a NOTREACHED, because we want the 764 // browser to try to survive when it gets illegal messages from the renderer. 765 base::KillProcess(GetHandle(), RESULT_CODE_KILLED_BAD_MESSAGE, 766 false); 767} 768 769void RenderProcessHostImpl::WidgetRestored() { 770 // Verify we were properly backgrounded. 771 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0)); 772 visible_widgets_++; 773 SetBackgrounded(false); 774} 775 776void RenderProcessHostImpl::WidgetHidden() { 777 // On startup, the browser will call Hide 778 if (backgrounded_) 779 return; 780 781 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0)); 782 visible_widgets_--; 783 DCHECK_GE(visible_widgets_, 0); 784 if (visible_widgets_ == 0) { 785 DCHECK(!backgrounded_); 786 SetBackgrounded(true); 787 } 788} 789 790int RenderProcessHostImpl::VisibleWidgetCount() const { 791 return visible_widgets_; 792} 793 794bool RenderProcessHostImpl::IsGuest() const { 795 return is_guest_; 796} 797 798StoragePartition* RenderProcessHostImpl::GetStoragePartition() const { 799 return storage_partition_impl_; 800} 801 802void RenderProcessHostImpl::AppendRendererCommandLine( 803 CommandLine* command_line) const { 804 // Pass the process type first, so it shows first in process listings. 805 command_line->AppendSwitchASCII(switches::kProcessType, 806 switches::kRendererProcess); 807 808 // Now send any options from our own command line we want to propagate. 809 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess(); 810 PropagateBrowserCommandLineToRenderer(browser_command_line, command_line); 811 812 // Pass on the browser locale. 813 const std::string locale = 814 GetContentClient()->browser()->GetApplicationLocale(); 815 command_line->AppendSwitchASCII(switches::kLang, locale); 816 817 // If we run base::FieldTrials, we want to pass to their state to the 818 // renderer so that it can act in accordance with each state, or record 819 // histograms relating to the base::FieldTrial states. 820 std::string field_trial_states; 821 base::FieldTrialList::StatesToString(&field_trial_states); 822 if (!field_trial_states.empty()) { 823 command_line->AppendSwitchASCII(switches::kForceFieldTrials, 824 field_trial_states); 825 } 826 827 if (content::IsThreadedCompositingEnabled()) 828 command_line->AppendSwitch(switches::kEnableThreadedCompositing); 829 830 if (content::IsDelegatedRendererEnabled()) 831 command_line->AppendSwitch(switches::kEnableDelegatedRenderer); 832 833 GetContentClient()->browser()->AppendExtraCommandLineSwitches( 834 command_line, GetID()); 835 836 // Appending disable-gpu-feature switches due to software rendering list. 837 GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance(); 838 DCHECK(gpu_data_manager); 839 gpu_data_manager->AppendRendererCommandLine(command_line); 840} 841 842void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer( 843 const CommandLine& browser_cmd, 844 CommandLine* renderer_cmd) const { 845 // Propagate the following switches to the renderer command line (along 846 // with any associated values) if present in the browser command line. 847 static const char* const kSwitchNames[] = { 848 switches::kAllowFiltersOverIPC, 849 switches::kAudioBufferSize, 850 switches::kAuditAllHandles, 851 switches::kAuditHandles, 852 switches::kBlockCrossSiteDocuments, 853 switches::kDirectNPAPIRequests, 854 switches::kDisable3DAPIs, 855 switches::kDisableAcceleratedCompositing, 856 switches::kDisableAcceleratedVideoDecode, 857 switches::kDisableApplicationCache, 858 switches::kDisableAudio, 859 switches::kDisableBreakpad, 860 switches::kDisableDatabases, 861 switches::kDisableDelegatedRenderer, 862 switches::kDisableDesktopNotifications, 863 switches::kDisableDeviceOrientation, 864 switches::kDisableFileSystem, 865 switches::kDisableGeolocation, 866 switches::kDisableGLMultisampling, 867 switches::kDisableGpuVsync, 868 switches::kDisableGpu, 869 switches::kDisableGpuCompositing, 870 switches::kDisableHistogramCustomizer, 871 switches::kDisableLocalStorage, 872 switches::kDisableLogging, 873 switches::kDisableSeccompFilterSandbox, 874 switches::kDisableSessionStorage, 875 switches::kDisableSharedWorkers, 876 switches::kDisableSpeechInput, 877 switches::kDisableTouchDragDrop, 878 switches::kDisableTouchEditing, 879#if defined(OS_ANDROID) 880 switches::kDisableWebRTC, 881 switches::kEnableSpeechRecognition, 882#endif 883 switches::kDisableWebAudio, 884#if defined(ENABLE_WEBRTC) 885 switches::kDisableDeviceEnumeration, 886 switches::kDisableSCTPDataChannels, 887 switches::kDisableWebRtcHWDecoding, 888 switches::kDisableWebRtcHWEncoding, 889#endif 890 switches::kEnableWebAnimationsCSS, 891 switches::kEnableWebAnimationsSVG, 892 switches::kEnableWebMIDI, 893 switches::kEnableExperimentalCanvasFeatures, 894 switches::kEnableExperimentalWebSocket, 895 switches::kDomAutomationController, 896 switches::kEnableAccessibilityLogging, 897 switches::kEnableBeginFrameScheduling, 898 switches::kEnableBrowserInputController, 899 switches::kEnableBrowserPluginForAllViewTypes, 900 switches::kEnableDCHECK, 901 switches::kEnableDelegatedRenderer, 902 switches::kEnableEncryptedMedia, 903 switches::kDisableLegacyEncryptedMedia, 904 switches::kOverrideEncryptedMediaCanPlayType, 905#if defined(OS_ANDROID) 906 switches::kMediaDrmEnableNonCompositing, 907#endif 908 switches::kEnableExperimentalWebPlatformFeatures, 909 switches::kEnableFixedLayout, 910 switches::kEnableDeferredImageDecoding, 911 switches::kEnableGPUServiceLogging, 912 switches::kEnableGPUClientLogging, 913 switches::kEnableGpuClientTracing, 914 switches::kEnableGpuBenchmarking, 915#if defined(OS_WIN) 916 switches::kEnableHighResolutionTime, 917#endif 918 switches::kEnableMP3StreamParser, 919 switches::kEnableMemoryBenchmarking, 920 switches::kEnableOverlayScrollbars, 921 switches::kEnableSkiaBenchmarking, 922 switches::kEnableLogging, 923 switches::kEnableSpeechSynthesis, 924 switches::kEnableTouchDragDrop, 925 switches::kEnableTouchEditing, 926#if defined(ENABLE_WEBRTC) 927 switches::kEnableWebRtcAecRecordings, 928 switches::kEnableWebRtcTcpServerSocket, 929#endif 930 switches::kDisableWebKitMediaSource, 931 switches::kEnableOverscrollNotifications, 932 switches::kEnableStrictSiteIsolation, 933 switches::kDisableFullScreen, 934#if defined(ENABLE_PLUGINS) 935 switches::kEnablePepperTesting, 936 switches::kDisablePepper3d, 937#endif 938 switches::kEnablePreparsedJsCaching, 939 switches::kEnablePruneGpuCommandBuffers, 940 switches::kEnablePinch, 941 switches::kDisablePinch, 942#if defined(OS_MACOSX) 943 // Allow this to be set when invoking the browser and relayed along. 944 switches::kEnableSandboxLogging, 945#endif 946 switches::kEnableSoftwareCompositing, 947 switches::kEnableStatsTable, 948 switches::kEnableThreadedCompositing, 949 switches::kEnableCompositingForFixedPosition, 950 switches::kEnableHighDpiCompositingForFixedPosition, 951 switches::kDisableCompositingForFixedPosition, 952 switches::kEnableAcceleratedOverflowScroll, 953 switches::kEnableCompositingForTransition, 954 switches::kDisableCompositingForTransition, 955 switches::kEnableAcceleratedFixedRootBackground, 956 switches::kDisableAcceleratedFixedRootBackground, 957 switches::kDisableThreadedCompositing, 958 switches::kDisableTouchAdjustment, 959 switches::kDefaultTileWidth, 960 switches::kDefaultTileHeight, 961 switches::kMaxUntiledLayerWidth, 962 switches::kMaxUntiledLayerHeight, 963 switches::kEnableViewport, 964 switches::kEnableInbandTextTracks, 965 switches::kEnableOpusPlayback, 966 switches::kDisableVp8AlphaPlayback, 967 switches::kEnableEac3Playback, 968 switches::kForceDeviceScaleFactor, 969 switches::kFullMemoryCrashReport, 970#if defined(OS_ANDROID) 971 switches::kHideScrollbars, 972#endif 973#if !defined (GOOGLE_CHROME_BUILD) 974 // These are unsupported and not fully tested modes, so don't enable them 975 // for official Google Chrome builds. 976 switches::kInProcessPlugins, 977#endif // GOOGLE_CHROME_BUILD 978 switches::kJavaScriptFlags, 979 switches::kLoggingLevel, 980 switches::kMemoryMetrics, 981#if defined(OS_ANDROID) 982 switches::kNetworkCountryIso, 983 switches::kDisableGestureRequirementForMediaPlayback, 984#endif 985#if defined(GOOGLE_TV) 986 switches::kUseExternalVideoSurfaceThresholdInPixels, 987#endif 988 switches::kNoReferrers, 989 switches::kNoSandbox, 990 switches::kEnableVtune, 991 switches::kPpapiInProcess, 992 switches::kRegisterPepperPlugins, 993 switches::kRendererAssertTest, 994#if defined(OS_POSIX) 995 switches::kChildCleanExit, 996#endif 997 switches::kRendererStartupDialog, 998 switches::kShowPaintRects, 999 switches::kSitePerProcess, 1000 switches::kStatsCollectionController, 1001 switches::kTestSandbox, 1002 switches::kTouchEvents, 1003 switches::kTraceStartup, 1004 // This flag needs to be propagated to the renderer process for 1005 // --in-process-webgl. 1006 switches::kUseGL, 1007 switches::kUseMobileUserAgent, 1008 switches::kUserAgent, 1009 switches::kV, 1010 switches::kVideoThreads, 1011 switches::kVModule, 1012 switches::kWebCoreLogChannels, 1013 switches::kEnableWebGLDraftExtensions, 1014 switches::kEnableHTMLImports, 1015 switches::kEnableInputModeAttribute, 1016 switches::kTraceToConsole, 1017 switches::kDisableDeviceMotion, 1018 // Please keep these in alphabetical order. Compositor switches here should 1019 // also be added to chrome/browser/chromeos/login/chrome_restart_request.cc. 1020 cc::switches::kBackgroundColorInsteadOfCheckerboard, 1021 cc::switches::kCompositeToMailbox, 1022 cc::switches::kDisableCompositedAntialiasing, 1023 cc::switches::kDisableImplSidePainting, 1024 cc::switches::kDisableLCDText, 1025 cc::switches::kDisableMapImage, 1026 cc::switches::kDisableThreadedAnimation, 1027 cc::switches::kEnableImplSidePainting, 1028 cc::switches::kEnableLCDText, 1029 cc::switches::kEnableMapImage, 1030 cc::switches::kEnablePartialSwap, 1031 cc::switches::kEnablePerTilePainting, 1032 cc::switches::kEnablePinchVirtualViewport, 1033 cc::switches::kEnableTopControlsPositionCalculation, 1034 cc::switches::kForceDirectLayerDrawing, 1035 cc::switches::kLowResolutionContentsScaleFactor, 1036 cc::switches::kMaxTilesForInterestArea, 1037 cc::switches::kMaxUnusedResourceMemoryUsagePercentage, 1038 cc::switches::kNumRasterThreads, 1039 cc::switches::kShowCompositedLayerBorders, 1040 cc::switches::kShowFPSCounter, 1041 cc::switches::kShowNonOccludingRects, 1042 cc::switches::kShowOccludingRects, 1043 cc::switches::kShowPropertyChangedRects, 1044 cc::switches::kShowReplicaScreenSpaceRects, 1045 cc::switches::kShowScreenSpaceRects, 1046 cc::switches::kShowSurfaceDamageRects, 1047 cc::switches::kSlowDownRasterScaleFactor, 1048 cc::switches::kStrictLayerPropertyChangeChecking, 1049 cc::switches::kTopControlsHeight, 1050 cc::switches::kTopControlsHideThreshold, 1051 cc::switches::kTopControlsShowThreshold, 1052 cc::switches::kTraceOverdraw, 1053 }; 1054 renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames, 1055 arraysize(kSwitchNames)); 1056 1057 // Disable databases in incognito mode. 1058 if (GetBrowserContext()->IsOffTheRecord() && 1059 !browser_cmd.HasSwitch(switches::kDisableDatabases)) { 1060 renderer_cmd->AppendSwitch(switches::kDisableDatabases); 1061#if defined(OS_ANDROID) 1062 renderer_cmd->AppendSwitch(switches::kDisableMediaHistoryLogging); 1063#endif 1064 } 1065 1066 // Enforce the extra command line flags for impl-side painting. 1067 if (cc::switches::IsImplSidePaintingEnabled() && 1068 !browser_cmd.HasSwitch(switches::kEnableDeferredImageDecoding)) 1069 renderer_cmd->AppendSwitch(switches::kEnableDeferredImageDecoding); 1070} 1071 1072base::ProcessHandle RenderProcessHostImpl::GetHandle() const { 1073 if (run_renderer_in_process()) 1074 return base::Process::Current().handle(); 1075 1076 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting()) 1077 return base::kNullProcessHandle; 1078 1079 return child_process_launcher_->GetHandle(); 1080} 1081 1082bool RenderProcessHostImpl::FastShutdownIfPossible() { 1083 if (run_renderer_in_process()) 1084 return false; // Single process mode never shutdown the renderer. 1085 1086 if (!GetContentClient()->browser()->IsFastShutdownPossible()) 1087 return false; 1088 1089 if (!child_process_launcher_.get() || 1090 child_process_launcher_->IsStarting() || 1091 !GetHandle()) 1092 return false; // Render process hasn't started or is probably crashed. 1093 1094 // Test if there's an unload listener. 1095 // NOTE: It's possible that an onunload listener may be installed 1096 // while we're shutting down, so there's a small race here. Given that 1097 // the window is small, it's unlikely that the web page has much 1098 // state that will be lost by not calling its unload handlers properly. 1099 if (!SuddenTerminationAllowed()) 1100 return false; 1101 1102 ProcessDied(false /* already_dead */); 1103 fast_shutdown_started_ = true; 1104 return true; 1105} 1106 1107void RenderProcessHostImpl::DumpHandles() { 1108#if defined(OS_WIN) 1109 Send(new ChildProcessMsg_DumpHandles()); 1110 return; 1111#endif 1112 1113 NOTIMPLEMENTED(); 1114} 1115 1116// This is a platform specific function for mapping a transport DIB given its id 1117TransportDIB* RenderProcessHostImpl::MapTransportDIB( 1118 TransportDIB::Id dib_id) { 1119#if defined(OS_WIN) 1120 // On Windows we need to duplicate the handle from the remote process 1121 HANDLE section; 1122 DuplicateHandle(GetHandle(), dib_id.handle, GetCurrentProcess(), §ion, 1123 STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE, 1124 FALSE, 0); 1125 return TransportDIB::Map(section); 1126#elif defined(TOOLKIT_GTK) 1127 return TransportDIB::Map(dib_id.shmkey); 1128#elif defined(OS_ANDROID) 1129 return TransportDIB::Map(dib_id); 1130#else 1131 // On POSIX, the browser allocates all DIBs and keeps a file descriptor around 1132 // for each. 1133 return widget_helper_->MapTransportDIB(dib_id); 1134#endif 1135} 1136 1137TransportDIB* RenderProcessHostImpl::GetTransportDIB( 1138 TransportDIB::Id dib_id) { 1139 if (!TransportDIB::is_valid_id(dib_id)) 1140 return NULL; 1141 1142 const std::map<TransportDIB::Id, TransportDIB*>::iterator 1143 i = cached_dibs_.find(dib_id); 1144 if (i != cached_dibs_.end()) { 1145 cached_dibs_cleaner_.Reset(); 1146 return i->second; 1147 } 1148 1149 TransportDIB* dib = MapTransportDIB(dib_id); 1150 if (!dib) 1151 return NULL; 1152 1153 if (cached_dibs_.size() >= MAX_MAPPED_TRANSPORT_DIBS) { 1154 // Clean a single entry from the cache 1155 std::map<TransportDIB::Id, TransportDIB*>::iterator smallest_iterator; 1156 size_t smallest_size = std::numeric_limits<size_t>::max(); 1157 1158 for (std::map<TransportDIB::Id, TransportDIB*>::iterator 1159 i = cached_dibs_.begin(); i != cached_dibs_.end(); ++i) { 1160 if (i->second->size() <= smallest_size) { 1161 smallest_iterator = i; 1162 smallest_size = i->second->size(); 1163 } 1164 } 1165 1166#if defined(TOOLKIT_GTK) 1167 smallest_iterator->second->Detach(); 1168#else 1169 delete smallest_iterator->second; 1170#endif 1171 cached_dibs_.erase(smallest_iterator); 1172 } 1173 1174 cached_dibs_[dib_id] = dib; 1175 cached_dibs_cleaner_.Reset(); 1176 return dib; 1177} 1178 1179void RenderProcessHostImpl::ClearTransportDIBCache() { 1180#if defined(TOOLKIT_GTK) 1181 std::map<TransportDIB::Id, TransportDIB*>::const_iterator dib = 1182 cached_dibs_.begin(); 1183 for (; dib != cached_dibs_.end(); ++dib) 1184 dib->second->Detach(); 1185#else 1186 STLDeleteContainerPairSecondPointers( 1187 cached_dibs_.begin(), cached_dibs_.end()); 1188#endif 1189 cached_dibs_.clear(); 1190} 1191 1192bool RenderProcessHostImpl::Send(IPC::Message* msg) { 1193 if (!channel_) { 1194 if (!is_initialized_) { 1195 queued_messages_.push(msg); 1196 return true; 1197 } else { 1198 delete msg; 1199 return false; 1200 } 1201 } 1202 1203 if (child_process_launcher_.get() && child_process_launcher_->IsStarting()) { 1204 queued_messages_.push(msg); 1205 return true; 1206 } 1207 1208 return channel_->Send(msg); 1209} 1210 1211bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) { 1212 // If we're about to be deleted, or have initiated the fast shutdown sequence, 1213 // we ignore incoming messages. 1214 1215 if (deleting_soon_ || fast_shutdown_started_) 1216 return false; 1217 1218 mark_child_process_activity_time(); 1219 if (msg.routing_id() == MSG_ROUTING_CONTROL) { 1220 // Dispatch control messages. 1221 bool msg_is_ok = true; 1222 IPC_BEGIN_MESSAGE_MAP_EX(RenderProcessHostImpl, msg, msg_is_ok) 1223 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest, 1224 OnShutdownRequest) 1225 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_DumpHandlesDone, 1226 OnDumpHandlesDone) 1227 IPC_MESSAGE_HANDLER(ViewHostMsg_SuddenTerminationChanged, 1228 SuddenTerminationChanged) 1229 IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction, 1230 OnUserMetricsRecordAction) 1231 IPC_MESSAGE_HANDLER(ViewHostMsg_SavedPageAsMHTML, OnSavedPageAsMHTML) 1232 // Adding single handlers for your service here is fine, but once your 1233 // service needs more than one handler, please extract them into a new 1234 // message filter and add that filter to CreateMessageFilters(). 1235 IPC_END_MESSAGE_MAP_EX() 1236 1237 if (!msg_is_ok) { 1238 // The message had a handler, but its de-serialization failed. 1239 // We consider this a capital crime. Kill the renderer if we have one. 1240 LOG(ERROR) << "bad message " << msg.type() << " terminating renderer."; 1241 RecordAction(UserMetricsAction("BadMessageTerminate_BRPH")); 1242 ReceivedBadMessage(); 1243 } 1244 return true; 1245 } 1246 1247 // Dispatch incoming messages to the appropriate IPC::Listener. 1248 IPC::Listener* listener = listeners_.Lookup(msg.routing_id()); 1249 if (!listener) { 1250 if (msg.is_sync()) { 1251 // The listener has gone away, so we must respond or else the caller will 1252 // hang waiting for a reply. 1253 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg); 1254 reply->set_reply_error(); 1255 Send(reply); 1256 } 1257 1258 // If this is a SwapBuffers, we need to ack it if we're not going to handle 1259 // it so that the GPU process doesn't get stuck in unscheduled state. 1260 bool msg_is_ok = true; 1261 IPC_BEGIN_MESSAGE_MAP_EX(RenderProcessHostImpl, msg, msg_is_ok) 1262 IPC_MESSAGE_HANDLER(ViewHostMsg_CompositorSurfaceBuffersSwapped, 1263 OnCompositorSurfaceBuffersSwappedNoHost) 1264 IPC_END_MESSAGE_MAP_EX() 1265 return true; 1266 } 1267 return listener->OnMessageReceived(msg); 1268} 1269 1270void RenderProcessHostImpl::OnChannelConnected(int32 peer_pid) { 1271#if defined(IPC_MESSAGE_LOG_ENABLED) 1272 Send(new ChildProcessMsg_SetIPCLoggingEnabled( 1273 IPC::Logging::GetInstance()->Enabled())); 1274#endif 1275 1276 tracked_objects::ThreadData::Status status = 1277 tracked_objects::ThreadData::status(); 1278 Send(new ChildProcessMsg_SetProfilerStatus(status)); 1279} 1280 1281void RenderProcessHostImpl::OnChannelError() { 1282 ProcessDied(true /* already_dead */); 1283} 1284 1285BrowserContext* RenderProcessHostImpl::GetBrowserContext() const { 1286 return browser_context_; 1287} 1288 1289bool RenderProcessHostImpl::InSameStoragePartition( 1290 StoragePartition* partition) const { 1291 return storage_partition_impl_ == partition; 1292} 1293 1294int RenderProcessHostImpl::GetID() const { 1295 return id_; 1296} 1297 1298bool RenderProcessHostImpl::HasConnection() const { 1299 return channel_.get() != NULL; 1300} 1301 1302void RenderProcessHostImpl::SetIgnoreInputEvents(bool ignore_input_events) { 1303 ignore_input_events_ = ignore_input_events; 1304} 1305 1306bool RenderProcessHostImpl::IgnoreInputEvents() const { 1307 return ignore_input_events_; 1308} 1309 1310void RenderProcessHostImpl::Cleanup() { 1311 // When no other owners of this object, we can delete ourselves 1312 if (listeners_.IsEmpty()) { 1313 DCHECK_EQ(0, pending_views_); 1314 NotificationService::current()->Notify( 1315 NOTIFICATION_RENDERER_PROCESS_TERMINATED, 1316 Source<RenderProcessHost>(this), 1317 NotificationService::NoDetails()); 1318 1319 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this); 1320 deleting_soon_ = true; 1321 // It's important not to wait for the DeleteTask to delete the channel 1322 // proxy. Kill it off now. That way, in case the profile is going away, the 1323 // rest of the objects attached to this RenderProcessHost start going 1324 // away first, since deleting the channel proxy will post a 1325 // OnChannelClosed() to IPC::ChannelProxy::Context on the IO thread. 1326 channel_.reset(); 1327 gpu_message_filter_ = NULL; 1328 1329 // Remove ourself from the list of renderer processes so that we can't be 1330 // reused in between now and when the Delete task runs. 1331 UnregisterHost(GetID()); 1332 } 1333} 1334 1335void RenderProcessHostImpl::AddPendingView() { 1336 pending_views_++; 1337} 1338 1339void RenderProcessHostImpl::RemovePendingView() { 1340 DCHECK(pending_views_); 1341 pending_views_--; 1342} 1343 1344void RenderProcessHostImpl::SetSuddenTerminationAllowed(bool enabled) { 1345 sudden_termination_allowed_ = enabled; 1346} 1347 1348bool RenderProcessHostImpl::SuddenTerminationAllowed() const { 1349 return sudden_termination_allowed_; 1350} 1351 1352base::TimeDelta RenderProcessHostImpl::GetChildProcessIdleTime() const { 1353 return base::TimeTicks::Now() - child_process_activity_time_; 1354} 1355 1356void RenderProcessHostImpl::SurfaceUpdated(int32 surface_id) { 1357 if (!gpu_message_filter_) 1358 return; 1359 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( 1360 &GpuMessageFilter::SurfaceUpdated, 1361 gpu_message_filter_, 1362 surface_id)); 1363} 1364 1365void RenderProcessHostImpl::ResumeRequestsForView(int route_id) { 1366 widget_helper_->ResumeRequestsForView(route_id); 1367} 1368 1369IPC::ChannelProxy* RenderProcessHostImpl::GetChannel() { 1370 return channel_.get(); 1371} 1372 1373bool RenderProcessHostImpl::FastShutdownForPageCount(size_t count) { 1374 if (static_cast<size_t>(GetActiveViewCount()) == count) 1375 return FastShutdownIfPossible(); 1376 return false; 1377} 1378 1379bool RenderProcessHostImpl::FastShutdownStarted() const { 1380 return fast_shutdown_started_; 1381} 1382 1383// static 1384void RenderProcessHostImpl::RegisterHost(int host_id, RenderProcessHost* host) { 1385 g_all_hosts.Get().AddWithID(host, host_id); 1386} 1387 1388// static 1389void RenderProcessHostImpl::UnregisterHost(int host_id) { 1390 RenderProcessHost* host = g_all_hosts.Get().Lookup(host_id); 1391 if (!host) 1392 return; 1393 1394 g_all_hosts.Get().Remove(host_id); 1395 1396 // Look up the map of site to process for the given browser_context, 1397 // in case we need to remove this process from it. It will be registered 1398 // under any sites it rendered that use process-per-site mode. 1399 SiteProcessMap* map = 1400 GetSiteProcessMapForBrowserContext(host->GetBrowserContext()); 1401 map->RemoveProcess(host); 1402} 1403 1404// static 1405bool RenderProcessHostImpl::IsSuitableHost( 1406 RenderProcessHost* host, 1407 BrowserContext* browser_context, 1408 const GURL& site_url) { 1409 if (run_renderer_in_process()) 1410 return true; 1411 1412 if (host->GetBrowserContext() != browser_context) 1413 return false; 1414 1415 // Check whether the given host and the intended site_url will be using the 1416 // same StoragePartition, since a RenderProcessHost can only support a single 1417 // StoragePartition. This is relevant for packaged apps, browser tags, and 1418 // isolated sites. 1419 StoragePartition* dest_partition = 1420 BrowserContext::GetStoragePartitionForSite(browser_context, site_url); 1421 if (!host->InSameStoragePartition(dest_partition)) 1422 return false; 1423 1424 // All URLs are suitable if this is associated with a guest renderer process. 1425 // TODO(fsamuel, creis): Further validation is needed to ensure that only 1426 // normal web URLs are permitted in guest processes. We need to investigate 1427 // where this validation should happen. 1428 if (host->IsGuest()) 1429 return true; 1430 1431 if (!host->IsGuest() && site_url.SchemeIs(chrome::kGuestScheme)) 1432 return false; 1433 1434 if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings( 1435 host->GetID()) != 1436 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL( 1437 browser_context, site_url)) { 1438 return false; 1439 } 1440 1441 return GetContentClient()->browser()->IsSuitableHost(host, site_url); 1442} 1443 1444// static 1445bool RenderProcessHost::run_renderer_in_process() { 1446 return g_run_renderer_in_process_; 1447} 1448 1449// static 1450void RenderProcessHost::SetRunRendererInProcess(bool value) { 1451 g_run_renderer_in_process_ = value; 1452 1453 CommandLine* command_line = CommandLine::ForCurrentProcess(); 1454 if (value && !command_line->HasSwitch(switches::kLang)) { 1455 // Modify the current process' command line to include the browser locale, 1456 // as the renderer expects this flag to be set. 1457 const std::string locale = 1458 GetContentClient()->browser()->GetApplicationLocale(); 1459 command_line->AppendSwitchASCII(switches::kLang, locale); 1460 } 1461} 1462 1463RenderProcessHost::iterator RenderProcessHost::AllHostsIterator() { 1464 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1465 return iterator(g_all_hosts.Pointer()); 1466} 1467 1468// static 1469RenderProcessHost* RenderProcessHost::FromID(int render_process_id) { 1470 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); 1471 return g_all_hosts.Get().Lookup(render_process_id); 1472} 1473 1474// static 1475bool RenderProcessHost::ShouldTryToUseExistingProcessHost( 1476 BrowserContext* browser_context, const GURL& url) { 1477 // Experimental: 1478 // If --enable-strict-site-isolation or --site-per-process is enabled, do not 1479 // try to reuse renderer processes when over the limit. (We could allow pages 1480 // from the same site to share, if we knew what the given process was 1481 // dedicated to. Allowing no sharing is simpler for now.) This may cause 1482 // resource exhaustion issues if too many sites are open at once. 1483 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 1484 if (command_line.HasSwitch(switches::kEnableStrictSiteIsolation) || 1485 command_line.HasSwitch(switches::kSitePerProcess)) 1486 return false; 1487 1488 if (run_renderer_in_process()) 1489 return true; 1490 1491 // NOTE: Sometimes it's necessary to create more render processes than 1492 // GetMaxRendererProcessCount(), for instance when we want to create 1493 // a renderer process for a browser context that has no existing 1494 // renderers. This is OK in moderation, since the 1495 // GetMaxRendererProcessCount() is conservative. 1496 if (g_all_hosts.Get().size() >= GetMaxRendererProcessCount()) 1497 return true; 1498 1499 return GetContentClient()->browser()-> 1500 ShouldTryToUseExistingProcessHost(browser_context, url); 1501} 1502 1503// static 1504RenderProcessHost* RenderProcessHost::GetExistingProcessHost( 1505 BrowserContext* browser_context, 1506 const GURL& site_url) { 1507 // First figure out which existing renderers we can use. 1508 std::vector<RenderProcessHost*> suitable_renderers; 1509 suitable_renderers.reserve(g_all_hosts.Get().size()); 1510 1511 iterator iter(AllHostsIterator()); 1512 while (!iter.IsAtEnd()) { 1513 if (RenderProcessHostImpl::IsSuitableHost( 1514 iter.GetCurrentValue(), 1515 browser_context, site_url)) 1516 suitable_renderers.push_back(iter.GetCurrentValue()); 1517 1518 iter.Advance(); 1519 } 1520 1521 // Now pick a random suitable renderer, if we have any. 1522 if (!suitable_renderers.empty()) { 1523 int suitable_count = static_cast<int>(suitable_renderers.size()); 1524 int random_index = base::RandInt(0, suitable_count - 1); 1525 return suitable_renderers[random_index]; 1526 } 1527 1528 return NULL; 1529} 1530 1531// static 1532bool RenderProcessHost::ShouldUseProcessPerSite( 1533 BrowserContext* browser_context, 1534 const GURL& url) { 1535 // Returns true if we should use the process-per-site model. This will be 1536 // the case if the --process-per-site switch is specified, or in 1537 // process-per-site-instance for particular sites (e.g., WebUI). 1538 // Note that --single-process is handled in ShouldTryToUseExistingProcessHost. 1539 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); 1540 if (command_line.HasSwitch(switches::kProcessPerSite)) 1541 return true; 1542 1543 // We want to consolidate particular sites like WebUI even when we are using 1544 // the process-per-tab or process-per-site-instance models. 1545 // Note: DevTools pages have WebUI type but should not reuse the same host. 1546 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL( 1547 browser_context, url) && 1548 !url.SchemeIs(chrome::kChromeDevToolsScheme)) { 1549 return true; 1550 } 1551 1552 // Otherwise let the content client decide, defaulting to false. 1553 return GetContentClient()->browser()->ShouldUseProcessPerSite(browser_context, 1554 url); 1555} 1556 1557// static 1558RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSite( 1559 BrowserContext* browser_context, 1560 const GURL& url) { 1561 // Look up the map of site to process for the given browser_context. 1562 SiteProcessMap* map = 1563 GetSiteProcessMapForBrowserContext(browser_context); 1564 1565 // See if we have an existing process with appropriate bindings for this site. 1566 // If not, the caller should create a new process and register it. 1567 std::string site = SiteInstance::GetSiteForURL(browser_context, url) 1568 .possibly_invalid_spec(); 1569 RenderProcessHost* host = map->FindProcess(site); 1570 if (host && !IsSuitableHost(host, browser_context, url)) { 1571 // The registered process does not have an appropriate set of bindings for 1572 // the url. Remove it from the map so we can register a better one. 1573 RecordAction(UserMetricsAction("BindingsMismatch_GetProcessHostPerSite")); 1574 map->RemoveProcess(host); 1575 host = NULL; 1576 } 1577 1578 return host; 1579} 1580 1581void RenderProcessHostImpl::RegisterProcessHostForSite( 1582 BrowserContext* browser_context, 1583 RenderProcessHost* process, 1584 const GURL& url) { 1585 // Look up the map of site to process for the given browser_context. 1586 SiteProcessMap* map = 1587 GetSiteProcessMapForBrowserContext(browser_context); 1588 1589 // Only register valid, non-empty sites. Empty or invalid sites will not 1590 // use process-per-site mode. We cannot check whether the process has 1591 // appropriate bindings here, because the bindings have not yet been granted. 1592 std::string site = SiteInstance::GetSiteForURL(browser_context, url) 1593 .possibly_invalid_spec(); 1594 if (!site.empty()) 1595 map->RegisterProcess(site, process); 1596} 1597 1598void RenderProcessHostImpl::ProcessDied(bool already_dead) { 1599 // Our child process has died. If we didn't expect it, it's a crash. 1600 // In any case, we need to let everyone know it's gone. 1601 // The OnChannelError notification can fire multiple times due to nested sync 1602 // calls to a renderer. If we don't have a valid channel here it means we 1603 // already handled the error. 1604 1605 // child_process_launcher_ can be NULL in single process mode or if fast 1606 // termination happened. 1607 int exit_code = 0; 1608 base::TerminationStatus status = 1609 child_process_launcher_.get() ? 1610 child_process_launcher_->GetChildTerminationStatus(already_dead, 1611 &exit_code) : 1612 base::TERMINATION_STATUS_NORMAL_TERMINATION; 1613 1614 RendererClosedDetails details(GetHandle(), status, exit_code); 1615 NotificationService::current()->Notify( 1616 NOTIFICATION_RENDERER_PROCESS_CLOSED, 1617 Source<RenderProcessHost>(this), 1618 Details<RendererClosedDetails>(&details)); 1619 1620 child_process_launcher_.reset(); 1621 channel_.reset(); 1622 gpu_message_filter_ = NULL; 1623 1624 IDMap<IPC::Listener>::iterator iter(&listeners_); 1625 while (!iter.IsAtEnd()) { 1626 iter.GetCurrentValue()->OnMessageReceived( 1627 ViewHostMsg_RenderProcessGone(iter.GetCurrentKey(), 1628 static_cast<int>(status), 1629 exit_code)); 1630 iter.Advance(); 1631 } 1632 1633 ClearTransportDIBCache(); 1634 1635 // this object is not deleted at this point and may be reused later. 1636 // TODO(darin): clean this up 1637} 1638 1639int RenderProcessHostImpl::GetActiveViewCount() { 1640 int num_active_views = 0; 1641 scoped_ptr<RenderWidgetHostIterator> widgets( 1642 RenderWidgetHost::GetRenderWidgetHosts()); 1643 while (RenderWidgetHost* widget = widgets->GetNextHost()) { 1644 // Count only RenderWidgetHosts in this process. 1645 if (widget->GetProcess()->GetID() == GetID()) 1646 num_active_views++; 1647 } 1648 return num_active_views; 1649} 1650 1651// Frame subscription API for this class is for accelerated composited path 1652// only. These calls are redirected to GpuMessageFilter. 1653void RenderProcessHostImpl::BeginFrameSubscription( 1654 int route_id, 1655 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) { 1656 if (!gpu_message_filter_) 1657 return; 1658 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( 1659 &GpuMessageFilter::BeginFrameSubscription, 1660 gpu_message_filter_, 1661 route_id, base::Passed(&subscriber))); 1662} 1663 1664void RenderProcessHostImpl::EndFrameSubscription(int route_id) { 1665 if (!gpu_message_filter_) 1666 return; 1667 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind( 1668 &GpuMessageFilter::EndFrameSubscription, 1669 gpu_message_filter_, 1670 route_id)); 1671} 1672 1673void RenderProcessHostImpl::OnShutdownRequest() { 1674 // Don't shut down if there are active RenderViews, or if there are pending 1675 // RenderViews being swapped back in. 1676 // In single process mode, we never shutdown the renderer. 1677 int num_active_views = GetActiveViewCount(); 1678 if (pending_views_ || num_active_views > 0 || run_renderer_in_process()) 1679 return; 1680 1681 // Notify any contents that might have swapped out renderers from this 1682 // process. They should not attempt to swap them back in. 1683 NotificationService::current()->Notify( 1684 NOTIFICATION_RENDERER_PROCESS_CLOSING, 1685 Source<RenderProcessHost>(this), 1686 NotificationService::NoDetails()); 1687 1688 Send(new ChildProcessMsg_Shutdown()); 1689} 1690 1691void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) { 1692 SetSuddenTerminationAllowed(enabled); 1693} 1694 1695void RenderProcessHostImpl::OnDumpHandlesDone() { 1696 Cleanup(); 1697} 1698 1699void RenderProcessHostImpl::SetBackgrounded(bool backgrounded) { 1700 // Note: we always set the backgrounded_ value. If the process is NULL 1701 // (and hence hasn't been created yet), we will set the process priority 1702 // later when we create the process. 1703 backgrounded_ = backgrounded; 1704 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting()) 1705 return; 1706 1707#if defined(OS_WIN) 1708 // The cbstext.dll loads as a global GetMessage hook in the browser process 1709 // and intercepts/unintercepts the kernel32 API SetPriorityClass in a 1710 // background thread. If the UI thread invokes this API just when it is 1711 // intercepted the stack is messed up on return from the interceptor 1712 // which causes random crashes in the browser process. Our hack for now 1713 // is to not invoke the SetPriorityClass API if the dll is loaded. 1714 if (GetModuleHandle(L"cbstext.dll")) 1715 return; 1716#endif // OS_WIN 1717 1718 child_process_launcher_->SetProcessBackgrounded(backgrounded); 1719} 1720 1721void RenderProcessHostImpl::OnProcessLaunched() { 1722 // No point doing anything, since this object will be destructed soon. We 1723 // especially don't want to send the RENDERER_PROCESS_CREATED notification, 1724 // since some clients might expect a RENDERER_PROCESS_TERMINATED afterwards to 1725 // properly cleanup. 1726 if (deleting_soon_) 1727 return; 1728 1729 if (child_process_launcher_) { 1730 if (!child_process_launcher_->GetHandle()) { 1731 OnChannelError(); 1732 return; 1733 } 1734 1735 child_process_launcher_->SetProcessBackgrounded(backgrounded_); 1736 } 1737 1738 // NOTE: This needs to be before sending queued messages because 1739 // ExtensionService uses this notification to initialize the renderer process 1740 // with state that must be there before any JavaScript executes. 1741 // 1742 // The queued messages contain such things as "navigate". If this notification 1743 // was after, we can end up executing JavaScript before the initialization 1744 // happens. 1745 NotificationService::current()->Notify( 1746 NOTIFICATION_RENDERER_PROCESS_CREATED, 1747 Source<RenderProcessHost>(this), 1748 NotificationService::NoDetails()); 1749 1750 while (!queued_messages_.empty()) { 1751 Send(queued_messages_.front()); 1752 queued_messages_.pop(); 1753 } 1754} 1755 1756void RenderProcessHostImpl::OnUserMetricsRecordAction( 1757 const std::string& action) { 1758 RecordComputedAction(action); 1759} 1760 1761void RenderProcessHostImpl::OnSavedPageAsMHTML(int job_id, int64 data_size) { 1762 MHTMLGenerationManager::GetInstance()->MHTMLGenerated(job_id, data_size); 1763} 1764 1765void RenderProcessHostImpl::OnCompositorSurfaceBuffersSwappedNoHost( 1766 const ViewHostMsg_CompositorSurfaceBuffersSwapped_Params& params) { 1767 TRACE_EVENT0("renderer_host", 1768 "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwappedNoHost"); 1769 AcceleratedSurfaceMsg_BufferPresented_Params ack_params; 1770 ack_params.sync_point = 0; 1771 RenderWidgetHostImpl::AcknowledgeBufferPresent(params.route_id, 1772 params.gpu_process_host_id, 1773 ack_params); 1774} 1775 1776void RenderProcessHostImpl::OnGpuSwitching() { 1777 // We are updating all widgets including swapped out ones. 1778 scoped_ptr<RenderWidgetHostIterator> widgets( 1779 RenderWidgetHostImpl::GetAllRenderWidgetHosts()); 1780 while (RenderWidgetHost* widget = widgets->GetNextHost()) { 1781 if (!widget->IsRenderView()) 1782 continue; 1783 1784 // Skip widgets in other processes. 1785 if (widget->GetProcess()->GetID() != GetID()) 1786 continue; 1787 1788 RenderViewHost* rvh = RenderViewHost::From(widget); 1789 rvh->UpdateWebkitPreferences(rvh->GetWebkitPreferences()); 1790 } 1791} 1792 1793} // namespace content 1794