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