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