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