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