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