IndexedDBFactory now ForceCloses databases.
[chromium-blink-merge.git] / content / browser / renderer_host / render_process_host_impl.cc
blobd795a6e67f969533af3efbcacf11bdce5f55ae31
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"
10 #include <algorithm>
11 #include <limits>
12 #include <vector>
14 #if defined(OS_POSIX)
15 #include <utility> // for pair<>
16 #endif
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/gpu/gpu_messages.h"
111 #include "content/common/resource_messages.h"
112 #include "content/common/view_messages.h"
113 #include "content/port/browser/render_widget_host_view_frame_subscriber.h"
114 #include "content/public/browser/browser_context.h"
115 #include "content/public/browser/content_browser_client.h"
116 #include "content/public/browser/notification_service.h"
117 #include "content/public/browser/notification_types.h"
118 #include "content/public/browser/render_process_host_factory.h"
119 #include "content/public/browser/render_process_host_observer.h"
120 #include "content/public/browser/render_widget_host.h"
121 #include "content/public/browser/render_widget_host_iterator.h"
122 #include "content/public/browser/resource_context.h"
123 #include "content/public/browser/user_metrics.h"
124 #include "content/public/common/content_constants.h"
125 #include "content/public/common/content_switches.h"
126 #include "content/public/common/process_type.h"
127 #include "content/public/common/result_codes.h"
128 #include "content/public/common/url_constants.h"
129 #include "gpu/command_buffer/service/gpu_switches.h"
130 #include "ipc/ipc_channel.h"
131 #include "ipc/ipc_logging.h"
132 #include "ipc/ipc_switches.h"
133 #include "media/base/media_switches.h"
134 #include "net/url_request/url_request_context_getter.h"
135 #include "ppapi/shared_impl/ppapi_switches.h"
136 #include "ui/base/ui_base_switches.h"
137 #include "ui/events/event_switches.h"
138 #include "ui/gfx/switches.h"
139 #include "ui/gl/gl_switches.h"
140 #include "webkit/browser/fileapi/sandbox_file_system_backend.h"
141 #include "webkit/common/resource_type.h"
143 #if defined(OS_WIN)
144 #include "base/win/scoped_com_initializer.h"
145 #include "content/common/font_cache_dispatcher_win.h"
146 #include "content/common/sandbox_win.h"
147 #include "content/public/common/sandboxed_process_launcher_delegate.h"
148 #endif
150 #if defined(ENABLE_WEBRTC)
151 #include "content/browser/media/webrtc_internals.h"
152 #include "content/browser/renderer_host/media/webrtc_identity_service_host.h"
153 #include "content/common/media/media_stream_messages.h"
154 #endif
156 #include "third_party/skia/include/core/SkBitmap.h"
158 extern bool g_exited_main_message_loop;
160 static const char* kSiteProcessMapKeyName = "content_site_process_map";
162 namespace content {
163 namespace {
165 void CacheShaderInfo(int32 id, base::FilePath path) {
166 ShaderCacheFactory::GetInstance()->SetCacheInfo(id, path);
169 void RemoveShaderInfo(int32 id) {
170 ShaderCacheFactory::GetInstance()->RemoveCacheInfo(id);
173 net::URLRequestContext* GetRequestContext(
174 scoped_refptr<net::URLRequestContextGetter> request_context,
175 scoped_refptr<net::URLRequestContextGetter> media_request_context,
176 ResourceType::Type resource_type) {
177 // If the request has resource type of ResourceType::MEDIA, we use a request
178 // context specific to media for handling it because these resources have
179 // specific needs for caching.
180 if (resource_type == ResourceType::MEDIA)
181 return media_request_context->GetURLRequestContext();
182 return request_context->GetURLRequestContext();
185 void GetContexts(
186 ResourceContext* resource_context,
187 scoped_refptr<net::URLRequestContextGetter> request_context,
188 scoped_refptr<net::URLRequestContextGetter> media_request_context,
189 const ResourceHostMsg_Request& request,
190 ResourceContext** resource_context_out,
191 net::URLRequestContext** request_context_out) {
192 *resource_context_out = resource_context;
193 *request_context_out =
194 GetRequestContext(request_context, media_request_context,
195 request.resource_type);
198 #if defined(ENABLE_WEBRTC)
199 // Creates a file used for diagnostic echo canceller recordings for handing
200 // over to the renderer.
201 IPC::PlatformFileForTransit CreateAecDumpFileForProcess(
202 base::FilePath file_path,
203 base::ProcessHandle process) {
204 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
205 base::PlatformFileError error = base::PLATFORM_FILE_OK;
206 base::PlatformFile aec_dump_file = base::CreatePlatformFile(
207 file_path,
208 base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE,
209 NULL,
210 &error);
211 if (error != base::PLATFORM_FILE_OK) {
212 VLOG(1) << "Could not open AEC dump file, error=" << error;
213 return IPC::InvalidPlatformFileForTransit();
215 return IPC::GetFileHandleForProcess(aec_dump_file, process, true);
218 // Does nothing. Just to avoid races between enable and disable.
219 void DisableAecDumpOnFileThread() {
220 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
223 #endif
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 {
235 public:
236 typedef base::hash_map<std::string, RenderProcessHost*> SiteToProcessMap;
237 SiteProcessMap() {}
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);
245 if (i != map_.end())
246 return i->second;
247 return NULL;
250 void RemoveProcess(RenderProcessHost* host) {
251 // Find all instances of this process in the map, then separately remove
252 // them.
253 std::set<std::string> sites;
254 for (SiteToProcessMap::const_iterator i = map_.begin();
255 i != map_.end();
256 i++) {
257 if (i->second == host)
258 sites.insert(i->first);
260 for (std::set<std::string>::iterator i = sites.begin();
261 i != sites.end();
262 i++) {
263 SiteToProcessMap::iterator iter = map_.find(*i);
264 if (iter != map_.end()) {
265 DCHECK_EQ(iter->second, host);
266 map_.erase(iter);
271 private:
272 SiteToProcessMap map_;
275 // Find the SiteProcessMap specific to the given context.
276 SiteProcessMap* GetSiteProcessMapForBrowserContext(BrowserContext* context) {
277 DCHECK(context);
278 SiteProcessMap* map = static_cast<SiteProcessMap*>(
279 context->GetUserData(kSiteProcessMapKeyName));
280 if (!map) {
281 map = new SiteProcessMap();
282 context->SetUserData(kSiteProcessMapKeyName, map);
284 return map;
287 #if defined(OS_WIN)
288 // NOTE: changes to this class need to be reviewed by the security team.
289 class RendererSandboxedProcessLauncherDelegate
290 : public content::SandboxedProcessLauncherDelegate {
291 public:
292 RendererSandboxedProcessLauncherDelegate() {}
293 virtual ~RendererSandboxedProcessLauncherDelegate() {}
295 virtual void PreSpawnTarget(sandbox::TargetPolicy* policy,
296 bool* success) {
297 AddBaseHandleClosePolicy(policy);
298 GetContentClient()->browser()->PreSpawnRenderer(policy, success);
301 #endif // OS_WIN
303 } // namespace
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;
314 base::MessageLoop*
315 RenderProcessHostImpl::GetInProcessRendererThreadForTesting() {
316 return g_in_process_thread;
319 // Stores the maximum number of renderer processes the content module can
320 // create.
321 static size_t g_max_renderer_count_override = 0;
323 // static
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:
338 // 128 MB -> 3
339 // 512 MB -> 6
340 // 1024 MB -> 12
341 // 4096 MB -> 51
342 // 16384 MB -> 82 (kMaxRendererProcessCount)
344 static size_t max_count = 0;
345 if (!max_count) {
346 const size_t kEstimatedWebContentsMemoryUsage =
347 #if defined(ARCH_CPU_64_BITS)
348 60; // In MB
349 #else
350 40; // In MB
351 #endif
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);
359 return max_count;
362 // static
363 bool g_run_renderer_in_process_ = false;
365 // static
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,
374 bool is_guest)
375 : fast_shutdown_started_(false),
376 deleting_soon_(false),
377 #ifndef NDEBUG
378 is_self_deleted_(false),
379 #endif
380 pending_views_(0),
381 visible_widgets_(0),
382 backgrounded_(true),
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),
393 is_guest_(is_guest),
394 gpu_observer_registered_(false),
395 power_monitor_broadcaster_(this),
396 geolocation_dispatcher_host_(NULL),
397 weak_factory_(this) {
398 widget_helper_ = new RenderWidgetHelper();
400 ChildProcessSecurityPolicyImpl::GetInstance()->Add(GetID());
402 CHECK(!g_exited_main_message_loop);
403 RegisterHost(GetID(), this);
404 g_all_hosts.Get().set_check_on_null_data(true);
405 // Initialize |child_process_activity_time_| to a reasonable value.
406 mark_child_process_activity_time();
408 if (!GetBrowserContext()->IsOffTheRecord() &&
409 !CommandLine::ForCurrentProcess()->HasSwitch(
410 switches::kDisableGpuShaderDiskCache)) {
411 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
412 base::Bind(&CacheShaderInfo, GetID(),
413 storage_partition_impl_->GetPath()));
416 // Note: When we create the RenderProcessHostImpl, it's technically
417 // backgrounded, because it has no visible listeners. But the process
418 // doesn't actually exist yet, so we'll Background it later, after
419 // creation.
422 // static
423 void RenderProcessHostImpl::ShutDownInProcessRenderer() {
424 DCHECK(g_run_renderer_in_process_);
426 switch (g_all_hosts.Pointer()->size()) {
427 case 0:
428 return;
429 case 1: {
430 RenderProcessHostImpl* host = static_cast<RenderProcessHostImpl*>(
431 AllHostsIterator().GetCurrentValue());
432 FOR_EACH_OBSERVER(RenderProcessHostObserver,
433 host->observers_,
434 RenderProcessHostDestroyed(host));
435 #ifndef NDEBUG
436 host->is_self_deleted_ = true;
437 #endif
438 delete host;
439 return;
441 default:
442 NOTREACHED() << "There should be only one RenderProcessHost when running "
443 << "in-process.";
447 RenderProcessHostImpl::~RenderProcessHostImpl() {
448 #ifndef NDEBUG
449 DCHECK(is_self_deleted_)
450 << "RenderProcessHostImpl is destroyed by something other than itself";
451 #endif
453 // Make sure to clean up the in-process renderer before the channel, otherwise
454 // it may still run and have its IPCs fail, causing asserts.
455 in_process_renderer_.reset();
457 ChildProcessSecurityPolicyImpl::GetInstance()->Remove(GetID());
459 if (gpu_observer_registered_) {
460 GpuDataManagerImpl::GetInstance()->RemoveObserver(this);
461 gpu_observer_registered_ = false;
464 // We may have some unsent messages at this point, but that's OK.
465 channel_.reset();
466 while (!queued_messages_.empty()) {
467 delete queued_messages_.front();
468 queued_messages_.pop();
471 ClearTransportDIBCache();
472 UnregisterHost(GetID());
474 if (!CommandLine::ForCurrentProcess()->HasSwitch(
475 switches::kDisableGpuShaderDiskCache)) {
476 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
477 base::Bind(&RemoveShaderInfo, GetID()));
481 void RenderProcessHostImpl::EnableSendQueue() {
482 is_initialized_ = false;
485 bool RenderProcessHostImpl::Init() {
486 // calling Init() more than once does nothing, this makes it more convenient
487 // for the view host which may not be sure in some cases
488 if (channel_)
489 return true;
491 CommandLine::StringType renderer_prefix;
492 #if defined(OS_POSIX)
493 // A command prefix is something prepended to the command line of the spawned
494 // process. It is supported only on POSIX systems.
495 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
496 renderer_prefix =
497 browser_command_line.GetSwitchValueNative(switches::kRendererCmdPrefix);
498 #endif // defined(OS_POSIX)
500 #if defined(OS_LINUX)
501 int flags = renderer_prefix.empty() ? ChildProcessHost::CHILD_ALLOW_SELF :
502 ChildProcessHost::CHILD_NORMAL;
503 #else
504 int flags = ChildProcessHost::CHILD_NORMAL;
505 #endif
507 // Find the renderer before creating the channel so if this fails early we
508 // return without creating the channel.
509 base::FilePath renderer_path = ChildProcessHost::GetChildPath(flags);
510 if (renderer_path.empty())
511 return false;
513 // Setup the IPC channel.
514 const std::string channel_id =
515 IPC::Channel::GenerateVerifiedChannelID(std::string());
516 channel_.reset(
517 new IPC::ChannelProxy(channel_id,
518 IPC::Channel::MODE_SERVER,
519 this,
520 BrowserThread::GetMessageLoopProxyForThread(
521 BrowserThread::IO).get()));
523 // Call the embedder first so that their IPC filters have priority.
524 GetContentClient()->browser()->RenderProcessWillLaunch(this);
526 CreateMessageFilters();
528 if (run_renderer_in_process()) {
529 DCHECK(g_renderer_main_thread_factory);
530 // Crank up a thread and run the initialization there. With the way that
531 // messages flow between the browser and renderer, this thread is required
532 // to prevent a deadlock in single-process mode. Since the primordial
533 // thread in the renderer process runs the WebKit code and can sometimes
534 // make blocking calls to the UI thread (i.e. this thread), they need to run
535 // on separate threads.
536 in_process_renderer_.reset(g_renderer_main_thread_factory(channel_id));
538 base::Thread::Options options;
539 #if defined(OS_WIN) && !defined(OS_MACOSX)
540 // In-process plugins require this to be a UI message loop.
541 options.message_loop_type = base::MessageLoop::TYPE_UI;
542 #else
543 // We can't have multiple UI loops on Linux and Android, so we don't support
544 // in-process plugins.
545 options.message_loop_type = base::MessageLoop::TYPE_DEFAULT;
546 #endif
547 in_process_renderer_->StartWithOptions(options);
549 g_in_process_thread = in_process_renderer_->message_loop();
551 OnProcessLaunched(); // Fake a callback that the process is ready.
552 } else {
553 // Build command line for renderer. We call AppendRendererCommandLine()
554 // first so the process type argument will appear first.
555 CommandLine* cmd_line = new CommandLine(renderer_path);
556 if (!renderer_prefix.empty())
557 cmd_line->PrependWrapper(renderer_prefix);
558 AppendRendererCommandLine(cmd_line);
559 cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id);
561 // Spawn the child process asynchronously to avoid blocking the UI thread.
562 // As long as there's no renderer prefix, we can use the zygote process
563 // at this stage.
564 child_process_launcher_.reset(new ChildProcessLauncher(
565 #if defined(OS_WIN)
566 new RendererSandboxedProcessLauncherDelegate,
567 #elif defined(OS_POSIX)
568 renderer_prefix.empty(),
569 base::EnvironmentMap(),
570 channel_->TakeClientFileDescriptor(),
571 #endif
572 cmd_line,
573 GetID(),
574 this));
576 fast_shutdown_started_ = false;
579 if (!gpu_observer_registered_) {
580 gpu_observer_registered_ = true;
581 GpuDataManagerImpl::GetInstance()->AddObserver(this);
584 is_initialized_ = true;
585 return true;
588 void RenderProcessHostImpl::CreateMessageFilters() {
589 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
590 AddFilter(new ResourceSchedulerFilter(GetID()));
591 MediaInternals* media_internals = MediaInternals::GetInstance();;
592 media::AudioManager* audio_manager =
593 BrowserMainLoop::GetInstance()->audio_manager();
594 // Add BrowserPluginMessageFilter to ensure it gets the first stab at messages
595 // from guests.
596 if (supports_browser_plugin_) {
597 scoped_refptr<BrowserPluginMessageFilter> bp_message_filter(
598 new BrowserPluginMessageFilter(GetID(), IsGuest()));
599 AddFilter(bp_message_filter.get());
602 scoped_refptr<RenderMessageFilter> render_message_filter(
603 new RenderMessageFilter(
604 GetID(),
605 IsGuest(),
606 #if defined(ENABLE_PLUGINS)
607 PluginServiceImpl::GetInstance(),
608 #else
609 NULL,
610 #endif
611 GetBrowserContext(),
612 GetBrowserContext()->GetRequestContextForRenderProcess(GetID()),
613 widget_helper_.get(),
614 audio_manager,
615 media_internals,
616 storage_partition_impl_->GetDOMStorageContext()));
617 AddFilter(render_message_filter.get());
618 AddFilter(
619 new RenderFrameMessageFilter(GetID(), widget_helper_.get()));
620 BrowserContext* browser_context = GetBrowserContext();
621 ResourceContext* resource_context = browser_context->GetResourceContext();
623 scoped_refptr<net::URLRequestContextGetter> request_context(
624 browser_context->GetRequestContextForRenderProcess(GetID()));
625 scoped_refptr<net::URLRequestContextGetter> media_request_context(
626 browser_context->GetMediaRequestContextForRenderProcess(GetID()));
628 ResourceMessageFilter::GetContextsCallback get_contexts_callback(
629 base::Bind(&GetContexts, browser_context->GetResourceContext(),
630 request_context, media_request_context));
632 ResourceMessageFilter* resource_message_filter = new ResourceMessageFilter(
633 GetID(), PROCESS_TYPE_RENDERER,
634 storage_partition_impl_->GetAppCacheService(),
635 ChromeBlobStorageContext::GetFor(browser_context),
636 storage_partition_impl_->GetFileSystemContext(),
637 get_contexts_callback);
639 AddFilter(resource_message_filter);
640 MediaStreamManager* media_stream_manager =
641 BrowserMainLoop::GetInstance()->media_stream_manager();
642 AddFilter(new AudioInputRendererHost(
643 audio_manager,
644 media_stream_manager,
645 BrowserMainLoop::GetInstance()->audio_mirroring_manager(),
646 BrowserMainLoop::GetInstance()->user_input_monitor()));
647 // The AudioRendererHost needs to be available for lookup, so it's
648 // stashed in a member variable.
649 audio_renderer_host_ = new AudioRendererHost(
650 GetID(),
651 audio_manager,
652 BrowserMainLoop::GetInstance()->audio_mirroring_manager(),
653 media_internals,
654 media_stream_manager);
655 AddFilter(audio_renderer_host_);
656 AddFilter(
657 new MIDIHost(GetID(), BrowserMainLoop::GetInstance()->midi_manager()));
658 AddFilter(new MIDIDispatcherHost(GetID(), browser_context));
659 AddFilter(new VideoCaptureHost(media_stream_manager));
660 AddFilter(new AppCacheDispatcherHost(
661 storage_partition_impl_->GetAppCacheService(),
662 GetID()));
663 AddFilter(new ClipboardMessageFilter);
664 AddFilter(new DOMStorageMessageFilter(
665 GetID(),
666 storage_partition_impl_->GetDOMStorageContext()));
667 AddFilter(new IndexedDBDispatcherHost(
668 storage_partition_impl_->GetIndexedDBContext()));
670 scoped_refptr<ServiceWorkerDispatcherHost> service_worker_filter =
671 new ServiceWorkerDispatcherHost(GetID());
672 service_worker_filter->Init(
673 storage_partition_impl_->GetServiceWorkerContext());
674 AddFilter(service_worker_filter);
676 if (IsGuest()) {
677 if (!g_browser_plugin_geolocation_context.Get().get()) {
678 g_browser_plugin_geolocation_context.Get() =
679 new BrowserPluginGeolocationPermissionContext();
681 geolocation_dispatcher_host_ = GeolocationDispatcherHost::New(
682 GetID(), g_browser_plugin_geolocation_context.Get().get());
683 } else {
684 geolocation_dispatcher_host_ = GeolocationDispatcherHost::New(
685 GetID(), browser_context->GetGeolocationPermissionContext());
687 AddFilter(geolocation_dispatcher_host_);
688 gpu_message_filter_ = new GpuMessageFilter(GetID(), widget_helper_.get());
689 AddFilter(gpu_message_filter_);
690 #if defined(ENABLE_WEBRTC)
691 AddFilter(new WebRTCIdentityServiceHost(
692 GetID(), storage_partition_impl_->GetWebRTCIdentityStore()));
693 peer_connection_tracker_host_ = new PeerConnectionTrackerHost(GetID());
694 AddFilter(peer_connection_tracker_host_.get());
695 AddFilter(new MediaStreamDispatcherHost(
696 GetID(), browser_context->GetResourceContext(), media_stream_manager));
697 AddFilter(
698 new DeviceRequestMessageFilter(resource_context, media_stream_manager));
699 #endif
700 #if defined(ENABLE_PLUGINS)
701 AddFilter(new PepperRendererConnection(GetID()));
702 #endif
703 #if defined(ENABLE_INPUT_SPEECH)
704 AddFilter(new InputTagSpeechDispatcherHost(
705 IsGuest(), GetID(), storage_partition_impl_->GetURLRequestContext()));
706 #endif
707 AddFilter(new SpeechRecognitionDispatcherHost(
708 IsGuest(), GetID(), storage_partition_impl_->GetURLRequestContext()));
709 AddFilter(new FileAPIMessageFilter(
710 GetID(),
711 storage_partition_impl_->GetURLRequestContext(),
712 storage_partition_impl_->GetFileSystemContext(),
713 ChromeBlobStorageContext::GetFor(browser_context),
714 StreamContext::GetFor(browser_context)));
715 AddFilter(new FileUtilitiesMessageFilter(GetID()));
716 AddFilter(new MimeRegistryMessageFilter());
717 AddFilter(new DatabaseMessageFilter(
718 storage_partition_impl_->GetDatabaseTracker()));
719 #if defined(OS_MACOSX)
720 AddFilter(new TextInputClientMessageFilter(GetID()));
721 #elif defined(OS_WIN)
722 channel_->AddFilter(new FontCacheDispatcher());
723 #elif defined(OS_ANDROID)
724 browser_demuxer_android_ = new BrowserDemuxerAndroid();
725 AddFilter(browser_demuxer_android_);
726 #endif
728 SocketStreamDispatcherHost::GetRequestContextCallback
729 request_context_callback(
730 base::Bind(&GetRequestContext, request_context,
731 media_request_context));
733 SocketStreamDispatcherHost* socket_stream_dispatcher_host =
734 new SocketStreamDispatcherHost(
735 GetID(), request_context_callback, resource_context);
736 AddFilter(socket_stream_dispatcher_host);
738 WebSocketDispatcherHost::GetRequestContextCallback
739 websocket_request_context_callback(
740 base::Bind(&GetRequestContext, request_context,
741 media_request_context, ResourceType::SUB_RESOURCE));
743 AddFilter(new WebSocketDispatcherHost(websocket_request_context_callback));
745 message_port_message_filter_ = new MessagePortMessageFilter(
746 base::Bind(&RenderWidgetHelper::GetNextRoutingID,
747 base::Unretained(widget_helper_.get())));
748 AddFilter(message_port_message_filter_);
750 AddFilter(new WorkerMessageFilter(
751 GetID(),
752 resource_context,
753 WorkerStoragePartition(
754 storage_partition_impl_->GetURLRequestContext(),
755 storage_partition_impl_->GetMediaURLRequestContext(),
756 storage_partition_impl_->GetAppCacheService(),
757 storage_partition_impl_->GetQuotaManager(),
758 storage_partition_impl_->GetFileSystemContext(),
759 storage_partition_impl_->GetDatabaseTracker(),
760 storage_partition_impl_->GetIndexedDBContext()),
761 message_port_message_filter_));
763 #if defined(ENABLE_WEBRTC)
764 AddFilter(new P2PSocketDispatcherHost(
765 resource_context,
766 browser_context->GetRequestContextForRenderProcess(GetID())));
767 #endif
769 AddFilter(new TraceMessageFilter());
770 AddFilter(new ResolveProxyMsgHelper(
771 browser_context->GetRequestContextForRenderProcess(GetID())));
772 AddFilter(new QuotaDispatcherHost(
773 GetID(),
774 storage_partition_impl_->GetQuotaManager(),
775 GetContentClient()->browser()->CreateQuotaPermissionContext()));
776 AddFilter(new GamepadBrowserMessageFilter());
777 AddFilter(new DeviceMotionMessageFilter());
778 AddFilter(new DeviceOrientationMessageFilter());
779 AddFilter(new ProfilerMessageFilter(PROCESS_TYPE_RENDERER));
780 AddFilter(new HistogramMessageFilter());
781 #if defined(USE_TCMALLOC) && (defined(OS_LINUX) || defined(OS_ANDROID))
782 if (CommandLine::ForCurrentProcess()->HasSwitch(
783 switches::kEnableMemoryBenchmarking))
784 AddFilter(new MemoryBenchmarkMessageFilter());
785 #endif
786 AddFilter(new VibrationMessageFilter());
789 int RenderProcessHostImpl::GetNextRoutingID() {
790 return widget_helper_->GetNextRoutingID();
794 void RenderProcessHostImpl::ResumeDeferredNavigation(
795 const GlobalRequestID& request_id) {
796 widget_helper_->ResumeDeferredNavigation(request_id);
799 void RenderProcessHostImpl::AddRoute(
800 int32 routing_id,
801 IPC::Listener* listener) {
802 listeners_.AddWithID(listener, routing_id);
805 void RenderProcessHostImpl::RemoveRoute(int32 routing_id) {
806 DCHECK(listeners_.Lookup(routing_id) != NULL);
807 listeners_.Remove(routing_id);
809 #if defined(OS_WIN)
810 // Dump the handle table if handle auditing is enabled.
811 const CommandLine& browser_command_line =
812 *CommandLine::ForCurrentProcess();
813 if (browser_command_line.HasSwitch(switches::kAuditHandles) ||
814 browser_command_line.HasSwitch(switches::kAuditAllHandles)) {
815 DumpHandles();
817 // We wait to close the channels until the child process has finished
818 // dumping handles and sends us ChildProcessHostMsg_DumpHandlesDone.
819 return;
821 #endif
822 // Keep the one renderer thread around forever in single process mode.
823 if (!run_renderer_in_process())
824 Cleanup();
827 void RenderProcessHostImpl::AddObserver(RenderProcessHostObserver* observer) {
828 observers_.AddObserver(observer);
831 void RenderProcessHostImpl::RemoveObserver(
832 RenderProcessHostObserver* observer) {
833 observers_.RemoveObserver(observer);
836 bool RenderProcessHostImpl::WaitForBackingStoreMsg(
837 int render_widget_id,
838 const base::TimeDelta& max_delay,
839 IPC::Message* msg) {
840 // The post task to this thread with the process id could be in queue, and we
841 // don't want to dispatch a message before then since it will need the handle.
842 if (child_process_launcher_.get() && child_process_launcher_->IsStarting())
843 return false;
845 return widget_helper_->WaitForBackingStoreMsg(render_widget_id,
846 max_delay, msg);
849 void RenderProcessHostImpl::ReceivedBadMessage() {
850 CommandLine* command_line = CommandLine::ForCurrentProcess();
851 if (command_line->HasSwitch(switches::kDisableKillAfterBadIPC))
852 return;
854 if (run_renderer_in_process()) {
855 // In single process mode it is better if we don't suicide but just
856 // crash.
857 CHECK(false);
859 // We kill the renderer but don't include a NOTREACHED, because we want the
860 // browser to try to survive when it gets illegal messages from the renderer.
861 base::KillProcess(GetHandle(), RESULT_CODE_KILLED_BAD_MESSAGE,
862 false);
865 void RenderProcessHostImpl::WidgetRestored() {
866 // Verify we were properly backgrounded.
867 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0));
868 visible_widgets_++;
869 SetBackgrounded(false);
872 void RenderProcessHostImpl::WidgetHidden() {
873 // On startup, the browser will call Hide
874 if (backgrounded_)
875 return;
877 DCHECK_EQ(backgrounded_, (visible_widgets_ == 0));
878 visible_widgets_--;
879 DCHECK_GE(visible_widgets_, 0);
880 if (visible_widgets_ == 0) {
881 DCHECK(!backgrounded_);
882 SetBackgrounded(true);
886 int RenderProcessHostImpl::VisibleWidgetCount() const {
887 return visible_widgets_;
890 bool RenderProcessHostImpl::IsGuest() const {
891 return is_guest_;
894 StoragePartition* RenderProcessHostImpl::GetStoragePartition() const {
895 return storage_partition_impl_;
898 static void AppendGpuCommandLineFlags(CommandLine* command_line) {
899 if (content::IsThreadedCompositingEnabled())
900 command_line->AppendSwitch(switches::kEnableThreadedCompositing);
902 if (content::IsDelegatedRendererEnabled())
903 command_line->AppendSwitch(switches::kEnableDelegatedRenderer);
905 if (content::IsDeadlineSchedulingEnabled())
906 command_line->AppendSwitch(switches::kEnableDeadlineScheduling);
908 // Appending disable-gpu-feature switches due to software rendering list.
909 GpuDataManagerImpl* gpu_data_manager = GpuDataManagerImpl::GetInstance();
910 DCHECK(gpu_data_manager);
911 gpu_data_manager->AppendRendererCommandLine(command_line);
914 void RenderProcessHostImpl::AppendRendererCommandLine(
915 CommandLine* command_line) const {
916 // Pass the process type first, so it shows first in process listings.
917 command_line->AppendSwitchASCII(switches::kProcessType,
918 switches::kRendererProcess);
920 // Now send any options from our own command line we want to propagate.
921 const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
922 PropagateBrowserCommandLineToRenderer(browser_command_line, command_line);
924 // Pass on the browser locale.
925 const std::string locale =
926 GetContentClient()->browser()->GetApplicationLocale();
927 command_line->AppendSwitchASCII(switches::kLang, locale);
929 // If we run base::FieldTrials, we want to pass to their state to the
930 // renderer so that it can act in accordance with each state, or record
931 // histograms relating to the base::FieldTrial states.
932 std::string field_trial_states;
933 base::FieldTrialList::StatesToString(&field_trial_states);
934 if (!field_trial_states.empty()) {
935 command_line->AppendSwitchASCII(switches::kForceFieldTrials,
936 field_trial_states);
939 GetContentClient()->browser()->AppendExtraCommandLineSwitches(
940 command_line, GetID());
942 AppendGpuCommandLineFlags(command_line);
945 void RenderProcessHostImpl::PropagateBrowserCommandLineToRenderer(
946 const CommandLine& browser_cmd,
947 CommandLine* renderer_cmd) const {
948 // Propagate the following switches to the renderer command line (along
949 // with any associated values) if present in the browser command line.
950 static const char* const kSwitchNames[] = {
951 switches::kAudioBufferSize,
952 switches::kAuditAllHandles,
953 switches::kAuditHandles,
954 switches::kBlockCrossSiteDocuments,
955 switches::kDefaultTileWidth,
956 switches::kDefaultTileHeight,
957 switches::kDisable3DAPIs,
958 switches::kDisableAcceleratedCompositing,
959 switches::kDisableAcceleratedFixedRootBackground,
960 switches::kDisableAcceleratedScrollableFrames,
961 switches::kDisableAcceleratedVideoDecode,
962 switches::kDisableApplicationCache,
963 switches::kDisableAudio,
964 switches::kDisableBreakpad,
965 switches::kDisableCompositedScrollingForFrames,
966 switches::kDisableCompositingForFixedPosition,
967 switches::kDisableCompositingForTransition,
968 switches::kDisableDatabases,
969 switches::kDisableDeadlineScheduling,
970 switches::kDisableDelegatedRenderer,
971 switches::kDisableDesktopNotifications,
972 switches::kDisableDeviceMotion,
973 switches::kDisableDeviceOrientation,
974 switches::kDisableDirectNPAPIRequests,
975 switches::kDisableFileSystem,
976 switches::kDisableFiltersOverIPC,
977 switches::kDisableFullScreen,
978 switches::kDisableGeolocation,
979 switches::kDisableGpu,
980 switches::kDisableGpuCompositing,
981 switches::kDisableGpuVsync,
982 switches::kDisableHistogramCustomizer,
983 switches::kDisableLayerSquashing,
984 switches::kDisableLocalStorage,
985 switches::kDisableLogging,
986 switches::kDisableOpusPlayback,
987 switches::kDisablePinch,
988 switches::kDisablePrefixedEncryptedMedia,
989 switches::kDisableSeccompFilterSandbox,
990 switches::kDisableSessionStorage,
991 switches::kDisableSharedWorkers,
992 switches::kDisableSpeechInput,
993 switches::kDisableThreadedCompositing,
994 switches::kDisableTouchAdjustment,
995 switches::kDisableTouchDragDrop,
996 switches::kDisableTouchEditing,
997 switches::kDisableUniversalAcceleratedOverflowScroll,
998 switches::kDisableUnprefixedMediaSource,
999 switches::kDisableVp8AlphaPlayback,
1000 switches::kDisableWebAnimationsCSS,
1001 switches::kDisableWebKitMediaSource,
1002 switches::kDomAutomationController,
1003 switches::kEnableAcceleratedFixedRootBackground,
1004 switches::kEnableAcceleratedOverflowScroll,
1005 switches::kEnableAcceleratedScrollableFrames,
1006 switches::kEnableAccessibilityLogging,
1007 switches::kEnableBeginFrameScheduling,
1008 switches::kEnableBrowserPluginForAllViewTypes,
1009 switches::kEnableCompositedScrollingForFrames,
1010 switches::kEnableCompositingForFixedPosition,
1011 switches::kEnableCompositingForTransition,
1012 switches::kEnableDCHECK,
1013 switches::kEnableDeadlineScheduling,
1014 switches::kEnableDeferredImageDecoding,
1015 switches::kEnableDelegatedRenderer,
1016 switches::kEnableEac3Playback,
1017 switches::kEnableEncryptedMedia,
1018 switches::kEnableExperimentalCanvasFeatures,
1019 switches::kEnableExperimentalWebPlatformFeatures,
1020 switches::kEnableExperimentalWebSocket,
1021 switches::kEnableFastTextAutosizing,
1022 switches::kEnableGpuBenchmarking,
1023 switches::kEnableGPUClientLogging,
1024 switches::kEnableGpuClientTracing,
1025 switches::kEnableGPUServiceLogging,
1026 switches::kEnableHighDpiCompositingForFixedPosition,
1027 switches::kEnableHTMLImports,
1028 switches::kEnableInbandTextTracks,
1029 switches::kEnableInputModeAttribute,
1030 switches::kEnableLayerSquashing,
1031 switches::kEnableLogging,
1032 switches::kEnableMP3StreamParser,
1033 switches::kEnableMemoryBenchmarking,
1034 switches::kEnableOverlayFullscreenVideo,
1035 switches::kEnableOverlayScrollbars,
1036 switches::kEnableOverscrollNotifications,
1037 switches::kEnablePinch,
1038 switches::kEnablePreparsedJsCaching,
1039 switches::kEnablePruneGpuCommandBuffers,
1040 switches::kEnableRepaintAfterLayout,
1041 switches::kEnableServiceWorker,
1042 switches::kEnableSkiaBenchmarking,
1043 switches::kEnableSoftwareCompositing,
1044 switches::kEnableSpeechSynthesis,
1045 switches::kEnableStatsTable,
1046 switches::kEnableStrictSiteIsolation,
1047 switches::kEnableThreadedCompositing,
1048 switches::kEnableUniversalAcceleratedOverflowScroll,
1049 switches::kEnableTouchDragDrop,
1050 switches::kEnableTouchEditing,
1051 switches::kEnableViewport,
1052 switches::kEnableViewportMeta,
1053 switches::kMainFrameResizesAreOrientationChanges,
1054 switches::kEnableVtune,
1055 switches::kEnableWebAnimationsCSS,
1056 switches::kEnableWebAnimationsSVG,
1057 switches::kEnableWebGLDraftExtensions,
1058 switches::kEnableWebMIDI,
1059 switches::kForceDeviceScaleFactor,
1060 switches::kFullMemoryCrashReport,
1061 switches::kJavaScriptFlags,
1062 switches::kLoggingLevel,
1063 switches::kMaxUntiledLayerWidth,
1064 switches::kMaxUntiledLayerHeight,
1065 switches::kMemoryMetrics,
1066 switches::kNoReferrers,
1067 switches::kNoSandbox,
1068 switches::kPpapiInProcess,
1069 switches::kProfilerTiming,
1070 switches::kReduceSecurityForTesting,
1071 switches::kRegisterPepperPlugins,
1072 switches::kRendererAssertTest,
1073 switches::kRendererStartupDialog,
1074 switches::kShowPaintRects,
1075 switches::kSitePerProcess,
1076 switches::kStatsCollectionController,
1077 switches::kTestSandbox,
1078 switches::kTouchEvents,
1079 switches::kTraceToConsole,
1080 switches::kUseDiscardableMemory,
1081 // This flag needs to be propagated to the renderer process for
1082 // --in-process-webgl.
1083 switches::kUseGL,
1084 switches::kUseMobileUserAgent,
1085 switches::kUserAgent,
1086 switches::kV,
1087 switches::kVideoThreads,
1088 switches::kVModule,
1089 switches::kWebCoreLogChannels,
1090 switches::kWebGLCommandBufferSizeKb,
1091 // Please keep these in alphabetical order. Compositor switches here should
1092 // also be added to chrome/browser/chromeos/login/chrome_restart_request.cc.
1093 cc::switches::kBackgroundColorInsteadOfCheckerboard,
1094 cc::switches::kCompositeToMailbox,
1095 cc::switches::kDisableCompositedAntialiasing,
1096 cc::switches::kDisableCompositorTouchHitTesting,
1097 cc::switches::kDisableImplSidePainting,
1098 cc::switches::kDisableLCDText,
1099 cc::switches::kDisableMapImage,
1100 cc::switches::kDisableThreadedAnimation,
1101 cc::switches::kEnableGPURasterization,
1102 cc::switches::kEnableImplSidePainting,
1103 cc::switches::kEnableLCDText,
1104 cc::switches::kEnableMapImage,
1105 cc::switches::kEnablePartialSwap,
1106 cc::switches::kEnablePerTilePainting,
1107 cc::switches::kEnablePinchVirtualViewport,
1108 cc::switches::kEnableTopControlsPositionCalculation,
1109 cc::switches::kMaxTilesForInterestArea,
1110 cc::switches::kMaxUnusedResourceMemoryUsagePercentage,
1111 cc::switches::kNumRasterThreads,
1112 cc::switches::kShowCompositedLayerBorders,
1113 cc::switches::kShowFPSCounter,
1114 cc::switches::kShowLayerAnimationBounds,
1115 cc::switches::kShowNonOccludingRects,
1116 cc::switches::kShowOccludingRects,
1117 cc::switches::kShowPropertyChangedRects,
1118 cc::switches::kShowReplicaScreenSpaceRects,
1119 cc::switches::kShowScreenSpaceRects,
1120 cc::switches::kShowSurfaceDamageRects,
1121 cc::switches::kSlowDownRasterScaleFactor,
1122 cc::switches::kStrictLayerPropertyChangeChecking,
1123 cc::switches::kTopControlsHeight,
1124 cc::switches::kTopControlsHideThreshold,
1125 cc::switches::kTopControlsShowThreshold,
1126 cc::switches::kTraceOverdraw,
1127 #if defined(ENABLE_PLUGINS)
1128 switches::kEnablePepperTesting,
1129 #endif
1130 #if defined(ENABLE_WEBRTC)
1131 switches::kEnableAudioTrackProcessing,
1132 switches::kDisableDeviceEnumeration,
1133 switches::kDisableSCTPDataChannels,
1134 switches::kDisableWebRtcHWDecoding,
1135 switches::kDisableWebRtcHWEncoding,
1136 switches::kEnableWebRtcAecRecordings,
1137 switches::kEnableWebRtcHWVp8Encoding,
1138 switches::kEnableWebRtcTcpServerSocket,
1139 #endif
1140 #if defined(GOOGLE_TV)
1141 switches::kUseExternalVideoSurfaceThresholdInPixels,
1142 #endif
1143 #if defined(OS_ANDROID)
1144 switches::kDisableGestureRequirementForMediaPlayback,
1145 switches::kDisableLowEndDeviceMode,
1146 switches::kDisableWebRTC,
1147 switches::kEnableLowEndDeviceMode,
1148 switches::kEnableSpeechRecognition,
1149 switches::kHideScrollbars,
1150 switches::kMediaDrmEnableNonCompositing,
1151 switches::kNetworkCountryIso,
1152 #endif
1153 #if defined(OS_ANDROID) && defined(ARCH_CPU_X86)
1154 switches::kEnableWebAudio,
1155 #else
1156 // Need to be able to disable webaudio on other platforms where it
1157 // is enabled by default.
1158 switches::kDisableWebAudio,
1159 #endif
1160 #if defined(OS_MACOSX)
1161 // Allow this to be set when invoking the browser and relayed along.
1162 switches::kEnableSandboxLogging,
1163 #endif
1164 #if defined(OS_POSIX)
1165 switches::kChildCleanExit,
1166 #endif
1167 #if defined(OS_WIN)
1168 switches::kEnableDirectWrite,
1169 switches::kEnableHighResolutionTime,
1170 #endif
1172 renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames,
1173 arraysize(kSwitchNames));
1175 if (browser_cmd.HasSwitch(switches::kTraceStartup) &&
1176 BrowserMainLoop::GetInstance()->is_tracing_startup()) {
1177 // Pass kTraceStartup switch to renderer only if startup tracing has not
1178 // finished.
1179 renderer_cmd->AppendSwitchASCII(
1180 switches::kTraceStartup,
1181 browser_cmd.GetSwitchValueASCII(switches::kTraceStartup));
1184 // Disable databases in incognito mode.
1185 if (GetBrowserContext()->IsOffTheRecord() &&
1186 !browser_cmd.HasSwitch(switches::kDisableDatabases)) {
1187 renderer_cmd->AppendSwitch(switches::kDisableDatabases);
1188 #if defined(OS_ANDROID)
1189 renderer_cmd->AppendSwitch(switches::kDisableMediaHistoryLogging);
1190 #endif
1193 // Enforce the extra command line flags for impl-side painting.
1194 if (cc::switches::IsImplSidePaintingEnabled() &&
1195 !browser_cmd.HasSwitch(switches::kEnableDeferredImageDecoding))
1196 renderer_cmd->AppendSwitch(switches::kEnableDeferredImageDecoding);
1199 base::ProcessHandle RenderProcessHostImpl::GetHandle() const {
1200 if (run_renderer_in_process())
1201 return base::Process::Current().handle();
1203 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting())
1204 return base::kNullProcessHandle;
1206 return child_process_launcher_->GetHandle();
1209 bool RenderProcessHostImpl::FastShutdownIfPossible() {
1210 if (run_renderer_in_process())
1211 return false; // Single process mode never shutdown the renderer.
1213 if (!GetContentClient()->browser()->IsFastShutdownPossible())
1214 return false;
1216 if (!child_process_launcher_.get() ||
1217 child_process_launcher_->IsStarting() ||
1218 !GetHandle())
1219 return false; // Render process hasn't started or is probably crashed.
1221 // Test if there's an unload listener.
1222 // NOTE: It's possible that an onunload listener may be installed
1223 // while we're shutting down, so there's a small race here. Given that
1224 // the window is small, it's unlikely that the web page has much
1225 // state that will be lost by not calling its unload handlers properly.
1226 if (!SuddenTerminationAllowed())
1227 return false;
1229 // Set this before ProcessDied() so observers can tell if the render process
1230 // died due to fast shutdown versus another cause.
1231 fast_shutdown_started_ = true;
1233 ProcessDied(false /* already_dead */);
1234 return true;
1237 void RenderProcessHostImpl::DumpHandles() {
1238 #if defined(OS_WIN)
1239 Send(new ChildProcessMsg_DumpHandles());
1240 return;
1241 #endif
1243 NOTIMPLEMENTED();
1246 // This is a platform specific function for mapping a transport DIB given its id
1247 TransportDIB* RenderProcessHostImpl::MapTransportDIB(
1248 TransportDIB::Id dib_id) {
1249 #if defined(OS_WIN)
1250 // On Windows we need to duplicate the handle from the remote process
1251 HANDLE section;
1252 DuplicateHandle(GetHandle(), dib_id.handle, GetCurrentProcess(), &section,
1253 STANDARD_RIGHTS_REQUIRED | FILE_MAP_READ | FILE_MAP_WRITE,
1254 FALSE, 0);
1255 return TransportDIB::Map(section);
1256 #elif defined(TOOLKIT_GTK)
1257 return TransportDIB::Map(dib_id.shmkey);
1258 #elif defined(OS_ANDROID)
1259 return TransportDIB::Map(dib_id);
1260 #else
1261 // On POSIX, the browser allocates all DIBs and keeps a file descriptor around
1262 // for each.
1263 return widget_helper_->MapTransportDIB(dib_id);
1264 #endif
1267 TransportDIB* RenderProcessHostImpl::GetTransportDIB(
1268 TransportDIB::Id dib_id) {
1269 if (!TransportDIB::is_valid_id(dib_id))
1270 return NULL;
1272 const std::map<TransportDIB::Id, TransportDIB*>::iterator
1273 i = cached_dibs_.find(dib_id);
1274 if (i != cached_dibs_.end()) {
1275 cached_dibs_cleaner_.Reset();
1276 return i->second;
1279 TransportDIB* dib = MapTransportDIB(dib_id);
1280 if (!dib)
1281 return NULL;
1283 if (cached_dibs_.size() >= MAX_MAPPED_TRANSPORT_DIBS) {
1284 // Clean a single entry from the cache
1285 std::map<TransportDIB::Id, TransportDIB*>::iterator smallest_iterator;
1286 size_t smallest_size = std::numeric_limits<size_t>::max();
1288 for (std::map<TransportDIB::Id, TransportDIB*>::iterator
1289 i = cached_dibs_.begin(); i != cached_dibs_.end(); ++i) {
1290 if (i->second->size() <= smallest_size) {
1291 smallest_iterator = i;
1292 smallest_size = i->second->size();
1296 #if defined(TOOLKIT_GTK)
1297 smallest_iterator->second->Detach();
1298 #else
1299 delete smallest_iterator->second;
1300 #endif
1301 cached_dibs_.erase(smallest_iterator);
1304 cached_dibs_[dib_id] = dib;
1305 cached_dibs_cleaner_.Reset();
1306 return dib;
1309 void RenderProcessHostImpl::ClearTransportDIBCache() {
1310 #if defined(TOOLKIT_GTK)
1311 std::map<TransportDIB::Id, TransportDIB*>::const_iterator dib =
1312 cached_dibs_.begin();
1313 for (; dib != cached_dibs_.end(); ++dib)
1314 dib->second->Detach();
1315 #else
1316 STLDeleteContainerPairSecondPointers(
1317 cached_dibs_.begin(), cached_dibs_.end());
1318 #endif
1319 cached_dibs_.clear();
1322 bool RenderProcessHostImpl::Send(IPC::Message* msg) {
1323 if (!channel_) {
1324 if (!is_initialized_) {
1325 queued_messages_.push(msg);
1326 return true;
1327 } else {
1328 delete msg;
1329 return false;
1333 if (child_process_launcher_.get() && child_process_launcher_->IsStarting()) {
1334 queued_messages_.push(msg);
1335 return true;
1338 return channel_->Send(msg);
1341 bool RenderProcessHostImpl::OnMessageReceived(const IPC::Message& msg) {
1342 // If we're about to be deleted, or have initiated the fast shutdown sequence,
1343 // we ignore incoming messages.
1345 if (deleting_soon_ || fast_shutdown_started_)
1346 return false;
1348 mark_child_process_activity_time();
1349 if (msg.routing_id() == MSG_ROUTING_CONTROL) {
1350 // Dispatch control messages.
1351 bool msg_is_ok = true;
1352 IPC_BEGIN_MESSAGE_MAP_EX(RenderProcessHostImpl, msg, msg_is_ok)
1353 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest,
1354 OnShutdownRequest)
1355 IPC_MESSAGE_HANDLER(ChildProcessHostMsg_DumpHandlesDone,
1356 OnDumpHandlesDone)
1357 IPC_MESSAGE_HANDLER(ViewHostMsg_SuddenTerminationChanged,
1358 SuddenTerminationChanged)
1359 IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction,
1360 OnUserMetricsRecordAction)
1361 IPC_MESSAGE_HANDLER(ViewHostMsg_SavedPageAsMHTML, OnSavedPageAsMHTML)
1362 // Adding single handlers for your service here is fine, but once your
1363 // service needs more than one handler, please extract them into a new
1364 // message filter and add that filter to CreateMessageFilters().
1365 IPC_END_MESSAGE_MAP_EX()
1367 if (!msg_is_ok) {
1368 // The message had a handler, but its de-serialization failed.
1369 // We consider this a capital crime. Kill the renderer if we have one.
1370 LOG(ERROR) << "bad message " << msg.type() << " terminating renderer.";
1371 RecordAction(UserMetricsAction("BadMessageTerminate_BRPH"));
1372 ReceivedBadMessage();
1374 return true;
1377 // Dispatch incoming messages to the appropriate IPC::Listener.
1378 IPC::Listener* listener = listeners_.Lookup(msg.routing_id());
1379 if (!listener) {
1380 if (msg.is_sync()) {
1381 // The listener has gone away, so we must respond or else the caller will
1382 // hang waiting for a reply.
1383 IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg);
1384 reply->set_reply_error();
1385 Send(reply);
1388 // If this is a SwapBuffers, we need to ack it if we're not going to handle
1389 // it so that the GPU process doesn't get stuck in unscheduled state.
1390 bool msg_is_ok = true;
1391 IPC_BEGIN_MESSAGE_MAP_EX(RenderProcessHostImpl, msg, msg_is_ok)
1392 IPC_MESSAGE_HANDLER(ViewHostMsg_CompositorSurfaceBuffersSwapped,
1393 OnCompositorSurfaceBuffersSwappedNoHost)
1394 IPC_END_MESSAGE_MAP_EX()
1395 return true;
1397 return listener->OnMessageReceived(msg);
1400 void RenderProcessHostImpl::OnChannelConnected(int32 peer_pid) {
1401 #if defined(IPC_MESSAGE_LOG_ENABLED)
1402 Send(new ChildProcessMsg_SetIPCLoggingEnabled(
1403 IPC::Logging::GetInstance()->Enabled()));
1404 #endif
1406 tracked_objects::ThreadData::Status status =
1407 tracked_objects::ThreadData::status();
1408 Send(new ChildProcessMsg_SetProfilerStatus(status));
1410 Send(new ViewMsg_SetRendererProcessID(GetID()));
1413 void RenderProcessHostImpl::OnChannelError() {
1414 ProcessDied(true /* already_dead */);
1417 BrowserContext* RenderProcessHostImpl::GetBrowserContext() const {
1418 return browser_context_;
1421 bool RenderProcessHostImpl::InSameStoragePartition(
1422 StoragePartition* partition) const {
1423 return storage_partition_impl_ == partition;
1426 int RenderProcessHostImpl::GetID() const {
1427 return id_;
1430 bool RenderProcessHostImpl::HasConnection() const {
1431 return channel_.get() != NULL;
1434 void RenderProcessHostImpl::SetIgnoreInputEvents(bool ignore_input_events) {
1435 ignore_input_events_ = ignore_input_events;
1438 bool RenderProcessHostImpl::IgnoreInputEvents() const {
1439 return ignore_input_events_;
1442 void RenderProcessHostImpl::Cleanup() {
1443 // When there are no other owners of this object, we can delete ourselves.
1444 if (listeners_.IsEmpty()) {
1445 DCHECK_EQ(0, pending_views_);
1446 FOR_EACH_OBSERVER(RenderProcessHostObserver,
1447 observers_,
1448 RenderProcessHostDestroyed(this));
1449 NotificationService::current()->Notify(
1450 NOTIFICATION_RENDERER_PROCESS_TERMINATED,
1451 Source<RenderProcessHost>(this),
1452 NotificationService::NoDetails());
1454 #ifndef NDEBUG
1455 is_self_deleted_ = true;
1456 #endif
1457 base::MessageLoop::current()->DeleteSoon(FROM_HERE, this);
1458 deleting_soon_ = true;
1459 // It's important not to wait for the DeleteTask to delete the channel
1460 // proxy. Kill it off now. That way, in case the profile is going away, the
1461 // rest of the objects attached to this RenderProcessHost start going
1462 // away first, since deleting the channel proxy will post a
1463 // OnChannelClosed() to IPC::ChannelProxy::Context on the IO thread.
1464 channel_.reset();
1465 gpu_message_filter_ = NULL;
1466 message_port_message_filter_ = NULL;
1467 geolocation_dispatcher_host_ = NULL;
1469 // Remove ourself from the list of renderer processes so that we can't be
1470 // reused in between now and when the Delete task runs.
1471 UnregisterHost(GetID());
1475 void RenderProcessHostImpl::AddPendingView() {
1476 pending_views_++;
1479 void RenderProcessHostImpl::RemovePendingView() {
1480 DCHECK(pending_views_);
1481 pending_views_--;
1484 void RenderProcessHostImpl::SetSuddenTerminationAllowed(bool enabled) {
1485 sudden_termination_allowed_ = enabled;
1488 bool RenderProcessHostImpl::SuddenTerminationAllowed() const {
1489 return sudden_termination_allowed_;
1492 base::TimeDelta RenderProcessHostImpl::GetChildProcessIdleTime() const {
1493 return base::TimeTicks::Now() - child_process_activity_time_;
1496 void RenderProcessHostImpl::SurfaceUpdated(int32 surface_id) {
1497 if (!gpu_message_filter_)
1498 return;
1499 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
1500 &GpuMessageFilter::SurfaceUpdated,
1501 gpu_message_filter_,
1502 surface_id));
1505 void RenderProcessHostImpl::ResumeRequestsForView(int route_id) {
1506 widget_helper_->ResumeRequestsForView(route_id);
1509 void RenderProcessHostImpl::FilterURL(bool empty_allowed, GURL* url) {
1510 FilterURL(this, empty_allowed, url);
1513 #if defined(ENABLE_WEBRTC)
1514 void RenderProcessHostImpl::EnableAecDump(const base::FilePath& file) {
1515 BrowserThread::PostTaskAndReplyWithResult(
1516 BrowserThread::FILE, FROM_HERE,
1517 base::Bind(&CreateAecDumpFileForProcess, file, GetHandle()),
1518 base::Bind(&RenderProcessHostImpl::SendAecDumpFileToRenderer,
1519 weak_factory_.GetWeakPtr()));
1522 void RenderProcessHostImpl::DisableAecDump() {
1523 // Posting on the FILE thread and then replying back on the UI thread is only
1524 // for avoiding races between enable and disable. Nothing is done on the FILE
1525 // thread.
1526 BrowserThread::PostTaskAndReply(
1527 BrowserThread::FILE, FROM_HERE,
1528 base::Bind(&DisableAecDumpOnFileThread),
1529 base::Bind(&RenderProcessHostImpl::SendDisableAecDumpToRenderer,
1530 weak_factory_.GetWeakPtr()));
1532 #endif
1534 IPC::ChannelProxy* RenderProcessHostImpl::GetChannel() {
1535 return channel_.get();
1538 void RenderProcessHostImpl::AddFilter(BrowserMessageFilter* filter) {
1539 channel_->AddFilter(filter->GetFilter());
1542 bool RenderProcessHostImpl::FastShutdownForPageCount(size_t count) {
1543 if (static_cast<size_t>(GetActiveViewCount()) == count)
1544 return FastShutdownIfPossible();
1545 return false;
1548 bool RenderProcessHostImpl::FastShutdownStarted() const {
1549 return fast_shutdown_started_;
1552 // static
1553 void RenderProcessHostImpl::RegisterHost(int host_id, RenderProcessHost* host) {
1554 g_all_hosts.Get().AddWithID(host, host_id);
1557 // static
1558 void RenderProcessHostImpl::UnregisterHost(int host_id) {
1559 RenderProcessHost* host = g_all_hosts.Get().Lookup(host_id);
1560 if (!host)
1561 return;
1563 g_all_hosts.Get().Remove(host_id);
1565 // Look up the map of site to process for the given browser_context,
1566 // in case we need to remove this process from it. It will be registered
1567 // under any sites it rendered that use process-per-site mode.
1568 SiteProcessMap* map =
1569 GetSiteProcessMapForBrowserContext(host->GetBrowserContext());
1570 map->RemoveProcess(host);
1573 // static
1574 void RenderProcessHostImpl::FilterURL(RenderProcessHost* rph,
1575 bool empty_allowed,
1576 GURL* url) {
1577 ChildProcessSecurityPolicyImpl* policy =
1578 ChildProcessSecurityPolicyImpl::GetInstance();
1580 if (empty_allowed && url->is_empty())
1581 return;
1583 // The browser process should never hear the swappedout:// URL from any
1584 // of the renderer's messages. Check for this in debug builds, but don't
1585 // let it crash a release browser.
1586 DCHECK(GURL(kSwappedOutURL) != *url);
1588 if (!url->is_valid()) {
1589 // Have to use about:blank for the denied case, instead of an empty GURL.
1590 // This is because the browser treats navigation to an empty GURL as a
1591 // navigation to the home page. This is often a privileged page
1592 // (chrome://newtab/) which is exactly what we don't want.
1593 *url = GURL(kAboutBlankURL);
1594 RecordAction(UserMetricsAction("FilterURLTermiate_Invalid"));
1595 return;
1598 if (url->SchemeIs(chrome::kAboutScheme)) {
1599 // The renderer treats all URLs in the about: scheme as being about:blank.
1600 // Canonicalize about: URLs to about:blank.
1601 *url = GURL(kAboutBlankURL);
1602 RecordAction(UserMetricsAction("FilterURLTermiate_About"));
1605 // Do not allow browser plugin guests to navigate to non-web URLs, since they
1606 // cannot swap processes or grant bindings.
1607 bool non_web_url_in_guest = rph->IsGuest() &&
1608 !(url->is_valid() && policy->IsWebSafeScheme(url->scheme()));
1610 if (non_web_url_in_guest || !policy->CanRequestURL(rph->GetID(), *url)) {
1611 // If this renderer is not permitted to request this URL, we invalidate the
1612 // URL. This prevents us from storing the blocked URL and becoming confused
1613 // later.
1614 VLOG(1) << "Blocked URL " << url->spec();
1615 *url = GURL(kAboutBlankURL);
1616 RecordAction(UserMetricsAction("FilterURLTermiate_Blocked"));
1620 // static
1621 bool RenderProcessHostImpl::IsSuitableHost(
1622 RenderProcessHost* host,
1623 BrowserContext* browser_context,
1624 const GURL& site_url) {
1625 if (run_renderer_in_process())
1626 return true;
1628 if (host->GetBrowserContext() != browser_context)
1629 return false;
1631 // Do not allow sharing of guest hosts. This is to prevent bugs where guest
1632 // and non-guest storage gets mixed. In the future, we might consider enabling
1633 // the sharing of guests, in this case this check should be removed and
1634 // InSameStoragePartition should handle the possible sharing.
1635 if (host->IsGuest())
1636 return false;
1638 // Check whether the given host and the intended site_url will be using the
1639 // same StoragePartition, since a RenderProcessHost can only support a single
1640 // StoragePartition. This is relevant for packaged apps and isolated sites.
1641 StoragePartition* dest_partition =
1642 BrowserContext::GetStoragePartitionForSite(browser_context, site_url);
1643 if (!host->InSameStoragePartition(dest_partition))
1644 return false;
1646 if (ChildProcessSecurityPolicyImpl::GetInstance()->HasWebUIBindings(
1647 host->GetID()) !=
1648 WebUIControllerFactoryRegistry::GetInstance()->UseWebUIBindingsForURL(
1649 browser_context, site_url)) {
1650 return false;
1653 return GetContentClient()->browser()->IsSuitableHost(host, site_url);
1656 // static
1657 bool RenderProcessHost::run_renderer_in_process() {
1658 return g_run_renderer_in_process_;
1661 // static
1662 void RenderProcessHost::SetRunRendererInProcess(bool value) {
1663 g_run_renderer_in_process_ = value;
1665 CommandLine* command_line = CommandLine::ForCurrentProcess();
1666 if (value) {
1667 if (!command_line->HasSwitch(switches::kLang)) {
1668 // Modify the current process' command line to include the browser locale,
1669 // as the renderer expects this flag to be set.
1670 const std::string locale =
1671 GetContentClient()->browser()->GetApplicationLocale();
1672 command_line->AppendSwitchASCII(switches::kLang, locale);
1674 // TODO(piman): we should really send configuration through bools rather
1675 // than by parsing strings, i.e. sending an IPC rather than command line
1676 // args. crbug.com/314909
1677 AppendGpuCommandLineFlags(command_line);
1681 // static
1682 RenderProcessHost::iterator RenderProcessHost::AllHostsIterator() {
1683 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1684 return iterator(g_all_hosts.Pointer());
1687 // static
1688 RenderProcessHost* RenderProcessHost::FromID(int render_process_id) {
1689 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
1690 return g_all_hosts.Get().Lookup(render_process_id);
1693 // static
1694 bool RenderProcessHost::ShouldTryToUseExistingProcessHost(
1695 BrowserContext* browser_context, const GURL& url) {
1696 // Experimental:
1697 // If --enable-strict-site-isolation or --site-per-process is enabled, do not
1698 // try to reuse renderer processes when over the limit. (We could allow pages
1699 // from the same site to share, if we knew what the given process was
1700 // dedicated to. Allowing no sharing is simpler for now.) This may cause
1701 // resource exhaustion issues if too many sites are open at once.
1702 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1703 if (command_line.HasSwitch(switches::kEnableStrictSiteIsolation) ||
1704 command_line.HasSwitch(switches::kSitePerProcess))
1705 return false;
1707 if (run_renderer_in_process())
1708 return true;
1710 // NOTE: Sometimes it's necessary to create more render processes than
1711 // GetMaxRendererProcessCount(), for instance when we want to create
1712 // a renderer process for a browser context that has no existing
1713 // renderers. This is OK in moderation, since the
1714 // GetMaxRendererProcessCount() is conservative.
1715 if (g_all_hosts.Get().size() >= GetMaxRendererProcessCount())
1716 return true;
1718 return GetContentClient()->browser()->
1719 ShouldTryToUseExistingProcessHost(browser_context, url);
1722 // static
1723 RenderProcessHost* RenderProcessHost::GetExistingProcessHost(
1724 BrowserContext* browser_context,
1725 const GURL& site_url) {
1726 // First figure out which existing renderers we can use.
1727 std::vector<RenderProcessHost*> suitable_renderers;
1728 suitable_renderers.reserve(g_all_hosts.Get().size());
1730 iterator iter(AllHostsIterator());
1731 while (!iter.IsAtEnd()) {
1732 if (RenderProcessHostImpl::IsSuitableHost(
1733 iter.GetCurrentValue(),
1734 browser_context, site_url))
1735 suitable_renderers.push_back(iter.GetCurrentValue());
1737 iter.Advance();
1740 // Now pick a random suitable renderer, if we have any.
1741 if (!suitable_renderers.empty()) {
1742 int suitable_count = static_cast<int>(suitable_renderers.size());
1743 int random_index = base::RandInt(0, suitable_count - 1);
1744 return suitable_renderers[random_index];
1747 return NULL;
1750 // static
1751 bool RenderProcessHost::ShouldUseProcessPerSite(
1752 BrowserContext* browser_context,
1753 const GURL& url) {
1754 // Returns true if we should use the process-per-site model. This will be
1755 // the case if the --process-per-site switch is specified, or in
1756 // process-per-site-instance for particular sites (e.g., WebUI).
1757 // Note that --single-process is handled in ShouldTryToUseExistingProcessHost.
1758 const CommandLine& command_line = *CommandLine::ForCurrentProcess();
1759 if (command_line.HasSwitch(switches::kProcessPerSite))
1760 return true;
1762 // We want to consolidate particular sites like WebUI even when we are using
1763 // the process-per-tab or process-per-site-instance models.
1764 // Note: DevTools pages have WebUI type but should not reuse the same host.
1765 if (WebUIControllerFactoryRegistry::GetInstance()->UseWebUIForURL(
1766 browser_context, url) &&
1767 !url.SchemeIs(chrome::kChromeDevToolsScheme)) {
1768 return true;
1771 // Otherwise let the content client decide, defaulting to false.
1772 return GetContentClient()->browser()->ShouldUseProcessPerSite(browser_context,
1773 url);
1776 // static
1777 RenderProcessHost* RenderProcessHostImpl::GetProcessHostForSite(
1778 BrowserContext* browser_context,
1779 const GURL& url) {
1780 // Look up the map of site to process for the given browser_context.
1781 SiteProcessMap* map =
1782 GetSiteProcessMapForBrowserContext(browser_context);
1784 // See if we have an existing process with appropriate bindings for this site.
1785 // If not, the caller should create a new process and register it.
1786 std::string site = SiteInstance::GetSiteForURL(browser_context, url)
1787 .possibly_invalid_spec();
1788 RenderProcessHost* host = map->FindProcess(site);
1789 if (host && !IsSuitableHost(host, browser_context, url)) {
1790 // The registered process does not have an appropriate set of bindings for
1791 // the url. Remove it from the map so we can register a better one.
1792 RecordAction(UserMetricsAction("BindingsMismatch_GetProcessHostPerSite"));
1793 map->RemoveProcess(host);
1794 host = NULL;
1797 return host;
1800 void RenderProcessHostImpl::RegisterProcessHostForSite(
1801 BrowserContext* browser_context,
1802 RenderProcessHost* process,
1803 const GURL& url) {
1804 // Look up the map of site to process for the given browser_context.
1805 SiteProcessMap* map =
1806 GetSiteProcessMapForBrowserContext(browser_context);
1808 // Only register valid, non-empty sites. Empty or invalid sites will not
1809 // use process-per-site mode. We cannot check whether the process has
1810 // appropriate bindings here, because the bindings have not yet been granted.
1811 std::string site = SiteInstance::GetSiteForURL(browser_context, url)
1812 .possibly_invalid_spec();
1813 if (!site.empty())
1814 map->RegisterProcess(site, process);
1817 void RenderProcessHostImpl::ProcessDied(bool already_dead) {
1818 // Our child process has died. If we didn't expect it, it's a crash.
1819 // In any case, we need to let everyone know it's gone.
1820 // The OnChannelError notification can fire multiple times due to nested sync
1821 // calls to a renderer. If we don't have a valid channel here it means we
1822 // already handled the error.
1824 // child_process_launcher_ can be NULL in single process mode or if fast
1825 // termination happened.
1826 int exit_code = 0;
1827 base::TerminationStatus status =
1828 child_process_launcher_.get() ?
1829 child_process_launcher_->GetChildTerminationStatus(already_dead,
1830 &exit_code) :
1831 base::TERMINATION_STATUS_NORMAL_TERMINATION;
1833 RendererClosedDetails details(GetHandle(), status, exit_code);
1834 NotificationService::current()->Notify(
1835 NOTIFICATION_RENDERER_PROCESS_CLOSED,
1836 Source<RenderProcessHost>(this),
1837 Details<RendererClosedDetails>(&details));
1838 FOR_EACH_OBSERVER(RenderProcessHostObserver,
1839 observers_,
1840 RenderProcessExited(this, GetHandle(), status, exit_code));
1842 child_process_launcher_.reset();
1843 channel_.reset();
1844 gpu_message_filter_ = NULL;
1845 message_port_message_filter_ = NULL;
1846 geolocation_dispatcher_host_ = NULL;
1848 IDMap<IPC::Listener>::iterator iter(&listeners_);
1849 while (!iter.IsAtEnd()) {
1850 iter.GetCurrentValue()->OnMessageReceived(
1851 ViewHostMsg_RenderProcessGone(iter.GetCurrentKey(),
1852 static_cast<int>(status),
1853 exit_code));
1854 iter.Advance();
1857 ClearTransportDIBCache();
1859 // this object is not deleted at this point and may be reused later.
1860 // TODO(darin): clean this up
1863 int RenderProcessHostImpl::GetActiveViewCount() {
1864 int num_active_views = 0;
1865 scoped_ptr<RenderWidgetHostIterator> widgets(
1866 RenderWidgetHost::GetRenderWidgetHosts());
1867 while (RenderWidgetHost* widget = widgets->GetNextHost()) {
1868 // Count only RenderWidgetHosts in this process.
1869 if (widget->GetProcess()->GetID() == GetID())
1870 num_active_views++;
1872 return num_active_views;
1875 // Frame subscription API for this class is for accelerated composited path
1876 // only. These calls are redirected to GpuMessageFilter.
1877 void RenderProcessHostImpl::BeginFrameSubscription(
1878 int route_id,
1879 scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber) {
1880 if (!gpu_message_filter_)
1881 return;
1882 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
1883 &GpuMessageFilter::BeginFrameSubscription,
1884 gpu_message_filter_,
1885 route_id, base::Passed(&subscriber)));
1888 void RenderProcessHostImpl::EndFrameSubscription(int route_id) {
1889 if (!gpu_message_filter_)
1890 return;
1891 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, base::Bind(
1892 &GpuMessageFilter::EndFrameSubscription,
1893 gpu_message_filter_,
1894 route_id));
1897 void RenderProcessHostImpl::OnShutdownRequest() {
1898 // Don't shut down if there are active RenderViews, or if there are pending
1899 // RenderViews being swapped back in.
1900 // In single process mode, we never shutdown the renderer.
1901 int num_active_views = GetActiveViewCount();
1902 if (pending_views_ || num_active_views > 0 || run_renderer_in_process())
1903 return;
1905 // Notify any contents that might have swapped out renderers from this
1906 // process. They should not attempt to swap them back in.
1907 NotificationService::current()->Notify(
1908 NOTIFICATION_RENDERER_PROCESS_CLOSING,
1909 Source<RenderProcessHost>(this),
1910 NotificationService::NoDetails());
1912 Send(new ChildProcessMsg_Shutdown());
1915 void RenderProcessHostImpl::SuddenTerminationChanged(bool enabled) {
1916 SetSuddenTerminationAllowed(enabled);
1919 void RenderProcessHostImpl::OnDumpHandlesDone() {
1920 Cleanup();
1923 void RenderProcessHostImpl::SetBackgrounded(bool backgrounded) {
1924 // Note: we always set the backgrounded_ value. If the process is NULL
1925 // (and hence hasn't been created yet), we will set the process priority
1926 // later when we create the process.
1927 backgrounded_ = backgrounded;
1928 if (!child_process_launcher_.get() || child_process_launcher_->IsStarting())
1929 return;
1931 #if defined(OS_WIN)
1932 // The cbstext.dll loads as a global GetMessage hook in the browser process
1933 // and intercepts/unintercepts the kernel32 API SetPriorityClass in a
1934 // background thread. If the UI thread invokes this API just when it is
1935 // intercepted the stack is messed up on return from the interceptor
1936 // which causes random crashes in the browser process. Our hack for now
1937 // is to not invoke the SetPriorityClass API if the dll is loaded.
1938 if (GetModuleHandle(L"cbstext.dll"))
1939 return;
1940 #endif // OS_WIN
1942 child_process_launcher_->SetProcessBackgrounded(backgrounded);
1945 void RenderProcessHostImpl::OnProcessLaunched() {
1946 // No point doing anything, since this object will be destructed soon. We
1947 // especially don't want to send the RENDERER_PROCESS_CREATED notification,
1948 // since some clients might expect a RENDERER_PROCESS_TERMINATED afterwards to
1949 // properly cleanup.
1950 if (deleting_soon_)
1951 return;
1953 if (child_process_launcher_) {
1954 if (!child_process_launcher_->GetHandle()) {
1955 OnChannelError();
1956 return;
1959 child_process_launcher_->SetProcessBackgrounded(backgrounded_);
1962 // NOTE: This needs to be before sending queued messages because
1963 // ExtensionService uses this notification to initialize the renderer process
1964 // with state that must be there before any JavaScript executes.
1966 // The queued messages contain such things as "navigate". If this notification
1967 // was after, we can end up executing JavaScript before the initialization
1968 // happens.
1969 NotificationService::current()->Notify(
1970 NOTIFICATION_RENDERER_PROCESS_CREATED,
1971 Source<RenderProcessHost>(this),
1972 NotificationService::NoDetails());
1974 while (!queued_messages_.empty()) {
1975 Send(queued_messages_.front());
1976 queued_messages_.pop();
1979 #if defined(ENABLE_WEBRTC)
1980 if (WebRTCInternals::GetInstance()->aec_dump_enabled())
1981 EnableAecDump(WebRTCInternals::GetInstance()->aec_dump_file_path());
1982 #endif
1985 scoped_refptr<AudioRendererHost>
1986 RenderProcessHostImpl::audio_renderer_host() const {
1987 return audio_renderer_host_;
1990 void RenderProcessHostImpl::OnUserMetricsRecordAction(
1991 const std::string& action) {
1992 RecordComputedAction(action);
1995 void RenderProcessHostImpl::OnSavedPageAsMHTML(int job_id, int64 data_size) {
1996 MHTMLGenerationManager::GetInstance()->MHTMLGenerated(job_id, data_size);
1999 void RenderProcessHostImpl::OnCompositorSurfaceBuffersSwappedNoHost(
2000 const ViewHostMsg_CompositorSurfaceBuffersSwapped_Params& params) {
2001 TRACE_EVENT0("renderer_host",
2002 "RenderWidgetHostImpl::OnCompositorSurfaceBuffersSwappedNoHost");
2003 AcceleratedSurfaceMsg_BufferPresented_Params ack_params;
2004 ack_params.sync_point = 0;
2005 RenderWidgetHostImpl::AcknowledgeBufferPresent(params.route_id,
2006 params.gpu_process_host_id,
2007 ack_params);
2010 void RenderProcessHostImpl::OnGpuSwitching() {
2011 // We are updating all widgets including swapped out ones.
2012 scoped_ptr<RenderWidgetHostIterator> widgets(
2013 RenderWidgetHostImpl::GetAllRenderWidgetHosts());
2014 while (RenderWidgetHost* widget = widgets->GetNextHost()) {
2015 if (!widget->IsRenderView())
2016 continue;
2018 // Skip widgets in other processes.
2019 if (widget->GetProcess()->GetID() != GetID())
2020 continue;
2022 RenderViewHost* rvh = RenderViewHost::From(widget);
2023 rvh->UpdateWebkitPreferences(rvh->GetWebkitPreferences());
2027 #if defined(ENABLE_WEBRTC)
2028 void RenderProcessHostImpl::SendAecDumpFileToRenderer(
2029 IPC::PlatformFileForTransit file_for_transit) {
2030 if (file_for_transit == IPC::InvalidPlatformFileForTransit())
2031 return;
2032 Send(new MediaStreamMsg_EnableAecDump(file_for_transit));
2035 void RenderProcessHostImpl::SendDisableAecDumpToRenderer() {
2036 Send(new MediaStreamMsg_DisableAecDump());
2038 #endif
2040 } // namespace content