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