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.
5 // Represents the browser side of the browser <--> renderer communication
6 // channel. There will be one RenderProcessHost per renderer process.
8 #include "content/browser/renderer_host/render_process_host_impl.h"
15 #include <utility> // for pair<>
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/dom_storage/dom_storage_context_wrapper.h"
49 #include "content/browser/dom_storage/dom_storage_message_filter.h"
50 #include "content/browser/download/mhtml_generation_manager.h"
51 #include "content/browser/fileapi/chrome_blob_storage_context.h"
52 #include "content/browser/fileapi/fileapi_message_filter.h"
53 #include "content/browser/frame_host/render_frame_message_filter.h"
54 #include "content/browser/gpu/compositor_util.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/android/browser_demuxer_android.h"
64 #include "content/browser/media/media_internals.h"
65 #include "content/browser/message_port_message_filter.h"
66 #include "content/browser/mime_registry_message_filter.h"
67 #include "content/browser/plugin_service_impl.h"
68 #include "content/browser/profiler_message_filter.h"
69 #include "content/browser/quota_dispatcher_host.h"
70 #include "content/browser/renderer_host/clipboard_message_filter.h"
71 #include "content/browser/renderer_host/database_message_filter.h"
72 #include "content/browser/renderer_host/file_utilities_message_filter.h"
73 #include "content/browser/renderer_host/gamepad_browser_message_filter.h"
74 #include "content/browser/renderer_host/gpu_message_filter.h"
75 #include "content/browser/renderer_host/media/audio_input_renderer_host.h"
76 #include "content/browser/renderer_host/media/audio_mirroring_manager.h"
77 #include "content/browser/renderer_host/media/audio_renderer_host.h"
78 #include "content/browser/renderer_host/media/device_request_message_filter.h"
79 #include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
80 #include "content/browser/renderer_host/media/midi_dispatcher_host.h"
81 #include "content/browser/renderer_host/media/midi_host.h"
82 #include "content/browser/renderer_host/media/peer_connection_tracker_host.h"
83 #include "content/browser/renderer_host/media/video_capture_host.h"
84 #include "content/browser/renderer_host/memory_benchmark_message_filter.h"
85 #include "content/browser/renderer_host/p2p/socket_dispatcher_host.h"
86 #include "content/browser/renderer_host/pepper/pepper_message_filter.h"
87 #include "content/browser/renderer_host/pepper/pepper_renderer_connection.h"
88 #include "content/browser/renderer_host/render_message_filter.h"
89 #include "content/browser/renderer_host/render_view_host_delegate.h"
90 #include "content/browser/renderer_host/render_view_host_impl.h"
91 #include "content/browser/renderer_host/render_widget_helper.h"
92 #include "content/browser/renderer_host/render_widget_host_impl.h"
93 #include "content/browser/renderer_host/socket_stream_dispatcher_host.h"
94 #include "content/browser/renderer_host/text_input_client_message_filter.h"
95 #include "content/browser/renderer_host/websocket_dispatcher_host.h"
96 #include "content/browser/resolve_proxy_msg_helper.h"
97 #include "content/browser/service_worker/service_worker_context_wrapper.h"
98 #include "content/browser/service_worker/service_worker_dispatcher_host.h"
99 #include "content/browser/speech/input_tag_speech_dispatcher_host.h"
100 #include "content/browser/speech/speech_recognition_dispatcher_host.h"
101 #include "content/browser/storage_partition_impl.h"
102 #include "content/browser/streams/stream_context.h"
103 #include "content/browser/tracing/trace_message_filter.h"
104 #include "content/browser/vibration/vibration_message_filter.h"
105 #include "content/browser/webui/web_ui_controller_factory_registry.h"
106 #include "content/browser/worker_host/worker_message_filter.h"
107 #include "content/browser/worker_host/worker_storage_partition.h"
108 #include "content/common/child_process_host_impl.h"
109 #include "content/common/child_process_messages.h"
110 #include "content/common/content_switches_internal.h"
111 #include "content/common/gpu/gpu_messages.h"
112 #include "content/common/resource_messages.h"
113 #include "content/common/view_messages.h"
114 #include "content/port/browser/render_widget_host_view_frame_subscriber.h"
115 #include "content/public/browser/browser_context.h"
116 #include "content/public/browser/content_browser_client.h"
117 #include "content/public/browser/notification_service.h"
118 #include "content/public/browser/notification_types.h"
119 #include "content/public/browser/render_process_host_factory.h"
120 #include "content/public/browser/render_process_host_observer.h"
121 #include "content/public/browser/render_widget_host.h"
122 #include "content/public/browser/render_widget_host_iterator.h"
123 #include "content/public/browser/resource_context.h"
124 #include "content/public/browser/user_metrics.h"
125 #include "content/public/common/content_constants.h"
126 #include "content/public/common/content_switches.h"
127 #include "content/public/common/process_type.h"
128 #include "content/public/common/result_codes.h"
129 #include "content/public/common/url_constants.h"
130 #include "gpu/command_buffer/service/gpu_switches.h"
131 #include "ipc/ipc_channel.h"
132 #include "ipc/ipc_logging.h"
133 #include "ipc/ipc_switches.h"
134 #include "media/base/media_switches.h"
135 #include "net/url_request/url_request_context_getter.h"
136 #include "ppapi/shared_impl/ppapi_switches.h"
137 #include "ui/base/ui_base_switches.h"
138 #include "ui/events/event_switches.h"
139 #include "ui/gfx/switches.h"
140 #include "ui/gl/gl_switches.h"
141 #include "webkit/browser/fileapi/sandbox_file_system_backend.h"
142 #include "webkit/common/resource_type.h"
145 #include "base/win/scoped_com_initializer.h"
146 #include "content/common/font_cache_dispatcher_win.h"
147 #include "content/common/sandbox_win.h"
148 #include "content/public/common/sandboxed_process_launcher_delegate.h"
151 #if defined(ENABLE_WEBRTC)
152 #include "content/browser/media/webrtc_internals.h"
153 #include "content/browser/renderer_host/media/webrtc_identity_service_host.h"
154 #include "content/common/media/media_stream_messages.h"
157 #include "third_party/skia/include/core/SkBitmap.h"
159 extern bool g_exited_main_message_loop;
161 static const char* kSiteProcessMapKeyName = "content_site_process_map";
166 void CacheShaderInfo(int32 id, base::FilePath path) {
167 ShaderCacheFactory::GetInstance()->SetCacheInfo(id, path);
170 void RemoveShaderInfo(int32 id) {
171 ShaderCacheFactory::GetInstance()->RemoveCacheInfo(id);
174 net::URLRequestContext* GetRequestContext(
175 scoped_refptr<net::URLRequestContextGetter> request_context,
176 scoped_refptr<net::URLRequestContextGetter> media_request_context,
177 ResourceType::Type resource_type) {
178 // If the request has resource type of ResourceType::MEDIA, we use a request
179 // context specific to media for handling it because these resources have
180 // specific needs for caching.
181 if (resource_type == ResourceType::MEDIA)
182 return media_request_context->GetURLRequestContext();
183 return request_context->GetURLRequestContext();
187 ResourceContext* resource_context,
188 scoped_refptr<net::URLRequestContextGetter> request_context,
189 scoped_refptr<net::URLRequestContextGetter> media_request_context,
190 const ResourceHostMsg_Request& request,
191 ResourceContext** resource_context_out,
192 net::URLRequestContext** request_context_out) {
193 *resource_context_out = resource_context;
194 *request_context_out =
195 GetRequestContext(request_context, media_request_context,
196 request.resource_type);
199 #if defined(ENABLE_WEBRTC)
200 // Creates a file used for diagnostic echo canceller recordings for handing
201 // over to the renderer.
202 IPC::PlatformFileForTransit CreateAecDumpFileForProcess(
203 base::FilePath file_path,
204 base::ProcessHandle process) {
205 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
206 base::PlatformFileError error = base::PLATFORM_FILE_OK;
207 base::PlatformFile aec_dump_file = base::CreatePlatformFile(
209 base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_APPEND,
212 if (error != base::PLATFORM_FILE_OK) {
213 VLOG(1) << "Could not open AEC dump file, error=" << error;
214 return IPC::InvalidPlatformFileForTransit();
216 return IPC::GetFileHandleForProcess(aec_dump_file, process, true);
219 // Does nothing. Just to avoid races between enable and disable.
220 void DisableAecDumpOnFileThread() {
221 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
225 // the global list of all renderer processes
226 base::LazyInstance<IDMap<RenderProcessHost> >::Leaky
227 g_all_hosts = LAZY_INSTANCE_INITIALIZER;
229 base::LazyInstance<scoped_refptr<BrowserPluginGeolocationPermissionContext> >
230 g_browser_plugin_geolocation_context = LAZY_INSTANCE_INITIALIZER;
232 // Map of site to process, to ensure we only have one RenderProcessHost per
233 // site in process-per-site mode. Each map is specific to a BrowserContext.
234 class SiteProcessMap : public base::SupportsUserData::Data {
236 typedef base::hash_map<std::string, RenderProcessHost*> SiteToProcessMap;
239 void RegisterProcess(const std::string& site, RenderProcessHost* process) {
240 map_[site] = process;
243 RenderProcessHost* FindProcess(const std::string& site) {
244 SiteToProcessMap::iterator i = map_.find(site);
250 void RemoveProcess(RenderProcessHost* host) {
251 // Find all instances of this process in the map, then separately remove
253 std::set<std::string> sites;
254 for (SiteToProcessMap::const_iterator i = map_.begin();
257 if (i->second == host)
258 sites.insert(i->first);
260 for (std::set<std::string>::iterator i = sites.begin();
263 SiteToProcessMap::iterator iter = map_.find(*i);
264 if (iter != map_.end()) {
265 DCHECK_EQ(iter->second, host);
272 SiteToProcessMap map_;
275 // Find the SiteProcessMap specific to the given context.
276 SiteProcessMap* GetSiteProcessMapForBrowserContext(BrowserContext* context) {
278 SiteProcessMap* map = static_cast<SiteProcessMap*>(
279 context->GetUserData(kSiteProcessMapKeyName));
281 map = new SiteProcessMap();
282 context->SetUserData(kSiteProcessMapKeyName, map);
288 // NOTE: changes to this class need to be reviewed by the security team.
289 class RendererSandboxedProcessLauncherDelegate
290 : public content::SandboxedProcessLauncherDelegate {
292 RendererSandboxedProcessLauncherDelegate() {}
293 virtual ~RendererSandboxedProcessLauncherDelegate() {}
295 virtual void PreSpawnTarget(sandbox::TargetPolicy* policy,
297 AddBaseHandleClosePolicy(policy);
298 GetContentClient()->browser()->PreSpawnRenderer(policy, success);
305 RendererMainThreadFactoryFunction g_renderer_main_thread_factory = NULL;
307 void RenderProcessHost::RegisterRendererMainThreadFactory(
308 RendererMainThreadFactoryFunction create) {
309 g_renderer_main_thread_factory = create;
312 base::MessageLoop* g_in_process_thread;
315 RenderProcessHostImpl::GetInProcessRendererThreadForTesting() {
316 return g_in_process_thread;
319 // Stores the maximum number of renderer processes the content module can
321 static size_t g_max_renderer_count_override = 0;
324 size_t RenderProcessHost::GetMaxRendererProcessCount() {
325 if (g_max_renderer_count_override)
326 return g_max_renderer_count_override;
328 // Defines the maximum number of renderer processes according to the
329 // amount of installed memory as reported by the OS. The calculation
330 // assumes that you want the renderers to use half of the installed
331 // RAM and assuming that each WebContents uses ~40MB.
332 // If you modify this assumption, you need to adjust the
333 // ThirtyFourTabs test to match the expected number of processes.
335 // With the given amounts of installed memory below on a 32-bit CPU,
336 // the maximum renderer count will roughly be as follows:
342 // 16384 MB -> 82 (kMaxRendererProcessCount)
344 static size_t max_count = 0;
346 const size_t kEstimatedWebContentsMemoryUsage =
347 #if defined(ARCH_CPU_64_BITS)
352 max_count = base::SysInfo::AmountOfPhysicalMemoryMB() / 2;
353 max_count /= kEstimatedWebContentsMemoryUsage;
355 const size_t kMinRendererProcessCount = 3;
356 max_count = std::max(max_count, kMinRendererProcessCount);
357 max_count = std::min(max_count, kMaxRendererProcessCount);
363 bool g_run_renderer_in_process_ = false;
366 void RenderProcessHost::SetMaxRendererProcessCount(size_t count) {
367 g_max_renderer_count_override = count;
370 RenderProcessHostImpl::RenderProcessHostImpl(
371 BrowserContext* browser_context,
372 StoragePartitionImpl* storage_partition_impl,
373 bool supports_browser_plugin,
375 : fast_shutdown_started_(false),
376 deleting_soon_(false),
378 is_self_deleted_(false),
383 cached_dibs_cleaner_(
384 FROM_HERE, base::TimeDelta::FromSeconds(5),
385 this, &RenderProcessHostImpl::ClearTransportDIBCache),
386 is_initialized_(false),
387 id_(ChildProcessHostImpl::GenerateChildProcessUniqueId()),
388 browser_context_(browser_context),
389 storage_partition_impl_(storage_partition_impl),
390 sudden_termination_allowed_(true),
391 ignore_input_events_(false),
392 supports_browser_plugin_(supports_browser_plugin),
394 gpu_observer_registered_(false),
395 delayed_cleanup_needed_(false),
396 within_process_died_observer_(false),
397 power_monitor_broadcaster_(this),
398 geolocation_dispatcher_host_(NULL),
399 weak_factory_(this) {
400 widget_helper_ = new RenderWidgetHelper();
402 ChildProcessSecurityPolicyImpl::GetInstance()->Add(GetID());
404 CHECK(!g_exited_main_message_loop);
405 RegisterHost(GetID(), this);
406 g_all_hosts.Get().set_check_on_null_data(true);
407 // Initialize |child_process_activity_time_| to a reasonable value.
408 mark_child_process_activity_time();
410 if (!GetBrowserContext()->IsOffTheRecord() &&
411 !CommandLine::ForCurrentProcess()->HasSwitch(
412 switches::kDisableGpuShaderDiskCache)) {
413 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
414 base::Bind(&CacheShaderInfo, GetID(),
415 storage_partition_impl_->GetPath()));
418 // Note: When we create the RenderProcessHostImpl, it's technically
419 // backgrounded, because it has no visible listeners. But the process
420 // doesn't actually exist yet, so we'll Background it later, after
425 void RenderProcessHostImpl::ShutDownInProcessRenderer() {
426 DCHECK(g_run_renderer_in_process_);
428 switch (g_all_hosts.Pointer()->size()) {
432 RenderProcessHostImpl* host = static_cast<RenderProcessHostImpl*>(
433 AllHostsIterator().GetCurrentValue());
434 FOR_EACH_OBSERVER(RenderProcessHostObserver,
436 RenderProcessHostDestroyed(host));
438 host->is_self_deleted_ = true;
444 NOTREACHED() << "There should be only one RenderProcessHost when running "
449 RenderProcessHostImpl::~RenderProcessHostImpl() {
451 DCHECK(is_self_deleted_)
452 << "RenderProcessHostImpl is destroyed by something other than itself";
455 // Make sure to clean up the in-process renderer before the channel, otherwise
456 // it may still run and have its IPCs fail, causing asserts.
457 in_process_renderer_.reset();
459 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(GetID());
461 if (gpu_observer_registered_) {
462 GpuDataManagerImpl::GetInstance()->RemoveObserver(this);
463 gpu_observer_registered_ = false;
466 // We may have some unsent messages at this point, but that's OK.
468 while (!queued_messages_.empty()) {
469 delete queued_messages_.front();
470 queued_messages_.pop();
473 ClearTransportDIBCache();
474 UnregisterHost(GetID());
476 if (!CommandLine::ForCurrentProcess()->HasSwitch(
477 switches::kDisableGpuShaderDiskCache)) {
478 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
479 base::Bind(&RemoveShaderInfo, GetID()));
483 void RenderProcessHostImpl::EnableSendQueue() {
484 is_initialized_ = false;
487 bool RenderProcessHostImpl::Init() {
488 // calling Init() more than once does nothing, this makes it more convenient
489 // for the view host which may not be sure in some cases
493 CommandLine::StringType renderer_prefix;
494 #if defined(OS_POSIX)
495 // A command prefix is something prepended to the command line of the spawned
496 // process. It is supported only on POSIX systems.
497 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
499 browser_command_line.GetSwitchValueNative(switches::kRendererCmdPrefix);
500 #endif // defined(OS_POSIX)
502 #if defined(OS_LINUX)
503 int flags = renderer_prefix.empty() ? ChildProcessHost::CHILD_ALLOW_SELF :
504 ChildProcessHost::CHILD_NORMAL;
506 int flags = ChildProcessHost::CHILD_NORMAL;
509 // Find the renderer before creating the channel so if this fails early we
510 // return without creating the channel.
511 base::FilePath renderer_path = ChildProcessHost::GetChildPath(flags);
512 if (renderer_path.empty())
515 // Setup the IPC channel.
516 const std::string channel_id =
517 IPC::Channel::GenerateVerifiedChannelID(std::string());
519 new IPC::ChannelProxy(channel_id,
520 IPC::Channel::MODE_SERVER,
522 BrowserThread::GetMessageLoopProxyForThread(
523 BrowserThread::IO).get()));
525 // Call the embedder first so that their IPC filters have priority.
526 GetContentClient()->browser()->RenderProcessWillLaunch(this);
528 CreateMessageFilters();
530 if (run_renderer_in_process()) {
531 DCHECK(g_renderer_main_thread_factory);
532 // Crank up a thread and run the initialization there. With the way that
533 // messages flow between the browser and renderer, this thread is required
534 // to prevent a deadlock in single-process mode. Since the primordial
535 // thread in the renderer process runs the WebKit code and can sometimes
536 // make blocking calls to the UI thread (i.e. this thread), they need to run
537 // on separate threads.
538 in_process_renderer_.reset(g_renderer_main_thread_factory(channel_id));
540 base::Thread::Options options;
541 #if defined(OS_WIN) && !defined(OS_MACOSX)
542 // In-process plugins require this to be a UI message loop.
543 options.message_loop_type = base::MessageLoop::TYPE_UI;
545 // We can't have multiple UI loops on Linux and Android, so we don't support
546 // in-process plugins.
547 options.message_loop_type = base::MessageLoop::TYPE_DEFAULT;
549 in_process_renderer_->StartWithOptions(options);
551 g_in_process_thread = in_process_renderer_->message_loop();
553 OnProcessLaunched(); // Fake a callback that the process is ready.
555 // Build command line for renderer. We call AppendRendererCommandLine()
556 // first so the process type argument will appear first.
557 CommandLine* cmd_line = new CommandLine(renderer_path);
558 if (!renderer_prefix.empty())
559 cmd_line->PrependWrapper(renderer_prefix);
560 AppendRendererCommandLine(cmd_line);
561 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id);
563 // Spawn the child process asynchronously to avoid blocking the UI thread.
564 // As long as there's no renderer prefix, we can use the zygote process
566 child_process_launcher_.reset(new ChildProcessLauncher(
568 new RendererSandboxedProcessLauncherDelegate,
570 #elif defined(OS_POSIX)
571 renderer_prefix.empty(),
572 base::EnvironmentMap(),
573 channel_->TakeClientFileDescriptor(),
579 fast_shutdown_started_ = false;
582 if (!gpu_observer_registered_) {
583 gpu_observer_registered_ = true;
584 GpuDataManagerImpl::GetInstance()->AddObserver(this);
587 is_initialized_ = true;
591 void RenderProcessHostImpl::CreateMessageFilters() {
592 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
593 AddFilter(new ResourceSchedulerFilter(GetID()));
594 MediaInternals* media_internals = MediaInternals::GetInstance();;
595 media::AudioManager* audio_manager =
596 BrowserMainLoop::GetInstance()->audio_manager();
597 // Add BrowserPluginMessageFilter to ensure it gets the first stab at messages
599 if (supports_browser_plugin_) {
600 scoped_refptr<BrowserPluginMessageFilter> bp_message_filter(
601 new BrowserPluginMessageFilter(GetID(), IsGuest()));
602 AddFilter(bp_message_filter.get());
605 scoped_refptr<RenderMessageFilter> render_message_filter(
606 new RenderMessageFilter(
609 #if defined(ENABLE_PLUGINS)
610 PluginServiceImpl::GetInstance(),
615 GetBrowserContext()->GetRequestContextForRenderProcess(GetID()),
616 widget_helper_.get(),
619 storage_partition_impl_->GetDOMStorageContext()));
620 AddFilter(render_message_filter.get());
622 new RenderFrameMessageFilter(GetID(), widget_helper_.get()));
623 BrowserContext* browser_context = GetBrowserContext();
624 ResourceContext* resource_context = browser_context->GetResourceContext();
626 scoped_refptr<net::URLRequestContextGetter> request_context(
627 browser_context->GetRequestContextForRenderProcess(GetID()));
628 scoped_refptr<net::URLRequestContextGetter> media_request_context(
629 browser_context->GetMediaRequestContextForRenderProcess(GetID()));
631 ResourceMessageFilter::GetContextsCallback get_contexts_callback(
632 base::Bind(&GetContexts, browser_context->GetResourceContext(),
633 request_context, media_request_context));
635 ResourceMessageFilter* resource_message_filter = new ResourceMessageFilter(
636 GetID(), PROCESS_TYPE_RENDERER,
637 storage_partition_impl_->GetAppCacheService(),
638 ChromeBlobStorageContext::GetFor(browser_context),
639 storage_partition_impl_->GetFileSystemContext(),
640 get_contexts_callback);
642 AddFilter(resource_message_filter);
643 MediaStreamManager* media_stream_manager =
644 BrowserMainLoop::GetInstance()->media_stream_manager();
645 AddFilter(new AudioInputRendererHost(
647 media_stream_manager,
648 BrowserMainLoop::GetInstance()->audio_mirroring_manager(),
649 BrowserMainLoop::GetInstance()->user_input_monitor()));
650 // The AudioRendererHost needs to be available for lookup, so it's
651 // stashed in a member variable.
652 audio_renderer_host_ = new AudioRendererHost(
655 BrowserMainLoop::GetInstance()->audio_mirroring_manager(),
657 media_stream_manager);
658 AddFilter(audio_renderer_host_);
660 new MidiHost(GetID(), BrowserMainLoop::GetInstance()->midi_manager()));
661 AddFilter(new MidiDispatcherHost(GetID(), browser_context));
662 AddFilter(new VideoCaptureHost(media_stream_manager));
663 AddFilter(new AppCacheDispatcherHost(
664 storage_partition_impl_->GetAppCacheService(),
666 AddFilter(new ClipboardMessageFilter);
667 AddFilter(new DOMStorageMessageFilter(
669 storage_partition_impl_->GetDOMStorageContext()));
670 AddFilter(new IndexedDBDispatcherHost(
671 storage_partition_impl_->GetIndexedDBContext()));
673 scoped_refptr<ServiceWorkerDispatcherHost> service_worker_filter =
674 new ServiceWorkerDispatcherHost(GetID());
675 service_worker_filter->Init(
676 storage_partition_impl_->GetServiceWorkerContext());
677 AddFilter(service_worker_filter);
680 if (!g_browser_plugin_geolocation_context.Get().get()) {
681 g_browser_plugin_geolocation_context.Get() =
682 new BrowserPluginGeolocationPermissionContext();
684 geolocation_dispatcher_host_ = GeolocationDispatcherHost::New(
685 GetID(), g_browser_plugin_geolocation_context.Get().get());
687 geolocation_dispatcher_host_ = GeolocationDispatcherHost::New(
688 GetID(), browser_context->GetGeolocationPermissionContext());
690 AddFilter(geolocation_dispatcher_host_);
691 gpu_message_filter_ = new GpuMessageFilter(GetID(), widget_helper_.get());
692 AddFilter(gpu_message_filter_);
693 #if defined(ENABLE_WEBRTC)
694 AddFilter(new WebRTCIdentityServiceHost(
695 GetID(), storage_partition_impl_->GetWebRTCIdentityStore()));
696 peer_connection_tracker_host_ = new PeerConnectionTrackerHost(GetID());
697 AddFilter(peer_connection_tracker_host_.get());
698 AddFilter(new MediaStreamDispatcherHost(
700 browser_context->GetResourceContext()->GetMediaDeviceIDSalt(),
701 media_stream_manager));
703 new DeviceRequestMessageFilter(resource_context, media_stream_manager));
705 #if defined(ENABLE_PLUGINS)
706 AddFilter(new PepperRendererConnection(GetID()));
708 #if defined(ENABLE_INPUT_SPEECH)
709 AddFilter(new InputTagSpeechDispatcherHost(
710 IsGuest(), GetID(), storage_partition_impl_->GetURLRequestContext()));
712 AddFilter(new SpeechRecognitionDispatcherHost(
713 IsGuest(), GetID(), storage_partition_impl_->GetURLRequestContext()));
714 AddFilter(new FileAPIMessageFilter(
716 storage_partition_impl_->GetURLRequestContext(),
717 storage_partition_impl_->GetFileSystemContext(),
718 ChromeBlobStorageContext::GetFor(browser_context),
719 StreamContext::GetFor(browser_context)));
720 AddFilter(new FileUtilitiesMessageFilter(GetID()));
721 AddFilter(new MimeRegistryMessageFilter());
722 AddFilter(new DatabaseMessageFilter(
723 storage_partition_impl_->GetDatabaseTracker()));
724 #if defined(OS_MACOSX)
725 AddFilter(new TextInputClientMessageFilter(GetID()));
726 #elif defined(OS_WIN)
727 channel_->AddFilter(new FontCacheDispatcher());
728 #elif defined(OS_ANDROID)
729 browser_demuxer_android_ = new BrowserDemuxerAndroid();
730 AddFilter(browser_demuxer_android_);
733 SocketStreamDispatcherHost::GetRequestContextCallback
734 request_context_callback(
735 base::Bind(&GetRequestContext, request_context,
736 media_request_context));
738 SocketStreamDispatcherHost* socket_stream_dispatcher_host =
739 new SocketStreamDispatcherHost(
740 GetID(), request_context_callback, resource_context);
741 AddFilter(socket_stream_dispatcher_host);
743 WebSocketDispatcherHost::GetRequestContextCallback
744 websocket_request_context_callback(
745 base::Bind(&GetRequestContext, request_context,
746 media_request_context, ResourceType::SUB_RESOURCE));
748 AddFilter(new WebSocketDispatcherHost(websocket_request_context_callback));
750 message_port_message_filter_ = new MessagePortMessageFilter(
751 base::Bind(&RenderWidgetHelper::GetNextRoutingID,
752 base::Unretained(widget_helper_.get())));
753 AddFilter(message_port_message_filter_);
755 AddFilter(new WorkerMessageFilter(
758 WorkerStoragePartition(
759 storage_partition_impl_->GetURLRequestContext(),
760 storage_partition_impl_->GetMediaURLRequestContext(),
761 storage_partition_impl_->GetAppCacheService(),
762 storage_partition_impl_->GetQuotaManager(),
763 storage_partition_impl_->GetFileSystemContext(),
764 storage_partition_impl_->GetDatabaseTracker(),
765 storage_partition_impl_->GetIndexedDBContext()),
766 message_port_message_filter_));
768 #if defined(ENABLE_WEBRTC)
769 AddFilter(new P2PSocketDispatcherHost(
771 browser_context->GetRequestContextForRenderProcess(GetID())));
774 AddFilter(new TraceMessageFilter());
775 AddFilter(new ResolveProxyMsgHelper(
776 browser_context->GetRequestContextForRenderProcess(GetID())));
777 AddFilter(new QuotaDispatcherHost(
779 storage_partition_impl_->GetQuotaManager(),
780 GetContentClient()->browser()->CreateQuotaPermissionContext()));
781 AddFilter(new GamepadBrowserMessageFilter());
782 AddFilter(new DeviceMotionMessageFilter());
783 AddFilter(new DeviceOrientationMessageFilter());
784 AddFilter(new ProfilerMessageFilter(PROCESS_TYPE_RENDERER));
785 AddFilter(new HistogramMessageFilter());
786 #if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID))
787 if (CommandLine::ForCurrentProcess()->HasSwitch(
788 switches::kEnableMemoryBenchmarking))
789 AddFilter(new MemoryBenchmarkMessageFilter());
791 AddFilter(new VibrationMessageFilter());
794 int RenderProcessHostImpl::GetNextRoutingID() {
795 return widget_helper_->GetNextRoutingID();
799 void RenderProcessHostImpl::ResumeDeferredNavigation(
800 const GlobalRequestID& request_id) {
801 widget_helper_->ResumeDeferredNavigation(request_id);
804 void RenderProcessHostImpl::AddRoute(
806 IPC::Listener* listener) {
807 listeners_.AddWithID(listener, routing_id);
810 void RenderProcessHostImpl::RemoveRoute(int32 routing_id) {
811 DCHECK(listeners_.Lookup(routing_id) != NULL);
812 listeners_.Remove(routing_id);
815 // Dump the handle table if handle auditing is enabled.
816 const CommandLine& browser_command_line =
817 *CommandLine::ForCurrentProcess();
818 if (browser_command_line.HasSwitch(switches::kAuditHandles) ||
819 browser_command_line.HasSwitch(switches::kAuditAllHandles)) {
822 // We wait to close the channels until the child process has finished
823 // dumping handles and sends us ChildProcessHostMsg_DumpHandlesDone.
827 // Keep the one renderer thread around forever in single process mode.
828 if (!run_renderer_in_process())
832 void RenderProcessHostImpl::AddObserver(RenderProcessHostObserver* observer) {
833 observers_.AddObserver(observer);
836 void RenderProcessHostImpl::RemoveObserver(
837 RenderProcessHostObserver* observer) {
838 observers_.RemoveObserver(observer);
841 bool RenderProcessHostImpl::WaitForBackingStoreMsg(
842 int render_widget_id,
843 const base::TimeDelta& max_delay,
845 // The post task to this thread with the process id could be in queue, and we
846 // don't want to dispatch a message before then since it will need the handle.
847 if (child_process_launcher_.get() && child_process_launcher_->IsStarting())
850 return widget_helper_->WaitForBackingStoreMsg(render_widget_id,
854 void RenderProcessHostImpl::ReceivedBadMessage() {
855 CommandLine* command_line = CommandLine::ForCurrentProcess();
856 if (command_line->HasSwitch(switches::kDisableKillAfterBadIPC))
859 if (run_renderer_in_process()) {
860 // In single process mode it is better if we don't suicide but just
864 // We kill the renderer but don't include a NOTREACHED, because we want the
865 // browser to try to survive when it gets illegal messages from the renderer.
866 base::KillProcess(GetHandle(), RESULT_CODE_KILLED_BAD_MESSAGE,
870 void RenderProcessHostImpl::WidgetRestored() {
871 // Verify we were properly backgrounded.
872 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0));
874 SetBackgrounded(false);
877 void RenderProcessHostImpl::WidgetHidden() {
878 // On startup, the browser will call Hide
882 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0));
884 DCHECK_GE(visible_widgets_, 0);
885 if (visible_widgets_ == 0) {
886 DCHECK(!backgrounded_);
887 SetBackgrounded(true);
891 int RenderProcessHostImpl::VisibleWidgetCount() const {
892 return visible_widgets_;
895 bool RenderProcessHostImpl::IsGuest() const {
899 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const {
900 return storage_partition_impl_;
903 static void AppendGpuCommandLineFlags(CommandLine* command_line) {
904 if (content::IsThreadedCompositingEnabled())
905 command_line->AppendSwitch(switches::kEnableThreadedCompositing);
907 if (content::IsDelegatedRendererEnabled())
908 command_line->AppendSwitch(switches::kEnableDelegatedRenderer);
910 if (content::IsDeadlineSchedulingEnabled())
911 command_line->AppendSwitch(switches::kEnableDeadlineScheduling);
913 // Appending disable-gpu-feature switches due to software rendering list.
914 GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance();
915 DCHECK(gpu_data_manager);
916 gpu_data_manager->AppendRendererCommandLine(command_line);
919 void RenderProcessHostImpl::AppendRendererCommandLine(
920 CommandLine* command_line) const {
921 // Pass the process type first, so it shows first in process listings.
922 command_line->AppendSwitchASCII(switches::kProcessType,
923 switches::kRendererProcess);
925 // Now send any options from our own command line we want to propagate.
926 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
927 PropagateBrowserCommandLineToRenderer(browser_command_line, command_line);
929 // Pass on the browser locale.
930 const std::string locale =
931 GetContentClient()->browser()->GetApplicationLocale();
932 command_line->AppendSwitchASCII(switches::kLang, locale);
934 // If we run base::FieldTrials, we want to pass to their state to the
935 // renderer so that it can act in accordance with each state, or record
936 // histograms relating to the base::FieldTrial states.
937 std::string field_trial_states;
938 base::FieldTrialList::StatesToString(&field_trial_states);
939 if (!field_trial_states.empty()) {
940 command_line->AppendSwitchASCII(switches::kForceFieldTrials,
944 GetContentClient()->browser()->AppendExtraCommandLineSwitches(
945 command_line, GetID());
947 if (content::IsPinchToZoomEnabled())
948 command_line->AppendSwitch(switches::kEnablePinch);
950 AppendGpuCommandLineFlags(command_line);
953 void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
954 const CommandLine& browser_cmd,
955 CommandLine* renderer_cmd) const {
956 // Propagate the following switches to the renderer command line (along
957 // with any associated values) if present in the browser command line.
958 static const char* const kSwitchNames[] = {
959 switches::kAudioBufferSize,
960 switches::kAuditAllHandles,
961 switches::kAuditHandles,
962 switches::kBlinkPlatformLogChannels,
963 switches::kBlockCrossSiteDocuments,
964 switches::kDefaultTileWidth,
965 switches::kDefaultTileHeight,
966 switches::kDisable3DAPIs,
967 switches::kDisableAcceleratedCompositing,
968 switches::kDisableAcceleratedFixedRootBackground,
969 switches::kDisableAcceleratedScrollableFrames,
970 switches::kDisableAcceleratedVideoDecode,
971 switches::kDisableApplicationCache,
972 switches::kDisableAudio,
973 switches::kDisableBreakpad,
974 switches::kDisableCompositedScrollingForFrames,
975 switches::kDisableCompositingForFixedPosition,
976 switches::kDisableCompositingForTransition,
977 switches::kDisableDatabases,
978 switches::kDisableDeadlineScheduling,
979 switches::kDisableDelegatedRenderer,
980 switches::kDisableDesktopNotifications,
981 switches::kDisableDirectNPAPIRequests,
982 switches::kDisableFileSystem,
983 switches::kDisableFiltersOverIPC,
984 switches::kDisableFullScreen,
985 switches::kDisableGpu,
986 switches::kDisableGpuCompositing,
987 switches::kDisableGpuVsync,
988 switches::kDisableHistogramCustomizer,
989 switches::kDisableLayerSquashing,
990 switches::kDisableLocalStorage,
991 switches::kDisableLogging,
992 switches::kDisableOpusPlayback,
993 switches::kDisableOverlayScrollbar,
994 switches::kDisablePinch,
995 switches::kDisablePrefixedEncryptedMedia,
996 switches::kDisableRepaintAfterLayout,
997 switches::kDisableSeccompFilterSandbox,
998 switches::kDisableSessionStorage,
999 switches::kDisableSharedWorkers,
1000 switches::kDisableSpeechInput,
1001 switches::kDisableThreadedCompositing,
1002 switches::kDisableTouchAdjustment,
1003 switches::kDisableTouchDragDrop,
1004 switches::kDisableTouchEditing,
1005 switches::kDisableUniversalAcceleratedOverflowScroll,
1006 switches::kDisableUnprefixedMediaSource,
1007 switches::kDisableVp8AlphaPlayback,
1008 switches::kDisableWebAnimationsCSS,
1009 switches::kDisableWebKitMediaSource,
1010 switches::kDomAutomationController,
1011 switches::kEnableAcceleratedFixedRootBackground,
1012 switches::kEnableAcceleratedOverflowScroll,
1013 switches::kEnableAcceleratedScrollableFrames,
1014 switches::kEnableAccessibilityLogging,
1015 switches::kEnableADTSStreamParser,
1016 switches::kEnableBeginFrameScheduling,
1017 switches::kEnableBrowserPluginForAllViewTypes,
1018 switches::kEnableCompositedScrollingForFrames,
1019 switches::kEnableCompositingForFixedPosition,
1020 switches::kEnableCompositingForTransition,
1021 switches::kEnableDCHECK,
1022 switches::kEnableDeadlineScheduling,
1023 switches::kEnableDeferredImageDecoding,
1024 switches::kEnableDelegatedRenderer,
1025 switches::kEnableEncryptedMedia,
1026 switches::kEnableExperimentalCanvasFeatures,
1027 switches::kEnableExperimentalWebPlatformFeatures,
1028 switches::kEnableExperimentalWebSocket,
1029 switches::kEnableFastTextAutosizing,
1030 switches::kEnableGPUClientLogging,
1031 switches::kEnableGpuClientTracing,
1032 switches::kEnableGPUServiceLogging,
1033 switches::kEnableHighDpiCompositingForFixedPosition,
1034 switches::kEnableHTMLImports,
1035 switches::kEnableInbandTextTracks,
1036 switches::kEnableInputModeAttribute,
1037 switches::kEnableLayerSquashing,
1038 switches::kEnableLogging,
1039 switches::kEnableMP3StreamParser,
1040 switches::kEnableMemoryBenchmarking,
1041 switches::kEnableOverlayFullscreenVideo,
1042 switches::kEnableOverlayScrollbar,
1043 switches::kEnableOverscrollNotifications,
1044 switches::kEnablePinch,
1045 switches::kEnablePreparsedJsCaching,
1046 switches::kEnablePruneGpuCommandBuffers,
1047 switches::kEnableRepaintAfterLayout,
1048 switches::kEnableServiceWorker,
1049 switches::kEnableSkiaBenchmarking,
1050 switches::kEnableSoftwareCompositing,
1051 switches::kEnableSpeechSynthesis,
1052 switches::kEnableStatsTable,
1053 switches::kEnableStrictSiteIsolation,
1054 switches::kEnableTargetedStyleRecalc,
1055 switches::kEnableThreadedCompositing,
1056 switches::kEnableUniversalAcceleratedOverflowScroll,
1057 switches::kEnableTouchDragDrop,
1058 switches::kEnableTouchEditing,
1059 switches::kEnableViewport,
1060 switches::kEnableViewportMeta,
1061 switches::kMainFrameResizesAreOrientationChanges,
1062 switches::kEnableVtune,
1063 switches::kEnableWebAnimationsCSS,
1064 switches::kEnableWebAnimationsSVG,
1065 switches::kEnableWebGLDraftExtensions,
1066 switches::kEnableWebMIDI,
1067 switches::kForceDeviceScaleFactor,
1068 switches::kFullMemoryCrashReport,
1069 switches::kJavaScriptFlags,
1070 switches::kLoggingLevel,
1071 switches::kMaxUntiledLayerWidth,
1072 switches::kMaxUntiledLayerHeight,
1073 switches::kMemoryMetrics,
1074 switches::kNoReferrers,
1075 switches::kNoSandbox,
1076 switches::kNumRasterThreads,
1077 switches::kPpapiInProcess,
1078 switches::kProfilerTiming,
1079 switches::kReduceSecurityForTesting,
1080 switches::kRegisterPepperPlugins,
1081 switches::kRendererAssertTest,
1082 switches::kRendererStartupDialog,
1083 switches::kShowPaintRects,
1084 switches::kSitePerProcess,
1085 switches::kStatsCollectionController,
1086 switches::kTestSandbox,
1087 switches::kTouchEvents,
1088 switches::kTraceToConsole,
1089 switches::kUseDiscardableMemory,
1090 // This flag needs to be propagated to the renderer process for
1091 // --in-process-webgl.
1093 switches::kUseMobileUserAgent,
1094 switches::kUserAgent,
1096 switches::kVideoThreads,
1098 switches::kWebGLCommandBufferSizeKb,
1099 // Please keep these in alphabetical order. Compositor switches here should
1100 // also be added to chrome/browser/chromeos/login/chrome_restart_request.cc.
1101 cc::switches::kBackgroundColorInsteadOfCheckerboard,
1102 cc::switches::kCompositeToMailbox,
1103 cc::switches::kDisableCompositedAntialiasing,
1104 cc::switches::kDisableCompositorTouchHitTesting,
1105 cc::switches::kDisableGPURasterization,
1106 cc::switches::kDisableImplSidePainting,
1107 cc::switches::kDisableLCDText,
1108 cc::switches::kDisableMapImage,
1109 cc::switches::kDisableThreadedAnimation,
1110 cc::switches::kEnableGpuBenchmarking,
1111 cc::switches::kEnableGPURasterization,
1112 cc::switches::kEnableImplSidePainting,
1113 cc::switches::kEnableLCDText,
1114 cc::switches::kEnableMapImage,
1115 cc::switches::kEnablePerTilePainting,
1116 cc::switches::kEnablePinchVirtualViewport,
1117 cc::switches::kEnableTopControlsPositionCalculation,
1118 cc::switches::kMaxTilesForInterestArea,
1119 cc::switches::kMaxUnusedResourceMemoryUsagePercentage,
1120 cc::switches::kShowCompositedLayerBorders,
1121 cc::switches::kShowFPSCounter,
1122 cc::switches::kShowLayerAnimationBounds,
1123 cc::switches::kShowNonOccludingRects,
1124 cc::switches::kShowOccludingRects,
1125 cc::switches::kShowPropertyChangedRects,
1126 cc::switches::kShowReplicaScreenSpaceRects,
1127 cc::switches::kShowScreenSpaceRects,
1128 cc::switches::kShowSurfaceDamageRects,
1129 cc::switches::kSlowDownRasterScaleFactor,
1130 cc::switches::kStrictLayerPropertyChangeChecking,
1131 cc::switches::kTopControlsHeight,
1132 cc::switches::kTopControlsHideThreshold,
1133 cc::switches::kTopControlsShowThreshold,
1134 cc::switches::kTraceOverdraw,
1135 #if defined(ENABLE_PLUGINS)
1136 switches::kEnablePepperTesting,
1138 #if defined(ENABLE_WEBRTC)
1139 switches::kEnableAudioTrackProcessing,
1140 switches::kDisableDeviceEnumeration,
1141 switches::kDisableSCTPDataChannels,
1142 switches::kDisableWebRtcHWDecoding,
1143 switches::kDisableWebRtcHWEncoding,
1144 switches::kEnableWebRtcAecRecordings,
1145 switches::kEnableWebRtcHWVp8Encoding,
1146 switches::kEnableWebRtcTcpServerSocket,
1148 #if defined(OS_ANDROID)
1149 switches::kDisableGestureRequirementForMediaPlayback,
1150 switches::kDisableLowEndDeviceMode,
1151 switches::kDisableWebRTC,
1152 switches::kEnableLowEndDeviceMode,
1153 switches::kEnableSpeechRecognition,
1154 switches::kHideScrollbars,
1155 switches::kMediaDrmEnableNonCompositing,
1156 switches::kNetworkCountryIso,
1158 #if defined(OS_ANDROID) && defined(ARCH_CPU_X86)
1159 switches::kEnableWebAudio,
1161 // Need to be able to disable webaudio on other platforms where it
1162 // is enabled by default.
1163 switches::kDisableWebAudio,
1165 #if defined(OS_MACOSX)
1166 // Allow this to be set when invoking the browser and relayed along.
1167 switches::kEnableSandboxLogging,
1169 #if defined(OS_POSIX)
1170 switches::kChildCleanExit,
1173 switches::kEnableDirectWrite,
1174 switches::kEnableHighResolutionTime,
1177 renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames,
1178 arraysize(kSwitchNames));
1180 if (browser_cmd.HasSwitch(switches::kTraceStartup) &&
1181 BrowserMainLoop::GetInstance()->is_tracing_startup()) {
1182 // Pass kTraceStartup switch to renderer only if startup tracing has not
1184 renderer_cmd->AppendSwitchASCII(
1185 switches::kTraceStartup,
1186 browser_cmd.GetSwitchValueASCII(switches::kTraceStartup));
1189 // Disable databases in incognito mode.
1190 if (GetBrowserContext()->IsOffTheRecord() &&
1191 !browser_cmd.HasSwitch(switches::kDisableDatabases)) {
1192 renderer_cmd->AppendSwitch(switches::kDisableDatabases);
1193 #if defined(OS_ANDROID)
1194 renderer_cmd->AppendSwitch(switches::kDisableMediaHistoryLogging);
1198 // Enforce the extra command line flags for impl-side painting.
1199 if (cc::switches::IsImplSidePaintingEnabled() &&
1200 !browser_cmd.HasSwitch(switches::kEnableDeferredImageDecoding))
1201 renderer_cmd->AppendSwitch(switches::kEnableDeferredImageDecoding);
1204 base::ProcessHandle RenderProcessHostImpl::GetHandle() const {
1205 if (run_renderer_in_process())
1206 return base::Process::Current().handle();
1208 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting())
1209 return base::kNullProcessHandle;
1211 return child_process_launcher_->GetHandle();
1214 bool RenderProcessHostImpl::FastShutdownIfPossible() {
1215 if (run_renderer_in_process())
1216 return false; // Single process mode never shutdown the renderer.
1218 if (!GetContentClient()->browser()->IsFastShutdownPossible())
1221 if (!child_process_launcher_.get() ||
1222 child_process_launcher_->IsStarting() ||
1224 return false; // Render process hasn't started or is probably crashed.
1226 // Test if there's an unload listener.
1227 // NOTE: It's possible that an onunload listener may be installed
1228 // while we're shutting down, so there's a small race here. Given that
1229 // the window is small, it's unlikely that the web page has much
1230 // state that will be lost by not calling its unload handlers properly.
1231 if (!SuddenTerminationAllowed())
1234 // Set this before ProcessDied() so observers can tell if the render process
1235 // died due to fast shutdown versus another cause.
1236 fast_shutdown_started_ = true;
1238 ProcessDied(false /* already_dead */);
1242 void RenderProcessHostImpl::DumpHandles() {
1244 Send(new ChildProcessMsg_DumpHandles());
1251 // This is a platform specific function for mapping a transport DIB given its id
1252 TransportDIB* RenderProcessHostImpl::MapTransportDIB(
1253 TransportDIB::Id dib_id) {
1255 // On Windows we need to duplicate the handle from the remote process
1257 DuplicateHandle(GetHandle(), dib_id.handle, GetCurrentProcess(), §ion,
1258 FILE_MAP_READ | FILE_MAP_WRITE,
1260 return TransportDIB::Map(section);
1261 #elif defined(TOOLKIT_GTK)
1262 return TransportDIB::Map(dib_id.shmkey);
1263 #elif defined(OS_ANDROID)
1264 return TransportDIB::Map(dib_id);
1266 // On POSIX, the browser allocates all DIBs and keeps a file descriptor around
1268 return widget_helper_->MapTransportDIB(dib_id);
1272 TransportDIB* RenderProcessHostImpl::GetTransportDIB(
1273 TransportDIB::Id dib_id) {
1274 if (!TransportDIB::is_valid_id(dib_id))
1277 const std::map<TransportDIB::Id, TransportDIB*>::iterator
1278 i = cached_dibs_.find(dib_id);
1279 if (i != cached_dibs_.end()) {
1280 cached_dibs_cleaner_.Reset();
1284 TransportDIB* dib = MapTransportDIB(dib_id);
1288 if (cached_dibs_.size() >= MAX_MAPPED_TRANSPORT_DIBS) {
1289 // Clean a single entry from the cache
1290 std::map<TransportDIB::Id, TransportDIB*>::iterator smallest_iterator;
1291 size_t smallest_size = std::numeric_limits<size_t>::max();
1293 for (std::map<TransportDIB::Id, TransportDIB*>::iterator
1294 i = cached_dibs_.begin(); i != cached_dibs_.end(); ++i) {
1295 if (i->second->size() <= smallest_size) {
1296 smallest_iterator = i;
1297 smallest_size = i->second->size();
1301 #if defined(TOOLKIT_GTK)
1302 smallest_iterator->second->Detach();
1304 delete smallest_iterator->second;
1306 cached_dibs_.erase(smallest_iterator);
1309 cached_dibs_[dib_id] = dib;
1310 cached_dibs_cleaner_.Reset();
1314 void RenderProcessHostImpl::ClearTransportDIBCache() {
1315 #if defined(TOOLKIT_GTK)
1316 std::map<TransportDIB::Id, TransportDIB*>::const_iterator dib =
1317 cached_dibs_.begin();
1318 for (; dib != cached_dibs_.end(); ++dib)
1319 dib->second->Detach();
1321 STLDeleteContainerPairSecondPointers(
1322 cached_dibs_.begin(), cached_dibs_.end());
1324 cached_dibs_.clear();
1327 bool RenderProcessHostImpl::Send(IPC::Message* msg) {
1328 TRACE_EVENT0("renderer_host", "RenderProcessHostImpl::Send");
1330 if (!is_initialized_) {
1331 queued_messages_.push(msg);
1339 if (child_process_launcher_.get() && child_process_launcher_->IsStarting()) {
1340 queued_messages_.push(msg);
1344 return channel_->Send(msg);
1347 bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
1348 // If we're about to be deleted, or have initiated the fast shutdown sequence,
1349 // we ignore incoming messages.
1351 if (deleting_soon_ || fast_shutdown_started_)
1354 mark_child_process_activity_time();
1355 if (msg.routing_id() == MSG_ROUTING_CONTROL) {
1356 // Dispatch control messages.
1357 bool msg_is_ok = true;
1358 IPC_BEGIN_MESSAGE_MAP_EX(RenderProcessHostImpl, msg, msg_is_ok)
1359 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest,
1361 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_DumpHandlesDone,
1363 IPC_MESSAGE_HANDLER(ViewHostMsg_SuddenTerminationChanged,
1364 SuddenTerminationChanged)
1365 IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction,
1366 OnUserMetricsRecordAction)
1367 IPC_MESSAGE_HANDLER(ViewHostMsg_SavedPageAsMHTML, OnSavedPageAsMHTML)
1368 // Adding single handlers for your service here is fine, but once your
1369 // service needs more than one handler, please extract them into a new
1370 // message filter and add that filter to CreateMessageFilters().
1371 IPC_END_MESSAGE_MAP_EX()
1374 // The message had a handler, but its de-serialization failed.
1375 // We consider this a capital crime. Kill the renderer if we have one.
1376 LOG(ERROR) << "bad message " << msg.type() << " terminating renderer.";
1377 RecordAction(base::UserMetricsAction("BadMessageTerminate_BRPH"));
1378 ReceivedBadMessage();
1383 // Dispatch incoming messages to the appropriate IPC::Listener.
1384 IPC::Listener* listener = listeners_.Lookup(msg.routing_id());
1386 if (msg.is_sync()) {
1387 // The listener has gone away, so we must respond or else the caller will
1388 // hang waiting for a reply.
1389 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg);
1390 reply->set_reply_error();
1394 // If this is a SwapBuffers, we need to ack it if we're not going to handle
1395 // it so that the GPU process doesn't get stuck in unscheduled state.
1396 bool msg_is_ok = true;
1397 IPC_BEGIN_MESSAGE_MAP_EX(RenderProcessHostImpl, msg, msg_is_ok)
1398 IPC_MESSAGE_HANDLER(ViewHostMsg_CompositorSurfaceBuffersSwapped,
1399 OnCompositorSurfaceBuffersSwappedNoHost)
1400 IPC_END_MESSAGE_MAP_EX()
1403 return listener->OnMessageReceived(msg);
1406 void RenderProcessHostImpl::OnChannelConnected(int32 peer_pid) {
1407 #if defined(IPC_MESSAGE_LOG_ENABLED)
1408 Send(new ChildProcessMsg_SetIPCLoggingEnabled(
1409 IPC::Logging::GetInstance()->Enabled()));
1412 tracked_objects::ThreadData::Status status =
1413 tracked_objects::ThreadData::status();
1414 Send(new ChildProcessMsg_SetProfilerStatus(status));
1417 void RenderProcessHostImpl::OnChannelError() {
1418 ProcessDied(true /* already_dead */);
1421 BrowserContext* RenderProcessHostImpl::GetBrowserContext() const {
1422 return browser_context_;
1425 bool RenderProcessHostImpl::InSameStoragePartition(
1426 StoragePartition* partition) const {
1427 return storage_partition_impl_ == partition;
1430 int RenderProcessHostImpl::GetID() const {
1434 bool RenderProcessHostImpl::HasConnection() const {
1435 return channel_.get() != NULL;
1438 void RenderProcessHostImpl::SetIgnoreInputEvents(bool ignore_input_events) {
1439 ignore_input_events_ = ignore_input_events;
1442 bool RenderProcessHostImpl::IgnoreInputEvents() const {
1443 return ignore_input_events_;
1446 void RenderProcessHostImpl::Cleanup() {
1447 // If within_process_died_observer_ is true, one of our observers performed an
1448 // action that caused us to die (e.g. http://crbug.com/339504). Therefore,
1449 // delay the destruction until all of the observer callbacks have been made,
1450 // and guarantee that the RenderProcessHostDestroyed observer callback is
1451 // always the last callback fired.
1452 if (within_process_died_observer_) {
1453 delayed_cleanup_needed_ = true;
1456 delayed_cleanup_needed_ = false;
1458 // When there are no other owners of this object, we can delete ourselves.
1459 if (listeners_.IsEmpty()) {
1460 // We cannot clean up twice; if this fails, there is an issue with our
1462 DCHECK(!deleting_soon_);
1464 DCHECK_EQ(0, pending_views_);
1465 FOR_EACH_OBSERVER(RenderProcessHostObserver,
1467 RenderProcessHostDestroyed(this));
1468 NotificationService::current()->Notify(
1469 NOTIFICATION_RENDERER_PROCESS_TERMINATED,
1470 Source<RenderProcessHost>(this),
1471 NotificationService::NoDetails());
1474 is_self_deleted_ = true;
1476 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
1477 deleting_soon_ = true;
1478 // It's important not to wait for the DeleteTask to delete the channel
1479 // proxy. Kill it off now. That way, in case the profile is going away, the
1480 // rest of the objects attached to this RenderProcessHost start going
1481 // away first, since deleting the channel proxy will post a
1482 // OnChannelClosed() to IPC::ChannelProxy::Context on the IO thread.
1484 gpu_message_filter_ = NULL;
1485 message_port_message_filter_ = NULL;
1486 geolocation_dispatcher_host_ = NULL;
1488 // Remove ourself from the list of renderer processes so that we can't be
1489 // reused in between now and when the Delete task runs.
1490 UnregisterHost(GetID());
1494 void RenderProcessHostImpl::AddPendingView() {
1498 void RenderProcessHostImpl::RemovePendingView() {
1499 DCHECK(pending_views_);
1503 void RenderProcessHostImpl::SetSuddenTerminationAllowed(bool enabled) {
1504 sudden_termination_allowed_ = enabled;
1507 bool RenderProcessHostImpl::SuddenTerminationAllowed() const {
1508 return sudden_termination_allowed_;
1511 base::TimeDelta RenderProcessHostImpl::GetChildProcessIdleTime() const {
1512 return base::TimeTicks::Now() - child_process_activity_time_;
1515 void RenderProcessHostImpl::ResumeRequestsForView(int route_id) {
1516 widget_helper_->ResumeRequestsForView(route_id);
1519 void RenderProcessHostImpl::FilterURL(bool empty_allowed, GURL* url) {
1520 FilterURL(this, empty_allowed, url);
1523 #if defined(ENABLE_WEBRTC)
1524 void RenderProcessHostImpl::EnableAecDump(const base::FilePath& file) {
1525 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1526 BrowserThread::PostTaskAndReplyWithResult(
1527 BrowserThread::FILE, FROM_HERE,
1528 base::Bind(&CreateAecDumpFileForProcess, file, GetHandle()),
1529 base::Bind(&RenderProcessHostImpl::SendAecDumpFileToRenderer,
1530 weak_factory_.GetWeakPtr()));
1533 void RenderProcessHostImpl::DisableAecDump() {
1534 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1535 // Posting on the FILE thread and then replying back on the UI thread is only
1536 // for avoiding races between enable and disable. Nothing is done on the FILE
1538 BrowserThread::PostTaskAndReply(
1539 BrowserThread::FILE, FROM_HERE,
1540 base::Bind(&DisableAecDumpOnFileThread),
1541 base::Bind(&RenderProcessHostImpl::SendDisableAecDumpToRenderer,
1542 weak_factory_.GetWeakPtr()));
1545 void RenderProcessHostImpl::SetWebRtcLogMessageCallback(
1546 base::Callback<void(const std::string&)> callback) {
1547 webrtc_log_message_callback_ = callback;
1551 IPC::ChannelProxy* RenderProcessHostImpl::GetChannel() {
1552 return channel_.get();
1555 void RenderProcessHostImpl::AddFilter(BrowserMessageFilter* filter) {
1556 channel_->AddFilter(filter->GetFilter());
1559 bool RenderProcessHostImpl::FastShutdownForPageCount(size_t count) {
1560 if (static_cast<size_t>(GetActiveViewCount()) == count)
1561 return FastShutdownIfPossible();
1565 bool RenderProcessHostImpl::FastShutdownStarted() const {
1566 return fast_shutdown_started_;
1570 void RenderProcessHostImpl::RegisterHost(int host_id, RenderProcessHost* host) {
1571 g_all_hosts.Get().AddWithID(host, host_id);
1575 void RenderProcessHostImpl::UnregisterHost(int host_id) {
1576 RenderProcessHost* host = g_all_hosts.Get().Lookup(host_id);
1580 g_all_hosts.Get().Remove(host_id);
1582 // Look up the map of site to process for the given browser_context,
1583 // in case we need to remove this process from it. It will be registered
1584 // under any sites it rendered that use process-per-site mode.
1585 SiteProcessMap* map =
1586 GetSiteProcessMapForBrowserContext(host->GetBrowserContext());
1587 map->RemoveProcess(host);
1591 void RenderProcessHostImpl::FilterURL(RenderProcessHost* rph,
1594 ChildProcessSecurityPolicyImpl* policy =
1595 ChildProcessSecurityPolicyImpl::GetInstance();
1597 if (empty_allowed && url->is_empty())
1600 // The browser process should never hear the swappedout:// URL from any
1601 // of the renderer's messages. Check for this in debug builds, but don't
1602 // let it crash a release browser.
1603 DCHECK(GURL(kSwappedOutURL) != *url);
1605 if (!url->is_valid()) {
1606 // Have to use about:blank for the denied case, instead of an empty GURL.
1607 // This is because the browser treats navigation to an empty GURL as a
1608 // navigation to the home page. This is often a privileged page
1609 // (chrome://newtab/) which is exactly what we don't want.
1610 *url = GURL(kAboutBlankURL);
1611 RecordAction(base::UserMetricsAction("FilterURLTermiate_Invalid"));
1615 if (url->SchemeIs(chrome::kAboutScheme)) {
1616 // The renderer treats all URLs in the about: scheme as being about:blank.
1617 // Canonicalize about: URLs to about:blank.
1618 *url = GURL(kAboutBlankURL);
1619 RecordAction(base::UserMetricsAction("FilterURLTermiate_About"));
1622 // Do not allow browser plugin guests to navigate to non-web URLs, since they
1623 // cannot swap processes or grant bindings.
1624 bool non_web_url_in_guest = rph->IsGuest() &&
1625 !(url->is_valid() && policy->IsWebSafeScheme(url->scheme()));
1627 if (non_web_url_in_guest || !policy->CanRequestURL(rph->GetID(), *url)) {
1628 // If this renderer is not permitted to request this URL, we invalidate the
1629 // URL. This prevents us from storing the blocked URL and becoming confused
1631 VLOG(1) << "Blocked URL " << url->spec();
1632 *url = GURL(kAboutBlankURL);
1633 RecordAction(base::UserMetricsAction("FilterURLTermiate_Blocked"));
1638 bool RenderProcessHostImpl::IsSuitableHost(
1639 RenderProcessHost* host,
1640 BrowserContext* browser_context,
1641 const GURL& site_url) {
1642 if (run_renderer_in_process())
1645 if (host->GetBrowserContext() != browser_context)
1648 // Do not allow sharing of guest hosts. This is to prevent bugs where guest
1649 // and non-guest storage gets mixed. In the future, we might consider enabling
1650 // the sharing of guests, in this case this check should be removed and
1651 // InSameStoragePartition should handle the possible sharing.
1652 if (host->IsGuest())
1655 // Check whether the given host and the intended site_url will be using the
1656 // same StoragePartition, since a RenderProcessHost can only support a single
1657 // StoragePartition. This is relevant for packaged apps and isolated sites.
1658 StoragePartition* dest_partition =
1659 BrowserContext::GetStoragePartitionForSite(browser_context, site_url);
1660 if (!host->InSameStoragePartition(dest_partition))
1663 if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
1665 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL(
1666 browser_context, site_url)) {
1670 return GetContentClient()->browser()->IsSuitableHost(host, site_url);
1674 bool RenderProcessHost::run_renderer_in_process() {
1675 return g_run_renderer_in_process_;
1679 void RenderProcessHost::SetRunRendererInProcess(bool value) {
1680 g_run_renderer_in_process_ = value;
1682 CommandLine* command_line = CommandLine::ForCurrentProcess();
1684 if (!command_line->HasSwitch(switches::kLang)) {
1685 // Modify the current process' command line to include the browser locale,
1686 // as the renderer expects this flag to be set.
1687 const std::string locale =
1688 GetContentClient()->browser()->GetApplicationLocale();
1689 command_line->AppendSwitchASCII(switches::kLang, locale);
1691 // TODO(piman): we should really send configuration through bools rather
1692 // than by parsing strings, i.e. sending an IPC rather than command line
1693 // args. crbug.com/314909
1694 AppendGpuCommandLineFlags(command_line);
1699 RenderProcessHost::iterator RenderProcessHost::AllHostsIterator() {
1700 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1701 return iterator(g_all_hosts.Pointer());
1705 RenderProcessHost* RenderProcessHost::FromID(int render_process_id) {
1706 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1707 return g_all_hosts.Get().Lookup(render_process_id);
1711 bool RenderProcessHost::ShouldTryToUseExistingProcessHost(
1712 BrowserContext* browser_context, const GURL& url) {
1714 // If --enable-strict-site-isolation or --site-per-process is enabled, do not
1715 // try to reuse renderer processes when over the limit. (We could allow pages
1716 // from the same site to share, if we knew what the given process was
1717 // dedicated to. Allowing no sharing is simpler for now.) This may cause
1718 // resource exhaustion issues if too many sites are open at once.
1719 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1720 if (command_line.HasSwitch(switches::kEnableStrictSiteIsolation) ||
1721 command_line.HasSwitch(switches::kSitePerProcess))
1724 if (run_renderer_in_process())
1727 // NOTE: Sometimes it's necessary to create more render processes than
1728 // GetMaxRendererProcessCount(), for instance when we want to create
1729 // a renderer process for a browser context that has no existing
1730 // renderers. This is OK in moderation, since the
1731 // GetMaxRendererProcessCount() is conservative.
1732 if (g_all_hosts.Get().size() >= GetMaxRendererProcessCount())
1735 return GetContentClient()->browser()->
1736 ShouldTryToUseExistingProcessHost(browser_context, url);
1740 RenderProcessHost* RenderProcessHost::GetExistingProcessHost(
1741 BrowserContext* browser_context,
1742 const GURL& site_url) {
1743 // First figure out which existing renderers we can use.
1744 std::vector<RenderProcessHost*> suitable_renderers;
1745 suitable_renderers.reserve(g_all_hosts.Get().size());
1747 iterator iter(AllHostsIterator());
1748 while (!iter.IsAtEnd()) {
1749 if (RenderProcessHostImpl::IsSuitableHost(
1750 iter.GetCurrentValue(),
1751 browser_context, site_url))
1752 suitable_renderers.push_back(iter.GetCurrentValue());
1757 // Now pick a random suitable renderer, if we have any.
1758 if (!suitable_renderers.empty()) {
1759 int suitable_count = static_cast<int>(suitable_renderers.size());
1760 int random_index = base::RandInt(0, suitable_count - 1);
1761 return suitable_renderers[random_index];
1768 bool RenderProcessHost::ShouldUseProcessPerSite(
1769 BrowserContext* browser_context,
1771 // Returns true if we should use the process-per-site model. This will be
1772 // the case if the --process-per-site switch is specified, or in
1773 // process-per-site-instance for particular sites (e.g., WebUI).
1774 // Note that --single-process is handled in ShouldTryToUseExistingProcessHost.
1775 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1776 if (command_line.HasSwitch(switches::kProcessPerSite))
1779 // We want to consolidate particular sites like WebUI even when we are using
1780 // the process-per-tab or process-per-site-instance models.
1781 // Note: DevTools pages have WebUI type but should not reuse the same host.
1782 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
1783 browser_context, url) &&
1784 !url.SchemeIs(kChromeDevToolsScheme)) {
1788 // Otherwise let the content client decide, defaulting to false.
1789 return GetContentClient()->browser()->ShouldUseProcessPerSite(browser_context,
1794 RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSite(
1795 BrowserContext* browser_context,
1797 // Look up the map of site to process for the given browser_context.
1798 SiteProcessMap* map =
1799 GetSiteProcessMapForBrowserContext(browser_context);
1801 // See if we have an existing process with appropriate bindings for this site.
1802 // If not, the caller should create a new process and register it.
1803 std::string site = SiteInstance::GetSiteForURL(browser_context, url)
1804 .possibly_invalid_spec();
1805 RenderProcessHost* host = map->FindProcess(site);
1806 if (host && !IsSuitableHost(host, browser_context, url)) {
1807 // The registered process does not have an appropriate set of bindings for
1808 // the url. Remove it from the map so we can register a better one.
1810 base::UserMetricsAction("BindingsMismatch_GetProcessHostPerSite"));
1811 map->RemoveProcess(host);
1818 void RenderProcessHostImpl::RegisterProcessHostForSite(
1819 BrowserContext* browser_context,
1820 RenderProcessHost* process,
1822 // Look up the map of site to process for the given browser_context.
1823 SiteProcessMap* map =
1824 GetSiteProcessMapForBrowserContext(browser_context);
1826 // Only register valid, non-empty sites. Empty or invalid sites will not
1827 // use process-per-site mode. We cannot check whether the process has
1828 // appropriate bindings here, because the bindings have not yet been granted.
1829 std::string site = SiteInstance::GetSiteForURL(browser_context, url)
1830 .possibly_invalid_spec();
1832 map->RegisterProcess(site, process);
1835 void RenderProcessHostImpl::ProcessDied(bool already_dead) {
1836 // Our child process has died. If we didn't expect it, it's a crash.
1837 // In any case, we need to let everyone know it's gone.
1838 // The OnChannelError notification can fire multiple times due to nested sync
1839 // calls to a renderer. If we don't have a valid channel here it means we
1840 // already handled the error.
1842 // It should not be possible for us to be called re-entrantly.
1843 DCHECK(!within_process_died_observer_);
1845 // It should not be possible for a process death notification to come in while
1847 DCHECK(!deleting_soon_);
1849 // child_process_launcher_ can be NULL in single process mode or if fast
1850 // termination happened.
1852 base::TerminationStatus status =
1853 child_process_launcher_.get() ?
1854 child_process_launcher_->GetChildTerminationStatus(already_dead,
1856 base::TERMINATION_STATUS_NORMAL_TERMINATION;
1858 RendererClosedDetails details(GetHandle(), status, exit_code);
1859 within_process_died_observer_ = true;
1860 NotificationService::current()->Notify(
1861 NOTIFICATION_RENDERER_PROCESS_CLOSED,
1862 Source<RenderProcessHost>(this),
1863 Details<RendererClosedDetails>(&details));
1864 FOR_EACH_OBSERVER(RenderProcessHostObserver,
1866 RenderProcessExited(this, GetHandle(), status, exit_code));
1867 within_process_died_observer_ = false;
1869 child_process_launcher_.reset();
1871 gpu_message_filter_ = NULL;
1872 message_port_message_filter_ = NULL;
1873 geolocation_dispatcher_host_ = NULL;
1875 IDMap<IPC::Listener>::iterator iter(&listeners_);
1876 while (!iter.IsAtEnd()) {
1877 iter.GetCurrentValue()->OnMessageReceived(
1878 ViewHostMsg_RenderProcessGone(iter.GetCurrentKey(),
1879 static_cast<int>(status),
1884 ClearTransportDIBCache();
1886 // It's possible that one of the calls out to the observers might have caused
1887 // this object to be no longer needed.
1888 if (delayed_cleanup_needed_)
1891 // This object is not deleted at this point and might be reused later.
1892 // TODO(darin): clean this up
1895 int RenderProcessHostImpl::GetActiveViewCount() {
1896 int num_active_views = 0;
1897 scoped_ptr<RenderWidgetHostIterator> widgets(
1898 RenderWidgetHost::GetRenderWidgetHosts());
1899 while (RenderWidgetHost* widget = widgets->GetNextHost()) {
1900 // Count only RenderWidgetHosts in this process.
1901 if (widget->GetProcess()->GetID() == GetID())
1904 return num_active_views;
1907 // Frame subscription API for this class is for accelerated composited path
1908 // only. These calls are redirected to GpuMessageFilter.
1909 void RenderProcessHostImpl::BeginFrameSubscription(
1911 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
1912 if (!gpu_message_filter_)
1914 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
1915 &GpuMessageFilter::BeginFrameSubscription,
1916 gpu_message_filter_,
1917 route_id, base::Passed(&subscriber)));
1920 void RenderProcessHostImpl::EndFrameSubscription(int route_id) {
1921 if (!gpu_message_filter_)
1923 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
1924 &GpuMessageFilter::EndFrameSubscription,
1925 gpu_message_filter_,
1929 #if defined(ENABLE_WEBRTC)
1930 void RenderProcessHostImpl::WebRtcLogMessage(const std::string& message) {
1931 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1932 if (!webrtc_log_message_callback_.is_null())
1933 webrtc_log_message_callback_.Run(message);
1937 void RenderProcessHostImpl::OnShutdownRequest() {
1938 // Don't shut down if there are active RenderViews, or if there are pending
1939 // RenderViews being swapped back in.
1940 // In single process mode, we never shutdown the renderer.
1941 int num_active_views = GetActiveViewCount();
1942 if (pending_views_ || num_active_views > 0 || run_renderer_in_process())
1945 // Notify any contents that might have swapped out renderers from this
1946 // process. They should not attempt to swap them back in.
1947 NotificationService::current()->Notify(
1948 NOTIFICATION_RENDERER_PROCESS_CLOSING,
1949 Source<RenderProcessHost>(this),
1950 NotificationService::NoDetails());
1952 Send(new ChildProcessMsg_Shutdown());
1955 void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) {
1956 SetSuddenTerminationAllowed(enabled);
1959 void RenderProcessHostImpl::OnDumpHandlesDone() {
1963 void RenderProcessHostImpl::SetBackgrounded(bool backgrounded) {
1964 // Note: we always set the backgrounded_ value. If the process is NULL
1965 // (and hence hasn't been created yet), we will set the process priority
1966 // later when we create the process.
1967 backgrounded_ = backgrounded;
1968 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting())
1972 // The cbstext.dll loads as a global GetMessage hook in the browser process
1973 // and intercepts/unintercepts the kernel32 API SetPriorityClass in a
1974 // background thread. If the UI thread invokes this API just when it is
1975 // intercepted the stack is messed up on return from the interceptor
1976 // which causes random crashes in the browser process. Our hack for now
1977 // is to not invoke the SetPriorityClass API if the dll is loaded.
1978 if (GetModuleHandle(L"cbstext.dll"))
1982 child_process_launcher_->SetProcessBackgrounded(backgrounded);
1985 void RenderProcessHostImpl::OnProcessLaunched() {
1986 // No point doing anything, since this object will be destructed soon. We
1987 // especially don't want to send the RENDERER_PROCESS_CREATED notification,
1988 // since some clients might expect a RENDERER_PROCESS_TERMINATED afterwards to
1989 // properly cleanup.
1993 if (child_process_launcher_) {
1994 if (!child_process_launcher_->GetHandle()) {
1999 child_process_launcher_->SetProcessBackgrounded(backgrounded_);
2002 // NOTE: This needs to be before sending queued messages because
2003 // ExtensionService uses this notification to initialize the renderer process
2004 // with state that must be there before any JavaScript executes.
2006 // The queued messages contain such things as "navigate". If this notification
2007 // was after, we can end up executing JavaScript before the initialization
2009 NotificationService::current()->Notify(
2010 NOTIFICATION_RENDERER_PROCESS_CREATED,
2011 Source<RenderProcessHost>(this),
2012 NotificationService::NoDetails());
2014 while (!queued_messages_.empty()) {
2015 Send(queued_messages_.front());
2016 queued_messages_.pop();
2019 #if defined(ENABLE_WEBRTC)
2020 if (WebRTCInternals::GetInstance()->aec_dump_enabled())
2021 EnableAecDump(WebRTCInternals::GetInstance()->aec_dump_file_path());
2025 scoped_refptr<AudioRendererHost>
2026 RenderProcessHostImpl::audio_renderer_host() const {
2027 return audio_renderer_host_;
2030 void RenderProcessHostImpl::OnUserMetricsRecordAction(
2031 const std::string& action) {
2032 RecordComputedAction(action);
2035 void RenderProcessHostImpl::OnSavedPageAsMHTML(int job_id, int64 data_size) {
2036 MHTMLGenerationManager::GetInstance()->MHTMLGenerated(job_id, data_size);
2039 void RenderProcessHostImpl::OnCompositorSurfaceBuffersSwappedNoHost(
2040 const ViewHostMsg_CompositorSurfaceBuffersSwapped_Params& params) {
2041 TRACE_EVENT0("renderer_host",
2042 "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwappedNoHost");
2043 if (!ui::LatencyInfo::Verify(params.latency_info,
2044 "ViewHostMsg_CompositorSurfaceBuffersSwapped"))
2046 AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
2047 ack_params.sync_point = 0;
2048 RenderWidgetHostImpl::AcknowledgeBufferPresent(params.route_id,
2049 params.gpu_process_host_id,
2053 void RenderProcessHostImpl::OnGpuSwitching() {
2054 // We are updating all widgets including swapped out ones.
2055 scoped_ptr<RenderWidgetHostIterator> widgets(
2056 RenderWidgetHostImpl::GetAllRenderWidgetHosts());
2057 while (RenderWidgetHost* widget = widgets->GetNextHost()) {
2058 if (!widget->IsRenderView())
2061 // Skip widgets in other processes.
2062 if (widget->GetProcess()->GetID() != GetID())
2065 RenderViewHost* rvh = RenderViewHost::From(widget);
2066 rvh->UpdateWebkitPreferences(rvh->GetWebkitPreferences());
2070 #if defined(ENABLE_WEBRTC)
2071 void RenderProcessHostImpl::SendAecDumpFileToRenderer(
2072 IPC::PlatformFileForTransit file_for_transit) {
2073 if (file_for_transit == IPC::InvalidPlatformFileForTransit())
2075 Send(new MediaStreamMsg_EnableAecDump(file_for_transit));
2078 void RenderProcessHostImpl::SendDisableAecDumpToRenderer() {
2079 Send(new MediaStreamMsg_DisableAecDump());
2083 } // namespace content