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