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